diff --git a/rpcs3/Emu/RSX/Common/surface_utils.h b/rpcs3/Emu/RSX/Common/surface_utils.h index 7a53c9ee9c..5ff9490867 100644 --- a/rpcs3/Emu/RSX/Common/surface_utils.h +++ b/rpcs3/Emu/RSX/Common/surface_utils.h @@ -125,7 +125,7 @@ namespace rsx }; template - struct render_target_descriptor + struct render_target_descriptor : public rsx::ref_counted { u64 last_use_tag = 0; // tag indicating when this block was last confirmed to have been written to u32 base_addr = 0; @@ -165,6 +165,13 @@ namespace rsx } format_info; + struct + { + u64 timestamp = 0; + bool locked = false; + } + texture_cache_metadata; + render_target_descriptor() {} virtual ~render_target_descriptor() @@ -178,7 +185,11 @@ namespace rsx virtual image_storage_type get_surface(rsx::surface_access access_type) = 0; virtual bool is_depth_surface() const = 0; - virtual void release_ref(image_storage_type) const = 0; + + void reset() + { + texture_cache_metadata = {}; + } template T get_surface_width() const @@ -438,7 +449,7 @@ namespace rsx { for (auto &e : old_contents) { - release_ref(e.source); + ensure(dynamic_cast(e.source))->release(); } old_contents.clear(); @@ -696,5 +707,31 @@ namespace rsx ensure(access_type.is_read() || access_type.is_transfer()); transform_samples_to_pixels(region); } + + void on_lock() + { + add_ref(); + texture_cache_metadata.locked = true; + texture_cache_metadata.timestamp = rsx::get_shared_tag(); + } + + void on_unlock() + { + texture_cache_metadata.locked = false; + texture_cache_metadata.timestamp = rsx::get_shared_tag(); + release(); + } + + bool is_locked() const + { + return texture_cache_metadata.locked; + } + + bool has_flushable_data() const + { + ensure(is_locked()); + ensure(texture_cache_metadata.timestamp); + return (texture_cache_metadata.timestamp < last_use_tag); + } }; } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/Common/texture_cache_utils.h b/rpcs3/Emu/RSX/Common/texture_cache_utils.h index 7d547dfccc..8d033d254d 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_utils.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_utils.h @@ -1324,6 +1324,26 @@ namespace rsx return (get_protection() == utils::protection::no); } + bool is_synchronized() const + { + return synchronized; + } + + bool is_flushed() const + { + return flushed; + } + + bool should_flush() const + { + if (context == rsx::texture_upload_context::framebuffer_storage) + { + const auto surface = derived()->get_render_target(); + return surface->has_flushable_data(); + } + + return true; + } private: /** @@ -1359,14 +1379,14 @@ namespace rsx { // 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(); + surface->on_lock(); } 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(); + surface->on_unlock(); } } } diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 76b5697485..7874c0a536 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -322,10 +322,15 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /* !!g_cfg.video.write_color_buffers; if (lock && +#ifdef TEXTURE_CACHE_DEBUG !m_gl_texture_cache.is_protected( base_addr, surface->get_memory_range(), - rsx::texture_upload_context::framebuffer_storage)) + rsx::texture_upload_context::framebuffer_storage) +#else + !surface->is_locked() +#endif + ) { lock = false; } diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index 81d3074386..c8c7e22cec 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -47,7 +47,7 @@ namespace rsx namespace gl { - class render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor + class render_target : public viewable_image, public rsx::render_target_descriptor { void clear_memory(gl::command_context& cmd); void load_memory(gl::command_context& cmd); @@ -81,11 +81,6 @@ namespace gl return !!(aspect() & gl::image_aspect::depth); } - void release_ref(texture* t) const override - { - static_cast(t)->release(); - } - viewable_image* get_surface(rsx::surface_access /*access_type*/) override { // TODO @@ -232,6 +227,7 @@ struct gl_render_target_traits sink->set_rsx_pitch(ref->get_rsx_pitch()); sink->set_old_contents_region(prev, false); + sink->texture_cache_metadata = ref->texture_cache_metadata; sink->last_use_tag = ref->last_use_tag; sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data } @@ -293,6 +289,7 @@ struct gl_render_target_traits } surface->release(); + surface->reset(); } static diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 86559d45b8..0555c828fa 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -383,26 +383,6 @@ namespace gl return format; } - bool is_flushed() const - { - return flushed; - } - - bool is_synchronized() const - { - return synchronized; - } - - void set_flushed(bool state) - { - flushed = state; - } - - bool is_empty() const - { - return vram_texture == nullptr; - } - gl::texture_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap) { return vram_texture->get_view(remap_encoding, remap); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 562973aedd..9f6256c382 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2450,10 +2450,15 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context) !!g_cfg.video.write_color_buffers; if (lock && +#ifdef TEXTURE_CACHE_DEBUG !m_texture_cache.is_protected( base_addr, surface->get_memory_range(), - rsx::texture_upload_context::framebuffer_storage)) + rsx::texture_upload_context::framebuffer_storage) +#else + !surface->is_locked() +#endif + ) { lock = false; } diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp index 73465c9e43..08ec971124 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp @@ -788,11 +788,6 @@ namespace vk return !!(aspect() & VK_IMAGE_ASPECT_DEPTH_BIT); } - void render_target::release_ref(vk::viewable_image* t) const - { - static_cast(t)->release(); - } - bool render_target::matches_dimensions(u16 _width, u16 _height) const { // Use forward scaling to account for rounding and clamping errors diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 1c7a63322f..19e15cab46 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -24,7 +24,7 @@ namespace vk void resolve_image(vk::command_buffer& cmd, vk::viewable_image* dst, vk::viewable_image* src); void unresolve_image(vk::command_buffer& cmd, vk::viewable_image* dst, vk::viewable_image* src); - class render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor + class render_target : public viewable_image, public rsx::render_target_descriptor { u64 cyclic_reference_sync_tag = 0; u64 write_barrier_sync_tag = 0; @@ -64,7 +64,6 @@ namespace vk vk::viewable_image* get_surface(rsx::surface_access access_type) override; bool is_depth_surface() const override; - void release_ref(vk::viewable_image* t) const override; bool matches_dimensions(u16 _width, u16 _height) const; void reset_surface_counters(); @@ -338,6 +337,7 @@ namespace vk sink->rsx_pitch = ref->get_rsx_pitch(); sink->set_old_contents_region(prev, false); + sink->texture_cache_metadata = ref->texture_cache_metadata; sink->last_use_tag = ref->last_use_tag; sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data } @@ -411,6 +411,7 @@ namespace vk } surface->release(); + surface->reset(); } static void notify_surface_persist(const std::unique_ptr& /*surface*/) diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 507225bccd..6a4702b4b5 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -345,11 +345,6 @@ namespace vk } } - bool is_synchronized() const - { - return synchronized; - } - bool has_compatible_format(vk::image* tex) const { return vram_texture->info.format == tex->info.format;