Переглянути джерело

Support gl_BackSecondaryColor attribute

vonchenplus 4 роки тому
батько
коміт
36c21ff6cb

+ 16 - 0
src/shader_recompiler/backend/spirv/emit_context.cpp

@@ -1302,6 +1302,14 @@ void EmitContext::DefineInputs(const IR::Program& program) {
         Decorate(id, spv::Decoration::Location, location);
         Decorate(id, spv::Decoration::Location, location);
         input_back_color = id;
         input_back_color = id;
     }
     }
+    if (loads.AnyComponent(IR::Attribute::ColorBackSpecularR)) {
+        const size_t location = FindNextUnusedLocation(used_locations, previous_unused_location);
+        previous_unused_location = location;
+        used_locations.set(location);
+        const Id id{DefineInput(*this, F32[4], true)};
+        Decorate(id, spv::Decoration::Location, location);
+        input_back_secondary_color = id;
+    }
     for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) {
     for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) {
         if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) {
         if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) {
             const size_t location =
             const size_t location =
@@ -1395,6 +1403,14 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
         Decorate(id, spv::Decoration::Location, static_cast<u32>(location));
         Decorate(id, spv::Decoration::Location, static_cast<u32>(location));
         output_back_color = id;
         output_back_color = id;
     }
     }
+    if (info.stores.AnyComponent(IR::Attribute::ColorBackSpecularR)) {
+        const size_t location = FindNextUnusedLocation(used_locations, previous_unused_location);
+        previous_unused_location = location;
+        used_locations.set(location);
+        const Id id{DefineOutput(*this, F32[4], invocations)};
+        Decorate(id, spv::Decoration::Location, static_cast<u32>(location));
+        output_back_secondary_color = id;
+    }
     for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) {
     for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) {
         if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) {
         if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) {
             const size_t location =
             const size_t location =

+ 2 - 0
src/shader_recompiler/backend/spirv/emit_context.h

@@ -271,6 +271,7 @@ public:
     Id input_front_color{};
     Id input_front_color{};
     Id input_front_secondary_color{};
     Id input_front_secondary_color{};
     Id input_back_color{};
     Id input_back_color{};
+    Id input_back_secondary_color{};
     std::array<Id, 10> input_fixed_fnc_textures{};
     std::array<Id, 10> input_fixed_fnc_textures{};
     std::array<Id, 32> input_generics{};
     std::array<Id, 32> input_generics{};
 
 
@@ -279,6 +280,7 @@ public:
     Id output_front_color{};
     Id output_front_color{};
     Id output_front_secondary_color{};
     Id output_front_secondary_color{};
     Id output_back_color{};
     Id output_back_color{};
+    Id output_back_secondary_color{};
     std::array<Id, 10> output_fixed_fnc_textures{};
     std::array<Id, 10> output_fixed_fnc_textures{};
     std::array<std::array<GenericElementInfo, 4>, 32> output_generics{};
     std::array<std::array<GenericElementInfo, 4>, 32> output_generics{};
 
 

+ 15 - 0
src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp

@@ -135,6 +135,14 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
         const Id element_id{ctx.Const(element)};
         const Id element_id{ctx.Const(element)};
         return OutputAccessChain(ctx, ctx.output_f32, ctx.output_back_color, element_id);
         return OutputAccessChain(ctx, ctx.output_f32, ctx.output_back_color, element_id);
     }
     }
+    case IR::Attribute::ColorBackSpecularR:
+    case IR::Attribute::ColorBackSpecularG:
+    case IR::Attribute::ColorBackSpecularB:
+    case IR::Attribute::ColorBackSpecularA: {
+        const u32 element{static_cast<u32>(attr) % 4};
+        const Id element_id{ctx.Const(element)};
+        return OutputAccessChain(ctx, ctx.output_f32, ctx.output_back_secondary_color, element_id);
+    }
     case IR::Attribute::ClipDistance0:
     case IR::Attribute::ClipDistance0:
     case IR::Attribute::ClipDistance1:
     case IR::Attribute::ClipDistance1:
     case IR::Attribute::ClipDistance2:
     case IR::Attribute::ClipDistance2:
@@ -393,6 +401,13 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
         return ctx.OpLoad(ctx.F32[1], AttrPointer(ctx, ctx.input_f32, vertex, ctx.input_back_color,
         return ctx.OpLoad(ctx.F32[1], AttrPointer(ctx, ctx.input_f32, vertex, ctx.input_back_color,
                                                   ctx.Const(element)));
                                                   ctx.Const(element)));
     }
     }
+    case IR::Attribute::ColorBackSpecularR:
+    case IR::Attribute::ColorBackSpecularG:
+    case IR::Attribute::ColorBackSpecularB:
+    case IR::Attribute::ColorBackSpecularA: {
+        return ctx.OpLoad(ctx.F32[1], AttrPointer(ctx, ctx.input_f32, vertex, ctx.input_back_secondary_color,
+                                                  ctx.Const(element)));
+    }
     case IR::Attribute::InstanceId:
     case IR::Attribute::InstanceId:
         if (ctx.profile.support_vertex_instance_id) {
         if (ctx.profile.support_vertex_instance_id) {
             return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.instance_id));
             return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.instance_id));