mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-11 06:40:39 +00:00
rsx: Fix reference leaks in texture_cache<->surface_cache communication
- Properly commit orphaned blocks not invalidating existing cache structures - Do not ignore overwritten objects when commiting as unprotected fbo. Avoids stale references to invalidated surface objects.
This commit is contained in:
parent
ca8b0da141
commit
5d1b7eb945
@ -853,7 +853,7 @@ namespace rsx
|
|||||||
(invalidation_ignore_unsynchronized && tex.is_flushable() && (cause.skip_flush() || !tex.is_synchronized()) && !overlaps_fault_range) ||
|
(invalidation_ignore_unsynchronized && tex.is_flushable() && (cause.skip_flush() || !tex.is_synchronized()) && !overlaps_fault_range) ||
|
||||||
// HACK: When being superseded by an fbo, we preserve other overlapped fbos unless the start addresses match
|
// HACK: When being superseded by an fbo, we preserve other overlapped fbos unless the start addresses match
|
||||||
// If region is committed as fbo, all non-fbo data is removed but all fbos in the region must be preserved if possible
|
// If region is committed as fbo, all non-fbo data is removed but all fbos in the region must be preserved if possible
|
||||||
(overlaps_fault_range && tex.get_context() == texture_upload_context::framebuffer_storage && cause.skip_fbos() && (tex.get_section_base() != fault_range_in.start || cause == invalidation_cause::committed_as_fbo))
|
(overlaps_fault_range && tex.get_context() == texture_upload_context::framebuffer_storage && cause.skip_fbos() && tex.get_section_base() != fault_range_in.start)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// False positive
|
// False positive
|
||||||
|
@ -365,38 +365,40 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk
|
|||||||
|
|
||||||
if (!m_rtts.orphaned_surfaces.empty())
|
if (!m_rtts.orphaned_surfaces.empty())
|
||||||
{
|
{
|
||||||
if (g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer)
|
gl::texture::format format;
|
||||||
|
gl::texture::type type;
|
||||||
|
bool swap_bytes;
|
||||||
|
|
||||||
|
for (auto& surface : m_rtts.orphaned_surfaces)
|
||||||
{
|
{
|
||||||
gl::texture::format format;
|
const bool lock = surface->is_depth_surface() ? !!g_cfg.video.write_depth_buffer :
|
||||||
gl::texture::type type;
|
!!g_cfg.video.write_color_buffers;
|
||||||
bool swap_bytes;
|
|
||||||
|
|
||||||
for (auto& surface : m_rtts.orphaned_surfaces)
|
if (LIKELY(!lock))
|
||||||
{
|
{
|
||||||
if (surface->is_depth_surface())
|
m_gl_texture_cache.commit_framebuffer_memory_region(cmd, surface->get_memory_range());
|
||||||
{
|
continue;
|
||||||
if (!g_cfg.video.write_depth_buffer) continue;
|
|
||||||
|
|
||||||
const auto depth_format_gl = rsx::internals::surface_depth_format_to_gl(surface->get_surface_depth_format());
|
|
||||||
format = depth_format_gl.format;
|
|
||||||
type = depth_format_gl.type;
|
|
||||||
swap_bytes = (type != gl::texture::type::uint_24_8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!g_cfg.video.write_color_buffers) continue;
|
|
||||||
|
|
||||||
const auto color_format_gl = rsx::internals::surface_color_format_to_gl(surface->get_surface_color_format());
|
|
||||||
format = color_format_gl.format;
|
|
||||||
type = color_format_gl.type;
|
|
||||||
swap_bytes = color_format_gl.swap_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_gl_texture_cache.lock_memory_region(
|
|
||||||
cmd, surface, surface->get_memory_range(), false,
|
|
||||||
surface->get_surface_width(rsx::surface_metrics::pixels), surface->get_surface_height(rsx::surface_metrics::pixels), surface->get_rsx_pitch(),
|
|
||||||
format, type, swap_bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surface->is_depth_surface())
|
||||||
|
{
|
||||||
|
const auto depth_format_gl = rsx::internals::surface_depth_format_to_gl(surface->get_surface_depth_format());
|
||||||
|
format = depth_format_gl.format;
|
||||||
|
type = depth_format_gl.type;
|
||||||
|
swap_bytes = (type != gl::texture::type::uint_24_8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto color_format_gl = rsx::internals::surface_color_format_to_gl(surface->get_surface_color_format());
|
||||||
|
format = color_format_gl.format;
|
||||||
|
type = color_format_gl.type;
|
||||||
|
swap_bytes = color_format_gl.swap_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gl_texture_cache.lock_memory_region(
|
||||||
|
cmd, surface, surface->get_memory_range(), false,
|
||||||
|
surface->get_surface_width(rsx::surface_metrics::pixels), surface->get_surface_height(rsx::surface_metrics::pixels), surface->get_rsx_pitch(),
|
||||||
|
format, type, swap_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rtts.orphaned_surfaces.clear();
|
m_rtts.orphaned_surfaces.clear();
|
||||||
|
@ -2927,34 +2927,36 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
|||||||
|
|
||||||
if (!m_rtts.orphaned_surfaces.empty())
|
if (!m_rtts.orphaned_surfaces.empty())
|
||||||
{
|
{
|
||||||
if (g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer)
|
u32 gcm_format;
|
||||||
|
bool swap_bytes;
|
||||||
|
|
||||||
|
for (auto& surface : m_rtts.orphaned_surfaces)
|
||||||
{
|
{
|
||||||
u32 gcm_format;
|
const bool lock = surface->is_depth_surface() ? !!g_cfg.video.write_depth_buffer :
|
||||||
bool swap_bytes;
|
!!g_cfg.video.write_color_buffers;
|
||||||
|
|
||||||
for (auto& surface : m_rtts.orphaned_surfaces)
|
if (LIKELY(!lock))
|
||||||
{
|
{
|
||||||
if (surface->is_depth_surface())
|
m_texture_cache.commit_framebuffer_memory_region(*m_current_command_buffer, surface->get_memory_range());
|
||||||
{
|
continue;
|
||||||
if (!g_cfg.video.write_depth_buffer) continue;
|
|
||||||
|
|
||||||
gcm_format = (surface->get_surface_depth_format() != rsx::surface_depth_format::z16) ? CELL_GCM_TEXTURE_DEPTH16 : CELL_GCM_TEXTURE_DEPTH24_D8;
|
|
||||||
swap_bytes = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!g_cfg.video.write_color_buffers) continue;
|
|
||||||
|
|
||||||
auto info = get_compatible_gcm_format(surface->get_surface_color_format());
|
|
||||||
gcm_format = info.first;
|
|
||||||
swap_bytes = info.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_texture_cache.lock_memory_region(
|
|
||||||
*m_current_command_buffer, surface, surface->get_memory_range(), false,
|
|
||||||
surface->get_surface_width(rsx::surface_metrics::pixels), surface->get_surface_height(rsx::surface_metrics::pixels), surface->get_rsx_pitch(),
|
|
||||||
gcm_format, swap_bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surface->is_depth_surface())
|
||||||
|
{
|
||||||
|
gcm_format = (surface->get_surface_depth_format() != rsx::surface_depth_format::z16) ? CELL_GCM_TEXTURE_DEPTH16 : CELL_GCM_TEXTURE_DEPTH24_D8;
|
||||||
|
swap_bytes = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto info = get_compatible_gcm_format(surface->get_surface_color_format());
|
||||||
|
gcm_format = info.first;
|
||||||
|
swap_bytes = info.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_texture_cache.lock_memory_region(
|
||||||
|
*m_current_command_buffer, surface, surface->get_memory_range(), false,
|
||||||
|
surface->get_surface_width(rsx::surface_metrics::pixels), surface->get_surface_height(rsx::surface_metrics::pixels), surface->get_rsx_pitch(),
|
||||||
|
gcm_format, swap_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rtts.orphaned_surfaces.clear();
|
m_rtts.orphaned_surfaces.clear();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user