mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 16:51:20 +00:00
shader: separate exact descriptor row bounds from pointer offsets
This commit is contained in:
1 parent
487bbf95fd
commit
04cb4c6553
4 files changed
+15
-19
No files matched your search
@@ -525,12 +525,6 @@ struct ShaderInfo {
|
|||||||
|
|
||||||
struct DescriptorSource {
|
struct DescriptorSource {
|
||||||
struct IndirectDescriptor {
|
struct IndirectDescriptor {
|
||||||
struct PointerTable {
|
|
||||||
uint32_t maximum = 0;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
|
|
||||||
bool operator==(const PointerTable&) const = default;
|
|
||||||
};
|
|
||||||
struct SelectorRead {
|
struct SelectorRead {
|
||||||
struct CountedRows {
|
struct CountedRows {
|
||||||
uint32_t source = UINT32_MAX;
|
uint32_t source = UINT32_MAX;
|
||||||
@@ -553,7 +547,8 @@ struct DescriptorSource {
|
|||||||
bool operator==(const SelectorRead& other) const = default;
|
bool operator==(const SelectorRead& other) const = default;
|
||||||
};
|
};
|
||||||
std::optional<SelectorRead> selector;
|
std::optional<SelectorRead> selector;
|
||||||
std::optional<PointerTable> pointer_table;
|
std::optional<uint32_t> table_maximum;
|
||||||
|
std::optional<uint32_t> pointer_offset;
|
||||||
uint32_t table_source = 0;
|
uint32_t table_source = 0;
|
||||||
uint32_t table_offset = 0;
|
uint32_t table_offset = 0;
|
||||||
uint32_t table_immediate = 0;
|
uint32_t table_immediate = 0;
|
||||||
|
|||||||
@@ -367,13 +367,12 @@ bool MaterializeIndirectDescriptor(const ResourcePlan& p
|
|||||||
(table.Stride() & 3u) != 0u || table.Stride() < indirect.table_record_bytes)))
|
(table.Stride() & 3u) != 0u || table.Stride() < indirect.table_record_bytes)))
|
||||||
return false;
|
return false;
|
||||||
const bool affine = indirect.table_stride != 0u;
|
const bool affine = indirect.table_stride != 0u;
|
||||||
const auto* pointer = indirect.pointer_table ? &*indirect.pointer_table : nullptr;
|
const uint64_t step = indirect.table_maximum ? indirect.table_stride
|
||||||
const uint64_t step = pointer != nullptr ? indirect.table_stride
|
|
||||||
: affine ? uint64_t {1} << std::countr_zero(indirect.table_stride) : 4u;
|
: affine ? uint64_t {1} << std::countr_zero(indirect.table_stride) : 4u;
|
||||||
const uint64_t first = ((pointer != nullptr ? indirect.table_offset
|
const uint64_t first = ((indirect.table_maximum ? indirect.table_offset
|
||||||
: indirect.table_offset % step) & ~uint64_t {3}) +
|
: indirect.table_offset % step) & ~uint64_t {3}) +
|
||||||
(indirect.table_immediate & ~3u);
|
(indirect.table_immediate & ~3u);
|
||||||
const uint64_t domain = pointer != nullptr ? uint64_t {pointer->maximum} + 1u
|
const uint64_t domain = indirect.table_maximum ? uint64_t {*indirect.table_maximum} + 1u
|
||||||
: (uint64_t {1} << 32u) / step;
|
: (uint64_t {1} << 32u) / step;
|
||||||
const auto count = table_size >= first + 4u
|
const auto count = table_size >= first + 4u
|
||||||
? std::min((table_size - first - 4u) / step + 1u, domain)
|
? std::min((table_size - first - 4u) / step + 1u, domain)
|
||||||
@@ -390,11 +389,11 @@ bool MaterializeIndirectDescriptor(const ResourcePlan& p
|
|||||||
snapshot.flattened_srt.resize(mapping_offset + 2u, 0u);
|
snapshot.flattened_srt.resize(mapping_offset + 2u, 0u);
|
||||||
for (uint32_t word = 0; word < count; ++word) {
|
for (uint32_t word = 0; word < count; ++word) {
|
||||||
DescriptorValue candidate {.dword_count = dword_count};
|
DescriptorValue candidate {.dword_count = dword_count};
|
||||||
if (pointer != nullptr) {
|
if (indirect.pointer_offset) {
|
||||||
std::array<uint32_t, 2> address {};
|
std::array<uint32_t, 2> address {};
|
||||||
if (!ReadScalarTable(table_base, table_size, first + word * step, runtime, address) ||
|
if (!ReadScalarTable(table_base, table_size, first + word * step, runtime, address) ||
|
||||||
!ReadScalarTable((uint64_t {address[1]} << 32u) | address[0], UINT64_MAX,
|
!ReadScalarTable((uint64_t {address[1]} << 32u) | address[0], UINT64_MAX,
|
||||||
pointer->offset, runtime,
|
*indirect.pointer_offset, runtime,
|
||||||
std::span(candidate.dwords).first(dword_count))) return false;
|
std::span(candidate.dwords).first(dword_count))) return false;
|
||||||
} else if (affine) {
|
} else if (affine) {
|
||||||
if (!ReadScalarTable(table_base, table_size, first + word * step, runtime,
|
if (!ReadScalarTable(table_base, table_size, first + word * step, runtime,
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ public:
|
|||||||
std::vector<std::pair<const IndirectDescriptorPlan*, Value>> buffer_selections;
|
std::vector<std::pair<const IndirectDescriptorPlan*, Value>> buffer_selections;
|
||||||
for (const auto& plan: m_indirect_descriptors) {
|
for (const auto& plan: m_indirect_descriptors) {
|
||||||
auto key = plan.key;
|
auto key = plan.key;
|
||||||
if (m_sources[plan.source].indirect_descriptor->pointer_table) {
|
if (m_sources[plan.source].indirect_descriptor->table_maximum) {
|
||||||
auto* block = plan.handle->Parent();
|
auto* block = plan.handle->Parent();
|
||||||
const auto where = std::ranges::find_if(block->Instructions(),
|
const auto where = std::ranges::find_if(block->Instructions(),
|
||||||
[&](const Inst& inst) { return &inst == plan.handle; });
|
[&](const Inst& inst) { return &inst == plan.handle; });
|
||||||
@@ -974,7 +974,8 @@ private:
|
|||||||
if (current.indirect_descriptor.has_value()) {
|
if (current.indirect_descriptor.has_value()) {
|
||||||
const auto& a = *current.indirect_descriptor;
|
const auto& a = *current.indirect_descriptor;
|
||||||
const auto& b = *descriptor.indirect_descriptor;
|
const auto& b = *descriptor.indirect_descriptor;
|
||||||
if (a.selector != b.selector || a.pointer_table != b.pointer_table ||
|
if (a.selector != b.selector || a.table_maximum != b.table_maximum ||
|
||||||
|
a.pointer_offset != b.pointer_offset ||
|
||||||
a.table_source != b.table_source ||
|
a.table_source != b.table_source ||
|
||||||
a.table_offset != b.table_offset || a.table_immediate != b.table_immediate ||
|
a.table_offset != b.table_offset || a.table_immediate != b.table_immediate ||
|
||||||
a.table_stride != b.table_stride || a.indexed != b.indexed ||
|
a.table_stride != b.table_stride || a.indexed != b.indexed ||
|
||||||
@@ -2779,7 +2780,8 @@ private:
|
|||||||
indirect.table_source = InternSource(table_source);
|
indirect.table_source = InternSource(table_source);
|
||||||
indirect.table_immediate = low_memory->offset & ~3u;
|
indirect.table_immediate = low_memory->offset & ~3u;
|
||||||
indirect.table_scalar = true;
|
indirect.table_scalar = true;
|
||||||
indirect.pointer_table = {{maximum, descriptor_offset}};
|
indirect.table_maximum = maximum;
|
||||||
|
indirect.pointer_offset = descriptor_offset;
|
||||||
DescriptorSource source;
|
DescriptorSource source;
|
||||||
source.dword_count = handle.NumArgs();
|
source.dword_count = handle.NumArgs();
|
||||||
source.dwords.fill(Value(0u));
|
source.dwords.fill(Value(0u));
|
||||||
|
|||||||
@@ -656,9 +656,9 @@ void TestNestedPointerImageTable() {
|
|||||||
for (const auto source : {plan.info.images[0].source, plan.info.samplers[0].source}) {
|
for (const auto source : {plan.info.images[0].source, plan.info.samplers[0].source}) {
|
||||||
const auto& descriptor = plan.descriptor_sources[source];
|
const auto& descriptor = plan.descriptor_sources[source];
|
||||||
const auto& indirect = descriptor.indirect_descriptor;
|
const auto& indirect = descriptor.indirect_descriptor;
|
||||||
Check(indirect && !indirect->selector && indirect->pointer_table &&
|
Check(indirect && !indirect->selector && indirect->table_maximum == 65535u &&
|
||||||
indirect->pointer_table->maximum == 65535u && indirect->table_stride == 592u &&
|
indirect->table_stride == 592u &&
|
||||||
indirect->pointer_table->offset == (descriptor.dword_count == 8u ? 0x3d0u : 0x3f8u),
|
indirect->pointer_offset == (descriptor.dword_count == 8u ? 0x3d0u : 0x3f8u),
|
||||||
"nested pointer descriptors lost their row geometry or captured the GPU selector payload");
|
"nested pointer descriptors lost their row geometry or captured the GPU selector payload");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user