Selaa lähdekoodia

shader: Add coarse derivatives

FernandoS27 5 vuotta sitten
vanhempi
commit
080857b60e

+ 4 - 0
src/shader_recompiler/backend/spirv/emit_spirv.h

@@ -533,4 +533,8 @@ Id EmitDPdxFine(EmitContext& ctx, Id op_a);
 
 
 Id EmitDPdyFine(EmitContext& ctx, Id op_a);
 Id EmitDPdyFine(EmitContext& ctx, Id op_a);
 
 
+Id EmitDPdxCoarse(EmitContext& ctx, Id op_a);
+
+Id EmitDPdyCoarse(EmitContext& ctx, Id op_a);
+
 } // namespace Shader::Backend::SPIRV
 } // namespace Shader::Backend::SPIRV

+ 8 - 0
src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp

@@ -191,4 +191,12 @@ Id EmitDPdyFine(EmitContext& ctx, Id op_a) {
     return ctx.OpDPdyFine(ctx.F32[1], op_a);
     return ctx.OpDPdyFine(ctx.F32[1], op_a);
 }
 }
 
 
+Id EmitDPdxCoarse(EmitContext& ctx, Id op_a) {
+    return ctx.OpDPdxCoarse(ctx.F32[1], op_a);
+}
+
+Id EmitDPdyCoarse(EmitContext& ctx, Id op_a) {
+    return ctx.OpDPdyCoarse(ctx.F32[1], op_a);
+}
+
 } // namespace Shader::Backend::SPIRV
 } // namespace Shader::Backend::SPIRV

+ 8 - 0
src/shader_recompiler/frontend/ir/ir_emitter.cpp

@@ -1933,4 +1933,12 @@ F32 IREmitter::DPdyFine(const F32& a) {
     return Inst<F32>(Opcode::DPdyFine, a);
     return Inst<F32>(Opcode::DPdyFine, a);
 }
 }
 
 
+F32 IREmitter::DPdxCoarse(const F32& a) {
+    return Inst<F32>(Opcode::DPdxCoarse, a);
+}
+
+F32 IREmitter::DPdyCoarse(const F32& a) {
+    return Inst<F32>(Opcode::DPdyCoarse, a);
+}
+
 } // namespace Shader::IR
 } // namespace Shader::IR

+ 4 - 0
src/shader_recompiler/frontend/ir/ir_emitter.h

@@ -357,6 +357,10 @@ public:
 
 
     [[nodiscard]] F32 DPdyFine(const F32& a);
     [[nodiscard]] F32 DPdyFine(const F32& a);
 
 
+    [[nodiscard]] F32 DPdxCoarse(const F32& a);
+
+    [[nodiscard]] F32 DPdyCoarse(const F32& a);
+
 private:
 private:
     IR::Block::iterator insertion_point;
     IR::Block::iterator insertion_point;
 
 

+ 2 - 0
src/shader_recompiler/frontend/ir/opcodes.inc

@@ -513,3 +513,5 @@ OPCODE(ShuffleButterfly,                                    U32,            U32,
 OPCODE(FSwizzleAdd,                                         F32,            F32,            F32,            U32,                                            )
 OPCODE(FSwizzleAdd,                                         F32,            F32,            F32,            U32,                                            )
 OPCODE(DPdxFine,                                            F32,            F32,                                                                            )
 OPCODE(DPdxFine,                                            F32,            F32,                                                                            )
 OPCODE(DPdyFine,                                            F32,            F32,                                                                            )
 OPCODE(DPdyFine,                                            F32,            F32,                                                                            )
+OPCODE(DPdxCoarse,                                          F32,            F32,                                                                            )
+OPCODE(DPdyCoarse,                                          F32,            F32,                                                                            )

+ 2 - 0
src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp

@@ -532,6 +532,8 @@ void VisitUsages(Info& info, IR::Inst& inst) {
         break;
         break;
     case IR::Opcode::DPdxFine:
     case IR::Opcode::DPdxFine:
     case IR::Opcode::DPdyFine:
     case IR::Opcode::DPdyFine:
+    case IR::Opcode::DPdxCoarse:
+    case IR::Opcode::DPdyCoarse:
         info.uses_derivates = true;
         info.uses_derivates = true;
         break;
         break;
     case IR::Opcode::LoadStorageU8:
     case IR::Opcode::LoadStorageU8:

+ 0 - 8
src/shader_recompiler/ir_opt/constant_propagation_pass.cpp

@@ -428,19 +428,15 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) {
     if (!swizzle.IsImmediate()) {
     if (!swizzle.IsImmediate()) {
         return;
         return;
     }
     }
-
     const IR::Value value_1{GetThroughCast(inst.Arg(0).Resolve(), IR::Opcode::BitCastF32U32)};
     const IR::Value value_1{GetThroughCast(inst.Arg(0).Resolve(), IR::Opcode::BitCastF32U32)};
     const IR::Value value_2{GetThroughCast(inst.Arg(1).Resolve(), IR::Opcode::BitCastF32U32)};
     const IR::Value value_2{GetThroughCast(inst.Arg(1).Resolve(), IR::Opcode::BitCastF32U32)};
-
     if (value_1.IsImmediate()) {
     if (value_1.IsImmediate()) {
         return;
         return;
     }
     }
-
     const u32 swizzle_value{swizzle.U32()};
     const u32 swizzle_value{swizzle.U32()};
     if (swizzle_value != 0x99 && swizzle_value != 0xA5) {
     if (swizzle_value != 0x99 && swizzle_value != 0xA5) {
         return;
         return;
     }
     }
-
     IR::Inst* const inst2{value_1.InstRecursive()};
     IR::Inst* const inst2{value_1.InstRecursive()};
     if (inst2->GetOpcode() != IR::Opcode::ShuffleButterfly) {
     if (inst2->GetOpcode() != IR::Opcode::ShuffleButterfly) {
         return;
         return;
@@ -449,19 +445,15 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) {
     if (value_2 != value_3) {
     if (value_2 != value_3) {
         return;
         return;
     }
     }
-
     const IR::Value index{inst2->Arg(1)};
     const IR::Value index{inst2->Arg(1)};
     const IR::Value clamp{inst2->Arg(2)};
     const IR::Value clamp{inst2->Arg(2)};
     const IR::Value segmentation_mask{inst2->Arg(3)};
     const IR::Value segmentation_mask{inst2->Arg(3)};
-
     if (!index.IsImmediate() || !clamp.IsImmediate() || !segmentation_mask.IsImmediate()) {
     if (!index.IsImmediate() || !clamp.IsImmediate() || !segmentation_mask.IsImmediate()) {
         return;
         return;
     }
     }
-
     if (clamp.U32() != 3 || segmentation_mask.U32() != 28) {
     if (clamp.U32() != 3 || segmentation_mask.U32() != 28) {
         return;
         return;
     }
     }
-
     if (swizzle_value == 0x99) {
     if (swizzle_value == 0x99) {
         // DPdxFine
         // DPdxFine
         if (index.U32() == 1) {
         if (index.U32() == 1) {