mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +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>
|
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
|
u64 last_use_tag = 0; // tag indicating when this block was last confirmed to have been written to
|
||||||
u32 base_addr = 0;
|
u32 base_addr = 0;
|
||||||
@ -165,6 +165,13 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
format_info;
|
format_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u64 timestamp = 0;
|
||||||
|
bool locked = false;
|
||||||
|
}
|
||||||
|
texture_cache_metadata;
|
||||||
|
|
||||||
render_target_descriptor() {}
|
render_target_descriptor() {}
|
||||||
|
|
||||||
virtual ~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 image_storage_type get_surface(rsx::surface_access access_type) = 0;
|
||||||
virtual bool is_depth_surface() const = 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>
|
template<rsx::surface_metrics Metrics = rsx::surface_metrics::pixels, typename T = u32>
|
||||||
T get_surface_width() const
|
T get_surface_width() const
|
||||||
@ -438,7 +449,7 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
for (auto &e : old_contents)
|
for (auto &e : old_contents)
|
||||||
{
|
{
|
||||||
release_ref(e.source);
|
ensure(dynamic_cast<rsx::ref_counted*>(e.source))->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
old_contents.clear();
|
old_contents.clear();
|
||||||
@ -696,5 +707,31 @@ namespace rsx
|
|||||||
ensure(access_type.is_read() || access_type.is_transfer());
|
ensure(access_type.is_read() || access_type.is_transfer());
|
||||||
transform_samples_to_pixels(region);
|
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);
|
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:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -1359,14 +1379,14 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
// 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();
|
auto surface = derived()->get_render_target();
|
||||||
surface->add_ref();
|
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();
|
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;
|
!!g_cfg.video.write_color_buffers;
|
||||||
|
|
||||||
if (lock &&
|
if (lock &&
|
||||||
|
#ifdef TEXTURE_CACHE_DEBUG
|
||||||
!m_gl_texture_cache.is_protected(
|
!m_gl_texture_cache.is_protected(
|
||||||
base_addr,
|
base_addr,
|
||||||
surface->get_memory_range(),
|
surface->get_memory_range(),
|
||||||
rsx::texture_upload_context::framebuffer_storage))
|
rsx::texture_upload_context::framebuffer_storage)
|
||||||
|
#else
|
||||||
|
!surface->is_locked()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
lock = false;
|
lock = false;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ namespace rsx
|
|||||||
|
|
||||||
namespace gl
|
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 clear_memory(gl::command_context& cmd);
|
||||||
void load_memory(gl::command_context& cmd);
|
void load_memory(gl::command_context& cmd);
|
||||||
@ -81,11 +81,6 @@ namespace gl
|
|||||||
return !!(aspect() & gl::image_aspect::depth);
|
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
|
viewable_image* get_surface(rsx::surface_access /*access_type*/) override
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
@ -232,6 +227,7 @@ struct gl_render_target_traits
|
|||||||
|
|
||||||
sink->set_rsx_pitch(ref->get_rsx_pitch());
|
sink->set_rsx_pitch(ref->get_rsx_pitch());
|
||||||
sink->set_old_contents_region(prev, false);
|
sink->set_old_contents_region(prev, false);
|
||||||
|
sink->texture_cache_metadata = ref->texture_cache_metadata;
|
||||||
sink->last_use_tag = ref->last_use_tag;
|
sink->last_use_tag = ref->last_use_tag;
|
||||||
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
|
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->release();
|
||||||
|
surface->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -383,26 +383,6 @@ namespace gl
|
|||||||
return format;
|
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)
|
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);
|
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;
|
!!g_cfg.video.write_color_buffers;
|
||||||
|
|
||||||
if (lock &&
|
if (lock &&
|
||||||
|
#ifdef TEXTURE_CACHE_DEBUG
|
||||||
!m_texture_cache.is_protected(
|
!m_texture_cache.is_protected(
|
||||||
base_addr,
|
base_addr,
|
||||||
surface->get_memory_range(),
|
surface->get_memory_range(),
|
||||||
rsx::texture_upload_context::framebuffer_storage))
|
rsx::texture_upload_context::framebuffer_storage)
|
||||||
|
#else
|
||||||
|
!surface->is_locked()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
lock = false;
|
lock = false;
|
||||||
}
|
}
|
||||||
|
@ -788,11 +788,6 @@ namespace vk
|
|||||||
return !!(aspect() & VK_IMAGE_ASPECT_DEPTH_BIT);
|
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
|
bool render_target::matches_dimensions(u16 _width, u16 _height) const
|
||||||
{
|
{
|
||||||
// Use forward scaling to account for rounding and clamping errors
|
// 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 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);
|
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 cyclic_reference_sync_tag = 0;
|
||||||
u64 write_barrier_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;
|
vk::viewable_image* get_surface(rsx::surface_access access_type) override;
|
||||||
bool is_depth_surface() const override;
|
bool is_depth_surface() const override;
|
||||||
void release_ref(vk::viewable_image* t) const override;
|
|
||||||
bool matches_dimensions(u16 _width, u16 _height) const;
|
bool matches_dimensions(u16 _width, u16 _height) const;
|
||||||
void reset_surface_counters();
|
void reset_surface_counters();
|
||||||
|
|
||||||
@ -338,6 +337,7 @@ namespace vk
|
|||||||
|
|
||||||
sink->rsx_pitch = ref->get_rsx_pitch();
|
sink->rsx_pitch = ref->get_rsx_pitch();
|
||||||
sink->set_old_contents_region(prev, false);
|
sink->set_old_contents_region(prev, false);
|
||||||
|
sink->texture_cache_metadata = ref->texture_cache_metadata;
|
||||||
sink->last_use_tag = ref->last_use_tag;
|
sink->last_use_tag = ref->last_use_tag;
|
||||||
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
|
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
|
||||||
}
|
}
|
||||||
@ -411,6 +411,7 @@ namespace vk
|
|||||||
}
|
}
|
||||||
|
|
||||||
surface->release();
|
surface->release();
|
||||||
|
surface->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notify_surface_persist(const std::unique_ptr<vk::render_target>& /*surface*/)
|
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
|
bool has_compatible_format(vk::image* tex) const
|
||||||
{
|
{
|
||||||
return vram_texture->info.format == tex->info.format;
|
return vram_texture->info.format == tex->info.format;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user