vulkan/wsi: Prepare things for image to image blits

Right now, the WSI core supports copying WSI images to a linear buffer
for implementations that want the result in this form. This being said,
most of the blit logic can be re-used for image to image copies, and that's
exactly what we'll need if we want to hook-up DXGI swapchains in the
win32 WSI implementation. So let's rename a few fields so we no longer
imply that images are copied to a buffer, and the use_buffer_blit boolean
an enum so we can extend the implementation to support image -> image
copies.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16200>
This commit is contained in:
Boris Brezillon
2022-04-27 18:17:06 +02:00
committed by Marge Bot
parent bbcbf2cd91
commit fa4e729165
8 changed files with 110 additions and 98 deletions

View File

@@ -2427,7 +2427,7 @@ radv_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
const struct wsi_image_create_info *wsi_info =
vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
bool scanout = wsi_info && wsi_info->scanout;
bool prime_blit_src = wsi_info && wsi_info->buffer_blit_src;
bool prime_blit_src = wsi_info && wsi_info->blit_src;
return radv_image_create(device,
&(struct radv_image_create_info){

View File

@@ -98,7 +98,7 @@ radv_init_wsi(struct radv_physical_device *physical_device)
physical_device->wsi_device.supports_modifiers = physical_device->rad_info.gfx_level >= GFX9;
physical_device->wsi_device.set_memory_ownership = radv_wsi_set_memory_ownership;
physical_device->wsi_device.get_buffer_blit_queue = radv_wsi_get_prime_blit_queue;
physical_device->wsi_device.get_blit_queue = radv_wsi_get_prime_blit_queue;
wsi_device_setup_syncobj_fd(&physical_device->wsi_device, physical_device->local_fd);

View File

@@ -143,7 +143,7 @@ vn_wsi_create_image(struct vn_device *dev,
return result;
img->wsi.is_wsi = true;
img->wsi.is_prime_blit_src = wsi_info->buffer_blit_src;
img->wsi.is_prime_blit_src = wsi_info->blit_src;
img->wsi.tiling_override = create_info->tiling;
if (create_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {

View File

@@ -288,21 +288,23 @@ wsi_device_setup_syncobj_fd(struct wsi_device *wsi_device,
#endif
}
static bool
needs_buffer_blit(const struct wsi_device *wsi,
const struct wsi_base_image_params *params)
static enum wsi_swapchain_blit_type
get_blit_type(const struct wsi_device *wsi,
const struct wsi_base_image_params *params)
{
switch (params->image_type) {
case WSI_IMAGE_TYPE_CPU: {
const struct wsi_cpu_image_params *cpu_params =
container_of(params, const struct wsi_cpu_image_params, base);
return wsi_cpu_image_needs_buffer_blit(wsi, cpu_params);
return wsi_cpu_image_needs_buffer_blit(wsi, cpu_params) ?
WSI_SWAPCHAIN_BUFFER_BLIT : WSI_SWAPCHAIN_NO_BLIT;
}
#ifdef HAVE_LIBDRM
case WSI_IMAGE_TYPE_DRM: {
const struct wsi_drm_image_params *drm_params =
container_of(params, const struct wsi_drm_image_params, base);
return wsi_drm_image_needs_buffer_blit(wsi, drm_params);
return wsi_drm_image_needs_buffer_blit(wsi, drm_params) ?
WSI_SWAPCHAIN_BUFFER_BLIT : WSI_SWAPCHAIN_NO_BLIT;
}
#endif
default:
@@ -378,13 +380,13 @@ wsi_swapchain_init(const struct wsi_device *wsi,
chain->wsi = wsi;
chain->device = _device;
chain->alloc = *pAllocator;
chain->use_buffer_blit = needs_buffer_blit(wsi, image_params);
chain->blit.type = get_blit_type(wsi, image_params);
chain->buffer_blit_queue = VK_NULL_HANDLE;
if (chain->use_buffer_blit && wsi->get_buffer_blit_queue)
chain->buffer_blit_queue = wsi->get_buffer_blit_queue(_device);
chain->blit.queue = VK_NULL_HANDLE;
if (chain->blit.type != WSI_SWAPCHAIN_NO_BLIT && wsi->get_blit_queue)
chain->blit.queue = wsi->get_blit_queue(_device);
int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
int cmd_pools_count = chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
chain->cmd_pools =
vk_zalloc(pAllocator, sizeof(VkCommandPool) * cmd_pools_count, 8,
@@ -395,8 +397,8 @@ wsi_swapchain_init(const struct wsi_device *wsi,
for (uint32_t i = 0; i < cmd_pools_count; i++) {
int queue_family_index = i;
if (chain->buffer_blit_queue != VK_NULL_HANDLE) {
VK_FROM_HANDLE(vk_queue, queue, chain->buffer_blit_queue);
if (chain->blit.queue != VK_NULL_HANDLE) {
VK_FROM_HANDLE(vk_queue, queue, chain->blit.queue);
queue_family_index = queue->queue_family_index;
}
const VkCommandPoolCreateInfo cmd_pool_info = {
@@ -487,18 +489,18 @@ wsi_swapchain_finish(struct wsi_swapchain *chain)
vk_free(&chain->alloc, chain->fences);
}
if (chain->buffer_blit_semaphores) {
if (chain->blit.semaphores) {
for (unsigned i = 0; i < chain->image_count; i++)
chain->wsi->DestroySemaphore(chain->device, chain->buffer_blit_semaphores[i], &chain->alloc);
chain->wsi->DestroySemaphore(chain->device, chain->blit.semaphores[i], &chain->alloc);
vk_free(&chain->alloc, chain->buffer_blit_semaphores);
vk_free(&chain->alloc, chain->blit.semaphores);
}
chain->wsi->DestroySemaphore(chain->device, chain->dma_buf_semaphore,
&chain->alloc);
chain->wsi->DestroySemaphore(chain->device, chain->present_id_timeline,
&chain->alloc);
int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ?
int cmd_pools_count = chain->blit.queue != VK_NULL_HANDLE ?
1 : chain->wsi->queue_family_count;
for (uint32_t i = 0; i < cmd_pools_count; i++) {
chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i],
@@ -674,25 +676,25 @@ wsi_destroy_image(const struct wsi_swapchain *chain,
#endif
if (image->cpu_map != NULL) {
wsi->UnmapMemory(chain->device, image->buffer.buffer != VK_NULL_HANDLE ?
image->buffer.memory : image->memory);
wsi->UnmapMemory(chain->device, image->blit.buffer != VK_NULL_HANDLE ?
image->blit.memory : image->memory);
}
if (image->buffer.blit_cmd_buffers) {
if (image->blit.cmd_buffers) {
int cmd_buffer_count =
chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i],
1, &image->buffer.blit_cmd_buffers[i]);
1, &image->blit.cmd_buffers[i]);
}
vk_free(&chain->alloc, image->buffer.blit_cmd_buffers);
vk_free(&chain->alloc, image->blit.cmd_buffers);
}
wsi->FreeMemory(chain->device, image->memory, &chain->alloc);
wsi->DestroyImage(chain->device, image->image, &chain->alloc);
wsi->FreeMemory(chain->device, image->buffer.memory, &chain->alloc);
wsi->DestroyBuffer(chain->device, image->buffer.buffer, &chain->alloc);
wsi->FreeMemory(chain->device, image->blit.memory, &chain->alloc);
wsi->DestroyBuffer(chain->device, image->blit.buffer, &chain->alloc);
}
VKAPI_ATTR VkResult VKAPI_CALL
@@ -909,12 +911,12 @@ wsi_CreateSwapchainKHR(VkDevice _device,
}
}
if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) {
swapchain->buffer_blit_semaphores = vk_zalloc(alloc,
sizeof (*swapchain->buffer_blit_semaphores) * swapchain->image_count,
sizeof (*swapchain->buffer_blit_semaphores),
if (swapchain->blit.queue != VK_NULL_HANDLE) {
swapchain->blit.semaphores = vk_zalloc(alloc,
sizeof (*swapchain->blit.semaphores) * swapchain->image_count,
sizeof (*swapchain->blit.semaphores),
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!swapchain->buffer_blit_semaphores) {
if (!swapchain->blit.semaphores) {
wsi_device->DestroySemaphore(_device, swapchain->present_id_timeline, alloc);
swapchain->destroy(swapchain, alloc);
return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -1179,7 +1181,8 @@ wsi_common_queue_present(const struct wsi_device *wsi,
if (result != VK_SUCCESS)
goto fail_present;
if (swapchain->use_buffer_blit && swapchain->buffer_blit_queue != VK_NULL_HANDLE) {
if (swapchain->blit.type != WSI_SWAPCHAIN_NO_BLIT &&
swapchain->blit.queue != VK_NULL_HANDLE) {
const VkSemaphoreCreateInfo sem_info = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = NULL,
@@ -1187,7 +1190,7 @@ wsi_common_queue_present(const struct wsi_device *wsi,
};
result = wsi->CreateSemaphore(device, &sem_info,
&swapchain->alloc,
&swapchain->buffer_blit_semaphores[image_index]);
&swapchain->blit.semaphores[image_index]);
if (result != VK_SUCCESS)
goto fail_present;
}
@@ -1221,11 +1224,11 @@ wsi_common_queue_present(const struct wsi_device *wsi,
swapchain->get_wsi_image(swapchain, image_index);
VkQueue submit_queue = queue;
if (swapchain->use_buffer_blit) {
if (swapchain->buffer_blit_queue == VK_NULL_HANDLE) {
if (swapchain->blit.type != WSI_SWAPCHAIN_NO_BLIT) {
if (swapchain->blit.queue == VK_NULL_HANDLE) {
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers =
&image->buffer.blit_cmd_buffers[queue_family_index];
&image->blit.cmd_buffers[queue_family_index];
} else {
/* If we are using a blit using the driver's private queue, then
* do an empty submit signalling a semaphore, and then submit the
@@ -1234,7 +1237,7 @@ wsi_common_queue_present(const struct wsi_device *wsi,
*/
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores =
&swapchain->buffer_blit_semaphores[image_index];
&swapchain->blit.semaphores[image_index];
result = wsi->QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
if (result != VK_SUCCESS)
@@ -1243,13 +1246,13 @@ wsi_common_queue_present(const struct wsi_device *wsi,
/* Now prepare the blit submit. It needs to then wait on the
* semaphore we signaled above.
*/
submit_queue = swapchain->buffer_blit_queue;
submit_queue = swapchain->blit.queue;
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = submit_info.pSignalSemaphores;
submit_info.signalSemaphoreCount = 0;
submit_info.pSignalSemaphores = NULL;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &image->buffer.blit_cmd_buffers[0];
submit_info.pCommandBuffers = &image->blit.cmd_buffers[0];
submit_info.pWaitDstStageMask = stage_flags;
}
}
@@ -1524,11 +1527,11 @@ wsi_select_host_memory_type(const struct wsi_device *wsi,
}
VkResult
wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image,
VkExternalMemoryHandleTypeFlags handle_types,
bool implicit_sync)
wsi_create_buffer_blit_context(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image,
VkExternalMemoryHandleTypeFlags handle_types,
bool implicit_sync)
{
const struct wsi_device *wsi = chain->wsi;
VkResult result;
@@ -1546,12 +1549,12 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = wsi->CreateBuffer(chain->device, &buffer_info,
&chain->alloc, &image->buffer.buffer);
&chain->alloc, &image->blit.buffer);
if (result != VK_SUCCESS)
return result;
VkMemoryRequirements reqs;
wsi->GetBufferMemoryRequirements(chain->device, image->buffer.buffer, &reqs);
wsi->GetBufferMemoryRequirements(chain->device, image->blit.buffer, &reqs);
assert(reqs.size <= info->linear_size);
struct wsi_memory_allocate_info memory_wsi_info = {
@@ -1563,14 +1566,14 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = &memory_wsi_info,
.image = VK_NULL_HANDLE,
.buffer = image->buffer.buffer,
.buffer = image->blit.buffer,
};
VkMemoryAllocateInfo buf_mem_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &buf_mem_dedicated_info,
.allocationSize = info->linear_size,
.memoryTypeIndex =
info->select_buffer_memory_type(wsi, reqs.memoryTypeBits),
info->select_blit_dst_memory_type(wsi, reqs.memoryTypeBits),
};
void *sw_host_ptr = NULL;
@@ -1595,12 +1598,12 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
}
result = wsi->AllocateMemory(chain->device, &buf_mem_info,
&chain->alloc, &image->buffer.memory);
&chain->alloc, &image->blit.memory);
if (result != VK_SUCCESS)
return result;
result = wsi->BindBufferMemory(chain->device, image->buffer.buffer,
image->buffer.memory, 0);
result = wsi->BindBufferMemory(chain->device, image->blit.buffer,
image->blit.memory, 0);
if (result != VK_SUCCESS)
return result;
@@ -1634,7 +1637,7 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
}
VkResult
wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
wsi_finish_create_blit_context(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image)
{
@@ -1642,12 +1645,12 @@ wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
VkResult result;
int cmd_buffer_count =
chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
image->buffer.blit_cmd_buffers =
chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
image->blit.cmd_buffers =
vk_zalloc(&chain->alloc,
sizeof(VkCommandBuffer) * cmd_buffer_count, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!image->buffer.blit_cmd_buffers)
if (!image->blit.cmd_buffers)
return VK_ERROR_OUT_OF_HOST_MEMORY;
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
@@ -1659,14 +1662,14 @@ wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
.commandBufferCount = 1,
};
result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info,
&image->buffer.blit_cmd_buffers[i]);
&image->blit.cmd_buffers[i]);
if (result != VK_SUCCESS)
return result;
const VkCommandBufferBeginInfo begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
};
wsi->BeginCommandBuffer(image->buffer.blit_cmd_buffers[i], &begin_info);
wsi->BeginCommandBuffer(image->blit.cmd_buffers[i], &begin_info);
VkImageMemoryBarrier img_mem_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -1686,7 +1689,7 @@ wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
.layerCount = 1,
},
};
wsi->CmdPipelineBarrier(image->buffer.blit_cmd_buffers[i],
wsi->CmdPipelineBarrier(image->blit.cmd_buffers[i],
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
@@ -1708,17 +1711,17 @@ wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
.imageOffset = { .x = 0, .y = 0, .z = 0 },
.imageExtent = info->create.extent,
};
wsi->CmdCopyImageToBuffer(image->buffer.blit_cmd_buffers[i],
wsi->CmdCopyImageToBuffer(image->blit.cmd_buffers[i],
image->image,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
image->buffer.buffer,
image->blit.buffer,
1, &buffer_image_copy);
img_mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
img_mem_barrier.dstAccessMask = 0;
img_mem_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
img_mem_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
wsi->CmdPipelineBarrier(image->buffer.blit_cmd_buffers[i],
wsi->CmdPipelineBarrier(image->blit.cmd_buffers[i],
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
0,
@@ -1726,7 +1729,7 @@ wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
0, NULL,
1, &img_mem_barrier);
result = wsi->EndCommandBuffer(image->buffer.blit_cmd_buffers[i]);
result = wsi->EndCommandBuffer(image->blit.cmd_buffers[i]);
if (result != VK_SUCCESS)
return result;
}
@@ -1751,7 +1754,7 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
return result;
info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
info->wsi.buffer_blit_src = true;
info->wsi.blit_src = true;
const uint32_t cpp = vk_format_get_blocksize(pCreateInfo->imageFormat);
info->linear_stride = pCreateInfo->imageExtent.width * cpp;
@@ -1767,7 +1770,7 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
info->linear_size = info->linear_stride * pCreateInfo->imageExtent.height;
info->linear_size = ALIGN_POT(info->linear_size, size_align);
info->finish_create = wsi_finish_create_buffer_image;
info->finish_create = wsi_finish_create_blit_context;
return VK_SUCCESS;
}
@@ -1844,12 +1847,12 @@ wsi_create_cpu_buffer_image_mem(const struct wsi_swapchain *chain,
{
VkResult result;
result = wsi_create_buffer_image_mem(chain, info, image, 0,
false /* implicit_sync */);
result = wsi_create_buffer_blit_context(chain, info, image, 0,
false /* implicit_sync */);
if (result != VK_SUCCESS)
return result;
result = chain->wsi->MapMemory(chain->device, image->buffer.memory,
result = chain->wsi->MapMemory(chain->device, image->blit.memory,
0, VK_WHOLE_SIZE, 0, &image->cpu_map);
if (result != VK_SUCCESS)
return result;
@@ -1877,12 +1880,14 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
struct wsi_image_info *info)
{
assert(params->base.image_type == WSI_IMAGE_TYPE_CPU);
assert(chain->blit.type == WSI_SWAPCHAIN_NO_BLIT ||
chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT);
VkExternalMemoryHandleTypeFlags handle_types = 0;
if (params->alloc_shm)
handle_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
if (chain->use_buffer_blit) {
if (chain->blit.type != WSI_SWAPCHAIN_NO_BLIT) {
VkResult result = wsi_configure_buffer_image(chain, pCreateInfo,
1 /* stride_align */,
1 /* size_align */,
@@ -1890,7 +1895,7 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
if (result != VK_SUCCESS)
return result;
info->select_buffer_memory_type = wsi_select_host_memory_type;
info->select_blit_dst_memory_type = wsi_select_host_memory_type;
info->select_image_memory_type = wsi_select_device_memory_type;
info->create_mem = wsi_create_cpu_buffer_image_mem;
} else {

View File

@@ -60,8 +60,8 @@ struct wsi_image_create_info {
const void *pNext;
bool scanout;
/* if true, the image is a buffer blit source */
bool buffer_blit_src;
/* if true, the image is a blit source */
bool blit_src;
};
struct wsi_memory_allocate_info {
@@ -199,7 +199,7 @@ struct wsi_device {
* A driver can implement this callback to return a special queue to execute
* buffer blits.
*/
VkQueue (*get_buffer_blit_queue)(VkDevice device);
VkQueue (*get_blit_queue)(VkDevice device);
#define WSI_CB(cb) PFN_vk##cb cb
WSI_CB(AllocateMemory);

View File

@@ -574,16 +574,16 @@ wsi_create_prime_image_mem(const struct wsi_swapchain *chain,
{
const struct wsi_device *wsi = chain->wsi;
VkResult result =
wsi_create_buffer_image_mem(chain, info, image,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
true);
wsi_create_buffer_blit_context(chain, info, image,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
true);
if (result != VK_SUCCESS)
return result;
const VkMemoryGetFdInfoKHR linear_memory_get_fd_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
.pNext = NULL,
.memory = image->buffer.memory,
.memory = image->blit.memory,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
result = wsi->GetMemoryFdKHR(chain->device, &linear_memory_get_fd_info,
@@ -614,7 +614,7 @@ wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain,
info->prime_use_linear_modifier = use_modifier;
info->create_mem = wsi_create_prime_image_mem;
info->select_buffer_memory_type = select_buffer_memory_type;
info->select_blit_dst_memory_type = select_buffer_memory_type;
info->select_image_memory_type = wsi_select_device_memory_type;
return VK_SUCCESS;
@@ -641,7 +641,7 @@ wsi_drm_configure_image(const struct wsi_swapchain *chain,
{
assert(params->base.image_type == WSI_IMAGE_TYPE_DRM);
if (chain->use_buffer_blit) {
if (chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT) {
bool use_modifier = params->num_modifier_lists > 0;
wsi_memory_type_select_cb select_buffer_memory_type =
params->same_gpu ? wsi_select_device_memory_type :

View File

@@ -88,7 +88,7 @@ struct wsi_image_info {
uint32_t linear_size;
wsi_memory_type_select_cb select_image_memory_type;
wsi_memory_type_select_cb select_buffer_memory_type;
wsi_memory_type_select_cb select_blit_dst_memory_type;
uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size);
@@ -101,6 +101,11 @@ struct wsi_image_info {
struct wsi_image *image);
};
enum wsi_swapchain_blit_type {
WSI_SWAPCHAIN_NO_BLIT,
WSI_SWAPCHAIN_BUFFER_BLIT,
};
struct wsi_image {
VkImage image;
VkDeviceMemory memory;
@@ -108,8 +113,8 @@ struct wsi_image {
struct {
VkBuffer buffer;
VkDeviceMemory memory;
VkCommandBuffer *blit_cmd_buffers;
} buffer;
VkCommandBuffer *cmd_buffers;
} blit;
#ifndef _WIN32
uint64_t drm_modifier;
@@ -132,7 +137,6 @@ struct wsi_swapchain {
VkDevice device;
VkAllocationCallbacks alloc;
VkFence* fences;
VkSemaphore* buffer_blit_semaphores;
VkPresentModeKHR present_mode;
VkSemaphore present_id_timeline;
@@ -142,14 +146,17 @@ struct wsi_swapchain {
struct wsi_image_info image_info;
uint32_t image_count;
bool use_buffer_blit;
struct {
enum wsi_swapchain_blit_type type;
VkSemaphore *semaphores;
/* If the driver wants to use a special queue to execute the buffer blit,
* it'll implement the wsi_device::get_buffer_blit_queue callback.
* The created queue will be stored here and will be used to execute the
* buffer blit instead of using the present queue.
*/
VkQueue buffer_blit_queue;
/* If the driver wants to use a special queue to execute the buffer blit,
* it'll implement the wsi_device::get_blit_queue callback.
* The created queue will be stored here and will be used to execute the
* buffer blit instead of using the present queue.
*/
VkQueue queue;
} blit;
/* Command pools, one per queue family */
VkCommandPool *cmd_pools;
@@ -221,14 +228,14 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
struct wsi_image_info *info);
VkResult
wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image,
VkExternalMemoryHandleTypeFlags handle_types,
bool implicit_sync);
wsi_create_buffer_blit_context(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image,
VkExternalMemoryHandleTypeFlags handle_types,
bool implicit_sync);
VkResult
wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
wsi_finish_create_blit_context(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image);

View File

@@ -308,7 +308,7 @@ wsi_win32_image_init(VkDevice device_h,
const VkAllocationCallbacks *allocator,
struct wsi_win32_image *image)
{
assert(chain->base.use_buffer_blit);
assert(chain->base.blit.type == WSI_SWAPCHAIN_BUFFER_BLIT);
VkResult result = wsi_create_image(&chain->base, &chain->base.image_info,
&image->base);
if (result != VK_SUCCESS)
@@ -408,7 +408,7 @@ wsi_win32_queue_present(struct wsi_swapchain *drv_chain,
assert(image_index < chain->base.image_count);
struct wsi_win32_image *image = &chain->images[image_index];
assert(chain->base.use_buffer_blit);
assert(chain->base.blit.type == WSI_SWAPCHAIN_BUFFER_BLIT);
char *ptr = image->base.cpu_map;
char *dptr = image->ppvBits;