diff options
| author | 2021-05-30 23:08:17 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:34 -0400 | |
| commit | 05d41fa9b70af6d469f2f6f1474436c9255e9bc3 (patch) | |
| tree | 52bd8f8a6456c46fc9120aafa99b2d4a45b79746 /src/shader_recompiler/backend/spirv | |
| parent | shader: Implement ISCADD32I (diff) | |
| download | yuzu-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.cpp | 9 |
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 | ||
| 124 | Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size, | 124 | Id 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 | ||
| 149 | Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 147 | Id 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 | ||
| 154 | Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) { | 151 | Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) { |