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,
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();
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)
{
// 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))
{

View File

@ -91,7 +91,38 @@ namespace gl
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)
{
@ -104,29 +135,18 @@ namespace gl
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)
{
// 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_);
}
else
{
swizzle = src->get_native_component_layout();
auto components = get_component_mapping(gcm_format, rsx::component_order::default_);
dst->set_native_component_layout(components);
}
if (memcmp(remap.first.data(), rsx::default_remap_vector.first.data(), 4) ||
memcmp(remap.second.data(), rsx::default_remap_vector.second.data(), 4))
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;
const auto encoding = rsx::get_remap_encoding(remap);
return dst->get_view(encoding, remap);
}
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>;
friend baseclass;
private:
struct discardable_storage
struct temporary_image_t : public gl::viewable_image, public rsx::ref_counted
{
std::unique_ptr<gl::texture> image;
std::unique_ptr<gl::texture_view> view;
u64 properties_encoding = 0;
discardable_storage() = default;
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);
}
using gl::viewable_image::viewable_image;
};
private:
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()
{
baseclass::clear();
@ -615,10 +598,9 @@ namespace gl
{
for (auto& e : m_temporary_surfaces)
{
if (e.image.get() == view->image())
if (e.get() == view->image())
{
e.view.reset();
e.image.reset();
e->release();
return;
}
}
@ -889,7 +871,10 @@ namespace gl
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();
}