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:

committed by
Marge Bot

parent
bbcbf2cd91
commit
fa4e729165
@@ -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){
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
@@ -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 :
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user