mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
vk: Reimplement sampler caching to take border color into account
This commit is contained in:
parent
7eb730ee03
commit
75da7d80dc
@ -54,6 +54,7 @@ namespace vk
|
||||
ensure(max_allowed_samplers);
|
||||
rsx_log.warning("Trimming allocated samplers. Allocated = %u, Max = %u", allocated_sampler_count, limits.maxSamplerAllocationCount);
|
||||
|
||||
#if 0
|
||||
for (auto It = m_sampler_pool.begin(); It != m_sampler_pool.end();)
|
||||
{
|
||||
if (!It->second->has_refs())
|
||||
@ -65,6 +66,7 @@ namespace vk
|
||||
|
||||
++It;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,12 +86,8 @@ namespace vk
|
||||
class resource_manager
|
||||
{
|
||||
private:
|
||||
struct cached_sampler_object_t : public vk::sampler, public rsx::ref_counted
|
||||
{
|
||||
using vk::sampler::sampler;
|
||||
};
|
||||
sampler_pool_t m_sampler_pool;
|
||||
|
||||
std::unordered_map<u64, std::unique_ptr<cached_sampler_object_t>> m_sampler_pool;
|
||||
std::deque<eid_scope_t> m_eid_map;
|
||||
shared_mutex m_eid_map_lock;
|
||||
|
||||
@ -108,28 +104,6 @@ namespace vk
|
||||
return m_eid_map.back();
|
||||
}
|
||||
|
||||
template<bool _signed = false>
|
||||
u16 encode_fxp(f32 value)
|
||||
{
|
||||
u16 raw = u16(std::abs(value) * 256.);
|
||||
|
||||
if constexpr (!_signed)
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value >= 0.f) [[likely]]
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
return u16(0 - raw) & 0x1fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
resource_manager() = default;
|
||||
@ -144,20 +118,14 @@ namespace vk
|
||||
vk::sampler* get_sampler(const vk::render_device& dev, vk::sampler* previous,
|
||||
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,
|
||||
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, const vk::border_color_t& 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
|
||||
key |= u64(encode_fxp(min_lod)) << 20; // 12 bits
|
||||
key |= u64(encode_fxp(max_lod)) << 32; // 12 bits
|
||||
key |= u64(encode_fxp<true>(mipLodBias)) << 44; // 13 bits
|
||||
key |= u64(max_anisotropy) << 57; // 4 bits
|
||||
const auto key = m_sampler_pool.compute_storage_key(
|
||||
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);
|
||||
|
||||
if (previous)
|
||||
{
|
||||
@ -166,11 +134,9 @@ namespace vk
|
||||
as_cached_object->release();
|
||||
}
|
||||
|
||||
if (const auto found = m_sampler_pool.find(key);
|
||||
found != m_sampler_pool.end())
|
||||
if (const auto found = m_sampler_pool.find(key))
|
||||
{
|
||||
found->second->add_ref();
|
||||
return found->second.get();
|
||||
return found;
|
||||
}
|
||||
|
||||
auto result = std::make_unique<cached_sampler_object_t>(
|
||||
@ -179,9 +145,9 @@ namespace vk
|
||||
min_filter, mag_filter, mipmap_mode, border_color,
|
||||
depth_compare, depth_compare_mode);
|
||||
|
||||
auto It = m_sampler_pool.emplace(key, std::move(result));
|
||||
auto ret = It.first->second.get();
|
||||
ret->add_ref();
|
||||
result->add_ref();
|
||||
auto ret = result.get();
|
||||
m_sampler_pool.emplace(key, result);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ namespace vk
|
||||
bool get_descriptor_indexing_support() const { return pgpu->descriptor_indexing_support; }
|
||||
bool get_framebuffer_loops_support() const { return pgpu->optional_features_support.framebuffer_loops; }
|
||||
bool get_barycoords_support() const { return pgpu->optional_features_support.barycentric_coords; }
|
||||
bool get_custom_border_color_support() const { pgpu->optional_features_support.custom_border_color; }
|
||||
bool get_custom_border_color_support() const { return pgpu->optional_features_support.custom_border_color; }
|
||||
|
||||
u64 get_descriptor_update_after_bind_support() const { return pgpu->descriptor_indexing_support.update_after_bind_mask; }
|
||||
u32 get_descriptor_max_draw_calls() const { return pgpu->descriptor_max_draw_calls; }
|
||||
|
@ -21,6 +21,7 @@ namespace vk
|
||||
}
|
||||
|
||||
border_color_t::border_color_t(u32 encoded_color)
|
||||
: storage_key(0)
|
||||
{
|
||||
value = vk::get_border_color(encoded_color);
|
||||
|
||||
@ -34,7 +35,10 @@ namespace vk
|
||||
if (!g_render_device->get_custom_border_color_support())
|
||||
{
|
||||
value = get_closest_border_color_enum(color_value);
|
||||
return;
|
||||
}
|
||||
|
||||
storage_key = encoded_color;
|
||||
}
|
||||
|
||||
sampler::sampler(const vk::render_device& dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
|
||||
@ -98,4 +102,88 @@ namespace vk
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sampler_pool_key_t sampler_pool_t::compute_storage_key(
|
||||
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, const vk::border_color_t& border_color,
|
||||
VkBool32 depth_compare, VkCompareOp depth_compare_mode)
|
||||
{
|
||||
sampler_pool_key_t key{};
|
||||
|
||||
bool use_border_encoding = false;
|
||||
if (border_color.value > VK_BORDER_COLOR_INT_OPAQUE_WHITE)
|
||||
{
|
||||
// If there is no clamp to border in use, we can ignore the border color entirely
|
||||
if (clamp_u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
|
||||
clamp_v == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
|
||||
clamp_w == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
|
||||
{
|
||||
use_border_encoding = true;
|
||||
}
|
||||
}
|
||||
|
||||
key.base_key = u16(clamp_u) | u64(clamp_v) << 3 | u64(clamp_w) << 6;
|
||||
key.base_key |= u64(unnormalized_coordinates) << 9; // 1 bit
|
||||
key.base_key |= u64(min_filter) << 10 | u64(mag_filter) << 11; // 1 bit each
|
||||
key.base_key |= u64(mipmap_mode) << 12; // 1 bit
|
||||
|
||||
if (!use_border_encoding)
|
||||
{
|
||||
// Bits 13-16 are reserved for border color encoding
|
||||
key.base_key |= u64(border_color.value) << 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
key.border_color_key = border_color.storage_key;
|
||||
}
|
||||
|
||||
key.base_key |= u64(depth_compare) << 16; // 1 bit
|
||||
key.base_key |= u64(depth_compare_mode) << 17; // 3 bits
|
||||
key.base_key |= u64(rsx::encode_fx12(min_lod)) << 20; // 12 bits
|
||||
key.base_key |= u64(rsx::encode_fx12(max_lod)) << 32; // 12 bits
|
||||
key.base_key |= u64(rsx::encode_fx12<true>(mipLodBias)) << 44; // 13 bits (fx12 + sign)
|
||||
key.base_key |= u64(max_anisotropy) << 57; // 4 bits
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
void sampler_pool_t::clear()
|
||||
{
|
||||
m_generic_sampler_pool.clear();
|
||||
m_custom_color_sampler_pool.clear();
|
||||
}
|
||||
|
||||
vk::sampler* sampler_pool_t::find(const sampler_pool_key_t& key) const
|
||||
{
|
||||
if (!key.border_color_key) [[ likely ]]
|
||||
{
|
||||
const auto found = m_generic_sampler_pool.find(key.base_key);
|
||||
return found == m_generic_sampler_pool.end() ? nullptr : found->second.get();
|
||||
}
|
||||
|
||||
const auto block = m_custom_color_sampler_pool.equal_range(key.base_key);
|
||||
for (auto It = block.first; It != block.second; ++It)
|
||||
{
|
||||
if (It->second->key.border_color_key == key.border_color_key)
|
||||
{
|
||||
return It->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void sampler_pool_t::emplace(const sampler_pool_key_t& key, std::unique_ptr<cached_sampler_object_t>& object)
|
||||
{
|
||||
object->key = key;
|
||||
|
||||
if (!key.border_color_key) [[ likely ]]
|
||||
{
|
||||
m_generic_sampler_pool.emplace(key.base_key, std::move(object));
|
||||
return;
|
||||
}
|
||||
|
||||
m_custom_color_sampler_pool.emplace (key.base_key, std::move(object));
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ namespace vk
|
||||
{
|
||||
struct border_color_t
|
||||
{
|
||||
u32 storage_key;
|
||||
VkBorderColor value;
|
||||
color4f color_value;
|
||||
|
||||
@ -50,4 +51,37 @@ namespace vk
|
||||
private:
|
||||
VkDevice m_device;
|
||||
};
|
||||
|
||||
// Caching helpers
|
||||
struct sampler_pool_key_t
|
||||
{
|
||||
u64 base_key;
|
||||
u32 border_color_key;
|
||||
};
|
||||
|
||||
struct cached_sampler_object_t : public vk::sampler, public rsx::ref_counted
|
||||
{
|
||||
sampler_pool_key_t key;
|
||||
using vk::sampler::sampler;
|
||||
};
|
||||
|
||||
class sampler_pool_t
|
||||
{
|
||||
std::unordered_map<u64, std::unique_ptr<cached_sampler_object_t>> m_generic_sampler_pool;
|
||||
std::unordered_map<u64, std::unique_ptr<cached_sampler_object_t>> m_custom_color_sampler_pool;
|
||||
|
||||
public:
|
||||
|
||||
sampler_pool_key_t compute_storage_key(
|
||||
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, const vk::border_color_t& border_color,
|
||||
VkBool32 depth_compare, VkCompareOp depth_compare_mode);
|
||||
|
||||
void clear();
|
||||
|
||||
vk::sampler* find(const sampler_pool_key_t& key) const;
|
||||
|
||||
void emplace(const sampler_pool_key_t& key, std::unique_ptr<cached_sampler_object_t>& object);
|
||||
};
|
||||
}
|
||||
|
@ -914,4 +914,26 @@ namespace rsx
|
||||
|
||||
return base * scale;
|
||||
}
|
||||
|
||||
template<bool _signed = false>
|
||||
u16 encode_fx12(f32 value)
|
||||
{
|
||||
u16 raw = u16(std::abs(value) * 256.);
|
||||
|
||||
if constexpr (!_signed)
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value >= 0.f) [[likely]]
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
return u16(0 - raw) & 0x1fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user