forked from eden-emu/eden
		
	shader_recompiler: add gl_Layer translation GS for older hardware
This commit is contained in:
		
							parent
							
								
									a6e97dcd1c
								
							
						
					
					
						commit
						e8966fd1f9
					
				
					 9 changed files with 230 additions and 6 deletions
				
			
		|  | @ -9,6 +9,7 @@ | |||
| #include "common/settings.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/ir/basic_block.h" | ||||
| #include "shader_recompiler/frontend/ir/ir_emitter.h" | ||||
| #include "shader_recompiler/frontend/ir/post_order.h" | ||||
| #include "shader_recompiler/frontend/maxwell/structured_control_flow.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/translate.h" | ||||
|  | @ -233,6 +234,8 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo | |||
|         Optimization::VerificationPass(program); | ||||
|     } | ||||
|     Optimization::CollectShaderInfoPass(env, program); | ||||
|     Optimization::LayerPass(program, host_info); | ||||
| 
 | ||||
|     CollectInterpolationInfo(env, program); | ||||
|     AddNVNStorageBuffers(program); | ||||
|     return program; | ||||
|  | @ -331,4 +334,82 @@ void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& run | |||
|     } | ||||
| } | ||||
| 
 | ||||
| IR::Program GenerateGeometryPassthrough(ObjectPool<IR::Inst>& inst_pool, | ||||
|                                         ObjectPool<IR::Block>& block_pool, | ||||
|                                         const HostTranslateInfo& host_info, | ||||
|                                         IR::Program& source_program, | ||||
|                                         Shader::OutputTopology output_topology) { | ||||
|     IR::Program program; | ||||
|     program.stage = Stage::Geometry; | ||||
|     program.output_topology = output_topology; | ||||
|     switch (output_topology) { | ||||
|     case OutputTopology::PointList: | ||||
|         program.output_vertices = 1; | ||||
|         break; | ||||
|     case OutputTopology::LineStrip: | ||||
|         program.output_vertices = 2; | ||||
|         break; | ||||
|     default: | ||||
|         program.output_vertices = 3; | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     program.is_geometry_passthrough = false; | ||||
|     program.info.loads.mask = source_program.info.stores.mask; | ||||
|     program.info.stores.mask = source_program.info.stores.mask; | ||||
|     program.info.stores.Set(IR::Attribute::Layer, true); | ||||
|     program.info.stores.Set(source_program.info.emulated_layer, false); | ||||
| 
 | ||||
|     IR::Block* current_block = block_pool.Create(inst_pool); | ||||
|     auto& node{program.syntax_list.emplace_back()}; | ||||
|     node.type = IR::AbstractSyntaxNode::Type::Block; | ||||
|     node.data.block = current_block; | ||||
| 
 | ||||
|     IR::IREmitter ir{*current_block}; | ||||
|     for (u32 i = 0; i < program.output_vertices; i++) { | ||||
|         // Assign generics from input
 | ||||
|         for (u32 j = 0; j < 32; j++) { | ||||
|             if (!program.info.stores.Generic(j)) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             const IR::Attribute attr = IR::Attribute::Generic0X + (j * 4); | ||||
|             ir.SetAttribute(attr + 0, ir.GetAttribute(attr + 0, ir.Imm32(i)), ir.Imm32(0)); | ||||
|             ir.SetAttribute(attr + 1, ir.GetAttribute(attr + 1, ir.Imm32(i)), ir.Imm32(0)); | ||||
|             ir.SetAttribute(attr + 2, ir.GetAttribute(attr + 2, ir.Imm32(i)), ir.Imm32(0)); | ||||
|             ir.SetAttribute(attr + 3, ir.GetAttribute(attr + 3, ir.Imm32(i)), ir.Imm32(0)); | ||||
|         } | ||||
| 
 | ||||
|         // Assign position from input
 | ||||
|         const IR::Attribute attr = IR::Attribute::PositionX; | ||||
|         ir.SetAttribute(attr + 0, ir.GetAttribute(attr + 0, ir.Imm32(i)), ir.Imm32(0)); | ||||
|         ir.SetAttribute(attr + 1, ir.GetAttribute(attr + 1, ir.Imm32(i)), ir.Imm32(0)); | ||||
|         ir.SetAttribute(attr + 2, ir.GetAttribute(attr + 2, ir.Imm32(i)), ir.Imm32(0)); | ||||
|         ir.SetAttribute(attr + 3, ir.GetAttribute(attr + 3, ir.Imm32(i)), ir.Imm32(0)); | ||||
| 
 | ||||
|         // Assign layer
 | ||||
|         ir.SetAttribute(IR::Attribute::Layer, ir.GetAttribute(source_program.info.emulated_layer), | ||||
|                         ir.Imm32(0)); | ||||
| 
 | ||||
|         // Emit vertex
 | ||||
|         ir.EmitVertex(ir.Imm32(0)); | ||||
|     } | ||||
|     ir.EndPrimitive(ir.Imm32(0)); | ||||
| 
 | ||||
|     IR::Block* return_block{block_pool.Create(inst_pool)}; | ||||
|     IR::IREmitter{*return_block}.Epilogue(); | ||||
|     current_block->AddBranch(return_block); | ||||
| 
 | ||||
|     auto& merge{program.syntax_list.emplace_back()}; | ||||
|     merge.type = IR::AbstractSyntaxNode::Type::Block; | ||||
|     merge.data.block = return_block; | ||||
|     program.syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Return; | ||||
| 
 | ||||
|     program.blocks = GenerateBlocks(program.syntax_list); | ||||
|     program.post_order_blocks = PostOrder(program.syntax_list.front()); | ||||
|     Optimization::SsaRewritePass(program); | ||||
| 
 | ||||
|     return program; | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  |  | |||
|  | @ -25,4 +25,13 @@ namespace Shader::Maxwell { | |||
| 
 | ||||
| void ConvertLegacyToGeneric(IR::Program& program, const RuntimeInfo& runtime_info); | ||||
| 
 | ||||
| // Maxwell v1 and older Nvidia cards don't support setting gl_Layer from non-geometry stages.
 | ||||
| // This creates a workaround by setting the layer as a generic output and creating a
 | ||||
| // passthrough geometry shader that reads the generic and sets the layer.
 | ||||
| [[nodiscard]] IR::Program GenerateGeometryPassthrough(ObjectPool<IR::Inst>& inst_pool, | ||||
|                                                       ObjectPool<IR::Block>& block_pool, | ||||
|                                                       const HostTranslateInfo& host_info, | ||||
|                                                       IR::Program& source_program, | ||||
|                                                       Shader::OutputTopology output_topology); | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Liam
						Liam