mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: bound waterfall buffer descriptors with same-lane guards
Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
@@ -1956,18 +1956,25 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
Value UnsignedImageBound(Value key, const Inst& handle) const {
|
||||
Value UnsignedResourceBound(Value key, const Inst& handle) const {
|
||||
Value bound;
|
||||
for (const auto& use: handle.Uses()) {
|
||||
const auto& image = *use.user;
|
||||
const auto op = image.GetOpcode();
|
||||
const auto& access = *use.user;
|
||||
const auto op = access.GetOpcode();
|
||||
if (use.operand != 0u || (op != ValueOpcode::ImageSampleRaw &&
|
||||
op != ValueOpcode::ImageGatherRaw && op != ValueOpcode::ImageRead)) return {};
|
||||
// The image's own EXEC predicate proves the range for every accessing lane;
|
||||
op != ValueOpcode::ImageGatherRaw && op != ValueOpcode::ImageRead &&
|
||||
!IndirectBufferAccess(access))) return {};
|
||||
// The access's own EXEC predicate proves the range for every accessing lane;
|
||||
// an EXEC-nonzero branch alone only proves that some lane is active.
|
||||
const auto active = image.Arg(image.NumArgs() - 1u);
|
||||
const auto active = access.Arg(access.NumArgs() - 1u);
|
||||
auto candidate = UnsignedBound(active, key);
|
||||
if (candidate.IsEmpty()) candidate = UnsignedBoundOnEntry(key, image.Parent(), false, active);
|
||||
if (candidate.IsEmpty()) candidate = UnsignedBoundOnEntry(key, access.Parent(), false, active);
|
||||
if (candidate.IsEmpty()) {
|
||||
// A waterfall key inherits the local value's bound only where this same
|
||||
// EXEC predicate proves both their equality and the local range.
|
||||
const auto local = EqualLocalKey(active, key);
|
||||
if (!local.IsEmpty()) candidate = UnsignedBound(active, local, true, false, active);
|
||||
}
|
||||
if (candidate.IsEmpty() ||
|
||||
!ValidateRuntimeValue(m_program, candidate, RuntimeValueType::Integer)) return {};
|
||||
if (bound.IsEmpty()) bound = candidate;
|
||||
@@ -2881,7 +2888,7 @@ private:
|
||||
plan.retain_reads |= table_source.dword_count == 4u;
|
||||
} else if (table_source.dword_count == 2u) {
|
||||
auto guarded_count = UnsignedBoundOnEntry(key, handle.Parent());
|
||||
if (guarded_count.IsEmpty()) guarded_count = UnsignedImageBound(key, handle);
|
||||
if (guarded_count.IsEmpty()) guarded_count = UnsignedResourceBound(key, handle);
|
||||
// A runtime count can describe fewer rows than the mask's static bit range.
|
||||
if (guarded_count.IsEmpty()) guarded_count = UnsignedBoundOnEntry(key, handle.Parent(), true);
|
||||
if (!guarded_count.IsEmpty()) {
|
||||
@@ -3104,6 +3111,13 @@ private:
|
||||
return finish();
|
||||
}
|
||||
if (!legacy_store) {
|
||||
if (!plan.split_offsets) {
|
||||
const auto count = UnsignedResourceBound(key, handle);
|
||||
if (!count.IsEmpty()) {
|
||||
indirect.key_count = count;
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
if (table_source.dword_count == 2u && !plan.split_offsets) {
|
||||
const auto maximum = SelectorMaximum(key);
|
||||
if (maximum >= MaxIndirectDescriptorProbes) return false;
|
||||
|
||||
Reference in New Issue
Block a user