diff options
| author | 2021-05-20 15:58:39 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:32 -0400 | |
| commit | 0a54291c9c750d89feacef0644959326b9612b64 (patch) | |
| tree | 853e53b29e8287d3b232baf80f928e255c18f1d2 /src/shader_recompiler/backend/glasm/emit_glasm_image.cpp | |
| parent | glasm: Implement ImageWrite (diff) | |
| download | yuzu-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.cpp | 71 |
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 | ||
| 270 | void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 270 | void 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 | ||
| 372 | void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 375 | void 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 | } |