mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 13:50:09 +01:00
venus: handle VK_IMAGE_LAYOUT_PRESENT_SRC_KHR transfer
Whenver VK_IMAGE_LAYOUT_PRESENT_SRC_KHR is used, replace it with VK_IMAGE_LAYOUT_GENERAL as required for proper layout and ownership transfer for external memory backed swapchain images. This will be Android only until common WSI is fixed. Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Reviewed-by: Chia-I Wu <olvaffe@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10335>
This commit is contained in:
parent
293255889c
commit
174fca5498
3 changed files with 156 additions and 8 deletions
|
|
@ -134,6 +134,7 @@ vn_AllocateCommandBuffers(VkDevice device,
|
|||
vn_object_base_init(&cmd->base, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
&dev->base);
|
||||
cmd->device = dev;
|
||||
cmd->allocator = pool->allocator;
|
||||
|
||||
list_addtail(&cmd->head, &pool->command_buffers);
|
||||
|
||||
|
|
@ -170,6 +171,9 @@ vn_FreeCommandBuffers(VkDevice device,
|
|||
if (!cmd)
|
||||
continue;
|
||||
|
||||
if (cmd->image_barriers)
|
||||
vk_free(alloc, cmd->image_barriers);
|
||||
|
||||
vn_cs_encoder_fini(&cmd->cs);
|
||||
list_del(&cmd->head);
|
||||
|
||||
|
|
@ -939,6 +943,51 @@ vn_CmdResetEvent(VkCommandBuffer commandBuffer,
|
|||
vn_encode_vkCmdResetEvent(&cmd->cs, 0, commandBuffer, event, stageMask);
|
||||
}
|
||||
|
||||
static const VkImageMemoryBarrier *
|
||||
vn_get_intercepted_barriers(struct vn_command_buffer *cmd,
|
||||
const VkImageMemoryBarrier *img_barriers,
|
||||
uint32_t count)
|
||||
{
|
||||
/* XXX drop the #ifdef after fixing common wsi */
|
||||
#ifdef ANDROID
|
||||
bool has_present_src = false;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (img_barriers[i].oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
|
||||
img_barriers[i].newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
||||
has_present_src = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_present_src)
|
||||
return img_barriers;
|
||||
|
||||
size_t size = sizeof(VkImageMemoryBarrier) * count;
|
||||
/* avoid shrinking in case of non efficient reallocation implementation */
|
||||
VkImageMemoryBarrier *barriers = cmd->image_barriers;
|
||||
if (count > cmd->image_barrier_count) {
|
||||
barriers =
|
||||
vk_realloc(&cmd->allocator, cmd->image_barriers, size,
|
||||
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!barriers)
|
||||
return img_barriers;
|
||||
|
||||
/* update upon successful reallocation */
|
||||
cmd->image_barrier_count = count;
|
||||
cmd->image_barriers = barriers;
|
||||
}
|
||||
memcpy(barriers, img_barriers, size);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (barriers[i].oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||
barriers[i].oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
if (barriers[i].newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||
barriers[i].newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
return barriers;
|
||||
#else
|
||||
return img_barriers;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
vn_CmdWaitEvents(VkCommandBuffer commandBuffer,
|
||||
uint32_t eventCount,
|
||||
|
|
@ -963,13 +1012,14 @@ vn_CmdWaitEvents(VkCommandBuffer commandBuffer,
|
|||
if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
|
||||
return;
|
||||
|
||||
/* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
|
||||
const VkImageMemoryBarrier *img_barriers = vn_get_intercepted_barriers(
|
||||
cmd, pImageMemoryBarriers, imageMemoryBarrierCount);
|
||||
|
||||
vn_encode_vkCmdWaitEvents(&cmd->cs, 0, commandBuffer, eventCount, pEvents,
|
||||
srcStageMask, dstStageMask, memoryBarrierCount,
|
||||
pMemoryBarriers, bufferMemoryBarrierCount,
|
||||
pBufferMemoryBarriers, imageMemoryBarrierCount,
|
||||
pImageMemoryBarriers);
|
||||
img_barriers);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -995,12 +1045,13 @@ vn_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
|
|||
if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
|
||||
return;
|
||||
|
||||
/* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
|
||||
const VkImageMemoryBarrier *img_barriers = vn_get_intercepted_barriers(
|
||||
cmd, pImageMemoryBarriers, imageMemoryBarrierCount);
|
||||
|
||||
vn_encode_vkCmdPipelineBarrier(
|
||||
&cmd->cs, 0, commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
|
||||
memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
|
||||
pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
|
||||
pBufferMemoryBarriers, imageMemoryBarrierCount, img_barriers);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ struct vn_command_buffer {
|
|||
|
||||
struct vn_device *device;
|
||||
|
||||
/* for scrubbing VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
|
||||
VkAllocationCallbacks allocator;
|
||||
uint32_t image_barrier_count;
|
||||
VkImageMemoryBarrier *image_barriers;
|
||||
|
||||
struct list_head head;
|
||||
|
||||
enum vn_command_buffer_state state;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,43 @@
|
|||
|
||||
/* render pass commands */
|
||||
|
||||
static const VkAttachmentDescription *
|
||||
vn_get_intercepted_attachments(const VkAttachmentDescription *attachments,
|
||||
uint32_t count,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
/* XXX drop the #ifdef after fixing common wsi */
|
||||
#ifdef ANDROID
|
||||
bool has_present_src = false;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
|
||||
attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
||||
has_present_src = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_present_src)
|
||||
return attachments;
|
||||
|
||||
size_t size = sizeof(VkAttachmentDescription) * count;
|
||||
VkAttachmentDescription *out_attachments = vk_alloc(
|
||||
alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!out_attachments)
|
||||
return NULL;
|
||||
|
||||
memcpy(out_attachments, attachments, size);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (out_attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||
out_attachments[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
if (out_attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||
out_attachments[i].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
return out_attachments;
|
||||
#else
|
||||
return attachments;
|
||||
#endif
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_CreateRenderPass(VkDevice device,
|
||||
const VkRenderPassCreateInfo *pCreateInfo,
|
||||
|
|
@ -35,17 +72,63 @@ vn_CreateRenderPass(VkDevice device,
|
|||
|
||||
vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
|
||||
|
||||
/* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
|
||||
VkRenderPassCreateInfo local_pass_info = *pCreateInfo;
|
||||
local_pass_info.pAttachments = vn_get_intercepted_attachments(
|
||||
pCreateInfo->pAttachments, pCreateInfo->attachmentCount, alloc);
|
||||
if (!local_pass_info.pAttachments) {
|
||||
vk_free(alloc, pass);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
VkRenderPass pass_handle = vn_render_pass_to_handle(pass);
|
||||
vn_async_vkCreateRenderPass(dev->instance, device, pCreateInfo, NULL,
|
||||
vn_async_vkCreateRenderPass(dev->instance, device, &local_pass_info, NULL,
|
||||
&pass_handle);
|
||||
|
||||
if (local_pass_info.pAttachments != pCreateInfo->pAttachments)
|
||||
vk_free(alloc, (void *)local_pass_info.pAttachments);
|
||||
|
||||
*pRenderPass = pass_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static const VkAttachmentDescription2 *
|
||||
vn_get_intercepted_attachments2(const VkAttachmentDescription2 *attachments,
|
||||
uint32_t count,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
/* XXX drop the #ifdef after fixing common wsi */
|
||||
#ifdef ANDROID
|
||||
bool has_present_src = false;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
|
||||
attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
||||
has_present_src = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_present_src)
|
||||
return attachments;
|
||||
|
||||
size_t size = sizeof(VkAttachmentDescription2) * count;
|
||||
VkAttachmentDescription2 *out_attachments = vk_alloc(
|
||||
alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!out_attachments)
|
||||
return NULL;
|
||||
|
||||
memcpy(out_attachments, attachments, size);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (out_attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||
out_attachments[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
if (out_attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||
out_attachments[i].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
return out_attachments;
|
||||
#else
|
||||
return attachments;
|
||||
#endif
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_CreateRenderPass2(VkDevice device,
|
||||
const VkRenderPassCreateInfo2 *pCreateInfo,
|
||||
|
|
@ -64,12 +147,21 @@ vn_CreateRenderPass2(VkDevice device,
|
|||
|
||||
vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
|
||||
|
||||
/* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
|
||||
VkRenderPassCreateInfo2 local_pass_info = *pCreateInfo;
|
||||
local_pass_info.pAttachments = vn_get_intercepted_attachments2(
|
||||
pCreateInfo->pAttachments, pCreateInfo->attachmentCount, alloc);
|
||||
if (!local_pass_info.pAttachments) {
|
||||
vk_free(alloc, pass);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
VkRenderPass pass_handle = vn_render_pass_to_handle(pass);
|
||||
vn_async_vkCreateRenderPass2(dev->instance, device, pCreateInfo, NULL,
|
||||
vn_async_vkCreateRenderPass2(dev->instance, device, &local_pass_info, NULL,
|
||||
&pass_handle);
|
||||
|
||||
if (local_pass_info.pAttachments != pCreateInfo->pAttachments)
|
||||
vk_free(alloc, (void *)local_pass_info.pAttachments);
|
||||
|
||||
*pRenderPass = pass_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue