diff options
| author | 2022-11-30 17:16:00 -0500 | |
|---|---|---|
| committer | 2022-12-01 09:51:27 -0500 | |
| commit | 3ef006b5abbe78bb2ae423a7cab74d7da2f8bc08 (patch) | |
| tree | bf0c9ed637dc39faea655fb836b7a48a9f5d28ee /src/video_core/renderer_vulkan | |
| parent | Merge pull request #9308 from lat9nq/from-scratch (diff) | |
| download | yuzu-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.cpp | 33 |
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); | |||
| 46 | namespace { | 46 | namespace { |
| 47 | using Shader::Backend::SPIRV::EmitSPIRV; | 47 | using Shader::Backend::SPIRV::EmitSPIRV; |
| 48 | using Shader::Maxwell::ConvertLegacyToGeneric; | 48 | using Shader::Maxwell::ConvertLegacyToGeneric; |
| 49 | using Shader::Maxwell::GenerateGeometryPassthrough; | ||
| 49 | using Shader::Maxwell::MergeDualVertexPrograms; | 50 | using Shader::Maxwell::MergeDualVertexPrograms; |
| 50 | using Shader::Maxwell::TranslateProgram; | 51 | using Shader::Maxwell::TranslateProgram; |
| 51 | using VideoCommon::ComputeEnvironment; | 52 | using 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 | ||
| 64 | Shader::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 | |||
| 63 | Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) { | 75 | Shader::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); |