mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-03 12:28:07 +00:00
c/client: A working but non-spec conforming way to get Vulkan clients working
This commit is contained in:
parent
04c150a50d
commit
d778c236fe
|
@ -75,9 +75,28 @@ client_vk_swapchain_acquire_image(struct xrt_swapchain *xsc,
|
|||
uint32_t *out_index)
|
||||
{
|
||||
struct client_vk_swapchain *sc = client_vk_swapchain(xsc);
|
||||
struct vk_bundle *vk = &sc->c->vk;
|
||||
|
||||
// Pipe down call into fd swapchain.
|
||||
return xrt_swapchain_acquire_image(&sc->xscfd->base, out_index);
|
||||
xrt_result_t xret =
|
||||
xrt_swapchain_acquire_image(&sc->xscfd->base, out_index);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
|
||||
// Acquire ownership and complete layout transition
|
||||
VkSubmitInfo submitInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &sc->base.acquire[*out_index],
|
||||
};
|
||||
VkResult ret =
|
||||
vk->vkQueueSubmit(vk->queue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "Error: Could not submit to queue.\n");
|
||||
return XRT_ERROR_FAILED_TO_SUBMIT_VULKAN_COMMANDS;
|
||||
}
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -95,6 +114,20 @@ static xrt_result_t
|
|||
client_vk_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
|
||||
{
|
||||
struct client_vk_swapchain *sc = client_vk_swapchain(xsc);
|
||||
struct vk_bundle *vk = &sc->c->vk;
|
||||
|
||||
// Release ownership and begin layout transition
|
||||
VkSubmitInfo submitInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &sc->base.release[index],
|
||||
};
|
||||
VkResult ret =
|
||||
vk->vkQueueSubmit(vk->queue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "Error: Could not submit to queue.\n");
|
||||
return XRT_ERROR_FAILED_TO_SUBMIT_VULKAN_COMMANDS;
|
||||
}
|
||||
|
||||
// Pipe down call into fd swapchain.
|
||||
return xrt_swapchain_release_image(&sc->xscfd->base, index);
|
||||
|
@ -113,6 +146,10 @@ client_vk_compositor_destroy(struct xrt_compositor *xc)
|
|||
struct client_vk_compositor *c = client_vk_compositor(xc);
|
||||
|
||||
if (c->vk.cmd_pool != VK_NULL_HANDLE) {
|
||||
// Make sure that any of the command buffers from this command
|
||||
// pool are n used here, this pleases the validation layer.
|
||||
c->vk.vkDeviceWaitIdle(c->vk.device);
|
||||
|
||||
c->vk.vkDestroyCommandPool(c->vk.device, c->vk.cmd_pool, NULL);
|
||||
c->vk.cmd_pool = VK_NULL_HANDLE;
|
||||
}
|
||||
|
@ -253,9 +290,9 @@ client_vk_swapchain_create(struct xrt_compositor *xc,
|
|||
VkImageSubresourceRange subresource_range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = array_size,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
};
|
||||
|
||||
struct client_vk_swapchain *sc =
|
||||
|
@ -281,10 +318,15 @@ client_vk_swapchain_create(struct xrt_compositor *xc,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only to please the validation layer, that may or may
|
||||
* not be a bug in the validation layer. That may or may not be
|
||||
* fixed in the future version of the validation layer.
|
||||
*/
|
||||
vk_set_image_layout(&c->vk, cmd_buffer, sc->base.images[i], 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
subresource_range);
|
||||
}
|
||||
|
||||
|
@ -293,6 +335,90 @@ client_vk_swapchain_create(struct xrt_compositor *xc,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Prerecord command buffers for swapchain image ownership/layout
|
||||
// transitions
|
||||
for (uint32_t i = 0; i < xsc->num_images; i++) {
|
||||
ret = vk_init_cmd_buffer(&c->vk, &sc->base.acquire[i]);
|
||||
if (ret != VK_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
ret = vk_init_cmd_buffer(&c->vk, &sc->base.release[i]);
|
||||
if (ret != VK_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange subresource_range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
};
|
||||
|
||||
/*
|
||||
* The biggest reason is that VK_IMAGE_LAYOUT_PRESENT_SRC_KHR is
|
||||
* used here is that this is what hello_xr used to barrier to,
|
||||
* and it worked on a wide verity of drivers. So it's safe.
|
||||
*
|
||||
* There might not be a Vulkan renderer on the other endm
|
||||
* there could be a OpenGL compositor, heck there could be a X
|
||||
* server even. On Linux VK_IMAGE_LAYOUT_PRESENT_SRC_KHR is what
|
||||
* you use if you want to "flush" out all of the pixels to the
|
||||
* memory buffer that has been shared to you from a X11 server.
|
||||
*
|
||||
* This is not what the spec says you should do when it comes to
|
||||
* external images thou. Instead we should use the queue family
|
||||
* index `VK_QUEUE_FAMILY_EXTERNAL`. And use semaphores to
|
||||
* synchronize.
|
||||
*/
|
||||
VkImageMemoryBarrier acquire = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = vk_swapchain_access_flags(bits),
|
||||
.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.srcQueueFamilyIndex = c->vk.queue_family_index,
|
||||
.dstQueueFamilyIndex = c->vk.queue_family_index,
|
||||
.image = sc->base.images[i],
|
||||
.subresourceRange = subresource_range,
|
||||
};
|
||||
|
||||
VkImageMemoryBarrier release = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = vk_swapchain_access_flags(bits),
|
||||
.dstAccessMask = 0,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
.srcQueueFamilyIndex = c->vk.queue_family_index,
|
||||
.dstQueueFamilyIndex = c->vk.queue_family_index,
|
||||
.image = sc->base.images[i],
|
||||
.subresourceRange = subresource_range,
|
||||
};
|
||||
|
||||
//! @todo less conservative pipeline stage masks based on usage
|
||||
c->vk.vkCmdPipelineBarrier(sc->base.acquire[i],
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
0, 0, NULL, 0, NULL, 1, &acquire);
|
||||
c->vk.vkCmdPipelineBarrier(sc->base.release[i],
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
0, 0, NULL, 0, NULL, 1, &release);
|
||||
|
||||
ret = c->vk.vkEndCommandBuffer(sc->base.acquire[i]);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkEndCommandBuffer: %s",
|
||||
vk_result_string(ret));
|
||||
return NULL;
|
||||
}
|
||||
ret = c->vk.vkEndCommandBuffer(sc->base.release[i]);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkEndCommandBuffer: %s",
|
||||
vk_result_string(ret));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return &sc->base.base;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue