diff options
Diffstat (limited to 'src/intel/vulkan/anv_image.c')
-rw-r--r-- | src/intel/vulkan/anv_image.c | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 6ed77481488..3841234df14 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -638,6 +638,70 @@ fail: return r; } +static struct anv_image * +anv_swapchain_get_image(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; + } + + ANV_FROM_HANDLE(anv_image, image, images[index]); + free(images); + + return image; +} + +static VkResult +anv_image_from_swapchain(VkDevice device, + const VkImageCreateInfo *pCreateInfo, + const VkImageSwapchainCreateInfoKHR *swapchain_info, + const VkAllocationCallbacks *pAllocator, + VkImage *pImage) +{ + struct anv_image *swapchain_image = anv_swapchain_get_image(swapchain_info->swapchain, 0); + assert(swapchain_image); + + assert(swapchain_image->type == pCreateInfo->imageType); + assert(swapchain_image->vk_format == pCreateInfo->format); + assert(swapchain_image->extent.width == pCreateInfo->extent.width); + assert(swapchain_image->extent.height == pCreateInfo->extent.height); + assert(swapchain_image->extent.depth == pCreateInfo->extent.depth); + assert(swapchain_image->array_size == pCreateInfo->arrayLayers); + /* Color attachment is added by the wsi code. */ + assert(swapchain_image->usage == (pCreateInfo->usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)); + + VkImageCreateInfo local_create_info; + local_create_info = *pCreateInfo; + local_create_info.pNext = NULL; + /* The following parameters are implictly selected by the wsi code. */ + local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + local_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + + /* If the image has a particular modifier, specify that modifier. */ + struct wsi_image_create_info local_wsi_info = { + .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA, + .modifier_count = 1, + .modifiers = &swapchain_image->drm_format_mod, + }; + if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID) + __vk_append_struct(&local_create_info, &local_wsi_info); + + return anv_image_create(device, + &(struct anv_image_create_info) { + .vk_info = &local_create_info, + .external_format = swapchain_image->external_format, + }, + pAllocator, + pImage); +} + VkResult anv_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, @@ -658,6 +722,12 @@ anv_CreateImage(VkDevice device, return anv_image_from_gralloc(device, pCreateInfo, gralloc_info, pAllocator, pImage); + 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 anv_image_from_swapchain(device, pCreateInfo, swapchain_info, + pAllocator, pImage); + return anv_image_create(device, &(struct anv_image_create_info) { .vk_info = pCreateInfo, @@ -818,7 +888,8 @@ VkResult anv_BindImageMemory2( ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory); ANV_FROM_HANDLE(anv_image, image, bind_info->image); - if (mem->ahw) + /* Resolve will alter the image's aspects, do this first. */ + if (mem && mem->ahw) resolve_ahw_image(device, image, mem); VkImageAspectFlags aspects = image->aspects; @@ -831,12 +902,41 @@ VkResult anv_BindImageMemory2( aspects = plane_info->planeAspect; break; } + case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: { + const VkBindImageMemorySwapchainInfoKHR *swapchain_info = + (const VkBindImageMemorySwapchainInfoKHR *) s; + struct anv_image *swapchain_image = + anv_swapchain_get_image(swapchain_info->swapchain, + swapchain_info->imageIndex); + assert(swapchain_image); + assert(image->aspects == swapchain_image->aspects); + assert(mem == NULL); + + uint32_t aspect_bit; + anv_foreach_image_aspect_bit(aspect_bit, image, aspects) { + uint32_t plane = + anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit); + struct anv_device_memory mem = { + .bo = swapchain_image->planes[plane].address.bo, + }; + anv_image_bind_memory_plane(device, image, plane, + &mem, bind_info->memoryOffset); + } + break; + } default: anv_debug_ignored_stype(s->sType); break; } } + /* VkBindImageMemorySwapchainInfoKHR requires memory to be + * VK_NULL_HANDLE. In such case, just carry one with the next bind + * item. + */ + if (!mem) + continue; + uint32_t aspect_bit; anv_foreach_image_aspect_bit(aspect_bit, image, aspects) { uint32_t plane = |