mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
rsx: Implement cross-aspect slice gathering
- Fixes a data leak that can happen when a surface is rejected due to aspect mismatch. - Mismatch can lead to rejection due to area covered excluding the RTT and inevitable upload a texture from CPU at the same location. - Overlapping fbo/shader_read resources are not allowed.
This commit is contained in:
parent
377e06a4a2
commit
a756c0679e
@ -276,12 +276,6 @@ namespace rsx
|
||||
|
||||
auto add_rtt_resource = [&](auto& section, u16 slice)
|
||||
{
|
||||
if (section.is_depth != is_depth)
|
||||
{
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 slice_begin = (slice * attr.slice_h);
|
||||
const u32 slice_end = (slice_begin + attr.height);
|
||||
|
||||
@ -332,12 +326,6 @@ namespace rsx
|
||||
|
||||
auto add_local_resource = [&](auto& section, u32 address, u16 slice, bool scaling = true)
|
||||
{
|
||||
if (section->is_depth_texture() != is_depth)
|
||||
{
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
|
||||
// Intersect this resource with the original one
|
||||
const auto section_bpp = get_format_block_size_in_bytes(section->get_gcm_format());
|
||||
const auto normalized_width = (section->get_width() * section_bpp) / attr.bpp;
|
||||
@ -600,20 +588,54 @@ namespace rsx
|
||||
{
|
||||
verify(HERE), (select_hint & 0x1) == select_hint;
|
||||
|
||||
bool is_depth;
|
||||
bool is_depth = (select_hint == 0) ? fbos.back().is_depth : local.back()->is_depth_texture();
|
||||
bool aspect_mismatch = false;
|
||||
auto attr2 = attr;
|
||||
|
||||
if (is_depth = (select_hint == 0) ? fbos.back().is_depth : local.back()->is_depth_texture();
|
||||
is_depth)
|
||||
// Check for mixed sources with aspect mismatch
|
||||
// NOTE: If the last texture is a perfect match, this method would not have been called which means at least one transfer has to occur
|
||||
if ((fbos.size() + local.size()) > 1) [[unlikely]]
|
||||
{
|
||||
for (const auto& tex : local)
|
||||
{
|
||||
if (tex->is_depth_texture() != is_depth)
|
||||
{
|
||||
aspect_mismatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aspect_mismatch) [[likely]]
|
||||
{
|
||||
for (const auto& surface : fbos)
|
||||
{
|
||||
if (surface.is_depth != is_depth)
|
||||
{
|
||||
aspect_mismatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aspect_mismatch)
|
||||
{
|
||||
// Override with the requested format
|
||||
is_depth = is_gcm_depth_format(attr.gcm_format);
|
||||
}
|
||||
else if (is_depth)
|
||||
{
|
||||
// Depth format textures were found. Check if the data can be bitcast without conversion.
|
||||
if (const auto suggested_format = get_compatible_depth_format(attr.gcm_format);
|
||||
!is_gcm_depth_format(suggested_format))
|
||||
{
|
||||
// Failed!
|
||||
// Requested format cannot be directly read from a depth texture.
|
||||
// Typeless conversion will be performed to make data accessible.
|
||||
is_depth = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace request format with one that is compatible with existing data.
|
||||
attr2.gcm_format = suggested_format;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user