aboutsummaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-07-25 22:26:23 -0300
committerFernando Sahmkow <fsahmkow27@gmail.com>2021-11-16 22:11:28 +0100
commit656adee630cb1de738ed4dc6cf1cbc35af40f64f (patch)
tree5c5ec069a136655476180ce03fc24ccd911b3871 /src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
parent01379c5e3cd1181c7c7d37a672364fbcad627fb0 (diff)
spirv: Implement rescaling patching
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_image.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp26
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 2f925cc3e7..7d7c0627ec 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
ctx.OpImageWrite(Image(ctx, index, info), coords, color);
}
-Id EmitIsTextureScaled([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& index) {
- return ctx.false_value;
+Id EmitIsTextureScaled(EmitContext& ctx, const IR::Value& index) {
+ const Id push_constant_u32{ctx.TypePointer(spv::StorageClass::PushConstant, ctx.U32[1])};
+ const Id member_index{ctx.Const(ctx.rescaling_textures_member_index)};
+ Id bit{};
+ if (index.IsImmediate()) {
+ // Use BitwiseAnd instead of BitfieldExtract for better codegen on Nvidia OpenGL.
+ // LOP32I.NZ is used to set the predicate rather than BFE+ISETP.
+ const u32 index_value{index.U32()};
+ const Id word_index{ctx.Const(index_value / 32)};
+ const Id bit_index_mask{ctx.Const(1u << (index_value % 32))};
+ const Id pointer{ctx.OpAccessChain(push_constant_u32, ctx.rescaling_push_constants,
+ member_index, word_index)};
+ const Id word{ctx.OpLoad(ctx.U32[1], pointer)};
+ bit = ctx.OpBitwiseAnd(ctx.U32[1], word, bit_index_mask);
+ } else {
+ const Id index_value{ctx.Def(index)};
+ const Id word_index{ctx.OpShiftRightArithmetic(ctx.U32[1], index_value, ctx.Const(5u))};
+ const Id pointer{ctx.OpAccessChain(push_constant_u32, ctx.rescaling_push_constants,
+ member_index, word_index)};
+ const Id word{ctx.OpLoad(ctx.U32[1], pointer)};
+ const Id bit_index{ctx.OpBitwiseAnd(ctx.U32[1], index_value, ctx.Const(31u))};
+ bit = ctx.OpBitFieldUExtract(ctx.U32[1], index_value, bit_index, ctx.Const(1u));
+ }
+ return ctx.OpINotEqual(ctx.U1, bit, ctx.u32_zero_value);
}
} // namespace Shader::Backend::SPIRV