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
@@ -559,7 +559,7 @@ bool MaterializeResources(const Program& program, const SrtRuntime& runtime,
auto base = (static_cast<uint64_t>(value.dwords[0]) |
static_cast<uint64_t>(value.dwords[1]) << 32u) &
AddressMask;
if (address.kind == ResourceKind::ScalarBuffer) {
if (address.kind == ResourceKind::ScalarAddress) {
base &= ~uint64_t {3};
}
const auto before = static_cast<uint64_t>(-static_cast<int64_t>(address.min_offset));
@@ -724,7 +724,7 @@ private:
uint32_t AddAddress(uint32_t source, bool unbased, const MemoryInfo& memory, ValueOpcode op,
uint32_t pc) {
auto immediate = static_cast<int32_t>(memory.offset);
if (memory.kind == ResourceKind::ScalarBuffer) {
if (memory.kind == ResourceKind::ScalarAddress) {
immediate = static_cast<int32_t>(static_cast<uint32_t>(immediate) & ~3u);
}
const auto min_offset = unbased ? 0 : std::min(immediate, 0);
@@ -50,13 +50,17 @@ bool AddSignedAddress(uint64_t base, int64_t offset, uint64_t& result) {
}
bool IsRawRead(const ValueProgram& values, const Inst& inst) {
if (inst.GetOpcode() != ValueOpcode::LoadAddressU32 &&
inst.GetOpcode() != ValueOpcode::ReadConstBuffer) {
const auto op = inst.GetOpcode();
if (op != ValueOpcode::LoadAddressU32 && op != ValueOpcode::ReadConstBuffer) {
return false;
}
const auto index = inst.Flags<MemoryFlags>().index;
return index < values.memory_info.size() &&
values.memory_info[index].kind == ResourceKind::ScalarBuffer;
if (index >= values.memory_info.size()) {
return false;
}
const auto kind = values.memory_info[index].kind;
return (op == ValueOpcode::LoadAddressU32 && kind == ResourceKind::ScalarAddress) ||
(op == ValueOpcode::ReadConstBuffer && kind == ResourceKind::ScalarBuffer);
}
bool IsDescriptorHandle(ValueOpcode opcode) {
@@ -262,6 +266,22 @@ public:
m_values.dynamic_reads.clear();
for (auto* block: m_values.blocks) {
for (auto& inst: *block) {
const auto op = inst.GetOpcode();
if (op == ValueOpcode::LoadAddressU32 || op == ValueOpcode::ReadConstBuffer) {
const auto flags = inst.Flags<MemoryFlags>();
if (flags.index < m_values.memory_info.size()) {
const auto kind = m_values.memory_info[flags.index].kind;
const bool crosswired = (op == ValueOpcode::LoadAddressU32 &&
kind == ResourceKind::ScalarBuffer) ||
(op == ValueOpcode::ReadConstBuffer &&
kind == ResourceKind::ScalarAddress);
if (crosswired) {
return Fail(flags.pc, error,
fmt::format("{} has incompatible scalar memory metadata",
ValueOpcodeName(op)));
}
}
}
if (IsDescriptorHandle(inst.GetOpcode())) {
for (size_t index = 0; index < inst.NumArgs(); index++) {
if (!Collect(inst.Arg(index), 0, error)) {