1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 12:42:41 +01:00

rsx: Use a shared sampler pool instead of relying on the drivers

This commit is contained in:
kd-11 2019-05-17 00:03:37 +03:00 committed by kd-11
parent edb1a32bb1
commit e3f68c66d8
3 changed files with 67 additions and 19 deletions

View File

@ -775,7 +775,6 @@ VKGSRender::~VKGSRender()
}
m_aux_frame_context.buffer_views_to_clean.clear();
m_aux_frame_context.samplers_to_clean.clear();
//NOTE: aux_context uses descriptor pools borrowed from the main queues and any allocations will be automatically freed when pool is destroyed
for (auto &ctx : frame_context_storage)
@ -784,7 +783,6 @@ VKGSRender::~VKGSRender()
ctx.descriptor_pool.destroy();
ctx.buffer_views_to_clean.clear();
ctx.samplers_to_clean.clear();
}
m_draw_fbo.reset();
@ -798,13 +796,7 @@ VKGSRender::~VKGSRender()
m_rtts.destroy();
m_texture_cache.destroy();
//Sampler handles
for (auto& handle : fs_sampler_handles)
handle.reset();
for (auto& handle : vs_sampler_handles)
handle.reset();
m_resource_manager.destroy();
m_stencil_mirror_sampler.reset();
//Overlay text handler
@ -1594,14 +1586,13 @@ void VKGSRender::end()
if (!fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode))
{
m_current_frame->samplers_to_clean.push_back(std::move(fs_sampler_handles[i]));
replace = true;
}
}
if (replace)
{
fs_sampler_handles[i] = std::make_unique<vk::sampler>(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
fs_sampler_handles[i] = m_resource_manager.find_sampler(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode);
}
}
@ -1641,14 +1632,13 @@ void VKGSRender::end()
if (!vs_sampler_handles[i]->matches(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
unnormalized_coords, 0.f, 1.f, min_lod, max_lod, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color))
{
m_current_frame->samplers_to_clean.push_back(std::move(vs_sampler_handles[i]));
replace = true;
}
}
if (replace)
{
vs_sampler_handles[i] = std::make_unique<vk::sampler>(
vs_sampler_handles[i] = m_resource_manager.find_sampler(
*m_device,
VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
unnormalized_coords,
@ -2506,7 +2496,6 @@ void VKGSRender::process_swap_request(frame_context_t *ctx, bool free_resources)
m_ui_renderer->free_resources();
ctx->buffer_views_to_clean.clear();
ctx->samplers_to_clean.clear();
if (ctx->last_frame_sync_time > m_last_heap_sync_time)
{

View File

@ -164,7 +164,6 @@ struct frame_context_t
u32 used_descriptors = 0;
std::vector<std::unique_ptr<vk::buffer_view>> buffer_views_to_clean;
std::vector<std::unique_ptr<vk::sampler>> samplers_to_clean;
u32 present_image = UINT32_MAX;
command_buffer_chunk* swap_command_buffer = nullptr;
@ -205,7 +204,6 @@ struct frame_context_t
void swap_storage(frame_context_t &other)
{
std::swap(buffer_views_to_clean, other.buffer_views_to_clean);
std::swap(samplers_to_clean, other.samplers_to_clean);
}
void tag_frame_end(s64 attrib_loc, s64 vtxenv_loc, s64 fragenv_loc, s64 vtxlayout_loc, s64 fragtex_loc, s64 fragconst_loc,s64 vtxconst_loc, s64 index_loc, s64 texture_loc)
@ -279,6 +277,66 @@ struct flush_request_task
}
};
// TODO: This class will be expanded into a global allocator/collector eventually
class resource_manager
{
private:
std::unordered_multimap<u64, std::unique_ptr<vk::sampler>> m_sampler_pool;
bool value_compare(const f32& a, const f32& b)
{
return fabsf(a - b) < 0.0000001f;
}
public:
resource_manager() {}
~resource_manager() {}
void destroy()
{
m_sampler_pool.clear();
}
vk::sampler* find_sampler(VkDevice dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
VkBool32 unnormalized_coordinates, float mipLodBias, float max_anisotropy, float min_lod, float max_lod,
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color,
VkBool32 depth_compare = VK_FALSE, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER)
{
u64 key = u16(clamp_u) | u64(clamp_v) << 3 | u64(clamp_w) << 6;
key |= u64(unnormalized_coordinates) << 9; // 1 bit
key |= u64(min_filter) << 10 | u64(mag_filter) << 11; // 1 bit each
key |= u64(mipmap_mode) << 12; // 1 bit
key |= u64(border_color) << 13; // 3 bits
key |= u64(depth_compare) << 16; // 1 bit
key |= u64(depth_compare_mode) << 17; // 3 bits
const auto found = m_sampler_pool.equal_range(key);
for (auto It = found.first; It != found.second; ++It)
{
const auto& info = It->second->info;
if (!value_compare(info.mipLodBias, mipLodBias) ||
!value_compare(info.maxAnisotropy, max_anisotropy) ||
!value_compare(info.minLod, min_lod) ||
!value_compare(info.maxLod, max_lod))
{
continue;
}
return It->second.get();
}
auto result = std::make_unique<vk::sampler>(
dev, clamp_u, clamp_v, clamp_w, unnormalized_coordinates,
mipLodBias, max_anisotropy, min_lod, max_lod,
min_filter, mag_filter, mipmap_mode, border_color,
depth_compare, depth_compare_mode);
auto It = m_sampler_pool.emplace(key, std::move(result));
return It->second.get();
}
};
class VKGSRender : public GSRender, public ::rsx::reports::ZCULL_control
{
private:
@ -303,12 +361,14 @@ private:
std::unique_ptr<vk::sampler> m_stencil_mirror_sampler;
std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::fragment_textures_count> fs_sampler_state = {};
std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::vertex_textures_count> vs_sampler_state = {};
std::array<std::unique_ptr<vk::sampler>, rsx::limits::fragment_textures_count> fs_sampler_handles;
std::array<std::unique_ptr<vk::sampler>, rsx::limits::vertex_textures_count> vs_sampler_handles;
std::array<vk::sampler*, rsx::limits::fragment_textures_count> fs_sampler_handles{};
std::array<vk::sampler*, rsx::limits::vertex_textures_count> vs_sampler_handles{};
std::unique_ptr<vk::buffer_view> m_persistent_attribute_storage;
std::unique_ptr<vk::buffer_view> m_volatile_attribute_storage;
resource_manager m_resource_manager;
public:
//vk::fbo draw_fbo;
std::unique_ptr<vk::vertex_cache> m_vertex_cache;

View File

@ -1364,7 +1364,6 @@ namespace vk
VkBool32 depth_compare = false, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER)
: m_device(dev)
{
VkSamplerCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
info.addressModeU = clamp_u;
info.addressModeV = clamp_v;