Implement convert legacy to generic
This commit is contained in:
		| @@ -224,6 +224,8 @@ enum class Attribute : u64 { | |||||||
|  |  | ||||||
| constexpr size_t NUM_GENERICS = 32; | constexpr size_t NUM_GENERICS = 32; | ||||||
|  |  | ||||||
|  | constexpr size_t NUM_FIXED_FNC_TEXTURES = 10; | ||||||
|  |  | ||||||
| [[nodiscard]] bool IsGeneric(Attribute attribute) noexcept; | [[nodiscard]] bool IsGeneric(Attribute attribute) noexcept; | ||||||
|  |  | ||||||
| [[nodiscard]] u32 GenericAttributeIndex(Attribute attribute); | [[nodiscard]] u32 GenericAttributeIndex(Attribute attribute); | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <queue> | ||||||
|  |  | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "shader_recompiler/exception.h" | #include "shader_recompiler/exception.h" | ||||||
| @@ -226,4 +227,98 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b | |||||||
|     return result; |     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 | } // namespace Shader::Maxwell | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| #include "shader_recompiler/frontend/maxwell/control_flow.h" | #include "shader_recompiler/frontend/maxwell/control_flow.h" | ||||||
| #include "shader_recompiler/host_translate_info.h" | #include "shader_recompiler/host_translate_info.h" | ||||||
| #include "shader_recompiler/object_pool.h" | #include "shader_recompiler/object_pool.h" | ||||||
|  | #include "shader_recompiler/runtime_info.h" | ||||||
|  |  | ||||||
| namespace Shader::Maxwell { | namespace Shader::Maxwell { | ||||||
|  |  | ||||||
| @@ -20,4 +21,7 @@ namespace Shader::Maxwell { | |||||||
| [[nodiscard]] IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b, | [[nodiscard]] IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b, | ||||||
|                                                   Environment& env_vertex_b); |                                                   Environment& env_vertex_b); | ||||||
|  |  | ||||||
|  | [[nodiscard]] void ConvertLegacyToGeneric(IR::Program& program, | ||||||
|  |                                           const Shader::RuntimeInfo& runtime_info); | ||||||
|  |  | ||||||
| } // namespace Shader::Maxwell | } // namespace Shader::Maxwell | ||||||
|   | |||||||
| @@ -53,7 +53,8 @@ struct VaryingState { | |||||||
|         return AnyComponent(IR::Attribute::ColorFrontDiffuseR) || |         return AnyComponent(IR::Attribute::ColorFrontDiffuseR) || | ||||||
|                AnyComponent(IR::Attribute::ColorFrontSpecularR) || |                AnyComponent(IR::Attribute::ColorFrontSpecularR) || | ||||||
|                AnyComponent(IR::Attribute::ColorBackDiffuseR) || |                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 { |     [[nodiscard]] bool FixedFunctionTexture() const noexcept { | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ using Shader::Backend::GLSL::EmitGLSL; | |||||||
| using Shader::Backend::SPIRV::EmitSPIRV; | using Shader::Backend::SPIRV::EmitSPIRV; | ||||||
| using Shader::Maxwell::MergeDualVertexPrograms; | using Shader::Maxwell::MergeDualVertexPrograms; | ||||||
| using Shader::Maxwell::TranslateProgram; | using Shader::Maxwell::TranslateProgram; | ||||||
|  | using Shader::Maxwell::ConvertLegacyToGeneric; | ||||||
| using VideoCommon::ComputeEnvironment; | using VideoCommon::ComputeEnvironment; | ||||||
| using VideoCommon::FileEnvironment; | using VideoCommon::FileEnvironment; | ||||||
| using VideoCommon::GenericEnvironment; | using VideoCommon::GenericEnvironment; | ||||||
| @@ -462,12 +463,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||||||
|             MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)}; |             MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)}; | ||||||
|         switch (device.GetShaderBackend()) { |         switch (device.GetShaderBackend()) { | ||||||
|         case Settings::ShaderBackend::GLSL: |         case Settings::ShaderBackend::GLSL: | ||||||
|  |             ConvertLegacyToGeneric(program, runtime_info); | ||||||
|             sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); |             sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); | ||||||
|             break; |             break; | ||||||
|         case Settings::ShaderBackend::GLASM: |         case Settings::ShaderBackend::GLASM: | ||||||
|             sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); |             sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); | ||||||
|             break; |             break; | ||||||
|         case Settings::ShaderBackend::SPIRV: |         case Settings::ShaderBackend::SPIRV: | ||||||
|  |             ConvertLegacyToGeneric(program, runtime_info); | ||||||
|             sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding); |             sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -50,6 +50,7 @@ namespace { | |||||||
| using Shader::Backend::SPIRV::EmitSPIRV; | using Shader::Backend::SPIRV::EmitSPIRV; | ||||||
| using Shader::Maxwell::MergeDualVertexPrograms; | using Shader::Maxwell::MergeDualVertexPrograms; | ||||||
| using Shader::Maxwell::TranslateProgram; | using Shader::Maxwell::TranslateProgram; | ||||||
|  | using Shader::Maxwell::ConvertLegacyToGeneric; | ||||||
| using VideoCommon::ComputeEnvironment; | using VideoCommon::ComputeEnvironment; | ||||||
| using VideoCommon::FileEnvironment; | using VideoCommon::FileEnvironment; | ||||||
| using VideoCommon::GenericEnvironment; | using VideoCommon::GenericEnvironment; | ||||||
| @@ -543,6 +544,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||||||
|         infos[stage_index] = &program.info; |         infos[stage_index] = &program.info; | ||||||
|  |  | ||||||
|         const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)}; |         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)}; |         const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)}; | ||||||
|         device.SaveShader(code); |         device.SaveShader(code); | ||||||
|         modules[stage_index] = BuildShader(device, code); |         modules[stage_index] = BuildShader(device, code); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user