mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-23 12:26:56 +02:00
shader: bound scalar-read overlap checks by the bytes fixed-offset buffer writes reach
This commit is contained in:
@@ -125,6 +125,7 @@ struct BufferResource {
|
||||
uint32_t descriptor_index = UINT32_MAX;
|
||||
uint32_t first_use_pc = 0;
|
||||
uint32_t max_byte_extent = 0;
|
||||
uint32_t write_extent = 0; // UINT32_MAX once a write is runtime-addressed or formatted
|
||||
uint32_t packed_stride = 0;
|
||||
Prospero::BufferFormat descriptor_format = Prospero::BufferFormat::kInvalid;
|
||||
uint32_t descriptor_swizzle = DstSel(4, 5, 6, 7);
|
||||
|
||||
@@ -3749,10 +3749,10 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AddBuffer(uint32_t source, const MemoryInfo& memory, ValueOpcode op, uint32_t pc) {
|
||||
uint32_t AddBuffer(uint32_t source, const MemoryInfo& memory, const Inst& inst, uint32_t pc) {
|
||||
for (uint32_t i = 0; i < m_info.buffers.size(); i++) {
|
||||
if (m_info.buffers[i].source == source) {
|
||||
Merge(m_info.buffers[i], memory, op, pc);
|
||||
Merge(m_info.buffers[i], memory, inst, pc);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -3762,13 +3762,14 @@ private:
|
||||
BufferResource resource;
|
||||
resource.source = source;
|
||||
resource.first_use_pc = pc;
|
||||
Merge(resource, memory, op, pc);
|
||||
Merge(resource, memory, inst, pc);
|
||||
m_info.buffers.push_back(resource);
|
||||
return static_cast<uint32_t>(m_info.buffers.size() - 1);
|
||||
}
|
||||
|
||||
static void Merge(BufferResource& resource, const MemoryInfo& memory, ValueOpcode op,
|
||||
static void Merge(BufferResource& resource, const MemoryInfo& memory, const Inst& inst,
|
||||
uint32_t pc) {
|
||||
const auto op = inst.GetOpcode();
|
||||
const auto access = BufferAccessOf(op);
|
||||
const bool atomic = access == BufferAccess::Atomic;
|
||||
const bool write = access == BufferAccess::Write || atomic;
|
||||
@@ -3776,6 +3777,13 @@ private:
|
||||
resource.max_byte_extent = std::max(resource.max_byte_extent, ByteExtent(memory));
|
||||
resource.read = resource.read || !write || atomic;
|
||||
resource.written = resource.written || write;
|
||||
if (write) {
|
||||
// Formatted stores write the whole format; otherwise zero index, VGPR and SGPR offsets
|
||||
// leave only the immediate offset.
|
||||
const bool fixed = !memory.formatted && inst.Arg(1).Resolve() == Value(0u) &&
|
||||
inst.Arg(2).Resolve() == Value(0u) && inst.Arg(3).Resolve() == Value(0u);
|
||||
resource.write_extent = std::max(resource.write_extent, fixed ? ByteExtent(memory) : UINT32_MAX);
|
||||
}
|
||||
resource.atomic = resource.atomic || atomic;
|
||||
resource.formatted = resource.formatted || memory.formatted;
|
||||
resource.scalar = resource.scalar || op == ValueOpcode::ReadConstBuffer ||
|
||||
@@ -3945,7 +3953,7 @@ private:
|
||||
m_info.uses_dma = true;
|
||||
return;
|
||||
}
|
||||
resource = AddBuffer(source, memory, op, flags.pc);
|
||||
resource = AddBuffer(source, memory, inst, flags.pc);
|
||||
if (resource == UINT32_MAX) {
|
||||
Fail(flags.pc, "buffer resource limit exceeded");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user