summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-03-09 21:14:57 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:23 +0200
commit3a63fa0477ea8297c80133d35494e1dfdc012f95 (patch)
tree3cd8b9be6f91cb1628b0d47513b7adb88df5f7b2 /src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
parentshader: Initial support for textures and TEX (diff)
downloadyuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar
yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.gz
yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.bz2
yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.lz
yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.xz
yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.zst
yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.zip
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp56
1 files changed, 50 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 eb9c01c5a..125b58cf7 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
@@ -30,17 +30,61 @@ void EmitGetGotoVariable(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
}
-Id EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+static Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr,
+ u32 element_size, const IR::Value& binding, const IR::Value& offset) {
if (!binding.IsImmediate()) {
throw NotImplementedException("Constant buffer indexing");
}
+ const Id cbuf{ctx.cbufs[binding.U32()].*member_ptr};
+ const Id uniform_type{ctx.uniform_types.*member_ptr};
if (!offset.IsImmediate()) {
- throw NotImplementedException("Variable constant buffer offset");
+ Id index{ctx.Def(offset)};
+ if (element_size > 1) {
+ const u32 log2_element_size{static_cast<u32>(std::countr_zero(element_size))};
+ const Id shift{ctx.Constant(ctx.U32[1], log2_element_size)};
+ index = ctx.OpShiftRightArithmetic(ctx.U32[1], ctx.Def(offset), shift);
+ }
+ const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, index)};
+ return ctx.OpLoad(result_type, access_chain);
}
- const Id imm_offset{ctx.Constant(ctx.U32[1], offset.U32() / 4)};
- const Id cbuf{ctx.cbufs[binding.U32()]};
- const Id access_chain{ctx.OpAccessChain(ctx.uniform_u32, cbuf, ctx.u32_zero_value, imm_offset)};
- return ctx.OpLoad(ctx.U32[1], access_chain);
+ if (offset.U32() % element_size != 0) {
+ throw NotImplementedException("Unaligned immediate constant buffer load");
+ }
+ const Id imm_offset{ctx.Constant(ctx.U32[1], 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 EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ const Id load{GetCbuf(ctx, ctx.U8, &UniformDefinitions::U8, sizeof(u8), binding, offset)};
+ return ctx.OpUConvert(ctx.U32[1], load);
+}
+
+Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ const Id load{GetCbuf(ctx, ctx.S8, &UniformDefinitions::S8, sizeof(s8), binding, offset)};
+ return ctx.OpSConvert(ctx.U32[1], load);
+}
+
+Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ const Id load{GetCbuf(ctx, ctx.U16, &UniformDefinitions::U16, sizeof(u16), binding, offset)};
+ return ctx.OpUConvert(ctx.U32[1], load);
+}
+
+Id EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ const Id load{GetCbuf(ctx, ctx.S16, &UniformDefinitions::S16, sizeof(s16), binding, offset)};
+ return ctx.OpSConvert(ctx.U32[1], load);
+}
+
+Id EmitGetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ return GetCbuf(ctx, ctx.U32[1], &UniformDefinitions::U32, sizeof(u32), binding, offset);
+}
+
+Id EmitGetCbufF32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ return GetCbuf(ctx, ctx.F32[1], &UniformDefinitions::F32, sizeof(f32), binding, offset);
+}
+
+Id EmitGetCbufU64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
+ return GetCbuf(ctx, ctx.U64, &UniformDefinitions::U64, sizeof(u64), binding, offset);
}
void EmitGetAttribute(EmitContext&) {