summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-25 02:22:21 -0300
committerGravatar ameerj2021-07-22 21:51:33 -0400
commitca05a13c62ad7693f8be924c168e400e8139b0d2 (patch)
tree813638ab0c537089f3493f824707417dd429a48f /src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
parentglasm: Fix usage counting on phi nodes (diff)
downloadyuzu-ca05a13c62ad7693f8be924c168e400e8139b0d2.tar.gz
yuzu-ca05a13c62ad7693f8be924c168e400e8139b0d2.tar.xz
yuzu-ca05a13c62ad7693f8be924c168e400e8139b0d2.zip
glasm: Catch more register leaks
Add support for null registers. These are used when an instruction has no usages. This comes handy when an instruction is only used for its CC value, with the caveat of having to invalidate all pseudo-instructions before defining the instruction itself in the register allocator. This commits changes this. Workaround a bug on Nvidia's condition codes conditional execution using branches.
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm_image.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_image.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
index a7def0897..34725b8c6 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
@@ -181,7 +181,6 @@ void StoreSparse(EmitContext& ctx, IR::Inst* sparse_inst) {
181 ctx.Add("MOV.S {},-1;" 181 ctx.Add("MOV.S {},-1;"
182 "MOV.S {}(NONRESIDENT),0;", 182 "MOV.S {}(NONRESIDENT),0;",
183 sparse_ret, sparse_ret); 183 sparse_ret, sparse_ret);
184 sparse_inst->Invalidate();
185} 184}
186 185
187std::string_view FormatStorage(ImageFormat format) { 186std::string_view FormatStorage(ImageFormat format) {
@@ -215,12 +214,20 @@ void ImageAtomic(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Regis
215 const Register ret{ctx.reg_alloc.Define(inst)}; 214 const Register ret{ctx.reg_alloc.Define(inst)};
216 ctx.Add("ATOMIM.{} {},{},{},{},{};", op, ret, value, coord, image, type); 215 ctx.Add("ATOMIM.{} {},{},{},{},{};", op, ret, value, coord, image, type);
217} 216}
217
218IR::Inst* PrepareSparse(IR::Inst& inst) {
219 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
220 if (sparse_inst) {
221 sparse_inst->Invalidate();
222 }
223 return sparse_inst;
224}
218} // Anonymous namespace 225} // Anonymous namespace
219 226
220void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 227void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
221 const IR::Value& coord, Register bias_lc, const IR::Value& offset) { 228 const IR::Value& coord, Register bias_lc, const IR::Value& offset) {
222 const auto info{inst.Flags<IR::TextureInstInfo>()}; 229 const auto info{inst.Flags<IR::TextureInstInfo>()};
223 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 230 const auto sparse_inst{PrepareSparse(inst)};
224 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 231 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
225 const std::string_view lod_clamp_mod{info.has_lod_clamp ? ".LODCLAMP" : ""}; 232 const std::string_view lod_clamp_mod{info.has_lod_clamp ? ".LODCLAMP" : ""};
226 const std::string_view type{TextureType(info)}; 233 const std::string_view type{TextureType(info)};
@@ -259,7 +266,7 @@ void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu
259void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 266void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
260 const IR::Value& coord, ScalarF32 lod, const IR::Value& offset) { 267 const IR::Value& coord, ScalarF32 lod, const IR::Value& offset) {
261 const auto info{inst.Flags<IR::TextureInstInfo>()}; 268 const auto info{inst.Flags<IR::TextureInstInfo>()};
262 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 269 const auto sparse_inst{PrepareSparse(inst)};
263 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 270 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
264 const std::string_view type{TextureType(info)}; 271 const std::string_view type{TextureType(info)};
265 const std::string texture{Texture(ctx, info, index)}; 272 const std::string texture{Texture(ctx, info, index)};
@@ -288,7 +295,7 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
288 } 295 }
289 const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)}; 296 const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)};
290 const Register bias_lc_vec{ctx.reg_alloc.Consume(bias_lc)}; 297 const Register bias_lc_vec{ctx.reg_alloc.Consume(bias_lc)};
291 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 298 const auto sparse_inst{PrepareSparse(inst)};
292 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 299 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
293 const std::string_view type{TextureType(info)}; 300 const std::string_view type{TextureType(info)};
294 const std::string texture{Texture(ctx, info, index)}; 301 const std::string texture{Texture(ctx, info, index)};
@@ -393,7 +400,7 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
393 } 400 }
394 const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)}; 401 const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)};
395 const ScalarF32 lod_val{ctx.reg_alloc.Consume(lod)}; 402 const ScalarF32 lod_val{ctx.reg_alloc.Consume(lod)};
396 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 403 const auto sparse_inst{PrepareSparse(inst)};
397 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 404 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
398 const std::string_view type{TextureType(info)}; 405 const std::string_view type{TextureType(info)};
399 const std::string texture{Texture(ctx, info, index)}; 406 const std::string texture{Texture(ctx, info, index)};
@@ -436,7 +443,7 @@ void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
436 const auto [off_x, off_y]{AllocOffsetsRegs(ctx, offset2)}; 443 const auto [off_x, off_y]{AllocOffsetsRegs(ctx, offset2)};
437 const auto info{inst.Flags<IR::TextureInstInfo>()}; 444 const auto info{inst.Flags<IR::TextureInstInfo>()};
438 const char comp{"xyzw"[info.gather_component]}; 445 const char comp{"xyzw"[info.gather_component]};
439 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 446 const auto sparse_inst{PrepareSparse(inst)};
440 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 447 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
441 const std::string_view type{TextureType(info)}; 448 const std::string_view type{TextureType(info)};
442 const std::string texture{Texture(ctx, info, index)}; 449 const std::string texture{Texture(ctx, info, index)};
@@ -462,7 +469,7 @@ void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde
462 // Allocate offsets early so they don't overwrite any consumed register 469 // Allocate offsets early so they don't overwrite any consumed register
463 const auto [off_x, off_y]{AllocOffsetsRegs(ctx, offset2)}; 470 const auto [off_x, off_y]{AllocOffsetsRegs(ctx, offset2)};
464 const auto info{inst.Flags<IR::TextureInstInfo>()}; 471 const auto info{inst.Flags<IR::TextureInstInfo>()};
465 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 472 const auto sparse_inst{PrepareSparse(inst)};
466 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 473 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
467 const std::string_view type{TextureType(info)}; 474 const std::string_view type{TextureType(info)};
468 const std::string texture{Texture(ctx, info, index)}; 475 const std::string texture{Texture(ctx, info, index)};
@@ -500,7 +507,7 @@ void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde
500void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 507void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
501 const IR::Value& coord, const IR::Value& offset, ScalarS32 lod, ScalarS32 ms) { 508 const IR::Value& coord, const IR::Value& offset, ScalarS32 lod, ScalarS32 ms) {
502 const auto info{inst.Flags<IR::TextureInstInfo>()}; 509 const auto info{inst.Flags<IR::TextureInstInfo>()};
503 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 510 const auto sparse_inst{PrepareSparse(inst)};
504 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 511 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
505 const std::string_view type{TextureType(info)}; 512 const std::string_view type{TextureType(info)};
506 const std::string texture{Texture(ctx, info, index)}; 513 const std::string texture{Texture(ctx, info, index)};
@@ -547,7 +554,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
547 dpdx = ScopedRegister{ctx.reg_alloc}; 554 dpdx = ScopedRegister{ctx.reg_alloc};
548 dpdy = ScopedRegister{ctx.reg_alloc}; 555 dpdy = ScopedRegister{ctx.reg_alloc};
549 } 556 }
550 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 557 const auto sparse_inst{PrepareSparse(inst)};
551 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 558 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
552 const std::string_view type{TextureType(info)}; 559 const std::string_view type{TextureType(info)};
553 const std::string texture{Texture(ctx, info, index)}; 560 const std::string texture{Texture(ctx, info, index)};
@@ -581,7 +588,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
581 588
582void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord) { 589void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord) {
583 const auto info{inst.Flags<IR::TextureInstInfo>()}; 590 const auto info{inst.Flags<IR::TextureInstInfo>()};
584 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 591 const auto sparse_inst{PrepareSparse(inst)};
585 const std::string_view format{FormatStorage(info.image_format)}; 592 const std::string_view format{FormatStorage(info.image_format)};
586 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 593 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
587 const std::string_view type{TextureType(info)}; 594 const std::string_view type{TextureType(info)};