mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
rsx/texture-cache: Rework invalidation cause object to have more granular controls
This commit is contained in:
parent
109b841d8d
commit
9afebfdd72
@ -34,85 +34,132 @@ namespace rsx
|
|||||||
flush_once = 1
|
flush_once = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
struct invalidation_cause
|
class invalidation_cause
|
||||||
{
|
{
|
||||||
enum enum_type
|
public:
|
||||||
|
enum class enum_type
|
||||||
{
|
{
|
||||||
invalid = 0,
|
invalid = 0,
|
||||||
read,
|
read,
|
||||||
deferred_read,
|
deferred_read,
|
||||||
write,
|
write,
|
||||||
deferred_write,
|
deferred_write,
|
||||||
unmap, // fault range is being unmapped
|
unmap, // fault range is being unmapped
|
||||||
reprotect, // we are going to reprotect the fault range
|
reprotect, // we are going to reprotect the fault range
|
||||||
superseded_by_fbo, // used by texture_cache::locked_memory_region
|
superseded_by_fbo, // used by texture_cache::locked_memory_region
|
||||||
committed_as_fbo // same as superseded_by_fbo but without locking or preserving page flags
|
committed_as_fbo // same as superseded_by_fbo but without locking or preserving page flags
|
||||||
} cause;
|
};
|
||||||
|
|
||||||
|
enum flags : u32
|
||||||
|
{
|
||||||
|
cause_is_valid = (1 << 0),
|
||||||
|
cause_is_read = (1 << 1),
|
||||||
|
cause_is_write = (1 << 2),
|
||||||
|
cause_is_deferred = (1 << 3),
|
||||||
|
cause_skips_fbos = (1 << 4),
|
||||||
|
cause_skips_flush = (1 << 5),
|
||||||
|
cause_keeps_fault_range_protection = (1 << 6),
|
||||||
|
cause_uses_strict_data_bounds = (1 << 7),
|
||||||
|
};
|
||||||
|
|
||||||
|
using enum enum_type;
|
||||||
|
|
||||||
constexpr bool valid() const
|
constexpr bool valid() const
|
||||||
{
|
{
|
||||||
return cause != invalid;
|
return m_flag_bits & flags::cause_is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool is_read() const
|
constexpr bool is_read() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return (cause == read || cause == deferred_read);
|
return m_flag_bits & flags::cause_is_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool deferred_flush() const
|
constexpr bool deferred_flush() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return (cause == deferred_read || cause == deferred_write);
|
return m_flag_bits & flags::cause_is_deferred;
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool destroy_fault_range() const
|
|
||||||
{
|
|
||||||
AUDIT(valid());
|
|
||||||
return (cause == unmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool keep_fault_range_protection() const
|
constexpr bool keep_fault_range_protection() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return (cause == unmap || cause == reprotect || cause == superseded_by_fbo);
|
return m_flag_bits & flags::cause_keeps_fault_range_protection;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool skip_fbos() const
|
constexpr bool skip_fbos() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return (cause == superseded_by_fbo || cause == committed_as_fbo);
|
return m_flag_bits & flags::cause_skips_fbos;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool skip_flush() const
|
constexpr bool skip_flush() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return (cause == unmap) || (!g_cfg.video.strict_texture_flushing && cause == superseded_by_fbo);
|
return m_flag_bits & flags::cause_skips_flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr invalidation_cause undefer() const
|
constexpr bool use_strict_data_bounds() const
|
||||||
{
|
{
|
||||||
AUDIT(deferred_flush());
|
AUDIT(valid());
|
||||||
if (cause == deferred_read)
|
return m_flag_bits & flags::cause_uses_strict_data_bounds;
|
||||||
return read;
|
|
||||||
if (cause == deferred_write)
|
|
||||||
return write;
|
|
||||||
fmt::throw_exception("Unreachable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr invalidation_cause defer() const
|
inline invalidation_cause undefer() const
|
||||||
{
|
{
|
||||||
AUDIT(!deferred_flush());
|
ensure(m_flag_bits & cause_is_deferred);
|
||||||
if (cause == read)
|
return invalidation_cause(m_flag_bits & ~cause_is_deferred);
|
||||||
return deferred_read;
|
|
||||||
if (cause == write)
|
|
||||||
return deferred_write;
|
|
||||||
fmt::throw_exception("Unreachable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr invalidation_cause() : cause(invalid) {}
|
inline invalidation_cause defer() const
|
||||||
constexpr invalidation_cause(enum_type _cause) : cause(_cause) {}
|
{
|
||||||
operator enum_type&() { return cause; }
|
ensure(!(m_flag_bits & cause_is_deferred));
|
||||||
constexpr operator enum_type() const { return cause; }
|
return invalidation_cause(m_flag_bits | cause_is_deferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator == (const invalidation_cause& other) const
|
||||||
|
{
|
||||||
|
return m_flag_bits == other.m_flag_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidation_cause() = default;
|
||||||
|
invalidation_cause(enum_type cause) { flag_bits_from_cause(cause); }
|
||||||
|
invalidation_cause(u32 flag_bits)
|
||||||
|
: m_flag_bits(flag_bits | flags::cause_is_valid) // FIXME: Actual validation
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
u32 m_flag_bits = 0;
|
||||||
|
|
||||||
|
void flag_bits_from_cause(enum_type cause)
|
||||||
|
{
|
||||||
|
constexpr std::array s_lookup_table
|
||||||
|
{
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::read, flags::cause_is_read),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::deferred_read, flags::cause_is_read | flags::cause_is_deferred),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::write, flags::cause_is_write),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::deferred_write, flags::cause_is_write | flags::cause_is_deferred),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::unmap, flags::cause_keeps_fault_range_protection | flags::cause_skips_flush),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::reprotect, flags::cause_keeps_fault_range_protection),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::superseded_by_fbo, flags::cause_keeps_fault_range_protection | flags::cause_skips_fbos | flags::cause_skips_flush),
|
||||||
|
std::make_pair<enum_type, u32>(enum_type::committed_as_fbo, flags::cause_skips_fbos),
|
||||||
|
};
|
||||||
|
|
||||||
|
m_flag_bits = 0;
|
||||||
|
for (const auto& entry : s_lookup_table)
|
||||||
|
{
|
||||||
|
if (entry.first == cause)
|
||||||
|
{
|
||||||
|
m_flag_bits = entry.second | flags::cause_is_valid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cause == enum_type::superseded_by_fbo &&
|
||||||
|
g_cfg.video.strict_texture_flushing) [[ unlikely ]]
|
||||||
|
{
|
||||||
|
m_flag_bits &= ~flags::cause_skips_flush;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user