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 <lionel.g.landwerlin@intel.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
This commit is contained in:
Lionel Landwerlin 2019-03-25 15:02:47 +00:00
parent ed91ca0629
commit ce790c96a9
4 changed files with 115 additions and 3 deletions

View file

@ -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'),

View file

@ -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 =

View file

@ -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.
*/

View file

@ -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);