diff options
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_image.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 2f925cc3e..7d7c0627e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -470,8 +470,30 @@ void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id | |||
| 470 | ctx.OpImageWrite(Image(ctx, index, info), coords, color); | 470 | ctx.OpImageWrite(Image(ctx, index, info), coords, color); |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | Id EmitIsTextureScaled([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& index) { | 473 | Id EmitIsTextureScaled(EmitContext& ctx, const IR::Value& index) { |
| 474 | return ctx.false_value; | 474 | const Id push_constant_u32{ctx.TypePointer(spv::StorageClass::PushConstant, ctx.U32[1])}; |
| 475 | const Id member_index{ctx.Const(ctx.rescaling_textures_member_index)}; | ||
| 476 | Id bit{}; | ||
| 477 | if (index.IsImmediate()) { | ||
| 478 | // Use BitwiseAnd instead of BitfieldExtract for better codegen on Nvidia OpenGL. | ||
| 479 | // LOP32I.NZ is used to set the predicate rather than BFE+ISETP. | ||
| 480 | const u32 index_value{index.U32()}; | ||
| 481 | const Id word_index{ctx.Const(index_value / 32)}; | ||
| 482 | const Id bit_index_mask{ctx.Const(1u << (index_value % 32))}; | ||
| 483 | const Id pointer{ctx.OpAccessChain(push_constant_u32, ctx.rescaling_push_constants, | ||
| 484 | member_index, word_index)}; | ||
| 485 | const Id word{ctx.OpLoad(ctx.U32[1], pointer)}; | ||
| 486 | bit = ctx.OpBitwiseAnd(ctx.U32[1], word, bit_index_mask); | ||
| 487 | } else { | ||
| 488 | const Id index_value{ctx.Def(index)}; | ||
| 489 | const Id word_index{ctx.OpShiftRightArithmetic(ctx.U32[1], index_value, ctx.Const(5u))}; | ||
| 490 | const Id pointer{ctx.OpAccessChain(push_constant_u32, ctx.rescaling_push_constants, | ||
| 491 | member_index, word_index)}; | ||
| 492 | const Id word{ctx.OpLoad(ctx.U32[1], pointer)}; | ||
| 493 | const Id bit_index{ctx.OpBitwiseAnd(ctx.U32[1], index_value, ctx.Const(31u))}; | ||
| 494 | bit = ctx.OpBitFieldUExtract(ctx.U32[1], index_value, bit_index, ctx.Const(1u)); | ||
| 495 | } | ||
| 496 | return ctx.OpINotEqual(ctx.U1, bit, ctx.u32_zero_value); | ||
| 475 | } | 497 | } |
| 476 | 498 | ||
| 477 | } // namespace Shader::Backend::SPIRV | 499 | } // namespace Shader::Backend::SPIRV |