graphics: separate scalar address bindings

This commit is contained in:
nmzik
2026-08-16 08:04:07 +02:00
parent 83ee040b4d
commit 443bbcbf90
12 changed files with 229 additions and 32 deletions
@@ -302,9 +302,9 @@ uint32_t EmitBufferByteAddress(EmitterState& state, const IR::Instruction& inst,
return EmitBufferAddressFromParts(state, inst, index, offset, soffset);
}
bool IsFlatMemoryKind(IR::ResourceKind kind) {
return kind == IR::ResourceKind::Flat || kind == IR::ResourceKind::Global ||
kind == IR::ResourceKind::Scratch;
bool IsAddressMemoryKind(IR::ResourceKind kind) {
return kind == IR::ResourceKind::ScalarAddress || kind == IR::ResourceKind::Flat ||
kind == IR::ResourceKind::Global || kind == IR::ResourceKind::Scratch;
}
uint32_t EmitRelativeAddress(EmitterState& state, const IR::Instruction& inst, uint32_t first_src,
@@ -423,7 +423,7 @@ StorageBufferBindingForMemory(EmitterState& state, const IR::MemoryInfo& mem, ui
uint32_t EmitStorageBufferIndex(EmitterState& state, const IR::MemoryInfo& mem, uint32_t index,
uint32_t use_pc) {
if (IsFlatMemoryKind(mem.kind)) {
if (IsAddressMemoryKind(mem.kind)) {
return index;
}
const auto binding = StorageBufferBindingForMemory(state, mem, use_pc);
@@ -432,7 +432,7 @@ uint32_t EmitStorageBufferIndex(EmitterState& state, const IR::MemoryInfo& mem,
uint32_t EmitStorageBufferObjectPointer(EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc) {
if (IsFlatMemoryKind(mem.kind)) {
if (IsAddressMemoryKind(mem.kind)) {
if (state.address_memory_variable == 0) {
ExitDescriptorBindingFailure(state, IR::DescriptorBindingKind::AddressMemory,
mem.resource, "address memory binding was not emitted");
@@ -467,7 +467,7 @@ uint32_t EmitStorageBufferElementInBounds(EmitterState& state, const IR::MemoryI
uint32_t EmitStorageBufferElementPointer(EmitterState& state, const IR::MemoryInfo& mem,
uint32_t index, uint32_t use_pc) {
index = EmitStorageBufferIndex(state, mem, index, use_pc);
if (IsFlatMemoryKind(mem.kind)) {
if (IsAddressMemoryKind(mem.kind)) {
if (state.address_memory_variable == 0) {
ExitDescriptorBindingFailure(state, IR::DescriptorBindingKind::AddressMemory,
mem.resource, "address memory binding was not emitted");
@@ -102,8 +102,12 @@ uint32_t AddU64Low(EmitterState& state, uint32_t low, uint32_t high, uint32_t ad
uint32_t AddressByteAddress(ValueEmitContext& ctx, const IR::Inst& inst, const IR::MemoryInfo& mem,
uint32_t low, uint32_t high) {
auto& state = ctx.state;
const auto immediate = static_cast<int32_t>(mem.offset);
auto& state = ctx.state;
auto immediate = static_cast<int32_t>(mem.offset);
if (mem.kind == IR::ResourceKind::ScalarAddress) {
immediate = static_cast<int32_t>(static_cast<uint32_t>(immediate) & ~3u);
low = Binary(state, OpBitwiseAnd, state.uint_type, low, ConstantU32(state, ~3u));
}
const auto immediate_low = ConstantU32(state, static_cast<uint32_t>(immediate));
const auto immediate_high = ConstantU32(state, immediate < 0 ? UINT32_MAX : 0u);
const auto base = state.program.info.addresses[mem.resource].specialized_base;
@@ -137,11 +141,7 @@ uint32_t AddressByteAddress(ValueEmitContext& ctx, const IR::Inst& inst, const I
}
uint32_t ByteAddress(ValueEmitContext& ctx, const IR::Inst& inst, const IR::MemoryInfo& mem) {
if (mem.kind == IR::ResourceKind::Buffer || mem.kind == IR::ResourceKind::ScalarBuffer) {
if (mem.kind == IR::ResourceKind::ScalarBuffer) {
return Binary(ctx.state, OpIAdd, ctx.state.uint_type, ctx.Arg(inst, 1),
ConstantU32(ctx.state, mem.offset));
}
if (mem.kind == IR::ResourceKind::Buffer) {
return BufferByteAddress(ctx, inst, mem, ctx.Arg(inst, 1), ctx.Arg(inst, 2),
ctx.Arg(inst, 3));
}