From c03f0b3c893f2bc2ae4f1e1825c5ac1453c36710 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 18 Aug 2023 18:30:31 +0200 Subject: Shader Recomnpiler: implement textuzreGrad 3D emulation constant propagation --- .../backend/glasm/emit_glasm_image.cpp | 23 ++++++++++++++++++---- .../backend/glsl/emit_glsl_image.cpp | 8 +++++++- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'src/shader_recompiler/backend') diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp index 85ee27333..d0e308124 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp @@ -558,12 +558,15 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, const IR::Value& coord, const IR::Value& derivatives, const IR::Value& offset, const IR::Value& lod_clamp) { const auto info{inst.Flags()}; - ScopedRegister dpdx, dpdy; + ScopedRegister dpdx, dpdy, coords; const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; if (multi_component) { // Allocate this early to avoid aliasing other registers dpdx = ScopedRegister{ctx.reg_alloc}; dpdy = ScopedRegister{ctx.reg_alloc}; + if (info.num_derivates >= 3) { + coords = ScopedRegister{ctx.reg_alloc}; + } } const auto sparse_inst{PrepareSparse(inst)}; const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; @@ -580,15 +583,27 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, "MOV.F {}.y,{}.w;", dpdx.reg, derivatives_vec, dpdx.reg, derivatives_vec, dpdy.reg, derivatives_vec, dpdy.reg, derivatives_vec); + Register final_coord; + if (info.num_derivates >= 3) { + ctx.Add("MOV.F {}.z,{}.x;" + "MOV.F {}.z,{}.y;", + dpdx.reg, coord_vec, dpdy.reg, coord_vec); + ctx.Add("MOV.F {}.x,0;" + "MOV.F {}.y,0;", + "MOV.F {}.z,0;", coords.reg, coords.reg, coords.reg); + final_coord = coords.reg; + } else { + final_coord = coord_vec; + } if (info.has_lod_clamp) { const ScalarF32 lod_clamp_value{ctx.reg_alloc.Consume(lod_clamp)}; ctx.Add("MOV.F {}.w,{};" "TXD.F.LODCLAMP{} {},{},{},{},{},{}{};", - dpdy.reg, lod_clamp_value, sparse_mod, ret, coord_vec, dpdx.reg, dpdy.reg, + dpdy.reg, lod_clamp_value, sparse_mod, ret, final_coord, dpdx.reg, dpdy.reg, texture, type, offset_vec); } else { - ctx.Add("TXD.F{} {},{},{},{},{},{}{};", sparse_mod, ret, coord_vec, dpdx.reg, dpdy.reg, - texture, type, offset_vec); + ctx.Add("TXD.F{} {},{},{},{},{},{}{};", sparse_mod, ret, final_coord, dpdx.reg, + dpdy.reg, texture, type, offset_vec); } } else { ctx.Add("TXD.F{} {},{},{}.x,{}.y,{},{}{};", sparse_mod, ret, coord_vec, derivatives_vec, diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 418505475..3ad668a47 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp @@ -548,7 +548,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, if (sparse_inst) { throw NotImplementedException("EmitImageGradient Sparse"); } - if (!offset.IsEmpty()) { + if (!offset.IsEmpty() && info.num_derivates <= 2) { throw NotImplementedException("EmitImageGradient offset"); } const auto texture{Texture(ctx, info, index)}; @@ -556,6 +556,12 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; if (multi_component) { + if (info.num_derivates >= 3) { + const auto offset_vec{ctx.var_alloc.Consume(offset)}; + ctx.Add("{}=textureGrad({},{},vec3({}.xz, {}.x),vec3({}.yz, {}.y));", texel, texture, + coords, derivatives_vec, offset_vec, derivatives_vec, offset_vec); + return; + } ctx.Add("{}=textureGrad({},{},vec2({}.xz),vec2({}.yz));", texel, texture, coords, derivatives_vec, derivatives_vec); } else { -- cgit v1.2.3