rsx: Handle some corner cases in surface locking

This commit is contained in:
kd-11 2022-12-16 00:08:30 +03:00 committed by kd-11
parent bf96cbe980
commit 90cf47cdce
4 changed files with 30 additions and 6 deletions

View file

@ -722,6 +722,30 @@ namespace rsx
release(); release();
} }
void on_swap_out()
{
if (is_locked())
{
on_unlock();
}
else
{
release();
}
}
void on_swap_in(bool lock)
{
if (!is_locked() && lock)
{
on_lock();
}
else
{
add_ref();
}
}
bool is_locked() const bool is_locked() const
{ {
return texture_cache_metadata.locked; return texture_cache_metadata.locked;

View file

@ -1375,17 +1375,17 @@ namespace rsx
if (context == rsx::texture_upload_context::framebuffer_storage && !Emu.IsStopped()) if (context == rsx::texture_upload_context::framebuffer_storage && !Emu.IsStopped())
{ {
// Lock, unlock // Lock, unlock
auto surface = derived()->get_render_target();
if (prot == utils::protection::no && old_prot != utils::protection::no) 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 // Locked memory. We have to take ownership of the object in the surface cache as well
auto surface = derived()->get_render_target();
surface->on_lock(); surface->on_lock();
} }
else if (old_prot == utils::protection::no && prot != utils::protection::no) else if (old_prot == utils::protection::no && prot != utils::protection::no)
{ {
// Release the surface, the cache can remove it if needed // Release the surface, the cache can remove it if needed
ensure(prot == utils::protection::rw); ensure(prot == utils::protection::rw);
auto surface = derived()->get_render_target();
surface->on_unlock(); surface->on_unlock();
} }
} }

View file

@ -70,12 +70,12 @@ namespace gl
if (vram_texture && !managed_texture && get_protection() == utils::protection::no) if (vram_texture && !managed_texture && get_protection() == utils::protection::no)
{ {
// In-place image swap, still locked. Likely a color buffer that got rebound as depth buffer or vice-versa. // In-place image swap, still locked. Likely a color buffer that got rebound as depth buffer or vice-versa.
gl::as_rtt(vram_texture)->release(); gl::as_rtt(vram_texture)->on_swap_out();
if (!managed) if (!managed)
{ {
// Incoming is also an external resource, reference it immediately // Incoming is also an external resource, reference it immediately
gl::as_rtt(image)->add_ref(); gl::as_rtt(image)->on_swap_in(is_locked());
} }
} }

View file

@ -50,12 +50,12 @@ namespace vk
if (vram_texture && !managed_texture && get_protection() == utils::protection::no) if (vram_texture && !managed_texture && get_protection() == utils::protection::no)
{ {
// In-place image swap, still locked. Likely a color buffer that got rebound as depth buffer or vice-versa. // In-place image swap, still locked. Likely a color buffer that got rebound as depth buffer or vice-versa.
vk::as_rtt(vram_texture)->release(); vk::as_rtt(vram_texture)->on_swap_out();
if (!managed) if (!managed)
{ {
// Incoming is also an external resource, reference it immediately // Incoming is also an external resource, reference it immediately
vk::as_rtt(image)->add_ref(); vk::as_rtt(image)->on_swap_in(is_locked());
} }
} }