summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_image.cpp71
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h8
2 files changed, 44 insertions, 35 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
index ed0b65e16..385ca51ac 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
@@ -268,9 +268,16 @@ void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu
}
void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
- const IR::Value& coord, ScalarF32 dref, Register bias_lc,
- const IR::Value& offset) {
+ const IR::Value& coord, const IR::Value& dref,
+ const IR::Value& bias_lc, const IR::Value& offset) {
+ // Allocate early to avoid aliases
const auto info{inst.Flags<IR::TextureInstInfo>()};
+ ScopedRegister staging;
+ if (info.type == TextureType::ColorArrayCube) {
+ staging = ScopedRegister{ctx.reg_alloc};
+ }
+ const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)};
+ const Register bias_lc_vec{ctx.reg_alloc.Consume(bias_lc)};
const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
const std::string_view type{TextureType(info)};
@@ -287,14 +294,14 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
ctx.Add("MOV.F {}.z,{};"
"MOV.F {}.w,{}.x;"
"TXB.F.LODCLAMP{} {},{},{}.y,{},{}{};",
- coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, bias_lc,
- texture, type, offset_vec);
+ coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec,
+ bias_lc_vec, texture, type, offset_vec);
break;
case TextureType::ColorArray2D:
case TextureType::ColorCube:
ctx.Add("MOV.F {}.w,{};"
"TXB.F.LODCLAMP{} {},{},{},{},{}{};",
- coord_vec, dref, sparse_mod, ret, coord_vec, bias_lc, texture, type,
+ coord_vec, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, texture, type,
offset_vec);
break;
default:
@@ -309,25 +316,23 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
ctx.Add("MOV.F {}.z,{};"
"MOV.F {}.w,{}.x;"
"TXB.F{} {},{},{},{}{};",
- coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, texture,
- type, offset_vec);
+ coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec,
+ texture, type, offset_vec);
break;
case TextureType::ColorArray2D:
case TextureType::ColorCube:
ctx.Add("MOV.F {}.w,{};"
"TXB.F{} {},{},{},{},{}{};",
- coord_vec, dref, sparse_mod, ret, coord_vec, bias_lc, texture, type,
+ coord_vec, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, texture, type,
offset_vec);
break;
- case TextureType::ColorArrayCube: {
- const ScopedRegister pair{ctx.reg_alloc};
+ case TextureType::ColorArrayCube:
ctx.Add("MOV.F {}.x,{};"
"MOV.F {}.y,{}.x;"
"TXB.F{} {},{},{},{},{}{};",
- pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg,
- texture, type, offset_vec);
+ staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec,
+ staging.reg, texture, type, offset_vec);
break;
- }
default:
throw NotImplementedException("Invalid type {}", info.type.Value());
}
@@ -340,15 +345,14 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
const char dref_swizzle{w_swizzle ? 'w' : 'z'};
ctx.Add("MOV.F {}.{},{};"
"TEX.F.LODCLAMP{} {},{},{},{},{}{};",
- coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, bias_lc, texture,
- type, offset_vec);
+ coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec,
+ texture, type, offset_vec);
} else {
- const ScopedRegister pair{ctx.reg_alloc};
ctx.Add("MOV.F {}.x,{};"
"MOV.F {}.y,{};"
"TEX.F.LODCLAMP{} {},{},{},{},{}{};",
- pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg,
- texture, type, offset_vec);
+ staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec,
+ staging.reg, texture, type, offset_vec);
}
} else {
if (info.type != TextureType::ColorArrayCube) {
@@ -357,11 +361,10 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
const char dref_swizzle{w_swizzle ? 'w' : 'z'};
ctx.Add("MOV.F {}.{},{};"
"TEX.F{} {},{},{},{}{};",
- coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, texture, type,
- offset_vec);
+ coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, texture,
+ type, offset_vec);
} else {
- const ScopedRegister pair{ctx.reg_alloc};
- ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref, texture,
+ ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref_val, texture,
type, offset_vec);
}
}
@@ -370,9 +373,16 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
}
void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
- const IR::Value& coord, ScalarF32 dref, ScalarF32 lod,
- const IR::Value& offset) {
+ const IR::Value& coord, const IR::Value& dref,
+ const IR::Value& lod, const IR::Value& offset) {
+ // Allocate early to avoid aliases
const auto info{inst.Flags<IR::TextureInstInfo>()};
+ ScopedRegister staging;
+ if (info.type == TextureType::ColorArrayCube) {
+ staging = ScopedRegister{ctx.reg_alloc};
+ }
+ const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)};
+ const ScalarF32 lod_val{ctx.reg_alloc.Consume(lod)};
const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
const std::string_view type{TextureType(info)};
@@ -387,24 +397,23 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
ctx.Add("MOV.F {}.z,{};"
"MOV.F {}.w,{};"
"TXL.F{} {},{},{},{}{};",
- coord_vec, dref, coord_vec, lod, sparse_mod, ret, coord_vec, texture, type,
+ coord_vec, dref_val, coord_vec, lod_val, sparse_mod, ret, coord_vec, texture, type,
offset_vec);
break;
case TextureType::ColorArray2D:
case TextureType::ColorCube:
ctx.Add("MOV.F {}.w,{};"
"TXL.F{} {},{},{},{},{}{};",
- coord_vec, dref, sparse_mod, ret, coord_vec, lod, texture, type, offset_vec);
+ coord_vec, dref_val, sparse_mod, ret, coord_vec, lod_val, texture, type,
+ offset_vec);
break;
- case TextureType::ColorArrayCube: {
- const ScopedRegister pair{ctx.reg_alloc};
+ case TextureType::ColorArrayCube:
ctx.Add("MOV.F {}.x,{};"
"MOV.F {}.y,{};"
"TXL.F{} {},{},{},{},{}{};",
- pair.reg, dref, pair.reg, lod, sparse_mod, ret, coord_vec, pair.reg, texture, type,
- offset_vec);
+ staging.reg, dref_val, staging.reg, lod_val, sparse_mod, ret, coord_vec,
+ staging.reg, texture, type, offset_vec);
break;
- }
default:
throw NotImplementedException("Invalid type {}", info.type.Value());
}
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 0ce00db67..22d427817 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -533,11 +533,11 @@ void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu
void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
const IR::Value& coord, ScalarF32 lod, const IR::Value& offset);
void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
- const IR::Value& coord, ScalarF32 dref, Register bias_lc,
- const IR::Value& offset);
+ const IR::Value& coord, const IR::Value& dref,
+ const IR::Value& bias_lc, const IR::Value& offset);
void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
- const IR::Value& coord, ScalarF32 dref, ScalarF32 lod,
- const IR::Value& offset);
+ const IR::Value& coord, const IR::Value& dref,
+ const IR::Value& lod, const IR::Value& offset);
void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
const IR::Value& coord, const IR::Value& offset, const IR::Value& offset2);
void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,