diff options
Diffstat (limited to 'src')
7 files changed, 28 insertions, 8 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index dec4f434a..67d06faa0 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -533,4 +533,8 @@ Id EmitDPdxFine(EmitContext& ctx, Id op_a); | |||
| 533 | 533 | ||
| 534 | Id EmitDPdyFine(EmitContext& ctx, Id op_a); | 534 | Id EmitDPdyFine(EmitContext& ctx, Id op_a); |
| 535 | 535 | ||
| 536 | Id EmitDPdxCoarse(EmitContext& ctx, Id op_a); | ||
| 537 | |||
| 538 | Id EmitDPdyCoarse(EmitContext& ctx, Id op_a); | ||
| 539 | |||
| 536 | } // namespace Shader::Backend::SPIRV | 540 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp index d53412204..a255f9ba7 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp | |||
| @@ -191,4 +191,12 @@ Id EmitDPdyFine(EmitContext& ctx, Id op_a) { | |||
| 191 | return ctx.OpDPdyFine(ctx.F32[1], op_a); | 191 | return ctx.OpDPdyFine(ctx.F32[1], op_a); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | Id EmitDPdxCoarse(EmitContext& ctx, Id op_a) { | ||
| 195 | return ctx.OpDPdxCoarse(ctx.F32[1], op_a); | ||
| 196 | } | ||
| 197 | |||
| 198 | Id EmitDPdyCoarse(EmitContext& ctx, Id op_a) { | ||
| 199 | return ctx.OpDPdyCoarse(ctx.F32[1], op_a); | ||
| 200 | } | ||
| 201 | |||
| 194 | } // namespace Shader::Backend::SPIRV | 202 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 845a57b1e..b3c9fe72a 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -1933,4 +1933,12 @@ F32 IREmitter::DPdyFine(const F32& a) { | |||
| 1933 | return Inst<F32>(Opcode::DPdyFine, a); | 1933 | return Inst<F32>(Opcode::DPdyFine, a); |
| 1934 | } | 1934 | } |
| 1935 | 1935 | ||
| 1936 | F32 IREmitter::DPdxCoarse(const F32& a) { | ||
| 1937 | return Inst<F32>(Opcode::DPdxCoarse, a); | ||
| 1938 | } | ||
| 1939 | |||
| 1940 | F32 IREmitter::DPdyCoarse(const F32& a) { | ||
| 1941 | return Inst<F32>(Opcode::DPdyCoarse, a); | ||
| 1942 | } | ||
| 1943 | |||
| 1936 | } // namespace Shader::IR | 1944 | } // namespace Shader::IR |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index c7101d668..4441c495d 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -357,6 +357,10 @@ public: | |||
| 357 | 357 | ||
| 358 | [[nodiscard]] F32 DPdyFine(const F32& a); | 358 | [[nodiscard]] F32 DPdyFine(const F32& a); |
| 359 | 359 | ||
| 360 | [[nodiscard]] F32 DPdxCoarse(const F32& a); | ||
| 361 | |||
| 362 | [[nodiscard]] F32 DPdyCoarse(const F32& a); | ||
| 363 | |||
| 360 | private: | 364 | private: |
| 361 | IR::Block::iterator insertion_point; | 365 | IR::Block::iterator insertion_point; |
| 362 | 366 | ||
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index e4cb8964a..b6869d4e4 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -513,3 +513,5 @@ OPCODE(ShuffleButterfly, U32, U32, | |||
| 513 | OPCODE(FSwizzleAdd, F32, F32, F32, U32, ) | 513 | OPCODE(FSwizzleAdd, F32, F32, F32, U32, ) |
| 514 | OPCODE(DPdxFine, F32, F32, ) | 514 | OPCODE(DPdxFine, F32, F32, ) |
| 515 | OPCODE(DPdyFine, F32, F32, ) | 515 | OPCODE(DPdyFine, F32, F32, ) |
| 516 | OPCODE(DPdxCoarse, F32, F32, ) | ||
| 517 | OPCODE(DPdyCoarse, F32, F32, ) | ||
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 e5688667b..7473e0bc2 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -532,6 +532,8 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 532 | break; | 532 | break; |
| 533 | case IR::Opcode::DPdxFine: | 533 | case IR::Opcode::DPdxFine: |
| 534 | case IR::Opcode::DPdyFine: | 534 | case IR::Opcode::DPdyFine: |
| 535 | case IR::Opcode::DPdxCoarse: | ||
| 536 | case IR::Opcode::DPdyCoarse: | ||
| 535 | info.uses_derivates = true; | 537 | info.uses_derivates = true; |
| 536 | break; | 538 | break; |
| 537 | case IR::Opcode::LoadStorageU8: | 539 | case IR::Opcode::LoadStorageU8: |
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index 983fb20ab..7e86f64a8 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -428,19 +428,15 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) { | |||
| 428 | if (!swizzle.IsImmediate()) { | 428 | if (!swizzle.IsImmediate()) { |
| 429 | return; | 429 | return; |
| 430 | } | 430 | } |
| 431 | |||
| 432 | const IR::Value value_1{GetThroughCast(inst.Arg(0).Resolve(), IR::Opcode::BitCastF32U32)}; | 431 | const IR::Value value_1{GetThroughCast(inst.Arg(0).Resolve(), IR::Opcode::BitCastF32U32)}; |
| 433 | const IR::Value value_2{GetThroughCast(inst.Arg(1).Resolve(), IR::Opcode::BitCastF32U32)}; | 432 | const IR::Value value_2{GetThroughCast(inst.Arg(1).Resolve(), IR::Opcode::BitCastF32U32)}; |
| 434 | |||
| 435 | if (value_1.IsImmediate()) { | 433 | if (value_1.IsImmediate()) { |
| 436 | return; | 434 | return; |
| 437 | } | 435 | } |
| 438 | |||
| 439 | const u32 swizzle_value{swizzle.U32()}; | 436 | const u32 swizzle_value{swizzle.U32()}; |
| 440 | if (swizzle_value != 0x99 && swizzle_value != 0xA5) { | 437 | if (swizzle_value != 0x99 && swizzle_value != 0xA5) { |
| 441 | return; | 438 | return; |
| 442 | } | 439 | } |
| 443 | |||
| 444 | IR::Inst* const inst2{value_1.InstRecursive()}; | 440 | IR::Inst* const inst2{value_1.InstRecursive()}; |
| 445 | if (inst2->GetOpcode() != IR::Opcode::ShuffleButterfly) { | 441 | if (inst2->GetOpcode() != IR::Opcode::ShuffleButterfly) { |
| 446 | return; | 442 | return; |
| @@ -449,19 +445,15 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) { | |||
| 449 | if (value_2 != value_3) { | 445 | if (value_2 != value_3) { |
| 450 | return; | 446 | return; |
| 451 | } | 447 | } |
| 452 | |||
| 453 | const IR::Value index{inst2->Arg(1)}; | 448 | const IR::Value index{inst2->Arg(1)}; |
| 454 | const IR::Value clamp{inst2->Arg(2)}; | 449 | const IR::Value clamp{inst2->Arg(2)}; |
| 455 | const IR::Value segmentation_mask{inst2->Arg(3)}; | 450 | const IR::Value segmentation_mask{inst2->Arg(3)}; |
| 456 | |||
| 457 | if (!index.IsImmediate() || !clamp.IsImmediate() || !segmentation_mask.IsImmediate()) { | 451 | if (!index.IsImmediate() || !clamp.IsImmediate() || !segmentation_mask.IsImmediate()) { |
| 458 | return; | 452 | return; |
| 459 | } | 453 | } |
| 460 | |||
| 461 | if (clamp.U32() != 3 || segmentation_mask.U32() != 28) { | 454 | if (clamp.U32() != 3 || segmentation_mask.U32() != 28) { |
| 462 | return; | 455 | return; |
| 463 | } | 456 | } |
| 464 | |||
| 465 | if (swizzle_value == 0x99) { | 457 | if (swizzle_value == 0x99) { |
| 466 | // DPdxFine | 458 | // DPdxFine |
| 467 | if (index.U32() == 1) { | 459 | if (index.U32() == 1) { |