mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 05:40:13 +01:00
v3dv: implement interactions of VK_KHR_device_group with VK_KHR_swapchain
There are some interactions between these two extensions that need to be implemented when both are supported. Particularly: 1. Applications can create images that will be bound to swapchain memory by passing a VkImageSwapchainCreateInfoKHR in the pNext chain of VkImageCreateInfo. In this case we need to make sure that the created image takes some of its parameters from the underlying swapchain. 2. Applications can bind memory from a swapchain image to a VkImage by passing a VkBindImageMemorySwapchainInfoKHR in the pNext chain of VkBindImageMemoryInfo. Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11037>
This commit is contained in:
parent
bf60ba6e7f
commit
c672b23857
4 changed files with 93 additions and 2 deletions
|
|
@ -2030,8 +2030,25 @@ v3dv_BindImageMemory2(VkDevice _device,
|
|||
uint32_t bindInfoCount,
|
||||
const VkBindImageMemoryInfo *pBindInfos)
|
||||
{
|
||||
for (uint32_t i = 0; i < bindInfoCount; i++)
|
||||
bind_image_memory(&pBindInfos[i]);
|
||||
for (uint32_t i = 0; i < bindInfoCount; i++) {
|
||||
const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
|
||||
vk_find_struct_const(pBindInfos->pNext,
|
||||
BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
|
||||
if (swapchain_info && swapchain_info->swapchain) {
|
||||
struct v3dv_image *swapchain_image =
|
||||
v3dv_wsi_get_image_from_swapchain(swapchain_info->swapchain,
|
||||
swapchain_info->imageIndex);
|
||||
VkBindImageMemoryInfo swapchain_bind = {
|
||||
.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
|
||||
.image = pBindInfos[i].image,
|
||||
.memory = v3dv_device_memory_to_handle(swapchain_image->mem),
|
||||
.memoryOffset = swapchain_image->mem_offset,
|
||||
};
|
||||
bind_image_memory(&swapchain_bind);
|
||||
} else {
|
||||
bind_image_memory(&pBindInfos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,6 +345,53 @@ create_image(struct v3dv_device *device,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
create_image_from_swapchain(struct v3dv_device *device,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
const VkImageSwapchainCreateInfoKHR *swapchain_info,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkImage *pImage)
|
||||
{
|
||||
struct v3dv_image *swapchain_image =
|
||||
v3dv_wsi_get_image_from_swapchain(swapchain_info->swapchain, 0);
|
||||
assert(swapchain_image);
|
||||
|
||||
VkImageCreateInfo local_create_info = *pCreateInfo;
|
||||
local_create_info.pNext = NULL;
|
||||
|
||||
/* Added by wsi code. */
|
||||
local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
/* The spec requires TILING_OPTIMAL as input, but the swapchain image may
|
||||
* privately use a different tiling. See spec anchor
|
||||
* #swapchain-wsi-image-create-info .
|
||||
*/
|
||||
assert(local_create_info.tiling == VK_IMAGE_TILING_OPTIMAL);
|
||||
local_create_info.tiling = swapchain_image->tiling;
|
||||
|
||||
VkImageDrmFormatModifierListCreateInfoEXT local_modifier_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
|
||||
.drmFormatModifierCount = 1,
|
||||
.pDrmFormatModifiers = &swapchain_image->drm_format_mod,
|
||||
};
|
||||
|
||||
if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID)
|
||||
__vk_append_struct(&local_create_info, &local_modifier_info);
|
||||
|
||||
assert(swapchain_image->type == local_create_info.imageType);
|
||||
assert(swapchain_image->vk_format == local_create_info.format);
|
||||
assert(swapchain_image->extent.width == local_create_info.extent.width);
|
||||
assert(swapchain_image->extent.height == local_create_info.extent.height);
|
||||
assert(swapchain_image->extent.depth == local_create_info.extent.depth);
|
||||
assert(swapchain_image->array_size == local_create_info.arrayLayers);
|
||||
assert(swapchain_image->samples == local_create_info.samples);
|
||||
assert(swapchain_image->tiling == local_create_info.tiling);
|
||||
assert((swapchain_image->usage & local_create_info.usage) ==
|
||||
local_create_info.usage);
|
||||
|
||||
return create_image(device, &local_create_info, pAllocator, pImage);
|
||||
}
|
||||
|
||||
VkResult
|
||||
v3dv_CreateImage(VkDevice _device,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
|
|
@ -352,6 +399,13 @@ v3dv_CreateImage(VkDevice _device,
|
|||
VkImage *pImage)
|
||||
{
|
||||
V3DV_FROM_HANDLE(v3dv_device, device, _device);
|
||||
|
||||
const VkImageSwapchainCreateInfoKHR *swapchain_info =
|
||||
vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||
if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)
|
||||
return create_image_from_swapchain(device, pCreateInfo, swapchain_info,
|
||||
pAllocator, pImage);
|
||||
|
||||
return create_image(device, pCreateInfo, pAllocator, pImage);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ VkResult v3dv_physical_device_acquire_display(struct v3dv_instance *instance,
|
|||
|
||||
VkResult v3dv_wsi_init(struct v3dv_physical_device *physical_device);
|
||||
void v3dv_wsi_finish(struct v3dv_physical_device *physical_device);
|
||||
struct v3dv_image *v3dv_wsi_get_image_from_swapchain(VkSwapchainKHR swapchain,
|
||||
uint32_t index);
|
||||
|
||||
void v3dv_meta_clear_init(struct v3dv_device *device);
|
||||
void v3dv_meta_clear_finish(struct v3dv_device *device);
|
||||
|
|
|
|||
|
|
@ -262,6 +262,24 @@ VkResult v3dv_GetSwapchainImagesKHR(
|
|||
pSwapchainImages);
|
||||
}
|
||||
|
||||
struct v3dv_image *
|
||||
v3dv_wsi_get_image_from_swapchain(VkSwapchainKHR swapchain, uint32_t index)
|
||||
{
|
||||
uint32_t n_images = index + 1;
|
||||
VkImage *images = malloc(sizeof(*images) * n_images);
|
||||
VkResult result = wsi_common_get_images(swapchain, &n_images, images);
|
||||
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
free(images);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
V3DV_FROM_HANDLE(v3dv_image, image, images[index]);
|
||||
free(images);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
VkResult v3dv_AcquireNextImageKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue