vulkan/wsi: Move select_memory_type to common and rework it a bit

Instead of taking a single boolean for device-local, take a set of
required properties and denied properties.  This will let us require
additional things like being CPU mappable in the future.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17388>
This commit is contained in:
Jason Ekstrand 2022-07-06 16:29:03 -05:00
parent fbb7b6e052
commit 1cc20fbefd
3 changed files with 57 additions and 36 deletions

View file

@ -1251,6 +1251,48 @@ wsi_common_bind_swapchain_image(const struct wsi_device *wsi,
return wsi->BindImageMemory(chain->device, vk_image, image->memory, 0);
}
uint32_t
wsi_select_memory_type(const struct wsi_device *wsi,
VkMemoryPropertyFlags req_props,
VkMemoryPropertyFlags deny_props,
uint32_t type_bits)
{
assert(type_bits != 0);
VkMemoryPropertyFlags common_props = ~0;
u_foreach_bit(t, type_bits) {
const VkMemoryType type = wsi->memory_props.memoryTypes[t];
common_props &= type.propertyFlags;
if (deny_props & type.propertyFlags)
continue;
if (!(req_props & ~type.propertyFlags))
return t;
}
if ((deny_props & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) &&
(common_props & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
/* If they asked for non-device-local and all the types are device-local
* (this is commonly true for UMA platforms), try again without denying
* device-local types
*/
deny_props &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
return wsi_select_memory_type(wsi, req_props, deny_props, type_bits);
}
unreachable("No memory type found");
}
uint32_t
wsi_select_device_memory_type(const struct wsi_device *wsi,
uint32_t type_bits)
{
return wsi_select_memory_type(wsi, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
0 /* deny_props */, type_bits);
}
VkResult
wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,

View file

@ -294,44 +294,13 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd)
return match;
}
static uint32_t
select_memory_type(const struct wsi_device *wsi,
bool want_device_local,
uint32_t type_bits)
{
assert(type_bits);
bool all_local = true;
for (uint32_t i = 0; i < wsi->memory_props.memoryTypeCount; i++) {
const VkMemoryType type = wsi->memory_props.memoryTypes[i];
bool local = type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if ((type_bits & (1 << i)) && local == want_device_local)
return i;
all_local &= local;
}
/* ignore want_device_local when all memory types are device-local */
if (all_local) {
assert(!want_device_local);
return ffs(type_bits) - 1;
}
unreachable("No memory type found");
}
static uint32_t
prime_select_buffer_memory_type(const struct wsi_device *wsi,
uint32_t type_bits)
{
return select_memory_type(wsi, false, type_bits);
}
static uint32_t
prime_select_image_memory_type(const struct wsi_device *wsi,
uint32_t type_bits)
{
return select_memory_type(wsi, true, type_bits);
return wsi_select_memory_type(wsi, 0 /* req_props */,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
type_bits);
}
static const struct VkDrmFormatModifierPropertiesEXT *
@ -543,7 +512,8 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = sw_host_ptr ? (void *)&host_ptr_info : (void *)&memory_dedicated_info,
.allocationSize = reqs.size,
.memoryTypeIndex = select_memory_type(wsi, true, reqs.memoryTypeBits),
.memoryTypeIndex =
wsi_select_device_memory_type(wsi, reqs.memoryTypeBits),
};
result = wsi->AllocateMemory(chain->device, &memory_info,
&chain->alloc, &image->memory);
@ -666,7 +636,7 @@ wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain,
info->create_mem = wsi_create_prime_image_mem;
info->select_buffer_memory_type = prime_select_buffer_memory_type;
info->select_image_memory_type = prime_select_image_memory_type;
info->select_image_memory_type = wsi_select_device_memory_type;
return VK_SUCCESS;
}

View file

@ -145,6 +145,15 @@ wsi_swapchain_get_present_mode(struct wsi_device *wsi,
void wsi_swapchain_finish(struct wsi_swapchain *chain);
uint32_t
wsi_select_memory_type(const struct wsi_device *wsi,
VkMemoryPropertyFlags req_flags,
VkMemoryPropertyFlags deny_flags,
uint32_t type_bits);
uint32_t
wsi_select_device_memory_type(const struct wsi_device *wsi,
uint32_t type_bits);
VkResult
wsi_configure_native_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,