From ce790c96a958615f7d3b42635e2c4bac1fdf7543 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 25 Mar 2019 15:02:47 +0000 Subject: anv: implement VK_KHR_swapchain revision 70 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This revision allows for images to be : - created by reusing image parameters from swapchain - bound to memory from a swapchain v2: Add color attachment flag Use same implicit WSI parameters (tiling, samples, usage) v3: Fix missing break in vk_foreach_struct_const() switch (Lionel) v4: Fix accessing image aspects before android resolve (Tapani) Signed-off-by: Lionel Landwerlin Reviewed-by: Tapani Pälli --- src/intel/vulkan/anv_extensions.py | 2 +- src/intel/vulkan/anv_image.c | 102 ++++++++++++++++++++++++++++++++++++- src/intel/vulkan/anv_private.h | 2 +- src/vulkan/util/vk_util.h | 12 +++++ 4 files changed, 115 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index 0d691b59004..37c1203416e 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -108,7 +108,7 @@ EXTENSIONS = [ Extension('VK_KHR_storage_buffer_storage_class', 1, True), Extension('VK_KHR_surface', 25, 'ANV_HAS_SURFACE'), Extension('VK_KHR_surface_protected_capabilities', 1, 'ANV_HAS_SURFACE'), - Extension('VK_KHR_swapchain', 68, 'ANV_HAS_SURFACE'), + Extension('VK_KHR_swapchain', 70, 'ANV_HAS_SURFACE'), Extension('VK_KHR_variable_pointers', 1, True), Extension('VK_KHR_wayland_surface', 6, 'VK_USE_PLATFORM_WAYLAND_KHR'), Extension('VK_KHR_xcb_surface', 6, 'VK_USE_PLATFORM_XCB_KHR'), 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 = diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index daeadea3a64..1316077ae09 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2881,7 +2881,7 @@ struct anv_surface { }; struct anv_image { - VkImageType type; + VkImageType type; /**< VkImageCreateInfo::imageType */ /* The original VkFormat provided by the client. This may not match any * of the actual surface formats. */ diff --git a/src/vulkan/util/vk_util.h b/src/vulkan/util/vk_util.h index 89b90a60d20..8ae384b9fb5 100644 --- a/src/vulkan/util/vk_util.h +++ b/src/vulkan/util/vk_util.h @@ -196,6 +196,18 @@ __vk_find_struct(void *start, VkStructureType sType) #define vk_find_struct_const(__start, __sType) \ (const void *)__vk_find_struct((void *)(__start), VK_STRUCTURE_TYPE_##__sType) +static inline void +__vk_append_struct(void *start, void *element) +{ + vk_foreach_struct(s, start) { + if (s->pNext) + continue; + + s->pNext = (struct VkBaseOutStructure *) element; + break; + } +} + uint32_t vk_get_driver_version(void); uint32_t vk_get_version_override(void); -- cgit v1.2.3