summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar Liam2022-11-30 17:16:00 -0500
committerGravatar Liam2022-12-01 09:51:27 -0500
commit3ef006b5abbe78bb2ae423a7cab74d7da2f8bc08 (patch)
treebf0c9ed637dc39faea655fb836b7a48a9f5d28ee /src/video_core/renderer_vulkan
parentMerge pull request #9308 from lat9nq/from-scratch (diff)
downloadyuzu-3ef006b5abbe78bb2ae423a7cab74d7da2f8bc08.tar.gz
yuzu-3ef006b5abbe78bb2ae423a7cab74d7da2f8bc08.tar.xz
yuzu-3ef006b5abbe78bb2ae423a7cab74d7da2f8bc08.zip
shader_recompiler: add gl_Layer translation GS for older hardware
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp33
1 files changed, 32 insertions, 1 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..150413b04 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);
46namespace { 46namespace {
47using Shader::Backend::SPIRV::EmitSPIRV; 47using Shader::Backend::SPIRV::EmitSPIRV;
48using Shader::Maxwell::ConvertLegacyToGeneric; 48using Shader::Maxwell::ConvertLegacyToGeneric;
49using Shader::Maxwell::GenerateGeometryPassthrough;
49using Shader::Maxwell::MergeDualVertexPrograms; 50using Shader::Maxwell::MergeDualVertexPrograms;
50using Shader::Maxwell::TranslateProgram; 51using Shader::Maxwell::TranslateProgram;
51using VideoCommon::ComputeEnvironment; 52using VideoCommon::ComputeEnvironment;
@@ -60,6 +61,17 @@ auto MakeSpan(Container& container) {
60 return std::span(container.data(), container.size()); 61 return std::span(container.data(), container.size());
61} 62}
62 63
64Shader::OutputTopology MaxwellToOutputTopology(Maxwell::PrimitiveTopology topology) {
65 switch (topology) {
66 case Maxwell::PrimitiveTopology::Points:
67 return Shader::OutputTopology::PointList;
68 case Maxwell::PrimitiveTopology::LineStrip:
69 return Shader::OutputTopology::LineStrip;
70 default:
71 return Shader::OutputTopology::TriangleStrip;
72 }
73}
74
63Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) { 75Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) {
64 switch (comparison) { 76 switch (comparison) {
65 case Maxwell::ComparisonOp::Never_D3D: 77 case Maxwell::ComparisonOp::Never_D3D:
@@ -327,6 +339,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
327 .needs_demote_reorder = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR || 339 .needs_demote_reorder = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR ||
328 driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 340 driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR,
329 .support_snorm_render_buffer = true, 341 .support_snorm_render_buffer = true,
342 .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
330 }; 343 };
331} 344}
332 345
@@ -509,7 +522,19 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
509 std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs; 522 std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs;
510 const bool uses_vertex_a{key.unique_hashes[0] != 0}; 523 const bool uses_vertex_a{key.unique_hashes[0] != 0};
511 const bool uses_vertex_b{key.unique_hashes[1] != 0}; 524 const bool uses_vertex_b{key.unique_hashes[1] != 0};
525
526 // Layer passthrough generation for devices without VK_EXT_shader_viewport_index_layer
527 Shader::IR::Program* layer_source_program{};
528
512 for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 529 for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
530 const bool is_emulated_stage = layer_source_program != nullptr &&
531 index == static_cast<u32>(Maxwell::ShaderType::Geometry);
532 if (key.unique_hashes[index] == 0 && is_emulated_stage) {
533 auto topology = MaxwellToOutputTopology(key.state.topology);
534 programs[index] = GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
535 *layer_source_program, topology);
536 continue;
537 }
513 if (key.unique_hashes[index] == 0) { 538 if (key.unique_hashes[index] == 0) {
514 continue; 539 continue;
515 } 540 }
@@ -530,6 +555,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
530 auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)}; 555 auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
531 programs[index] = MergeDualVertexPrograms(program_va, program_vb, env); 556 programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
532 } 557 }
558
559 if (programs[index].info.requires_layer_emulation) {
560 layer_source_program = &programs[index];
561 }
533 } 562 }
534 std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; 563 std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{};
535 std::array<vk::ShaderModule, Maxwell::MaxShaderStage> modules; 564 std::array<vk::ShaderModule, Maxwell::MaxShaderStage> modules;
@@ -538,7 +567,9 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
538 Shader::Backend::Bindings binding; 567 Shader::Backend::Bindings binding;
539 for (size_t index = uses_vertex_a && uses_vertex_b ? 1 : 0; index < Maxwell::MaxShaderProgram; 568 for (size_t index = uses_vertex_a && uses_vertex_b ? 1 : 0; index < Maxwell::MaxShaderProgram;
540 ++index) { 569 ++index) {
541 if (key.unique_hashes[index] == 0) { 570 const bool is_emulated_stage = layer_source_program != nullptr &&
571 index == static_cast<u32>(Maxwell::ShaderType::Geometry);
572 if (key.unique_hashes[index] == 0 && !is_emulated_stage) {
542 continue; 573 continue;
543 } 574 }
544 UNIMPLEMENTED_IF(index == 0); 575 UNIMPLEMENTED_IF(index == 0);