diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 723455462e..77877b7622 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp @@ -18,8 +18,6 @@ namespace Shader::Backend::SPIRV { namespace { -constexpr size_t NUM_FIXEDFNCTEXTURE = 10; - enum class Operation { Increment, Decrement, @@ -1445,7 +1443,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { if (loads.AnyComponent(IR::Attribute::FogCoordinate)) { input_fog_frag_coord = DefineLegacyInput(*this, used_locations, previous_unused_location); } - for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { + for (size_t index = 0; index < IR::NUM_TEXTURES; ++index) { if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { input_fixed_fnc_textures[index] = DefineLegacyInput(*this, used_locations, previous_unused_location); @@ -1529,7 +1527,7 @@ void EmitContext::DefineOutputs(const IR::Program& program) { output_fog_frag_coord = DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); } - for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { + for (size_t index = 0; index < IR::NUM_TEXTURES; ++index) { if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { output_fixed_fnc_textures[index] = DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); diff --git a/src/shader_recompiler/frontend/ir/attribute.h b/src/shader_recompiler/frontend/ir/attribute.h index ca11994943..1867b1fef5 100644 --- a/src/shader_recompiler/frontend/ir/attribute.h +++ b/src/shader_recompiler/frontend/ir/attribute.h @@ -224,6 +224,8 @@ enum class Attribute : u64 { constexpr size_t NUM_GENERICS = 32; +const size_t NUM_TEXTURES = 10; + [[nodiscard]] bool IsGeneric(Attribute attribute) noexcept; [[nodiscard]] u32 GenericAttributeIndex(Attribute attribute); diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 1e476d83d9..56f1466f1b 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp @@ -839,15 +839,29 @@ void GatherInfoFromHeader(Environment& env, Info& info) { if (info.loads_indexed_attributes) { for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { const IR::Attribute attribute{IR::Attribute::Generic0X + index * 4}; - const auto mask = header.vtg.InputGeneric(index); + const auto mask = header.vtg.Mask(header.vtg.imap_generic_vector, index); for (size_t i = 0; i < 4; ++i) { info.loads.Set(attribute + i, mask[i]); } } for (size_t index = 0; index < 8; ++index) { - const u16 mask{header.vtg.clip_distances}; + const u16 mask{header.vtg.imap_systemc.clip_distances}; info.loads.Set(IR::Attribute::ClipDistance0 + index, ((mask >> index) & 1) != 0); } + for (size_t index = 0; index < 4; ++index) { + const IR::Attribute attribute{IR::Attribute::ColorFrontDiffuseR + index * 4}; + const auto mask{header.vtg.Mask(header.vtg.imap_color, index)}; + for (size_t i = 0; i < 4; ++i) { + info.loads.Set(attribute + i, mask[i]); + } + } + for (size_t index = 0; index < IR::NUM_TEXTURES; ++index) { + const IR::Attribute attribute{IR::Attribute::FixedFncTexture0S + index * 4}; + const auto mask = header.vtg.Mask(header.vtg.imap_texture, index); + for (size_t i = 0; i < 4; ++i) { + info.loads.Set(attribute + i, mask[i]); + } + } info.loads.Set(IR::Attribute::PrimitiveId, header.vtg.imap_systemb.primitive_array_id != 0); info.loads.Set(IR::Attribute::Layer, header.vtg.imap_systemb.rt_array_index != 0); info.loads.Set(IR::Attribute::ViewportIndex, header.vtg.imap_systemb.viewport_index != 0); @@ -856,21 +870,21 @@ void GatherInfoFromHeader(Environment& env, Info& info) { info.loads.Set(IR::Attribute::PositionY, header.vtg.imap_systemb.position_y != 0); info.loads.Set(IR::Attribute::PositionZ, header.vtg.imap_systemb.position_z != 0); info.loads.Set(IR::Attribute::PositionW, header.vtg.imap_systemb.position_w != 0); - info.loads.Set(IR::Attribute::PointSpriteS, header.vtg.point_sprite_s != 0); - info.loads.Set(IR::Attribute::PointSpriteT, header.vtg.point_sprite_t != 0); - info.loads.Set(IR::Attribute::FogCoordinate, header.vtg.fog_coordinate != 0); + info.loads.Set(IR::Attribute::PointSpriteS, header.vtg.imap_systemc.point_sprite_s != 0); + info.loads.Set(IR::Attribute::PointSpriteT, header.vtg.imap_systemc.point_sprite_t != 0); + info.loads.Set(IR::Attribute::FogCoordinate, header.vtg.imap_systemc.fog_coordinate != 0); info.loads.Set(IR::Attribute::TessellationEvaluationPointU, - header.vtg.tessellation_eval_point_u != 0); + header.vtg.imap_systemc.tessellation_eval_point_u != 0); info.loads.Set(IR::Attribute::TessellationEvaluationPointV, - header.vtg.tessellation_eval_point_v != 0); - info.loads.Set(IR::Attribute::InstanceId, header.vtg.instance_id != 0); - info.loads.Set(IR::Attribute::VertexId, header.vtg.vertex_id != 0); - // TODO: Legacy varyings + header.vtg.imap_systemc.tessellation_eval_point_v != 0); + info.loads.Set(IR::Attribute::InstanceId, header.vtg.imap_systemc.instance_id != 0); + info.loads.Set(IR::Attribute::VertexId, header.vtg.imap_systemc.vertex_id != 0); + info.loads.Set(IR::Attribute::FogCoordinate, header.vtg.imap_systemc.fog_coordinate != 0); } if (info.stores_indexed_attributes) { for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { const IR::Attribute attribute{IR::Attribute::Generic0X + index * 4}; - const auto mask{header.vtg.OutputGeneric(index)}; + const auto mask{header.vtg.Mask(header.vtg.omap_generic_vector, index)}; for (size_t i = 0; i < 4; ++i) { info.stores.Set(attribute + i, mask[i]); } @@ -879,6 +893,20 @@ void GatherInfoFromHeader(Environment& env, Info& info) { const u16 mask{header.vtg.omap_systemc.clip_distances}; info.stores.Set(IR::Attribute::ClipDistance0 + index, ((mask >> index) & 1) != 0); } + for (size_t index = 0; index < 4; ++index) { + const IR::Attribute attribute{IR::Attribute::ColorFrontDiffuseR + index * 4}; + const auto mask{header.vtg.Mask(header.vtg.omap_color, index)}; + for (size_t i = 0; i < 4; ++i) { + info.stores.Set(attribute + i, mask[i]); + } + } + for (size_t index = 0; index < IR::NUM_TEXTURES; ++index) { + const IR::Attribute attribute{IR::Attribute::FixedFncTexture0S + index * 4}; + const auto mask = header.vtg.Mask(header.vtg.omap_texture, index); + for (size_t i = 0; i < 4; ++i) { + info.stores.Set(attribute + i, mask[i]); + } + } info.stores.Set(IR::Attribute::PrimitiveId, header.vtg.omap_systemb.primitive_array_id != 0); info.stores.Set(IR::Attribute::Layer, header.vtg.omap_systemb.rt_array_index != 0); @@ -897,7 +925,7 @@ void GatherInfoFromHeader(Environment& env, Info& info) { header.vtg.omap_systemc.tessellation_eval_point_v != 0); info.stores.Set(IR::Attribute::InstanceId, header.vtg.omap_systemc.instance_id != 0); info.stores.Set(IR::Attribute::VertexId, header.vtg.omap_systemc.vertex_id != 0); - // TODO: Legacy varyings + info.stores.Set(IR::Attribute::FogCoordinate, header.vtg.omap_systemc.fog_coordinate != 0); } } } // Anonymous namespace diff --git a/src/shader_recompiler/program_header.h b/src/shader_recompiler/program_header.h index bd6c2bfb5e..b2de1c892e 100644 --- a/src/shader_recompiler/program_header.h +++ b/src/shader_recompiler/program_header.h @@ -86,7 +86,8 @@ struct ProgramHeader { std::array imap_generic_vector; - INSERT_PADDING_BYTES_NOINIT(2); // ImapColor + std::array imap_color; + union { BitField<0, 8, u16> clip_distances; BitField<8, 1, u16> point_sprite_s; @@ -96,8 +97,10 @@ struct ProgramHeader { BitField<13, 1, u16> tessellation_eval_point_v; BitField<14, 1, u16> instance_id; BitField<15, 1, u16> vertex_id; - }; - INSERT_PADDING_BYTES_NOINIT(5); // ImapFixedFncTexture[10] + } imap_systemc; + + std::array imap_texture; + INSERT_PADDING_BYTES_NOINIT(1); // ImapReserved INSERT_PADDING_BYTES_NOINIT(3); // OmapSystemValuesA @@ -115,7 +118,7 @@ struct ProgramHeader { std::array omap_generic_vector; - INSERT_PADDING_BYTES_NOINIT(2); // OmapColor + std::array omap_color; union { BitField<0, 8, u16> clip_distances; @@ -128,21 +131,13 @@ struct ProgramHeader { BitField<15, 1, u16> vertex_id; } omap_systemc; - INSERT_PADDING_BYTES_NOINIT(5); // OmapFixedFncTexture[10] + std::array omap_texture; + INSERT_PADDING_BYTES_NOINIT(1); // OmapReserved - [[nodiscard]] std::array InputGeneric(size_t index) const noexcept { - const int data{imap_generic_vector[index >> 1] >> ((index % 2) * 4)}; - return { - (data & 1) != 0, - (data & 2) != 0, - (data & 4) != 0, - (data & 8) != 0, - }; - } - - [[nodiscard]] std::array OutputGeneric(size_t index) const noexcept { - const int data{omap_generic_vector[index >> 1] >> ((index % 2) * 4)}; + template + [[nodiscard]] std::array Mask(const T& attr, size_t index) const noexcept { + const int data{attr[index >> 1] >> ((index % 2) * 4)}; return { (data & 1) != 0, (data & 2) != 0,