{
LVP_FROM_HANDLE(lvp_device, device, _device);
for (uint32_t i = 0; i < bindInfoCount; ++i) {
- LVP_FROM_HANDLE(lvp_device_memory, mem, pBindInfos[i].memory);
- LVP_FROM_HANDLE(lvp_image, image, pBindInfos[i].image);
+ const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
+ LVP_FROM_HANDLE(lvp_device_memory, mem, bind_info->memory);
+ LVP_FROM_HANDLE(lvp_image, image, bind_info->image);
+ bool did_bind = false;
+
+ vk_foreach_struct_const(s, bind_info->pNext) {
+ switch (s->sType) {
+ case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
+ const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
+ (const VkBindImageMemorySwapchainInfoKHR *) s;
+ struct lvp_image *swapchain_image =
+ lvp_swapchain_get_image(swapchain_info->swapchain,
+ swapchain_info->imageIndex);
+
+ image->pmem = swapchain_image->pmem;
+ image->memory_offset = swapchain_image->memory_offset;
+ device->pscreen->resource_bind_backing(device->pscreen,
+ image->bo,
+ image->pmem,
+ image->memory_offset);
+ did_bind = true;
+ }
+ default:
+ break;
+ }
+ }
- device->pscreen->resource_bind_backing(device->pscreen,
- image->bo,
- mem->pmem,
- pBindInfos[i].memoryOffset);
+ if (!did_bind) {
+ image->pmem = mem->pmem;
+ image->memory_offset = bind_info->memoryOffset;
+ device->pscreen->resource_bind_backing(device->pscreen,
+ image->bo,
+ mem->pmem,
+ bind_info->memoryOffset);
+ }
}
return VK_SUCCESS;
}
return VK_SUCCESS;
}
+struct lvp_image *
+lvp_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;
+ }
+
+ LVP_FROM_HANDLE(lvp_image, image, images[index]);
+ free(images);
+
+ return image;
+}
+
+static VkResult
+lvp_image_from_swapchain(VkDevice device,
+ const VkImageCreateInfo *pCreateInfo,
+ const VkImageSwapchainCreateInfoKHR *swapchain_info,
+ const VkAllocationCallbacks *pAllocator,
+ VkImage *pImage)
+{
+ struct lvp_image *swapchain_image = lvp_swapchain_get_image(swapchain_info->swapchain, 0);
+ assert(swapchain_image);
+
+ assert(swapchain_image->type == pCreateInfo->imageType);
+
+ 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;
+
+ assert(!(local_create_info.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
+ return lvp_image_create(device,
+ &(struct lvp_image_create_info) {
+ .vk_info = &local_create_info,
+ },
+ pAllocator,
+ pImage);
+}
+
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CreateImage(VkDevice device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkImage *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 lvp_image_from_swapchain(device, pCreateInfo, swapchain_info,
+ pAllocator, pImage);
return lvp_image_create(device,
&(struct lvp_image_create_info) {
.vk_info = pCreateInfo,