venus: refactor format properties cache to be extensible

Now the key consists of format + high order index from different pNext
chain structs. To be noted. we still don't want to cache modifiers to
avoid preparing dynamic length internal storage for per format
modifiers. The good thing is that most of the queries against modifier
support are one-time.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34207>
This commit is contained in:
Yiwei Zhang 2025-03-26 00:41:17 -07:00 committed by Marge Bot
parent 8e173230b6
commit 7155ffe275
2 changed files with 30 additions and 57 deletions

View file

@ -2079,34 +2079,6 @@ vn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
}
}
static struct vn_format_properties_entry *
vn_physical_device_get_format_properties(
struct vn_physical_device *physical_dev, VkFormat format)
{
return util_sparse_array_get(&physical_dev->format_properties, format);
}
static void
vn_physical_device_add_format_properties(
struct vn_physical_device *physical_dev,
struct vn_format_properties_entry *entry,
const VkFormatProperties *props,
const VkFormatProperties3 *props3)
{
simple_mtx_lock(&physical_dev->format_update_mutex);
if (!entry->valid) {
entry->properties = *props;
entry->valid = true;
}
if (props3 && !entry->props3_valid) {
entry->properties3 = *props3;
entry->props3_valid = true;
}
simple_mtx_unlock(&physical_dev->format_update_mutex);
}
void
vn_GetPhysicalDeviceQueueFamilyProperties2(
VkPhysicalDevice physicalDevice,
@ -2207,45 +2179,47 @@ vn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
struct vn_physical_device *physical_dev =
vn_physical_device_from_handle(physicalDevice);
struct vn_ring *ring = physical_dev->instance->ring.ring;
/* VkFormatProperties3 is cached if its the only struct in pNext */
VkFormatProperties *props = &pFormatProperties->formatProperties;
VkFormatProperties3 *props3 = NULL;
if (pFormatProperties->pNext) {
const VkBaseOutStructure *base = pFormatProperties->pNext;
if (base->sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 &&
base->pNext == NULL) {
props3 = (VkFormatProperties3 *)base;
bool cacheable = true;
uint64_t key = (uint64_t)format;
vk_foreach_struct_const(src, pFormatProperties->pNext) {
switch (src->sType) {
case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3:
props3 = (VkFormatProperties3 *)src;
key |= 1ull << 32;
break;
default:
cacheable = false;
break;
}
}
struct vn_format_properties_entry *entry = NULL;
if (!pFormatProperties->pNext || props3) {
entry = vn_physical_device_get_format_properties(physical_dev, format);
if (cacheable) {
entry = util_sparse_array_get(&physical_dev->format_properties, key);
if (entry->valid) {
const bool has_valid_props3 = props3 && entry->props3_valid;
if (has_valid_props3)
*props3 = entry->properties3;
/* Make the host call if our cache doesn't have props3 but the app
* now requests it.
*/
if (!props3 || has_valid_props3) {
pFormatProperties->formatProperties = entry->properties;
pFormatProperties->pNext = props3;
return;
}
*props = entry->props;
if (props3)
VN_COPY_STRUCT_GUTS(props3, &entry->props3, sizeof(*props3));
return;
}
}
vn_call_vkGetPhysicalDeviceFormatProperties2(ring, physicalDevice, format,
pFormatProperties);
vn_sanitize_format_properties(format, props, props3);
vn_sanitize_format_properties(format, &pFormatProperties->formatProperties,
props3);
if (entry) {
vn_physical_device_add_format_properties(
physical_dev, entry, &pFormatProperties->formatProperties, props3);
simple_mtx_lock(&physical_dev->format_update_mutex);
if (entry && !entry->valid) {
assert(cacheable);
entry->props = *props;
if (props3)
VN_COPY_STRUCT_GUTS(&entry->props3, props3, sizeof(*props3));
entry->valid = true;
}
simple_mtx_unlock(&physical_dev->format_update_mutex);
}
struct vn_physical_device_image_format_info {

View file

@ -19,9 +19,8 @@
struct vn_format_properties_entry {
atomic_bool valid;
VkFormatProperties properties;
atomic_bool props3_valid;
VkFormatProperties3 properties3;
VkFormatProperties props;
VkFormatProperties3 props3;
};
struct vn_image_format_properties {