summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp9
2 files changed, 11 insertions, 6 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
index 787612def..9ad668b86 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
@@ -18,6 +18,14 @@ void GetCbuf(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU
throw NotImplementedException("Indirect constant buffer loading");
}
const Register ret{ctx.reg_alloc.Define(inst)};
+ if (offset.type == Type::U32) {
+ // Avoid reading arrays out of bounds, matching hardware's behavior
+ const u32 imm_offset{offset.imm_u32};
+ if (offset.imm_u32 >= 0x10'000) {
+ ctx.Add("MOV.S {},0;", ret);
+ return;
+ }
+ }
ctx.Add("LDC.{} {},c{}[{}];", size, ret, binding.U32(), offset);
}
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) {
}
Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size,
- const IR::Value& binding, const IR::Value& offset, bool check_alignment = true) {
+ const IR::Value& binding, const IR::Value& offset) {
if (!binding.IsImmediate()) {
throw NotImplementedException("Constant buffer indexing");
}
@@ -138,17 +138,14 @@ Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr,
const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, index)};
return ctx.OpLoad(result_type, access_chain);
}
- if (check_alignment && offset.U32() % element_size != 0) {
- throw NotImplementedException("Unaligned immediate constant buffer load");
- }
+ // Hardware been proved to read the aligned offset (e.g. LDC.U32 at 6 will read offset 4)
const Id imm_offset{ctx.Const(offset.U32() / element_size)};
const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, imm_offset)};
return ctx.OpLoad(result_type, access_chain);
}
Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
- return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset,
- false);
+ return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset);
}
Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) {