rsx: Fix leaking surface cache refs from texture cache

- Lock surfaces in use by texture cache to prevent complete deletion
- Remove discarded surfaces from the reprotect cache to avoid uaf
This commit is contained in:
kd-11 2022-03-27 20:25:34 +03:00 committed by kd-11
parent b645a7faf5
commit d98d152d23
5 changed files with 40 additions and 12 deletions

View file

@ -874,6 +874,12 @@ namespace rsx
tex.set_dirty(true); tex.set_dirty(true);
result.invalidate_samplers = true; result.invalidate_samplers = true;
} }
if (tex.is_dirty() && tex.get_context() == rsx::texture_upload_context::framebuffer_storage)
{
// Make sure the region is not going to get immediately reprotected
m_flush_always_cache.erase(tex.get_section_range());
}
} }
} }

View file

@ -1353,9 +1353,28 @@ namespace rsx
set_dirty(false); set_dirty(false);
} }
if (context == rsx::texture_upload_context::framebuffer_storage)
{
// Lock, unlock
if (prot == utils::protection::no && old_prot != utils::protection::no)
{
// Locked memory. We have to take ownership of the object in the surface cache as well
auto surface = derived()->get_render_target();
surface->add_ref();
}
else if (old_prot == utils::protection::no && prot != utils::protection::no)
{
// Release the surface, the cache can remove it if needed
ensure(prot == utils::protection::rw);
auto surface = derived()->get_render_target();
surface->release();
}
}
} }
public: public:
inline void protect(utils::protection prot) inline void protect(utils::protection prot)
{ {
utils::protection old_prot = get_protection(); utils::protection old_prot = get_protection();
@ -1442,6 +1461,11 @@ namespace rsx
} }
flush_exclusions.clear(); flush_exclusions.clear();
if (context == rsx::texture_upload_context::framebuffer_storage)
{
derived()->get_render_target()->sync_tag();
}
} }
void on_speculative_flush() void on_speculative_flush()

View file

@ -81,12 +81,6 @@ namespace gl
rsx_log.error("Unexpected swizzled texture format 0x%x", static_cast<u32>(format)); rsx_log.error("Unexpected swizzled texture format 0x%x", static_cast<u32>(format));
} }
} }
if (context == rsx::texture_upload_context::framebuffer_storage)
{
// Update memory tag
static_cast<gl::render_target*>(vram_texture)->sync_tag();
}
} }
gl::texture_view* texture_cache::create_temporary_subresource_impl(gl::command_context& cmd, gl::texture* src, GLenum sized_internal_fmt, GLenum dst_type, gl::texture_view* texture_cache::create_temporary_subresource_impl(gl::command_context& cmd, gl::texture* src, GLenum sized_internal_fmt, GLenum dst_type,

View file

@ -406,6 +406,11 @@ namespace gl
return managed_texture.get(); return managed_texture.get();
} }
gl::render_target* get_render_target()
{
return gl::as_rtt(vram_texture);
}
gl::texture_view* get_raw_view() gl::texture_view* get_raw_view()
{ {
return vram_texture->get_view(0xAAE4, rsx::default_remap_vector); return vram_texture->get_view(0xAAE4, rsx::default_remap_vector);

View file

@ -151,6 +151,11 @@ namespace vk
return managed_texture; return managed_texture;
} }
vk::render_target* get_render_target()
{
return vk::as_rtt(vram_texture);
}
VkFormat get_format() const VkFormat get_format() const
{ {
if (context == rsx::texture_upload_context::dma) if (context == rsx::texture_upload_context::dma)
@ -293,12 +298,6 @@ namespace vk
rsx_log.error("Unexpected swizzled texture format 0x%x", gcm_format); rsx_log.error("Unexpected swizzled texture format 0x%x", gcm_format);
} }
} }
if (context == rsx::texture_upload_context::framebuffer_storage)
{
// Update memory tag
static_cast<vk::render_target*>(vram_texture)->sync_tag();
}
} }
void* map_synchronized(u32, u32) void* map_synchronized(u32, u32)