venus: handle VkBindImageMemorySwapchainInfoKHR

The common WSI advertises VK_KHR_swapchain v70.  We must handle
VkBindImageMemorySwapchainInfoKHR.

Fixes dEQP-VK.wsi.*.image_swapchain_create_info.

v2: try to match vn_wsi_create_image (Yiwei) and the common WSI
v3: match modifier as well (Yiwei)

Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14550>
This commit is contained in:
Chia-I Wu 2022-01-13 12:03:29 -08:00 committed by Marge Bot
parent 127263dc4a
commit bf32d3145c
5 changed files with 146 additions and 6 deletions

View File

@ -516,6 +516,8 @@ vn_android_image_from_anb(struct vn_device *dev,
goto fail;
img->wsi.is_wsi = true;
img->wsi.tiling_override = builder.create.tiling;
img->wsi.drm_format_modifier = builder.modifier.drmFormatModifier;
/* Android WSI image owns the memory */
img->wsi.memory = vn_device_memory_from_handle(memory);
img->wsi.memory_owned = true;

View File

@ -264,6 +264,16 @@ vn_CreateImage(VkDevice device,
external_info->handleTypes ==
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
#ifdef ANDROID
/* VkImageSwapchainCreateInfoKHR is not useful at all */
const VkImageSwapchainCreateInfoKHR *swapchain_info = NULL;
#else
const VkImageSwapchainCreateInfoKHR *swapchain_info = vk_find_struct_const(
pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
if (swapchain_info && !swapchain_info->swapchain)
swapchain_info = NULL;
#endif
if (wsi_info) {
result = vn_wsi_create_image(dev, pCreateInfo, wsi_info, alloc, &img);
} else if (anb_info) {
@ -271,6 +281,9 @@ vn_CreateImage(VkDevice device,
vn_android_image_from_anb(dev, pCreateInfo, anb_info, alloc, &img);
} else if (ahb_info) {
result = vn_android_image_from_ahb(dev, pCreateInfo, alloc, &img);
} else if (swapchain_info) {
result = vn_wsi_create_image_from_swapchain(
dev, pCreateInfo, swapchain_info, alloc, &img);
} else {
result = vn_image_create(dev, pCreateInfo, alloc, &img);
}
@ -444,13 +457,35 @@ vn_BindImageMemory2(VkDevice device,
struct vn_device_memory *mem =
vn_device_memory_from_handle(info->memory);
/* no bind info fixup needed */
if (mem && !mem->base_memory) {
if (img->wsi.is_wsi)
vn_image_bind_wsi_memory(img, mem);
continue;
}
if (!mem) {
#ifdef ANDROID
/* TODO handle VkNativeBufferANDROID when we bump up
* VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION
*/
unreachable("VkBindImageMemoryInfo with no memory");
#else
const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
vk_find_struct_const(info->pNext,
BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
assert(img->wsi.is_wsi && swapchain_info);
struct vn_image *swapchain_img =
vn_image_from_handle(wsi_common_get_image(
swapchain_info->swapchain, swapchain_info->imageIndex));
mem = swapchain_img->wsi.memory;
#endif
}
if (img->wsi.is_wsi)
vn_image_bind_wsi_memory(img, mem);
/* TODO handle VkBindImageMemorySwapchainInfoKHR */
if (!mem || !mem->base_memory)
continue;
if (!local_infos) {
const size_t size = sizeof(*local_infos) * bindInfoCount;
local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN,
@ -461,7 +496,12 @@ vn_BindImageMemory2(VkDevice device,
memcpy(local_infos, pBindInfos, size);
}
local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory);
/* If mem is suballocated, mem->base_memory is non-NULL and we must
* patch it in. If VkBindImageMemorySwapchainInfoKHR is given, we've
* looked mem up above and also need to patch it in.
*/
local_infos[i].memory = vn_device_memory_to_handle(
mem->base_memory ? mem->base_memory : mem);
local_infos[i].memoryOffset += mem->base_offset;
}
if (local_infos)

View File

@ -44,10 +44,14 @@ struct vn_image {
struct {
/* True if this is a swapchain image and VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
* is a valid layout. A swapchain image can be created internally
* (wsi_image_create_info) or externally (VkNativeBufferANDROID).
* (wsi_image_create_info) or externally (VkNativeBufferANDROID and
* VkImageSwapchainCreateInfoKHR).
*/
bool is_wsi;
bool is_prime_blit_src;
VkImageTiling tiling_override;
/* valid when tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT */
uint64_t drm_format_modifier;
struct vn_device_memory *memory;

View File

@ -134,6 +134,81 @@ vn_wsi_create_image(struct vn_device *dev,
img->wsi.is_wsi = true;
img->wsi.is_prime_blit_src = wsi_info->prime_blit_src;
img->wsi.tiling_override = create_info->tiling;
if (create_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
VkDevice dev_handle = vn_device_to_handle(dev);
VkImage img_handle = vn_image_to_handle(img);
VkImageDrmFormatModifierPropertiesEXT props = {
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
};
result = vn_GetImageDrmFormatModifierPropertiesEXT(dev_handle,
img_handle, &props);
if (result != VK_SUCCESS) {
vn_DestroyImage(dev_handle, img_handle, alloc);
return result;
}
img->wsi.drm_format_modifier = props.drmFormatModifier;
}
*out_img = img;
return VK_SUCCESS;
}
VkResult
vn_wsi_create_image_from_swapchain(
struct vn_device *dev,
const VkImageCreateInfo *create_info,
const VkImageSwapchainCreateInfoKHR *swapchain_info,
const VkAllocationCallbacks *alloc,
struct vn_image **out_img)
{
const struct vn_image *swapchain_img = vn_image_from_handle(
wsi_common_get_image(swapchain_info->swapchain, 0));
assert(swapchain_img->wsi.is_wsi);
/* must match what the common WSI and vn_wsi_create_image do */
VkImageCreateInfo local_create_info = *create_info;
/* match external memory */
const VkExternalMemoryImageCreateInfo local_external_info = {
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
.pNext = local_create_info.pNext,
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
local_create_info.pNext = &local_external_info;
/* match image tiling */
local_create_info.tiling = swapchain_img->wsi.tiling_override;
VkImageDrmFormatModifierListCreateInfoEXT local_mod_info;
if (local_create_info.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
local_mod_info = (const VkImageDrmFormatModifierListCreateInfoEXT){
.sType =
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
.pNext = local_create_info.pNext,
.drmFormatModifierCount = 1,
.pDrmFormatModifiers = &swapchain_img->wsi.drm_format_modifier,
};
local_create_info.pNext = &local_mod_info;
}
/* match image usage */
if (swapchain_img->wsi.is_prime_blit_src)
local_create_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
create_info = &local_create_info;
struct vn_image *img;
VkResult result = vn_image_create(dev, create_info, alloc, &img);
if (result != VK_SUCCESS)
return result;
img->wsi.is_wsi = true;
img->wsi.tiling_override = swapchain_img->wsi.tiling_override;
img->wsi.drm_format_modifier = swapchain_img->wsi.drm_format_modifier;
*out_img = img;
return VK_SUCCESS;

View File

@ -37,6 +37,14 @@ vn_wsi_create_image(struct vn_device *dev,
const VkAllocationCallbacks *alloc,
struct vn_image **out_img);
VkResult
vn_wsi_create_image_from_swapchain(
struct vn_device *dev,
const VkImageCreateInfo *create_info,
const VkImageSwapchainCreateInfoKHR *swapchain_info,
const VkAllocationCallbacks *alloc,
struct vn_image **out_img);
#else
static inline VkResult
@ -66,6 +74,17 @@ vn_wsi_create_image(struct vn_device *dev,
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
static inline VkResult
vn_wsi_create_image_from_swapchain(
struct vn_device *dev,
const VkImageCreateInfo *create_info,
const VkImageSwapchainCreateInfoKHR *swapchain_info,
const VkAllocationCallbacks *alloc,
struct vn_image **out_img)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
#endif /* VN_USE_WSI_PLATFORM */
#endif /* VN_WSI_H */