yuzu/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp

176 lines
5.7 KiB
C++
Raw Normal View History

2021-02-08 05:54:35 +00:00
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
2021-02-16 07:10:22 +00:00
#include <bit>
2021-02-08 05:54:35 +00:00
#include "shader_recompiler/backend/spirv/emit_spirv.h"
namespace Shader::Backend::SPIRV {
2021-02-16 07:10:22 +00:00
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);
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobalU8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobalS8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobalU16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobalS16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobal32(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobal64(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadGlobal128(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobalU8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobalS8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobalU16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobalS16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobal32(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobal64(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteGlobal128(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadStorageU8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadStorageS8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadStorageU16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadStorageS16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-19 21:10:18 +00:00
Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
2021-02-08 05:54:35 +00:00
if (!binding.IsImmediate()) {
2021-02-16 07:10:22 +00:00
throw NotImplementedException("Dynamic storage buffer indexing");
2021-02-08 05:54:35 +00:00
}
2021-02-16 07:10:22 +00:00
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);
2021-02-08 05:54:35 +00:00
}
2021-02-17 03:59:28 +00:00
void EmitLoadStorage64(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitLoadStorage128(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteStorageU8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteStorageS8(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteStorageU16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-17 03:59:28 +00:00
void EmitWriteStorageS16(EmitContext&) {
2021-02-08 05:54:35 +00:00
throw NotImplementedException("SPIR-V Instruction");
}
2021-02-19 21:10:18 +00:00
void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
Id value) {
2021-02-16 07:10:22 +00:00
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);
2021-02-08 05:54:35 +00:00
}
2021-02-19 21:10:18 +00:00
void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
Id value) {
if (!binding.IsImmediate()) {
throw NotImplementedException("Dynamic storage buffer indexing");
}
// TODO: Support reinterpreting bindings, guaranteed to be aligned
const Id ssbo{ctx.ssbos[binding.U32()]};
const Id low_index{StorageIndex(ctx, offset, sizeof(u32))};
const Id high_index{ctx.OpIAdd(ctx.U32[1], low_index, ctx.Constant(ctx.U32[1], 1U))};
const Id low_pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, low_index)};
const Id high_pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, high_index)};
ctx.OpStore(low_pointer, ctx.OpCompositeExtract(ctx.U32[1], value, 0U));
ctx.OpStore(high_pointer, ctx.OpCompositeExtract(ctx.U32[1], value, 1U));
2021-02-08 05:54:35 +00:00
}
void EmitWriteStorage128(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
Id value) {
if (!binding.IsImmediate()) {
throw NotImplementedException("Dynamic storage buffer indexing");
}
// TODO: Support reinterpreting bindings, guaranteed to be aligned
const Id ssbo{ctx.ssbos[binding.U32()]};
const Id base_index{StorageIndex(ctx, offset, sizeof(u32))};
for (u32 element = 0; element < 4; ++element) {
Id index = base_index;
if (element > 0) {
index = ctx.OpIAdd(ctx.U32[1], base_index, ctx.Constant(ctx.U32[1], element));
}
const Id pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, index)};
ctx.OpStore(pointer, ctx.OpCompositeExtract(ctx.U32[1], value, element));
}
2021-02-08 05:54:35 +00:00
}
} // namespace Shader::Backend::SPIRV