shader: zero image descriptors that only unreached blocks use

This commit is contained in:
Claxten authored and nmzik committed 2026-10-27 04:23:01 +01:00
1 parent 78adb9293d
commit 9801fd862b
6 files changed
+84 -13

No files matched your search

@@ -148,8 +148,8 @@ bool ImmediateBits(Value value, uint64_t& bits) {
}
// Scratch layout in bytes: per descriptor source its eight DWORDs and a known DWORD, one
// activity byte per source, then one qword per walked value (all ones when unknown). The
// walker's value slots, captured addresses, reachability and states follow.
// activity byte per source, then per image, then one qword per walked value (all ones when
// unknown). The walker's value slots, captured addresses, reachability and states follow.
constexpr uint32_t DescriptorStride = 9u * sizeof(uint32_t);
uint32_t ActiveOffset(const ResourcePlan& plan) {
@@ -157,7 +157,8 @@ uint32_t ActiveOffset(const ResourcePlan& plan) {
}
uint32_t OutputOffset(const ResourcePlan& plan) {
return (ActiveOffset(plan) + static_cast<uint32_t>(plan.descriptor_sources.size()) + 7u) & ~7u;
const auto active = plan.descriptor_sources.size() + plan.info.images.size();
return (ActiveOffset(plan) + static_cast<uint32_t>(active) + 7u) & ~7u;
}
const uint8_t* Scratch(const ResourcePlan& plan) {
@@ -1290,11 +1291,14 @@ void WalkerCompiler::Compile(std::span<const Value> values) {
for (const auto slot: blocks[block].srt_reads) flat(slot);
c.L(skip);
}
// A source no block lists is always active.
for (uint32_t source = 0; source < sources.size(); ++source) {
// A source or image no block lists is always active.
for (uint32_t index = 0; index < sources.size() + m_plan.info.images.size(); ++index) {
const bool image = index >= sources.size();
const uint32_t id = image ? index - static_cast<uint32_t>(sources.size()) : index;
bool listed = false;
for (uint32_t block = 0; block < blocks.size(); ++block) {
if (std::ranges::find(blocks[block].sources, source) == blocks[block].sources.end()) continue;
const auto& list = image ? blocks[block].images : blocks[block].sources;
if (std::ranges::find(list, id) == list.end()) continue;
if (listed) {
c.or_(c.al, c.byte[c.rdx + m_reach + block]);
} else {
@@ -1302,7 +1306,7 @@ void WalkerCompiler::Compile(std::span<const Value> values) {
}
listed = true;
}
const auto active = c.byte[c.rdx + ActiveOffset(m_plan) + source];
const auto active = c.byte[c.rdx + ActiveOffset(m_plan) + index];
if (listed) {
c.mov(active, c.al);
} else {
@@ -1409,6 +1413,10 @@ bool WalkedActive(const ResourcePlan& plan, uint32_t source) {
return Scratch(plan)[ActiveOffset(plan) + source] != 0u;
}
bool WalkedImageActive(const ResourcePlan& plan, uint32_t image) {
return Scratch(plan)[ActiveOffset(plan) + plan.descriptor_sources.size() + image] != 0u;
}
bool ValidateRuntimeValue(const ResourcePlan& program, Value value, RuntimeValueType type) {
return RuntimeValidator(program, type).Run(value);
}