summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp8
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp8
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h4
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc2
-rw-r--r--src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp2
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp8
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
534Id EmitDPdyFine(EmitContext& ctx, Id op_a); 534Id EmitDPdyFine(EmitContext& ctx, Id op_a);
535 535
536Id EmitDPdxCoarse(EmitContext& ctx, Id op_a);
537
538Id 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
194Id EmitDPdxCoarse(EmitContext& ctx, Id op_a) {
195 return ctx.OpDPdxCoarse(ctx.F32[1], op_a);
196}
197
198Id 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
1936F32 IREmitter::DPdxCoarse(const F32& a) {
1937 return Inst<F32>(Opcode::DPdxCoarse, a);
1938}
1939
1940F32 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
360private: 364private:
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,
513OPCODE(FSwizzleAdd, F32, F32, F32, U32, ) 513OPCODE(FSwizzleAdd, F32, F32, F32, U32, )
514OPCODE(DPdxFine, F32, F32, ) 514OPCODE(DPdxFine, F32, F32, )
515OPCODE(DPdyFine, F32, F32, ) 515OPCODE(DPdyFine, F32, F32, )
516OPCODE(DPdxCoarse, F32, F32, )
517OPCODE(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) {