mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 03:32:55 +00:00
rsx: Avoid expensive protection scan by sharing some data between surface and texture cache
This commit is contained in:
parent
8ec01450f8
commit
a05e3f02b8
@ -125,7 +125,7 @@ namespace rsx
|
||||
};
|
||||
|
||||
template <typename image_storage_type>
|
||||
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<rsx::surface_metrics Metrics = rsx::surface_metrics::pixels, typename T = u32>
|
||||
T get_surface_width() const
|
||||
@ -438,7 +449,7 @@ namespace rsx
|
||||
{
|
||||
for (auto &e : old_contents)
|
||||
{
|
||||
release_ref(e.source);
|
||||
ensure(dynamic_cast<rsx::ref_counted*>(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);
|
||||
}
|
||||
};
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace rsx
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor<texture*>
|
||||
class render_target : public viewable_image, public rsx::render_target_descriptor<texture*>
|
||||
{
|
||||
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<gl::render_target*>(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
|
||||
|
@ -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<u8, 4>, std::array<u8, 4>>& remap)
|
||||
{
|
||||
return vram_texture->get_view(remap_encoding, remap);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<vk::render_target*>(t)->release();
|
||||
}
|
||||
|
||||
bool render_target::matches_dimensions(u16 _width, u16 _height) const
|
||||
{
|
||||
// Use forward scaling to account for rounding and clamping errors
|
||||
|
@ -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<vk::viewable_image*>
|
||||
class render_target : public viewable_image, public rsx::render_target_descriptor<vk::viewable_image*>
|
||||
{
|
||||
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<vk::render_target>& /*surface*/)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user