Merge pull request #8873 from vonchenplus/fix_legacy_location_error
video_core: Fix legacy to generic location unpaired
This commit is contained in:
		| @@ -137,28 +137,35 @@ bool IsLegacyAttribute(IR::Attribute attribute) { | ||||
| } | ||||
|  | ||||
| std::map<IR::Attribute, IR::Attribute> GenerateLegacyToGenericMappings( | ||||
|     const VaryingState& state, std::queue<IR::Attribute> ununsed_generics) { | ||||
|     const VaryingState& state, std::queue<IR::Attribute> unused_generics, | ||||
|     const std::map<IR::Attribute, IR::Attribute>& previous_stage_mapping) { | ||||
|     std::map<IR::Attribute, IR::Attribute> mapping; | ||||
|     auto update_mapping = [&mapping, &unused_generics, previous_stage_mapping](IR::Attribute attr, | ||||
|                                                                                size_t count) { | ||||
|         if (previous_stage_mapping.find(attr) != previous_stage_mapping.end()) { | ||||
|             for (size_t i = 0; i < count; ++i) { | ||||
|                 mapping.insert({attr + i, previous_stage_mapping.at(attr + i)}); | ||||
|             } | ||||
|         } else { | ||||
|             for (size_t i = 0; i < count; ++i) { | ||||
|                 mapping.insert({attr + i, unused_generics.front() + i}); | ||||
|             } | ||||
|             unused_generics.pop(); | ||||
|         } | ||||
|     }; | ||||
|     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(); | ||||
|             update_mapping(attr, 4); | ||||
|         } | ||||
|     } | ||||
|     if (state[IR::Attribute::FogCoordinate]) { | ||||
|         mapping.insert({IR::Attribute::FogCoordinate, ununsed_generics.front()}); | ||||
|         ununsed_generics.pop(); | ||||
|         update_mapping(IR::Attribute::FogCoordinate, 1); | ||||
|     } | ||||
|     for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++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(); | ||||
|             update_mapping(attr, 4); | ||||
|         } | ||||
|     } | ||||
|     return mapping; | ||||
| @@ -265,21 +272,22 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b | ||||
| 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{}; | ||||
|         std::queue<IR::Attribute> unused_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); | ||||
|                 unused_output_generics.push(IR::Attribute::Generic0X + index * 4); | ||||
|             } | ||||
|         } | ||||
|         auto mappings = GenerateLegacyToGenericMappings(stores, ununsed_output_generics); | ||||
|         program.info.legacy_stores_mapping = | ||||
|             GenerateLegacyToGenericMappings(stores, unused_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])); | ||||
|                         stores.Set(program.info.legacy_stores_mapping[attr], true); | ||||
|                         inst.SetArg(0, Shader::IR::Value(program.info.legacy_stores_mapping[attr])); | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
| @@ -292,15 +300,16 @@ void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& run | ||||
|  | ||||
|     auto& loads = program.info.loads; | ||||
|     if (loads.Legacy()) { | ||||
|         std::queue<IR::Attribute> ununsed_input_generics{}; | ||||
|         std::queue<IR::Attribute> unused_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); | ||||
|                 unused_input_generics.push(IR::Attribute::Generic0X + index * 4); | ||||
|             } | ||||
|         } | ||||
|         auto mappings = GenerateLegacyToGenericMappings(loads, ununsed_input_generics); | ||||
|         auto mappings = GenerateLegacyToGenericMappings( | ||||
|             loads, unused_input_generics, runtime_info.previous_stage_legacy_stores_mapping); | ||||
|         for (IR::Block* const block : program.post_order_blocks) { | ||||
|             for (IR::Inst& inst : block->Instructions()) { | ||||
|                 switch (inst.GetOpcode()) { | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <array> | ||||
| #include <map> | ||||
| #include <optional> | ||||
| #include <vector> | ||||
|  | ||||
| @@ -60,6 +61,7 @@ struct TransformFeedbackVarying { | ||||
| struct RuntimeInfo { | ||||
|     std::array<AttributeType, 32> generic_input_types{}; | ||||
|     VaryingState previous_stage_stores; | ||||
|     std::map<IR::Attribute, IR::Attribute> previous_stage_legacy_stores_mapping; | ||||
|  | ||||
|     bool convert_depth_mode{}; | ||||
|     bool force_early_z{}; | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
|  | ||||
| #include <array> | ||||
| #include <bitset> | ||||
| #include <map> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/frontend/ir/type.h" | ||||
| @@ -127,6 +128,8 @@ struct Info { | ||||
|     VaryingState stores; | ||||
|     VaryingState passthrough; | ||||
|  | ||||
|     std::map<IR::Attribute, IR::Attribute> legacy_stores_mapping; | ||||
|  | ||||
|     bool loads_indexed_attributes{}; | ||||
|  | ||||
|     std::array<bool, 8> stores_frag_color{}; | ||||
|   | ||||
| @@ -63,6 +63,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | ||||
|     Shader::RuntimeInfo info; | ||||
|     if (previous_program) { | ||||
|         info.previous_stage_stores = previous_program->info.stores; | ||||
|         info.previous_stage_legacy_stores_mapping = previous_program->info.legacy_stores_mapping; | ||||
|     } else { | ||||
|         // Mark all stores as available for vertex shaders | ||||
|         info.previous_stage_stores.mask.set(); | ||||
|   | ||||
| @@ -134,6 +134,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program | ||||
|     Shader::RuntimeInfo info; | ||||
|     if (previous_program) { | ||||
|         info.previous_stage_stores = previous_program->info.stores; | ||||
|         info.previous_stage_legacy_stores_mapping = previous_program->info.legacy_stores_mapping; | ||||
|         if (previous_program->is_geometry_passthrough) { | ||||
|             info.previous_stage_stores.mask |= previous_program->info.passthrough.mask; | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user