comp: Guard acquire/release with a fence

Fixes validation warning when acquiring images before the command buffer
of the previous acquire or release on the same queue has finished.

VUID-vkQueueSubmit-pCommandBuffers-00071(ERROR / SPEC): msgNum: 774851941 - Validation Error: [ VUID-vkQueueSubmit-pCommandBuffers-00071 ] Object 0: handle = 0x558634c5c750, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x2e2f4d65 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] VkCommandBuffer 0x558634b85a10[] is already in use and is not marked for simultaneous use. The Vulkan spec states: If any element of the pCommandBuffers member of any element of pSubmits was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VUID-vkQueueSubmit-pCommandBuffers-00071)
    Objects: 1
        [0] 0x558634c5c750, type: 3, name: NULL
This commit is contained in:
Christoph Haag 2021-08-16 15:45:48 +02:00
parent 32d09aadc3
commit 778515739f
2 changed files with 27 additions and 2 deletions

View file

@ -16,6 +16,8 @@
#include <stdlib.h>
#include <assert.h>
#define MS_TO_NS(ms) (ms * 1000L * 1000L)
/*!
* Down-cast helper.
*
@ -81,6 +83,14 @@ client_vk_swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *out_index
return xret;
}
VkResult ret;
ret = vk->vkWaitForFences(vk->device, 1, &sc->acquire_release_fence[*out_index], true, MS_TO_NS(500));
vk_check_error("vkWaitForFences", ret, XRT_ERROR_VULKAN);
ret = vk->vkResetFences(vk->device, 1, &sc->acquire_release_fence[*out_index]);
vk_check_error("vkResetFences", ret, XRT_ERROR_VULKAN);
// Acquire ownership and complete layout transition
VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
@ -88,7 +98,7 @@ client_vk_swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *out_index
.pCommandBuffers = &sc->acquire[*out_index],
};
VkResult ret = vk_locked_submit(vk, vk->queue, 1, &submitInfo, VK_NULL_HANDLE);
ret = vk_locked_submit(vk, vk->queue, 1, &submitInfo, sc->acquire_release_fence[*out_index]);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "Could not submit to queue: %d", ret);
return XRT_ERROR_FAILED_TO_SUBMIT_VULKAN_COMMANDS;
@ -112,6 +122,14 @@ 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;
VkResult ret;
ret = vk->vkWaitForFences(vk->device, 1, &sc->acquire_release_fence[index], true, MS_TO_NS(500));
vk_check_error("vkWaitForFences", ret, XRT_ERROR_VULKAN);
vk->vkResetFences(vk->device, 1, &sc->acquire_release_fence[index]);
vk_check_error("vkResetFences", ret, XRT_ERROR_VULKAN);
// Release ownership and begin layout transition
VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
@ -119,7 +137,7 @@ client_vk_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
.pCommandBuffers = &sc->release[index],
};
VkResult ret = vk_locked_submit(vk, vk->queue, 1, &submitInfo, VK_NULL_HANDLE);
ret = vk_locked_submit(vk, vk->queue, 1, &submitInfo, sc->acquire_release_fence[index]);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "Could not submit to queue: %d", ret);
return XRT_ERROR_FAILED_TO_SUBMIT_VULKAN_COMMANDS;
@ -499,6 +517,12 @@ client_vk_swapchain_create(struct xrt_compositor *xc,
VK_ERROR(vk, "vkEndCommandBuffer: %s", vk_result_string(ret));
return XRT_ERROR_VULKAN;
}
VkFenceCreateInfo fence_create_info = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
};
vk->vkCreateFence(vk->device, &fence_create_info, NULL, &sc->acquire_release_fence[i]);
}
*out_xsc = &sc->base.base;

View file

@ -50,6 +50,7 @@ struct client_vk_swapchain
// Prerecorded swapchain image ownership/layout transition barriers
VkCommandBuffer acquire[XRT_MAX_SWAPCHAIN_IMAGES];
VkCommandBuffer release[XRT_MAX_SWAPCHAIN_IMAGES];
VkFence acquire_release_fence[XRT_MAX_SWAPCHAIN_IMAGES];
};
/*!