summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
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_opengl
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_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 3fe04a115..a38060100 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -39,6 +39,7 @@ using Shader::Backend::GLASM::EmitGLASM;
39using Shader::Backend::GLSL::EmitGLSL; 39using Shader::Backend::GLSL::EmitGLSL;
40using Shader::Backend::SPIRV::EmitSPIRV; 40using Shader::Backend::SPIRV::EmitSPIRV;
41using Shader::Maxwell::ConvertLegacyToGeneric; 41using Shader::Maxwell::ConvertLegacyToGeneric;
42using Shader::Maxwell::GenerateGeometryPassthrough;
42using Shader::Maxwell::MergeDualVertexPrograms; 43using Shader::Maxwell::MergeDualVertexPrograms;
43using Shader::Maxwell::TranslateProgram; 44using Shader::Maxwell::TranslateProgram;
44using VideoCommon::ComputeEnvironment; 45using VideoCommon::ComputeEnvironment;
@@ -56,6 +57,17 @@ auto MakeSpan(Container& container) {
56 return std::span(container.data(), container.size()); 57 return std::span(container.data(), container.size());
57} 58}
58 59
60Shader::OutputTopology MaxwellToOutputTopology(Maxwell::PrimitiveTopology topology) {
61 switch (topology) {
62 case Maxwell::PrimitiveTopology::Points:
63 return Shader::OutputTopology::PointList;
64 case Maxwell::PrimitiveTopology::LineStrip:
65 return Shader::OutputTopology::LineStrip;
66 default:
67 return Shader::OutputTopology::TriangleStrip;
68 }
69}
70
59Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, 71Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
60 const Shader::IR::Program& program, 72 const Shader::IR::Program& program,
61 const Shader::IR::Program* previous_program, 73 const Shader::IR::Program* previous_program,
@@ -220,6 +232,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
220 .support_int64 = device.HasShaderInt64(), 232 .support_int64 = device.HasShaderInt64(),
221 .needs_demote_reorder = device.IsAmd(), 233 .needs_demote_reorder = device.IsAmd(),
222 .support_snorm_render_buffer = false, 234 .support_snorm_render_buffer = false,
235 .support_viewport_index_layer = device.HasVertexViewportLayer(),
223 } { 236 } {
224 if (use_asynchronous_shaders) { 237 if (use_asynchronous_shaders) {
225 workers = CreateWorkers(); 238 workers = CreateWorkers();
@@ -314,9 +327,7 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
314 const auto& regs{maxwell3d->regs}; 327 const auto& regs{maxwell3d->regs};
315 graphics_key.raw = 0; 328 graphics_key.raw = 0;
316 graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0); 329 graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0);
317 graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0 330 graphics_key.gs_input_topology.Assign(regs.draw.topology.Value());
318 ? regs.draw.topology.Value()
319 : Maxwell::PrimitiveTopology{});
320 graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value()); 331 graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value());
321 graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value()); 332 graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value());
322 graphics_key.tessellation_clockwise.Assign( 333 graphics_key.tessellation_clockwise.Assign(
@@ -415,7 +426,19 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
415 std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs; 426 std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs;
416 const bool uses_vertex_a{key.unique_hashes[0] != 0}; 427 const bool uses_vertex_a{key.unique_hashes[0] != 0};
417 const bool uses_vertex_b{key.unique_hashes[1] != 0}; 428 const bool uses_vertex_b{key.unique_hashes[1] != 0};
429
430 // Layer passthrough generation for devices without GL_ARB_shader_viewport_layer_array
431 Shader::IR::Program* layer_source_program{};
432
418 for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 433 for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
434 const bool is_emulated_stage = layer_source_program != nullptr &&
435 index == static_cast<u32>(Maxwell::ShaderType::Geometry);
436 if (key.unique_hashes[index] == 0 && is_emulated_stage) {
437 auto topology = MaxwellToOutputTopology(key.gs_input_topology);
438 programs[index] = GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
439 *layer_source_program, topology);
440 continue;
441 }
419 if (key.unique_hashes[index] == 0) { 442 if (key.unique_hashes[index] == 0) {
420 continue; 443 continue;
421 } 444 }
@@ -443,6 +466,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
443 Shader::NumDescriptors(program_vb.info.storage_buffers_descriptors); 466 Shader::NumDescriptors(program_vb.info.storage_buffers_descriptors);
444 programs[index] = MergeDualVertexPrograms(program_va, program_vb, env); 467 programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
445 } 468 }
469
470 if (programs[index].info.requires_layer_emulation) {
471 layer_source_program = &programs[index];
472 }
446 } 473 }
447 const u32 glasm_storage_buffer_limit{device.GetMaxGLASMStorageBufferBlocks()}; 474 const u32 glasm_storage_buffer_limit{device.GetMaxGLASMStorageBufferBlocks()};
448 const bool glasm_use_storage_buffers{total_storage_buffers <= glasm_storage_buffer_limit}; 475 const bool glasm_use_storage_buffers{total_storage_buffers <= glasm_storage_buffer_limit};
@@ -456,7 +483,9 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
456 const bool use_glasm{device.UseAssemblyShaders()}; 483 const bool use_glasm{device.UseAssemblyShaders()};
457 const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; 484 const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0;
458 for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { 485 for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) {
459 if (key.unique_hashes[index] == 0) { 486 const bool is_emulated_stage = layer_source_program != nullptr &&
487 index == static_cast<u32>(Maxwell::ShaderType::Geometry);
488 if (key.unique_hashes[index] == 0 && !is_emulated_stage) {
460 continue; 489 continue;
461 } 490 }
462 UNIMPLEMENTED_IF(index == 0); 491 UNIMPLEMENTED_IF(index == 0);