venus: extend VkBuffer cache to cover concurrent sharing

vkd3d-proton always use concurrent sharing when there exists multiple
queue families, and all queue families are used. This change adds the
exact simple case to the existing cache.

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23916>
This commit is contained in:
Yiwei Zhang
2023-06-26 17:27:44 -07:00
committed by Marge Bot
parent 1e17234260
commit 87b99bf470
2 changed files with 34 additions and 12 deletions

View File

@@ -20,14 +20,34 @@
/* buffer commands */
static inline bool
vn_buffer_create_info_can_be_cached(const VkBufferCreateInfo *create_info,
struct vn_buffer_cache *cache)
static inline uint64_t
vn_buffer_get_cache_index(const VkBufferCreateInfo *create_info,
struct vn_buffer_cache *cache)
{
/* cache only VK_SHARING_MODE_EXCLUSIVE and without pNext for simplicity */
return (create_info->size <= cache->max_buffer_size) &&
(create_info->pNext == NULL) &&
(create_info->sharingMode == VK_SHARING_MODE_EXCLUSIVE);
/* For simplicity, cache only when below conditions are met:
* - pNext is NULL
* - VK_SHARING_MODE_EXCLUSIVE or VK_SHARING_MODE_CONCURRENT across all
*
* Combine sharing mode, flags and usage bits to form a unique index.
*
* Btw, we assume VkBufferCreateFlagBits won't exhaust all 32bits, at least
* no earlier than VkBufferUsageFlagBits.
*/
assert(!(create_info->flags & 0x80000000));
const bool is_exclusive =
create_info->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
const bool is_concurrent =
create_info->sharingMode == VK_SHARING_MODE_CONCURRENT &&
create_info->queueFamilyIndexCount == cache->queue_family_count;
if (create_info->size <= cache->max_buffer_size &&
create_info->pNext == NULL && (is_exclusive || is_concurrent)) {
return (uint64_t)is_concurrent << 63 |
(uint64_t)create_info->flags << 32 | create_info->usage;
}
/* index being zero suggests uncachable since usage must not be zero */
return 0;
}
static inline uint64_t
@@ -49,8 +69,12 @@ vn_buffer_get_max_buffer_size(struct vn_physical_device *physical_dev)
void
vn_buffer_cache_init(struct vn_device *dev)
{
assert(dev->physical_device->queue_family_count);
dev->buffer_cache.max_buffer_size =
vn_buffer_get_max_buffer_size(dev->physical_device);
dev->buffer_cache.queue_family_count =
dev->physical_device->queue_family_count;
simple_mtx_init(&dev->buffer_cache.mutex, mtx_plain);
util_sparse_array_init(&dev->buffer_cache.entries,
@@ -119,11 +143,8 @@ vn_buffer_get_cached_memory_requirements(
* VkBufferCreateInfo structure and the handleTypes member of the
* VkExternalMemoryBufferCreateInfo structure passed to vkCreateBuffer.
*/
if (vn_buffer_create_info_can_be_cached(create_info, cache)) {
/* Combine flags and usage bits to form a unique index. */
const uint64_t idx =
(uint64_t)create_info->flags << 32 | create_info->usage;
const uint64_t idx = vn_buffer_get_cache_index(create_info, cache);
if (idx) {
struct vn_buffer_cache_entry *entry =
util_sparse_array_get(&cache->entries, idx);

View File

@@ -25,6 +25,7 @@ struct vn_buffer_cache_entry {
struct vn_buffer_cache {
uint64_t max_buffer_size;
uint32_t queue_family_count;
/* cache memory type requirement for AHB backed VkBuffer */
uint32_t ahb_mem_type_bits;