forked from eden-emu/eden
		
	Implement convert legacy to generic
This commit is contained in:
		
							parent
							
								
									25324b011f
								
							
						
					
					
						commit
						dbfa89c40b
					
				
					 6 changed files with 108 additions and 1 deletions
				
			
		|  | @ -224,6 +224,8 @@ enum class Attribute : u64 { | |||
| 
 | ||||
| constexpr size_t NUM_GENERICS = 32; | ||||
| 
 | ||||
| constexpr size_t NUM_FIXED_FNC_TEXTURES = 10; | ||||
| 
 | ||||
| [[nodiscard]] bool IsGeneric(Attribute attribute) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] u32 GenericAttributeIndex(Attribute attribute); | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <algorithm> | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| #include <queue> | ||||
| 
 | ||||
| #include "common/settings.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
|  | @ -226,4 +227,98 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| bool IsLegacyAttribute(IR::Attribute attribute) { | ||||
|     return (attribute >= IR::Attribute::ColorFrontDiffuseR && | ||||
|             attribute <= IR::Attribute::ColorBackSpecularA) || | ||||
|            attribute == IR::Attribute::FogCoordinate || | ||||
|            (attribute >= IR::Attribute::FixedFncTexture0S && | ||||
|             attribute <= IR::Attribute::FixedFncTexture9Q); | ||||
| } | ||||
| 
 | ||||
| std::map<IR::Attribute, IR::Attribute> GenerateLegacyToGenericMappings( | ||||
|     const VaryingState& state, std::queue<IR::Attribute> ununsed_generics) { | ||||
|     std::map<IR::Attribute, IR::Attribute> mapping; | ||||
|     for (size_t index = 0; index < 4; ++index) { | ||||
|         auto attr = IR::Attribute::ColorFrontDiffuseR + index * 4; | ||||
|         if (state.AnyComponent(attr)) { | ||||
|             for (size_t i = 0; i < 4; ++i) { | ||||
|                 mapping.insert({attr + i, ununsed_generics.front() + i}); | ||||
|             } | ||||
|             ununsed_generics.pop(); | ||||
|         } | ||||
|     } | ||||
|     if (state[IR::Attribute::FogCoordinate]) { | ||||
|         mapping.insert({IR::Attribute::FogCoordinate, ununsed_generics.front()}); | ||||
|         ununsed_generics.pop(); | ||||
|     } | ||||
|     for (size_t index = 0; index < IR::NUM_FIXED_FNC_TEXTURES; ++index) { | ||||
|         auto attr = IR::Attribute::FixedFncTexture0S + index * 4; | ||||
|         if (state.AnyComponent(attr)) { | ||||
|             for (size_t i = 0; i < 4; ++i) { | ||||
|                 mapping.insert({attr + i, ununsed_generics.front() + i}); | ||||
|             } | ||||
|             ununsed_generics.pop(); | ||||
|         } | ||||
|     } | ||||
|     return mapping; | ||||
| } | ||||
| 
 | ||||
| void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) { | ||||
|     auto& stores = program.info.stores; | ||||
|     if (stores.Legacy()) { | ||||
|         std::queue<IR::Attribute> ununsed_output_generics{}; | ||||
|         for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | ||||
|             if (!stores.Generic(index)) { | ||||
|                 ununsed_output_generics.push(IR::Attribute::Generic0X + index * 4); | ||||
|             } | ||||
|         } | ||||
|         auto mappings = GenerateLegacyToGenericMappings(stores, ununsed_output_generics); | ||||
|         for (IR::Block* const block : program.post_order_blocks) { | ||||
|             for (IR::Inst& inst : block->Instructions()) { | ||||
|                 switch (inst.GetOpcode()) { | ||||
|                 case IR::Opcode::SetAttribute: { | ||||
|                     const auto attr = inst.Arg(0).Attribute(); | ||||
|                     if (IsLegacyAttribute(attr)) { | ||||
|                         stores.Set(mappings[attr], true); | ||||
|                         inst.SetArg(0, Shader::IR::Value(mappings[attr])); | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 default: | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     auto& loads = program.info.loads; | ||||
|     if (loads.Legacy()) { | ||||
|         std::queue<IR::Attribute> ununsed_input_generics{}; | ||||
|         for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | ||||
|             const AttributeType input_type{runtime_info.generic_input_types[index]}; | ||||
|             if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) || | ||||
|                 input_type == AttributeType::Disabled) { | ||||
|                 ununsed_input_generics.push(IR::Attribute::Generic0X + index * 4); | ||||
|             } | ||||
|         } | ||||
|         auto mappings = GenerateLegacyToGenericMappings(loads, ununsed_input_generics); | ||||
|         for (IR::Block* const block : program.post_order_blocks) { | ||||
|             for (IR::Inst& inst : block->Instructions()) { | ||||
|                 switch (inst.GetOpcode()) { | ||||
|                 case IR::Opcode::GetAttribute: { | ||||
|                     const auto attr = inst.Arg(0).Attribute(); | ||||
|                     if (IsLegacyAttribute(attr)) { | ||||
|                         loads.Set(mappings[attr], true); | ||||
|                         inst.SetArg(0, Shader::IR::Value(mappings[attr])); | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 default: | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include "shader_recompiler/frontend/maxwell/control_flow.h" | ||||
| #include "shader_recompiler/host_translate_info.h" | ||||
| #include "shader_recompiler/object_pool.h" | ||||
| #include "shader_recompiler/runtime_info.h" | ||||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| 
 | ||||
|  | @ -20,4 +21,7 @@ namespace Shader::Maxwell { | |||
| [[nodiscard]] IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b, | ||||
|                                                   Environment& env_vertex_b); | ||||
| 
 | ||||
| [[nodiscard]] void ConvertLegacyToGeneric(IR::Program& program, | ||||
|                                           const Shader::RuntimeInfo& runtime_info); | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  |  | |||
|  | @ -53,7 +53,8 @@ struct VaryingState { | |||
|         return AnyComponent(IR::Attribute::ColorFrontDiffuseR) || | ||||
|                AnyComponent(IR::Attribute::ColorFrontSpecularR) || | ||||
|                AnyComponent(IR::Attribute::ColorBackDiffuseR) || | ||||
|                AnyComponent(IR::Attribute::ColorBackSpecularR) || FixedFunctionTexture(); | ||||
|                AnyComponent(IR::Attribute::ColorBackSpecularR) || FixedFunctionTexture() || | ||||
|                mask[static_cast<size_t>(IR::Attribute::FogCoordinate)]; | ||||
|     } | ||||
| 
 | ||||
|     [[nodiscard]] bool FixedFunctionTexture() const noexcept { | ||||
|  |  | |||
|  | @ -44,6 +44,7 @@ using Shader::Backend::GLSL::EmitGLSL; | |||
| using Shader::Backend::SPIRV::EmitSPIRV; | ||||
| using Shader::Maxwell::MergeDualVertexPrograms; | ||||
| using Shader::Maxwell::TranslateProgram; | ||||
| using Shader::Maxwell::ConvertLegacyToGeneric; | ||||
| using VideoCommon::ComputeEnvironment; | ||||
| using VideoCommon::FileEnvironment; | ||||
| using VideoCommon::GenericEnvironment; | ||||
|  | @ -462,12 +463,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||
|             MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)}; | ||||
|         switch (device.GetShaderBackend()) { | ||||
|         case Settings::ShaderBackend::GLSL: | ||||
|             ConvertLegacyToGeneric(program, runtime_info); | ||||
|             sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); | ||||
|             break; | ||||
|         case Settings::ShaderBackend::GLASM: | ||||
|             sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); | ||||
|             break; | ||||
|         case Settings::ShaderBackend::SPIRV: | ||||
|             ConvertLegacyToGeneric(program, runtime_info); | ||||
|             sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding); | ||||
|             break; | ||||
|         } | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ namespace { | |||
| using Shader::Backend::SPIRV::EmitSPIRV; | ||||
| using Shader::Maxwell::MergeDualVertexPrograms; | ||||
| using Shader::Maxwell::TranslateProgram; | ||||
| using Shader::Maxwell::ConvertLegacyToGeneric; | ||||
| using VideoCommon::ComputeEnvironment; | ||||
| using VideoCommon::FileEnvironment; | ||||
| using VideoCommon::GenericEnvironment; | ||||
|  | @ -543,6 +544,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||
|         infos[stage_index] = &program.info; | ||||
| 
 | ||||
|         const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)}; | ||||
|         ConvertLegacyToGeneric(program, runtime_info); | ||||
|         const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)}; | ||||
|         device.SaveShader(code); | ||||
|         modules[stage_index] = BuildShader(device, code); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Feng Chen
						Feng Chen