summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2019-03-25 15:02:47 +0000
committerLionel Landwerlin <[email protected]>2019-04-08 18:27:02 +0100
commitce790c96a958615f7d3b42635e2c4bac1fdf7543 (patch)
tree1dad4b61faefb29ed3ecfea473d18abab53465e7
parented91ca0629a929bd3031d0acd908f7b46b6eb80c (diff)
anv: implement VK_KHR_swapchain revision 70
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 <[email protected]> Reviewed-by: Tapani Pälli <[email protected]>
-rw-r--r--src/intel/vulkan/anv_extensions.py2
-rw-r--r--src/intel/vulkan/anv_image.c102
-rw-r--r--src/intel/vulkan/anv_private.h2
-rw-r--r--src/vulkan/util/vk_util.h12
4 files changed, 115 insertions, 3 deletions
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);