summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan/vk_pipeline_cache.cpp')
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp55
1 files changed, 43 insertions, 12 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index d4b0a542a..38a6b7488 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -46,6 +46,7 @@ MICROPROFILE_DECLARE(Vulkan_PipelineCache);
namespace {
using Shader::Backend::SPIRV::EmitSPIRV;
using Shader::Maxwell::ConvertLegacyToGeneric;
+using Shader::Maxwell::GenerateGeometryPassthrough;
using Shader::Maxwell::MergeDualVertexPrograms;
using Shader::Maxwell::TranslateProgram;
using VideoCommon::ComputeEnvironment;
@@ -53,13 +54,24 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment;
-constexpr u32 CACHE_VERSION = 7;
+constexpr u32 CACHE_VERSION = 8;
template <typename Container>
auto MakeSpan(Container& container) {
return std::span(container.data(), container.size());
}
+Shader::OutputTopology MaxwellToOutputTopology(Maxwell::PrimitiveTopology topology) {
+ switch (topology) {
+ case Maxwell::PrimitiveTopology::Points:
+ return Shader::OutputTopology::PointList;
+ case Maxwell::PrimitiveTopology::LineStrip:
+ return Shader::OutputTopology::LineStrip;
+ default:
+ return Shader::OutputTopology::TriangleStrip;
+ }
+}
+
Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) {
switch (comparison) {
case Maxwell::ComparisonOp::Never_D3D:
@@ -275,9 +287,9 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"),
serialization_thread(1, "VkPipelineSerialization") {
const auto& float_control{device.FloatControlProperties()};
- const VkDriverIdKHR driver_id{device.GetDriverID()};
+ const VkDriverId driver_id{device.GetDriverID()};
profile = Shader::Profile{
- .supported_spirv = device.IsKhrSpirv1_4Supported() ? 0x00010400U : 0x00010000U,
+ .supported_spirv = device.SupportedSpirvVersion(),
.unified_descriptor_binding = true,
.support_descriptor_aliasing = true,
.support_int8 = device.IsInt8Supported(),
@@ -285,10 +297,10 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_int64 = device.IsShaderInt64Supported(),
.support_vertex_instance_id = false,
.support_float_controls = true,
- .support_separate_denorm_behavior = float_control.denormBehaviorIndependence ==
- VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR,
+ .support_separate_denorm_behavior =
+ float_control.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.support_separate_rounding_mode =
- float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR,
+ float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.support_fp16_denorm_preserve = float_control.shaderDenormPreserveFloat16 != VK_FALSE,
.support_fp32_denorm_preserve = float_control.shaderDenormPreserveFloat32 != VK_FALSE,
.support_fp16_denorm_flush = float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE,
@@ -315,18 +327,19 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.lower_left_origin_mode = false,
.need_declared_frag_colors = false,
- .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR,
+ .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
.has_broken_unsigned_image_offsets = false,
.has_broken_signed_operations = false,
- .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR,
+ .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY,
.ignore_nan_fp_comparisons = false,
};
host_info = Shader::HostTranslateInfo{
.support_float16 = device.IsFloat16Supported(),
.support_int64 = device.IsShaderInt64Supported(),
- .needs_demote_reorder = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR ||
- driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR,
+ .needs_demote_reorder =
+ driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE,
.support_snorm_render_buffer = true,
+ .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
};
}
@@ -395,7 +408,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
std::unique_ptr<PipelineStatistics> statistics;
} state;
- if (device.IsKhrPipelineEexecutablePropertiesEnabled()) {
+ if (device.IsKhrPipelineExecutablePropertiesEnabled()) {
state.statistics = std::make_unique<PipelineStatistics>(device);
}
const auto load_compute{[&](std::ifstream& file, FileEnvironment env) {
@@ -509,7 +522,19 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs;
const bool uses_vertex_a{key.unique_hashes[0] != 0};
const bool uses_vertex_b{key.unique_hashes[1] != 0};
+
+ // Layer passthrough generation for devices without VK_EXT_shader_viewport_index_layer
+ Shader::IR::Program* layer_source_program{};
+
for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
+ const bool is_emulated_stage = layer_source_program != nullptr &&
+ index == static_cast<u32>(Maxwell::ShaderType::Geometry);
+ if (key.unique_hashes[index] == 0 && is_emulated_stage) {
+ auto topology = MaxwellToOutputTopology(key.state.topology);
+ programs[index] = GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
+ *layer_source_program, topology);
+ continue;
+ }
if (key.unique_hashes[index] == 0) {
continue;
}
@@ -530,6 +555,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
}
+
+ if (programs[index].info.requires_layer_emulation) {
+ layer_source_program = &programs[index];
+ }
}
std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{};
std::array<vk::ShaderModule, Maxwell::MaxShaderStage> modules;
@@ -538,7 +567,9 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
Shader::Backend::Bindings binding;
for (size_t index = uses_vertex_a && uses_vertex_b ? 1 : 0; index < Maxwell::MaxShaderProgram;
++index) {
- if (key.unique_hashes[index] == 0) {
+ const bool is_emulated_stage = layer_source_program != nullptr &&
+ index == static_cast<u32>(Maxwell::ShaderType::Geometry);
+ if (key.unique_hashes[index] == 0 && !is_emulated_stage) {
continue;
}
UNIMPLEMENTED_IF(index == 0);