|
|
|
@ -1123,15 +1123,7 @@ private:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (const auto gmem = std::get_if<GmemNode>(&*node)) {
|
|
|
|
|
const Id gmem_buffer = global_buffers.at(gmem->GetDescriptor());
|
|
|
|
|
const Id real = AsUint(Visit(gmem->GetRealAddress()));
|
|
|
|
|
const Id base = AsUint(Visit(gmem->GetBaseAddress()));
|
|
|
|
|
|
|
|
|
|
Id offset = OpISub(t_uint, real, base);
|
|
|
|
|
offset = OpUDiv(t_uint, offset, Constant(t_uint, 4U));
|
|
|
|
|
return {OpLoad(t_float,
|
|
|
|
|
OpAccessChain(t_gmem_float, gmem_buffer, Constant(t_uint, 0U), offset)),
|
|
|
|
|
Type::Float};
|
|
|
|
|
return {OpLoad(t_uint, GetGlobalMemoryPointer(*gmem)), Type::Uint};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (const auto lmem = std::get_if<LmemNode>(&*node)) {
|
|
|
|
@ -1142,10 +1134,7 @@ private:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (const auto smem = std::get_if<SmemNode>(&*node)) {
|
|
|
|
|
Id address = AsUint(Visit(smem->GetAddress()));
|
|
|
|
|
address = OpShiftRightLogical(t_uint, address, Constant(t_uint, 2U));
|
|
|
|
|
const Id pointer = OpAccessChain(t_smem_uint, shared_memory, address);
|
|
|
|
|
return {OpLoad(t_uint, pointer), Type::Uint};
|
|
|
|
|
return {OpLoad(t_uint, GetSharedMemoryPointer(*smem)), Type::Uint};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (const auto internal_flag = std::get_if<InternalFlagNode>(&*node)) {
|
|
|
|
@ -1339,20 +1328,10 @@ private:
|
|
|
|
|
target = {OpAccessChain(t_prv_float, local_memory, address), Type::Float};
|
|
|
|
|
|
|
|
|
|
} else if (const auto smem = std::get_if<SmemNode>(&*dest)) {
|
|
|
|
|
ASSERT(stage == ShaderType::Compute);
|
|
|
|
|
Id address = AsUint(Visit(smem->GetAddress()));
|
|
|
|
|
address = OpShiftRightLogical(t_uint, address, Constant(t_uint, 2U));
|
|
|
|
|
target = {OpAccessChain(t_smem_uint, shared_memory, address), Type::Uint};
|
|
|
|
|
target = {GetSharedMemoryPointer(*smem), Type::Uint};
|
|
|
|
|
|
|
|
|
|
} else if (const auto gmem = std::get_if<GmemNode>(&*dest)) {
|
|
|
|
|
const Id real = AsUint(Visit(gmem->GetRealAddress()));
|
|
|
|
|
const Id base = AsUint(Visit(gmem->GetBaseAddress()));
|
|
|
|
|
const Id diff = OpISub(t_uint, real, base);
|
|
|
|
|
const Id offset = OpShiftRightLogical(t_uint, diff, Constant(t_uint, 2));
|
|
|
|
|
|
|
|
|
|
const Id gmem_buffer = global_buffers.at(gmem->GetDescriptor());
|
|
|
|
|
target = {OpAccessChain(t_gmem_float, gmem_buffer, Constant(t_uint, 0), offset),
|
|
|
|
|
Type::Float};
|
|
|
|
|
target = {GetGlobalMemoryPointer(*gmem), Type::Uint};
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
UNIMPLEMENTED();
|
|
|
|
@ -1804,11 +1783,16 @@ private:
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Expression UAtomicAdd(Operation operation) {
|
|
|
|
|
const auto& smem = std::get<SmemNode>(*operation[0]);
|
|
|
|
|
Id address = AsUint(Visit(smem.GetAddress()));
|
|
|
|
|
address = OpShiftRightLogical(t_uint, address, Constant(t_uint, 2U));
|
|
|
|
|
const Id pointer = OpAccessChain(t_smem_uint, shared_memory, address);
|
|
|
|
|
Expression AtomicAdd(Operation operation) {
|
|
|
|
|
Id pointer;
|
|
|
|
|
if (const auto smem = std::get_if<SmemNode>(&*operation[0])) {
|
|
|
|
|
pointer = GetSharedMemoryPointer(*smem);
|
|
|
|
|
} else if (const auto gmem = std::get_if<GmemNode>(&*operation[0])) {
|
|
|
|
|
pointer = GetGlobalMemoryPointer(*gmem);
|
|
|
|
|
} else {
|
|
|
|
|
UNREACHABLE();
|
|
|
|
|
return {Constant(t_uint, 0), Type::Uint};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device));
|
|
|
|
|
const Id semantics = Constant(t_uint, 0U);
|
|
|
|
@ -2243,6 +2227,22 @@ private:
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Id GetGlobalMemoryPointer(const GmemNode& gmem) {
|
|
|
|
|
const Id real = AsUint(Visit(gmem.GetRealAddress()));
|
|
|
|
|
const Id base = AsUint(Visit(gmem.GetBaseAddress()));
|
|
|
|
|
const Id diff = OpISub(t_uint, real, base);
|
|
|
|
|
const Id offset = OpShiftRightLogical(t_uint, diff, Constant(t_uint, 2));
|
|
|
|
|
const Id buffer = global_buffers.at(gmem.GetDescriptor());
|
|
|
|
|
return OpAccessChain(t_gmem_uint, buffer, Constant(t_uint, 0), offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Id GetSharedMemoryPointer(const SmemNode& smem) {
|
|
|
|
|
ASSERT(stage == ShaderType::Compute);
|
|
|
|
|
Id address = AsUint(Visit(smem.GetAddress()));
|
|
|
|
|
address = OpShiftRightLogical(t_uint, address, Constant(t_uint, 2U));
|
|
|
|
|
return OpAccessChain(t_smem_uint, shared_memory, address);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static constexpr std::array operation_decompilers = {
|
|
|
|
|
&SPIRVDecompiler::Assign,
|
|
|
|
|
|
|
|
|
@ -2389,7 +2389,7 @@ private:
|
|
|
|
|
&SPIRVDecompiler::AtomicImageXor,
|
|
|
|
|
&SPIRVDecompiler::AtomicImageExchange,
|
|
|
|
|
|
|
|
|
|
&SPIRVDecompiler::UAtomicAdd,
|
|
|
|
|
&SPIRVDecompiler::AtomicAdd,
|
|
|
|
|
|
|
|
|
|
&SPIRVDecompiler::Branch,
|
|
|
|
|
&SPIRVDecompiler::BranchIndirect,
|
|
|
|
@ -2485,9 +2485,9 @@ private:
|
|
|
|
|
|
|
|
|
|
Id t_smem_uint{};
|
|
|
|
|
|
|
|
|
|
const Id t_gmem_float = TypePointer(spv::StorageClass::StorageBuffer, t_float);
|
|
|
|
|
const Id t_gmem_uint = TypePointer(spv::StorageClass::StorageBuffer, t_uint);
|
|
|
|
|
const Id t_gmem_array =
|
|
|
|
|
Name(Decorate(TypeRuntimeArray(t_float), spv::Decoration::ArrayStride, 4U), "GmemArray");
|
|
|
|
|
Name(Decorate(TypeRuntimeArray(t_uint), spv::Decoration::ArrayStride, 4U), "GmemArray");
|
|
|
|
|
const Id t_gmem_struct = MemberDecorate(
|
|
|
|
|
Decorate(TypeStruct(t_gmem_array), spv::Decoration::Block), 0, spv::Decoration::Offset, 0);
|
|
|
|
|
const Id t_gmem_ssbo = TypePointer(spv::StorageClass::StorageBuffer, t_gmem_struct);
|
|
|
|
|