mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
shader: plan finite GPU-selected RGBA16 buffer stores
This commit is contained in:
@@ -253,12 +253,16 @@ bool NormalizeIndirectBuffer(DescriptorValue& value, bool indexed, const BufferR
|
||||
const auto format = Format::GetFormatInfo(descriptor.Format());
|
||||
if (!indexed || format.type == Format::ComponentType::Unknown)
|
||||
return SpecializationFail("indirect formatted buffers require a supported indexed format");
|
||||
if (!formatted_read &&
|
||||
((descriptor.Format() != Prospero::BufferFormat::k32UInt &&
|
||||
descriptor.Format() != Prospero::BufferFormat::k8SInt) ||
|
||||
descriptor.DstSelXYZW() != DstSel(4, 0, 0, 0) ||
|
||||
descriptor.Stride() != format.byte_size))
|
||||
return SpecializationFail("indirect formatted X stores require tight SInt8 or UInt32 identity records");
|
||||
if (!formatted_read) {
|
||||
const bool scalar = resource.max_byte_extent == 4u &&
|
||||
(descriptor.Format() == Prospero::BufferFormat::k32UInt ||
|
||||
descriptor.Format() == Prospero::BufferFormat::k8SInt);
|
||||
const bool rgba16 = resource.max_byte_extent == 16u &&
|
||||
descriptor.Format() == Prospero::BufferFormat::k16_16_16_16Float;
|
||||
if ((!scalar && !rgba16) || descriptor.Stride() != format.byte_size ||
|
||||
descriptor.DstSelXYZW() != (rgba16 ? DstSel(4, 5, 6, 7) : DstSel(4, 0, 0, 0)))
|
||||
return SpecializationFail("indirect formatted stores require tight identity SInt8, UInt32 or RGBA16Float records");
|
||||
}
|
||||
if (formatted_read &&
|
||||
(descriptor.Base48() == 0u || descriptor.Stride() == 0u || descriptor.NumRecords() == 0u)) {
|
||||
// Every index is out of bounds. Preserve the format and swizzle constants.
|
||||
|
||||
@@ -2618,7 +2618,7 @@ private:
|
||||
bool IndirectBufferAccess(const Inst& inst) const {
|
||||
const auto opcode = inst.GetOpcode();
|
||||
if (opcode != ValueOpcode::StoreBufferU32 && opcode != ValueOpcode::StoreBufferU8 &&
|
||||
opcode != ValueOpcode::LoadBufferU32x2) return false;
|
||||
opcode != ValueOpcode::StoreBufferU32x4 && opcode != ValueOpcode::LoadBufferU32x2) return false;
|
||||
const auto index = inst.Flags<MemoryFlags>().index;
|
||||
if (index >= m_program.memory_info.size()) return false;
|
||||
const auto& memory = m_program.memory_info[index];
|
||||
@@ -2630,6 +2630,9 @@ private:
|
||||
if (!memory.idxen) return false;
|
||||
if (opcode == ValueOpcode::StoreBufferU8)
|
||||
return !memory.formatted && memory.data_bits == 8u;
|
||||
if (opcode == ValueOpcode::StoreBufferU32x4)
|
||||
return memory.formatted && memory.data_bits == 32u && memory.data_dwords == 4u &&
|
||||
memory.component_count == 4u;
|
||||
return memory.formatted && memory.data_bits == 16u && memory.data_dwords == 2u &&
|
||||
memory.component_count == 4u;
|
||||
}
|
||||
@@ -3023,6 +3026,12 @@ private:
|
||||
return finish();
|
||||
}
|
||||
if (!legacy_store) {
|
||||
if (table_source.dword_count == 2u && !plan.split_offsets) {
|
||||
const auto maximum = SelectorMaximum(key);
|
||||
if (maximum >= MaxIndirectDescriptorProbes) return false;
|
||||
indirect.key_count = Value(maximum + 1u);
|
||||
return finish();
|
||||
}
|
||||
// A bounded V# supplies every reachable descriptor without reading the GPU key.
|
||||
// Separate U32 offsets could wrap each DWORD to a different table position.
|
||||
if (table_source.dword_count != 4u || plan.split_offsets) return false;
|
||||
|
||||
Reference in New Issue
Block a user