summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-30 23:08:17 -0300
committerGravatar ameerj2021-07-22 21:51:34 -0400
commit05d41fa9b70af6d469f2f6f1474436c9255e9bc3 (patch)
tree52bd8f8a6456c46fc9120aafa99b2d4a45b79746 /src/shader_recompiler/backend/spirv
parentshader: Implement ISCADD32I (diff)
downloadyuzu-05d41fa9b70af6d469f2f6f1474436c9255e9bc3.tar.gz
yuzu-05d41fa9b70af6d469f2f6f1474436c9255e9bc3.tar.xz
yuzu-05d41fa9b70af6d469f2f6f1474436c9255e9bc3.zip
shader: Add support for "negative" and unaligned offsets
"Negative" offsets don't exist. They are shown as such due to a bug in nvdisasm. Unaligned offsets have been proved to read the aligned offset. For example, when reading an U32, if the offset is 6, the offset read will be 4.
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp9
1 files changed, 3 insertions, 6 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index c1b69c234..442a958a5 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -122,7 +122,7 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
122} 122}
123 123
124Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size, 124Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size,
125 const IR::Value& binding, const IR::Value& offset, bool check_alignment = true) { 125 const IR::Value& binding, const IR::Value& offset) {
126 if (!binding.IsImmediate()) { 126 if (!binding.IsImmediate()) {
127 throw NotImplementedException("Constant buffer indexing"); 127 throw NotImplementedException("Constant buffer indexing");
128 } 128 }
@@ -138,17 +138,14 @@ Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr,
138 const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, index)}; 138 const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, index)};
139 return ctx.OpLoad(result_type, access_chain); 139 return ctx.OpLoad(result_type, access_chain);
140 } 140 }
141 if (check_alignment && offset.U32() % element_size != 0) { 141 // Hardware been proved to read the aligned offset (e.g. LDC.U32 at 6 will read offset 4)
142 throw NotImplementedException("Unaligned immediate constant buffer load");
143 }
144 const Id imm_offset{ctx.Const(offset.U32() / element_size)}; 142 const Id imm_offset{ctx.Const(offset.U32() / element_size)};
145 const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, imm_offset)}; 143 const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, imm_offset)};
146 return ctx.OpLoad(result_type, access_chain); 144 return ctx.OpLoad(result_type, access_chain);
147} 145}
148 146
149Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { 147Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
150 return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset, 148 return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset);
151 false);
152} 149}
153 150
154Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) { 151Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) {