gl: Reuse scratch images

This commit is contained in:
kd-11 2022-07-17 19:05:00 +03:00 committed by kd-11
parent 8a8fda3e02
commit 82bac4173e
3 changed files with 52 additions and 47 deletions

View File

@ -740,7 +740,7 @@ namespace gl
void fill_texture(gl::command_context& cmd, texture* dst, int format, void fill_texture(gl::command_context& cmd, texture* dst, int format,
const std::vector<rsx::subresource_layout> &input_layouts, const std::vector<rsx::subresource_layout> &input_layouts,
bool is_swizzled, GLenum gl_format, GLenum gl_type, std::vector<std::byte>& staging_buffer) bool is_swizzled, GLenum gl_format, GLenum gl_type, rsx::simple_array<std::byte>& staging_buffer)
{ {
const auto driver_caps = gl::get_driver_caps(); const auto driver_caps = gl::get_driver_caps();
rsx::texture_uploader_capabilities caps rsx::texture_uploader_capabilities caps
@ -1000,7 +1000,7 @@ namespace gl
void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector<rsx::subresource_layout>& subresources_layout) void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector<rsx::subresource_layout>& subresources_layout)
{ {
// Calculate staging buffer size // Calculate staging buffer size
std::vector<std::byte> data_upload_buf; rsx::simple_array<std::byte> data_upload_buf;
if (rsx::is_compressed_host_format(gcm_format)) if (rsx::is_compressed_host_format(gcm_format))
{ {

View File

@ -91,7 +91,38 @@ namespace gl
sized_internal_fmt = gl::get_sized_internal_format(gcm_format); sized_internal_fmt = gl::get_sized_internal_format(gcm_format);
} }
std::unique_ptr<gl::texture> dst = std::make_unique<gl::viewable_image>(dst_type, width, height, depth, mipmaps, sized_internal_fmt, rsx::classify_format(gcm_format)); temporary_image_t* dst = nullptr;
const u64 match_key =
(static_cast<u64>(width) << 0) |
(static_cast<u64>(height) << 16) |
(static_cast<u64>(depth) << 32) |
(static_cast<u64>(mipmaps) << 40) |
(static_cast<u64>(sized_internal_fmt) << 48);
// Search image cache
for (auto& e : m_temporary_surfaces)
{
if (e->has_refs())
{
continue;
}
if (e->properties_encoding == match_key)
{
dst = e.get();
break;
}
}
if (!dst)
{
std::unique_ptr<temporary_image_t> data = std::make_unique<temporary_image_t>(dst_type, width, height, depth, mipmaps, sized_internal_fmt, rsx::classify_format(gcm_format));
dst = data.get();
dst->properties_encoding = match_key;
m_temporary_surfaces.emplace_back(std::move(data));
}
dst->add_ref();
if (copy) if (copy)
{ {
@ -104,29 +135,18 @@ namespace gl
width, height, width, height width, height, width, height
}}; }};
copy_transfer_regions_impl(cmd, dst.get(), region); copy_transfer_regions_impl(cmd, dst, region);
} }
std::array<GLenum, 4> swizzle;
if (!src || static_cast<GLenum>(src->get_internal_format()) != sized_internal_fmt) if (!src || static_cast<GLenum>(src->get_internal_format()) != sized_internal_fmt)
{ {
// Apply base component map onto the new texture if a data cast has been done // Apply base component map onto the new texture if a data cast has been done
swizzle = get_component_mapping(gcm_format, rsx::component_order::default_); auto components = get_component_mapping(gcm_format, rsx::component_order::default_);
} dst->set_native_component_layout(components);
else
{
swizzle = src->get_native_component_layout();
} }
if (memcmp(remap.first.data(), rsx::default_remap_vector.first.data(), 4) || const auto encoding = rsx::get_remap_encoding(remap);
memcmp(remap.second.data(), rsx::default_remap_vector.second.data(), 4)) return dst->get_view(encoding, remap);
swizzle = apply_swizzle_remap(swizzle, remap);
auto view = std::make_unique<gl::texture_view>(dst.get(), dst_type, sized_internal_fmt, swizzle.data());
auto result = view.get();
m_temporary_surfaces.emplace_back(dst, view);
return result;
} }
void texture_cache::copy_transfer_regions_impl(gl::command_context& cmd, gl::texture* dst_image, const std::vector<copy_region_descriptor>& sources) const void texture_cache::copy_transfer_regions_impl(gl::command_context& cmd, gl::texture* dst_image, const std::vector<copy_region_descriptor>& sources) const

View File

@ -441,36 +441,19 @@ namespace gl
using baseclass = rsx::texture_cache<gl::texture_cache, gl::texture_cache_traits>; using baseclass = rsx::texture_cache<gl::texture_cache, gl::texture_cache_traits>;
friend baseclass; friend baseclass;
private: struct temporary_image_t : public gl::viewable_image, public rsx::ref_counted
struct discardable_storage
{ {
std::unique_ptr<gl::texture> image; u64 properties_encoding = 0;
std::unique_ptr<gl::texture_view> view;
discardable_storage() = default; using gl::viewable_image::viewable_image;
discardable_storage(std::unique_ptr<gl::texture>& tex)
{
image = std::move(tex);
}
discardable_storage(std::unique_ptr<gl::texture_view>& _view)
{
view = std::move(_view);
}
discardable_storage(std::unique_ptr<gl::texture>& tex, std::unique_ptr<gl::texture_view>& _view)
{
image = std::move(tex);
view = std::move(_view);
}
}; };
private:
blitter m_hw_blitter; blitter m_hw_blitter;
std::vector<discardable_storage> m_temporary_surfaces; std::vector<std::unique_ptr<temporary_image_t>> m_temporary_surfaces;
const u32 max_cached_image_pool_size = 256;
private:
void clear() void clear()
{ {
baseclass::clear(); baseclass::clear();
@ -615,10 +598,9 @@ namespace gl
{ {
for (auto& e : m_temporary_surfaces) for (auto& e : m_temporary_surfaces)
{ {
if (e.image.get() == view->image()) if (e.get() == view->image())
{ {
e.view.reset(); e->release();
e.image.reset();
return; return;
} }
} }
@ -889,7 +871,10 @@ namespace gl
purge_unreleased_sections(); purge_unreleased_sections();
} }
clear_temporary_subresources(); if (m_temporary_surfaces.size() > max_cached_image_pool_size)
{
m_temporary_surfaces.resize(max_cached_image_pool_size / 2);
}
baseclass::on_frame_end(); baseclass::on_frame_end();
} }