summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
index 21a0d72fa..5769a3c95 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
@@ -2,10 +2,26 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <bit>
+
#include "shader_recompiler/backend/spirv/emit_spirv.h"
namespace Shader::Backend::SPIRV {
+static Id StorageIndex(EmitContext& ctx, const IR::Value& offset, size_t element_size) {
+ if (offset.IsImmediate()) {
+ const u32 imm_offset{static_cast<u32>(offset.U32() / element_size)};
+ return ctx.Constant(ctx.U32[1], imm_offset);
+ }
+ const u32 shift{static_cast<u32>(std::countr_zero(element_size))};
+ const Id index{ctx.Def(offset)};
+ if (shift == 0) {
+ return index;
+ }
+ const Id shift_id{ctx.Constant(ctx.U32[1], shift)};
+ return ctx.OpShiftRightLogical(ctx.U32[1], index, shift_id);
+}
+
void EmitSPIRV::EmitLoadGlobalU8(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
}
@@ -79,11 +95,14 @@ void EmitSPIRV::EmitLoadStorageS16(EmitContext&) {
}
Id EmitSPIRV::EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding,
- [[maybe_unused]] const IR::Value& offset) {
+ const IR::Value& offset) {
if (!binding.IsImmediate()) {
- throw NotImplementedException("Storage buffer indexing");
+ throw NotImplementedException("Dynamic storage buffer indexing");
}
- return ctx.Name(ctx.OpUndef(ctx.u32[1]), "unimplemented_sbuf");
+ const Id ssbo{ctx.ssbos[binding.U32()]};
+ const Id index{StorageIndex(ctx, offset, sizeof(u32))};
+ const Id pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, index)};
+ return ctx.OpLoad(ctx.U32[1], pointer);
}
void EmitSPIRV::EmitLoadStorage64(EmitContext&) {
@@ -110,8 +129,15 @@ void EmitSPIRV::EmitWriteStorageS16(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
}
-void EmitSPIRV::EmitWriteStorage32(EmitContext& ctx) {
- ctx.Name(ctx.OpUndef(ctx.u32[1]), "unimplemented_sbuf_store");
+void EmitSPIRV::EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding,
+ const IR::Value& offset, Id value) {
+ if (!binding.IsImmediate()) {
+ throw NotImplementedException("Dynamic storage buffer indexing");
+ }
+ const Id ssbo{ctx.ssbos[binding.U32()]};
+ const Id index{StorageIndex(ctx, offset, sizeof(u32))};
+ const Id pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, index)};
+ ctx.OpStore(pointer, value);
}
void EmitSPIRV::EmitWriteStorage64(EmitContext&) {