summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-20 15:58:39 -0300
committerGravatar ameerj2021-07-22 21:51:32 -0400
commit0a54291c9c750d89feacef0644959326b9612b64 (patch)
tree853e53b29e8287d3b232baf80f928e255c18f1d2 /src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
parentglasm: Implement ImageWrite (diff)
downloadyuzu-0a54291c9c750d89feacef0644959326b9612b64.tar.gz
yuzu-0a54291c9c750d89feacef0644959326b9612b64.tar.xz
yuzu-0a54291c9c750d89feacef0644959326b9612b64.zip
glasm: Fix potential aliasing bug on cube array samples
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm_image.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_image.cpp71
1 files changed, 40 insertions, 31 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
268} 268}
269 269
270void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 270void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
271 const IR::Value& coord, ScalarF32 dref, Register bias_lc, 271 const IR::Value& coord, const IR::Value& dref,
272 const IR::Value& offset) { 272 const IR::Value& bias_lc, const IR::Value& offset) {
273 // Allocate early to avoid aliases
273 const auto info{inst.Flags<IR::TextureInstInfo>()}; 274 const auto info{inst.Flags<IR::TextureInstInfo>()};
275 ScopedRegister staging;
276 if (info.type == TextureType::ColorArrayCube) {
277 staging = ScopedRegister{ctx.reg_alloc};
278 }
279 const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)};
280 const Register bias_lc_vec{ctx.reg_alloc.Consume(bias_lc)};
274 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 281 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
275 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 282 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
276 const std::string_view type{TextureType(info)}; 283 const std::string_view type{TextureType(info)};
@@ -287,14 +294,14 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
287 ctx.Add("MOV.F {}.z,{};" 294 ctx.Add("MOV.F {}.z,{};"
288 "MOV.F {}.w,{}.x;" 295 "MOV.F {}.w,{}.x;"
289 "TXB.F.LODCLAMP{} {},{},{}.y,{},{}{};", 296 "TXB.F.LODCLAMP{} {},{},{}.y,{},{}{};",
290 coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, bias_lc, 297 coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec,
291 texture, type, offset_vec); 298 bias_lc_vec, texture, type, offset_vec);
292 break; 299 break;
293 case TextureType::ColorArray2D: 300 case TextureType::ColorArray2D:
294 case TextureType::ColorCube: 301 case TextureType::ColorCube:
295 ctx.Add("MOV.F {}.w,{};" 302 ctx.Add("MOV.F {}.w,{};"
296 "TXB.F.LODCLAMP{} {},{},{},{},{}{};", 303 "TXB.F.LODCLAMP{} {},{},{},{},{}{};",
297 coord_vec, dref, sparse_mod, ret, coord_vec, bias_lc, texture, type, 304 coord_vec, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, texture, type,
298 offset_vec); 305 offset_vec);
299 break; 306 break;
300 default: 307 default:
@@ -309,25 +316,23 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
309 ctx.Add("MOV.F {}.z,{};" 316 ctx.Add("MOV.F {}.z,{};"
310 "MOV.F {}.w,{}.x;" 317 "MOV.F {}.w,{}.x;"
311 "TXB.F{} {},{},{},{}{};", 318 "TXB.F{} {},{},{},{}{};",
312 coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, texture, 319 coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec,
313 type, offset_vec); 320 texture, type, offset_vec);
314 break; 321 break;
315 case TextureType::ColorArray2D: 322 case TextureType::ColorArray2D:
316 case TextureType::ColorCube: 323 case TextureType::ColorCube:
317 ctx.Add("MOV.F {}.w,{};" 324 ctx.Add("MOV.F {}.w,{};"
318 "TXB.F{} {},{},{},{},{}{};", 325 "TXB.F{} {},{},{},{},{}{};",
319 coord_vec, dref, sparse_mod, ret, coord_vec, bias_lc, texture, type, 326 coord_vec, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, texture, type,
320 offset_vec); 327 offset_vec);
321 break; 328 break;
322 case TextureType::ColorArrayCube: { 329 case TextureType::ColorArrayCube:
323 const ScopedRegister pair{ctx.reg_alloc};
324 ctx.Add("MOV.F {}.x,{};" 330 ctx.Add("MOV.F {}.x,{};"
325 "MOV.F {}.y,{}.x;" 331 "MOV.F {}.y,{}.x;"
326 "TXB.F{} {},{},{},{},{}{};", 332 "TXB.F{} {},{},{},{},{}{};",
327 pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg, 333 staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec,
328 texture, type, offset_vec); 334 staging.reg, texture, type, offset_vec);
329 break; 335 break;
330 }
331 default: 336 default:
332 throw NotImplementedException("Invalid type {}", info.type.Value()); 337 throw NotImplementedException("Invalid type {}", info.type.Value());
333 } 338 }
@@ -340,15 +345,14 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
340 const char dref_swizzle{w_swizzle ? 'w' : 'z'}; 345 const char dref_swizzle{w_swizzle ? 'w' : 'z'};
341 ctx.Add("MOV.F {}.{},{};" 346 ctx.Add("MOV.F {}.{},{};"
342 "TEX.F.LODCLAMP{} {},{},{},{},{}{};", 347 "TEX.F.LODCLAMP{} {},{},{},{},{}{};",
343 coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, bias_lc, texture, 348 coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec,
344 type, offset_vec); 349 texture, type, offset_vec);
345 } else { 350 } else {
346 const ScopedRegister pair{ctx.reg_alloc};
347 ctx.Add("MOV.F {}.x,{};" 351 ctx.Add("MOV.F {}.x,{};"
348 "MOV.F {}.y,{};" 352 "MOV.F {}.y,{};"
349 "TEX.F.LODCLAMP{} {},{},{},{},{}{};", 353 "TEX.F.LODCLAMP{} {},{},{},{},{}{};",
350 pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg, 354 staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec,
351 texture, type, offset_vec); 355 staging.reg, texture, type, offset_vec);
352 } 356 }
353 } else { 357 } else {
354 if (info.type != TextureType::ColorArrayCube) { 358 if (info.type != TextureType::ColorArrayCube) {
@@ -357,11 +361,10 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
357 const char dref_swizzle{w_swizzle ? 'w' : 'z'}; 361 const char dref_swizzle{w_swizzle ? 'w' : 'z'};
358 ctx.Add("MOV.F {}.{},{};" 362 ctx.Add("MOV.F {}.{},{};"
359 "TEX.F{} {},{},{},{}{};", 363 "TEX.F{} {},{},{},{}{};",
360 coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, texture, type, 364 coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, texture,
361 offset_vec); 365 type, offset_vec);
362 } else { 366 } else {
363 const ScopedRegister pair{ctx.reg_alloc}; 367 ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref_val, texture,
364 ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref, texture,
365 type, offset_vec); 368 type, offset_vec);
366 } 369 }
367 } 370 }
@@ -370,9 +373,16 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
370} 373}
371 374
372void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 375void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
373 const IR::Value& coord, ScalarF32 dref, ScalarF32 lod, 376 const IR::Value& coord, const IR::Value& dref,
374 const IR::Value& offset) { 377 const IR::Value& lod, const IR::Value& offset) {
378 // Allocate early to avoid aliases
375 const auto info{inst.Flags<IR::TextureInstInfo>()}; 379 const auto info{inst.Flags<IR::TextureInstInfo>()};
380 ScopedRegister staging;
381 if (info.type == TextureType::ColorArrayCube) {
382 staging = ScopedRegister{ctx.reg_alloc};
383 }
384 const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)};
385 const ScalarF32 lod_val{ctx.reg_alloc.Consume(lod)};
376 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; 386 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
377 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; 387 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
378 const std::string_view type{TextureType(info)}; 388 const std::string_view type{TextureType(info)};
@@ -387,24 +397,23 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
387 ctx.Add("MOV.F {}.z,{};" 397 ctx.Add("MOV.F {}.z,{};"
388 "MOV.F {}.w,{};" 398 "MOV.F {}.w,{};"
389 "TXL.F{} {},{},{},{}{};", 399 "TXL.F{} {},{},{},{}{};",
390 coord_vec, dref, coord_vec, lod, sparse_mod, ret, coord_vec, texture, type, 400 coord_vec, dref_val, coord_vec, lod_val, sparse_mod, ret, coord_vec, texture, type,
391 offset_vec); 401 offset_vec);
392 break; 402 break;
393 case TextureType::ColorArray2D: 403 case TextureType::ColorArray2D:
394 case TextureType::ColorCube: 404 case TextureType::ColorCube:
395 ctx.Add("MOV.F {}.w,{};" 405 ctx.Add("MOV.F {}.w,{};"
396 "TXL.F{} {},{},{},{},{}{};", 406 "TXL.F{} {},{},{},{},{}{};",
397 coord_vec, dref, sparse_mod, ret, coord_vec, lod, texture, type, offset_vec); 407 coord_vec, dref_val, sparse_mod, ret, coord_vec, lod_val, texture, type,
408 offset_vec);
398 break; 409 break;
399 case TextureType::ColorArrayCube: { 410 case TextureType::ColorArrayCube:
400 const ScopedRegister pair{ctx.reg_alloc};
401 ctx.Add("MOV.F {}.x,{};" 411 ctx.Add("MOV.F {}.x,{};"
402 "MOV.F {}.y,{};" 412 "MOV.F {}.y,{};"
403 "TXL.F{} {},{},{},{},{}{};", 413 "TXL.F{} {},{},{},{},{}{};",
404 pair.reg, dref, pair.reg, lod, sparse_mod, ret, coord_vec, pair.reg, texture, type, 414 staging.reg, dref_val, staging.reg, lod_val, sparse_mod, ret, coord_vec,
405 offset_vec); 415 staging.reg, texture, type, offset_vec);
406 break; 416 break;
407 }
408 default: 417 default:
409 throw NotImplementedException("Invalid type {}", info.type.Value()); 418 throw NotImplementedException("Invalid type {}", info.type.Value());
410 } 419 }