mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-12 15:05:31 +00:00
vk: Create more image semaphores that command buffers used.
Mostly workaround for vkAcquireNextImageKHR errors,
Create more cmdbuffers with slow vulkan implementation could produce
issues when old cmdbuffer is not finished but need to resize dynamic buffer.
Based on
```
Added additional image ready semaphore - this addresses validation errors
when calling vkAcquireNextImageKHR() which started appearing in SDK 1.3.275
```
88009a6149
This commit is contained in:
parent
ed3d760840
commit
10ee6eace3
2 changed files with 30 additions and 9 deletions
|
@ -211,8 +211,10 @@ typedef enum
|
||||||
} qvkrenderpasstype_t;
|
} qvkrenderpasstype_t;
|
||||||
|
|
||||||
// Vulkan constants: command and dynamic buffer count
|
// Vulkan constants: command and dynamic buffer count
|
||||||
#define NUM_CMDBUFFERS 32
|
#define NUM_CMDBUFFERS 2
|
||||||
#define NUM_DYNBUFFERS 2
|
#define NUM_DYNBUFFERS 2
|
||||||
|
// Vulkan constants: number of image semaphores (introduced with VulkanSDK 1.3.275)
|
||||||
|
#define NUM_IMG_SEMAPHORES (NUM_CMDBUFFERS * 2)
|
||||||
#define PUSH_CONSTANT_VERTEX_SIZE 17
|
#define PUSH_CONSTANT_VERTEX_SIZE 17
|
||||||
#define PUSH_CONSTANT_FRAGMENT_SIZE 11
|
#define PUSH_CONSTANT_FRAGMENT_SIZE 11
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ qvkrenderpass_t vk_renderpasses[RP_COUNT] = {
|
||||||
VkCommandPool vk_commandPool[NUM_CMDBUFFERS] = { 0 };
|
VkCommandPool vk_commandPool[NUM_CMDBUFFERS] = { 0 };
|
||||||
VkCommandPool vk_transferCommandPool = VK_NULL_HANDLE;
|
VkCommandPool vk_transferCommandPool = VK_NULL_HANDLE;
|
||||||
VkDescriptorPool vk_descriptorPool = VK_NULL_HANDLE;
|
VkDescriptorPool vk_descriptorPool = VK_NULL_HANDLE;
|
||||||
static VkCommandPool vk_stagingCommandPool[NUM_DYNBUFFERS] = { VK_NULL_HANDLE, VK_NULL_HANDLE };
|
static VkCommandPool vk_stagingCommandPool[NUM_DYNBUFFERS] = { 0 };
|
||||||
// Vulkan image views
|
// Vulkan image views
|
||||||
static VkImageView *vk_imageviews = NULL;
|
static VkImageView *vk_imageviews = NULL;
|
||||||
// Vulkan framebuffers
|
// Vulkan framebuffers
|
||||||
|
@ -113,7 +113,7 @@ static VkCommandBuffer *vk_commandbuffers = NULL;
|
||||||
// command buffer double buffering fences
|
// command buffer double buffering fences
|
||||||
static VkFence vk_fences[NUM_CMDBUFFERS];
|
static VkFence vk_fences[NUM_CMDBUFFERS];
|
||||||
// semaphore: signal when next image is available for rendering
|
// semaphore: signal when next image is available for rendering
|
||||||
static VkSemaphore vk_imageAvailableSemaphores[NUM_CMDBUFFERS];
|
static VkSemaphore vk_imageAvailableSemaphores[NUM_IMG_SEMAPHORES];
|
||||||
// semaphore: signal when rendering to current command buffer is complete
|
// semaphore: signal when rendering to current command buffer is complete
|
||||||
static VkSemaphore vk_renderFinishedSemaphores[NUM_CMDBUFFERS];
|
static VkSemaphore vk_renderFinishedSemaphores[NUM_CMDBUFFERS];
|
||||||
// tracker variables
|
// tracker variables
|
||||||
|
@ -122,6 +122,8 @@ VkCommandBuffer vk_activeCmdbuffer = VK_NULL_HANDLE;
|
||||||
int vk_activeBufferIdx = 0;
|
int vk_activeBufferIdx = 0;
|
||||||
// index of currently acquired image
|
// index of currently acquired image
|
||||||
static uint32_t vk_imageIndex = 0;
|
static uint32_t vk_imageIndex = 0;
|
||||||
|
// index of currently used image semaphore
|
||||||
|
uint32_t vk_imageSemaphoreIdx = 0;
|
||||||
// index of currently used staging buffer
|
// index of currently used staging buffer
|
||||||
static int vk_activeStagingBuffer = 0;
|
static int vk_activeStagingBuffer = 0;
|
||||||
// started rendering frame?
|
// started rendering frame?
|
||||||
|
@ -1645,9 +1647,15 @@ void QVk_Shutdown( void )
|
||||||
}
|
}
|
||||||
if (vk_device.logical != VK_NULL_HANDLE)
|
if (vk_device.logical != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_CMDBUFFERS; ++i)
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_IMG_SEMAPHORES; ++i)
|
||||||
{
|
{
|
||||||
vkDestroySemaphore(vk_device.logical, vk_imageAvailableSemaphores[i], NULL);
|
vkDestroySemaphore(vk_device.logical, vk_imageAvailableSemaphores[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_CMDBUFFERS; ++i)
|
||||||
|
{
|
||||||
vkDestroySemaphore(vk_device.logical, vk_renderFinishedSemaphores[i], NULL);
|
vkDestroySemaphore(vk_device.logical, vk_renderFinishedSemaphores[i], NULL);
|
||||||
vkDestroyFence(vk_device.logical, vk_fences[i], NULL);
|
vkDestroyFence(vk_device.logical, vk_fences[i], NULL);
|
||||||
}
|
}
|
||||||
|
@ -2018,6 +2026,12 @@ qboolean QVk_Init(void)
|
||||||
vk_scissor.offset.y = 0;
|
vk_scissor.offset.y = 0;
|
||||||
vk_scissor.extent = vk_swapchain.extent;
|
vk_scissor.extent = vk_swapchain.extent;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_DYNBUFFERS; i++ )
|
||||||
|
{
|
||||||
|
vk_stagingCommandPool[i] = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
// setup fences and semaphores
|
// setup fences and semaphores
|
||||||
VkFenceCreateInfo fCreateInfo = {
|
VkFenceCreateInfo fCreateInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||||
|
@ -2029,20 +2043,24 @@ qboolean QVk_Init(void)
|
||||||
.pNext = NULL,
|
.pNext = NULL,
|
||||||
.flags = 0
|
.flags = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i = 0; i < NUM_CMDBUFFERS; ++i)
|
for (i = 0; i < NUM_CMDBUFFERS; ++i)
|
||||||
{
|
{
|
||||||
vk_commandPool[i] = VK_NULL_HANDLE;
|
vk_commandPool[i] = VK_NULL_HANDLE;
|
||||||
VK_VERIFY(vkCreateFence(vk_device.logical, &fCreateInfo, NULL, &vk_fences[i]));
|
VK_VERIFY(vkCreateFence(vk_device.logical, &fCreateInfo, NULL, &vk_fences[i]));
|
||||||
VK_VERIFY(vkCreateSemaphore(vk_device.logical, &sCreateInfo, NULL, &vk_imageAvailableSemaphores[i]));
|
|
||||||
VK_VERIFY(vkCreateSemaphore(vk_device.logical, &sCreateInfo, NULL, &vk_renderFinishedSemaphores[i]));
|
VK_VERIFY(vkCreateSemaphore(vk_device.logical, &sCreateInfo, NULL, &vk_renderFinishedSemaphores[i]));
|
||||||
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_fences[i],
|
QVk_DebugSetObjectName((uint64_t)vk_fences[i],
|
||||||
VK_OBJECT_TYPE_FENCE, va("Fence #%d", i));
|
VK_OBJECT_TYPE_FENCE, va("Fence #%d", i));
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_imageAvailableSemaphores[i],
|
|
||||||
VK_OBJECT_TYPE_SEMAPHORE, va("Semaphore: image available #%d", i));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_renderFinishedSemaphores[i],
|
QVk_DebugSetObjectName((uint64_t)vk_renderFinishedSemaphores[i],
|
||||||
VK_OBJECT_TYPE_SEMAPHORE, va("Semaphore: render finished #%d", i));
|
VK_OBJECT_TYPE_SEMAPHORE, va("Semaphore: render finished #%d", i));
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < NUM_IMG_SEMAPHORES; ++i)
|
||||||
|
{
|
||||||
|
VK_VERIFY(vkCreateSemaphore(vk_device.logical, &sCreateInfo, NULL, &vk_imageAvailableSemaphores[i]));
|
||||||
|
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_imageAvailableSemaphores[i], VK_OBJECT_TYPE_SEMAPHORE, va("Semaphore: image available #%d", i));
|
||||||
|
}
|
||||||
R_Printf(PRINT_ALL, "...created synchronization objects\n");
|
R_Printf(PRINT_ALL, "...created synchronization objects\n");
|
||||||
|
|
||||||
// setup render passes
|
// setup render passes
|
||||||
|
@ -2185,7 +2203,7 @@ VkResult QVk_BeginFrame(const VkViewport* viewport, const VkRect2D* scissor)
|
||||||
ReleaseSwapBuffers();
|
ReleaseSwapBuffers();
|
||||||
|
|
||||||
VkResult result = vkAcquireNextImageKHR(vk_device.logical, vk_swapchain.sc, 500000000 /* 0.5 sec */,
|
VkResult result = vkAcquireNextImageKHR(vk_device.logical, vk_swapchain.sc, 500000000 /* 0.5 sec */,
|
||||||
vk_imageAvailableSemaphores[vk_activeBufferIdx], VK_NULL_HANDLE, &vk_imageIndex);
|
vk_imageAvailableSemaphores[vk_imageSemaphoreIdx], VK_NULL_HANDLE, &vk_imageIndex);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_SURFACE_LOST_KHR || result == VK_TIMEOUT)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_SURFACE_LOST_KHR || result == VK_TIMEOUT)
|
||||||
{
|
{
|
||||||
vk_recreateSwapchainNeeded = true;
|
vk_recreateSwapchainNeeded = true;
|
||||||
|
@ -2264,7 +2282,7 @@ VkResult QVk_EndFrame(qboolean force)
|
||||||
VkSubmitInfo submitInfo = {
|
VkSubmitInfo submitInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||||
.waitSemaphoreCount = 1,
|
.waitSemaphoreCount = 1,
|
||||||
.pWaitSemaphores = &vk_imageAvailableSemaphores[vk_activeBufferIdx],
|
.pWaitSemaphores = &vk_imageAvailableSemaphores[vk_imageSemaphoreIdx],
|
||||||
.signalSemaphoreCount = 1,
|
.signalSemaphoreCount = 1,
|
||||||
.pSignalSemaphores = &vk_renderFinishedSemaphores[vk_activeBufferIdx],
|
.pSignalSemaphores = &vk_renderFinishedSemaphores[vk_activeBufferIdx],
|
||||||
.pWaitDstStageMask = &waitStages,
|
.pWaitDstStageMask = &waitStages,
|
||||||
|
@ -2299,6 +2317,7 @@ VkResult QVk_EndFrame(qboolean force)
|
||||||
}
|
}
|
||||||
|
|
||||||
vk_activeBufferIdx = (vk_activeBufferIdx + 1) % NUM_CMDBUFFERS;
|
vk_activeBufferIdx = (vk_activeBufferIdx + 1) % NUM_CMDBUFFERS;
|
||||||
|
vk_imageSemaphoreIdx = (vk_imageSemaphoreIdx + 1) % NUM_IMG_SEMAPHORES;
|
||||||
|
|
||||||
vk_frameStarted = false;
|
vk_frameStarted = false;
|
||||||
return renderResult;
|
return renderResult;
|
||||||
|
|
Loading…
Reference in a new issue