Skip to content

Commit

Permalink
Created Fence Pool and Renamed Semaphore Pool to Circular Pool Semaph…
Browse files Browse the repository at this point in the history
…ore Pool
  • Loading branch information
ravi688 committed Feb 10, 2024
1 parent fb175f0 commit ed6aedf
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 83 deletions.
92 changes: 92 additions & 0 deletions include/PlayVk/PlayVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,98 @@ static VkFence pvkCreateFence(VkDevice device, VkFenceCreateFlags flags)
return fence;
}

typedef struct PvkSemaphoreCircularPool
{
VkSemaphore* semaphores;
uint32_t reserveCount;
uint32_t acquiredIndex;
} PvkSemaphoreCircularPool;

static PvkSemaphoreCircularPool* pvkCreateSemaphoreCircularPool(VkDevice device, uint32_t reserveCount)
{
PvkSemaphoreCircularPool* pool = (PvkSemaphoreCircularPool*)malloc(sizeof(PvkSemaphoreCircularPool));
pool->semaphores = (VkSemaphore*)malloc(sizeof(VkSemaphore) * reserveCount);
pool->reserveCount = reserveCount;
pool->acquiredIndex = 0;
for(uint32_t i = 0; i < reserveCount; i++)
pool->semaphores[i] = pvkCreateSemaphore(device);
return pool;
}

static void pvkDestroySemaphoreCircularPool(VkDevice device, PvkSemaphoreCircularPool* pool)
{
for(uint32_t i = 0; i < pool->reserveCount; i++)
vkDestroySemaphore(device, pool->semaphores[i], NULL);
memset((void*)pool, 0, sizeof(pool));
free(pool);
}

static VkSemaphore pvkSemaphoreCircularPoolAcquire(PvkSemaphoreCircularPool* pool, uint32_t* outIndex)
{
VkSemaphore semaphore = pool->semaphores[pool->acquiredIndex];
if(outIndex != NULL)
*outIndex = pool->acquiredIndex;
pool->acquiredIndex = (pool->acquiredIndex + 1) % pool->reserveCount;
return semaphore;
}

static VkSemaphore pvkSemaphoreCircularPoolRecreate(VkDevice device, PvkSemaphoreCircularPool* pool, uint32_t index)
{
vkDestroySemaphore(device, pool->semaphores[index], NULL);
pool->semaphores[index] = pvkCreateSemaphore(device);
return pool->semaphores[index];
}

static void pvkResetFences(VkDevice device, uint32_t fenceCount, VkFence* fences)
{
PVK_CHECK(vkWaitForFences(device, fenceCount, fences, VK_TRUE, 0));
PVK_CHECK(vkResetFences(device, fenceCount, fences));
}

typedef struct PvkFencePool
{
VkFence* fences;
uint32_t reserveCount;
} PvkFencePool;

static PvkFencePool* pvkCreateFencePool(VkDevice device, uint32_t reserveCount)
{
PvkFencePool* pool = (PvkFencePool*)malloc(sizeof(PvkFencePool));
pool->fences = (VkFence*)malloc(sizeof(VkFence) * reserveCount);
pool->reserveCount = reserveCount;
for(uint32_t i = 0; i < reserveCount; i++)
pool->fences[i] = pvkCreateFence(device, VK_FENCE_CREATE_SIGNALED_BIT);
return pool;
}

static void pvkDestroyFencePool(VkDevice device, PvkFencePool* pool)
{
PVK_CHECK(vkWaitForFences(device, pool->reserveCount, pool->fences, VK_TRUE, 0));
for(uint32_t i = 0; i < pool->reserveCount; i++)
vkDestroyFence(device, pool->fences[i], NULL);
memset((void*)pool, 0, sizeof(pool));
free(pool);
}

static bool pvkFencePoolAcquire(VkDevice device, PvkFencePool* pool, VkFence* outFence)
{
VkFence* fences = pool->fences;
uint32_t fenceCount = pool->reserveCount;
for(uint32_t i = 0; i < fenceCount; i++)
{
VkResult result = vkWaitForFences(device, 1, &fences[i], VK_TRUE, 0);
if(result == VK_SUCCESS)
{
PVK_CHECK(vkResetFences(device, 1, &fences[i]));
*outFence = fences[i];
return true;
}
else if(result != VK_TIMEOUT) PVK_CHECK(result);
}
return false;
}


static void pvkSubmit(VkCommandBuffer commandBuffer, VkQueue queue, VkSemaphore wait, VkSemaphore signal, VkFence signalFence)
{
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
Expand Down
93 changes: 10 additions & 83 deletions source/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

#include <PlayVk/PlayVk.h>
#include <bufferlib/buffer.h>

#define FENCE_WAIT_TIME 5 /* nano seconds */

Expand Down Expand Up @@ -298,56 +297,6 @@ static VkDescriptorSetLayout pvkCreateObjectSetLayout(VkDevice device)
return setLayout;
}

typedef buffer_t VkSemaphoreList;

typedef struct PvkSemaphoreFIFOPool
{
VkSemaphoreList semaphores;
uint32_t acquiredIndex;
} PvkSemaphoreFIFOPool;

PvkSemaphoreFIFOPool* pvkCreateSemaphoreFIFOPool(VkDevice device, uint32_t reserveCount)
{
PvkSemaphoreFIFOPool* pool = (PvkSemaphoreFIFOPool*)malloc(sizeof(PvkSemaphoreFIFOPool));
pool->semaphores = buf_create(sizeof(VkSemaphore), reserveCount, 0);
pool->acquiredIndex = 0;
for(uint32_t i = 0; i < reserveCount; i++)
{
VkSemaphore semaphore = pvkCreateSemaphore(device);
buf_push(&pool->semaphores, &semaphore);
}
return pool;
}

void pvkDestroySemaphoreFIFOPool(VkDevice device, PvkSemaphoreFIFOPool* pool)
{
uint32_t reserveCount = (uint32_t)buf_get_capacity(&pool->semaphores);
for(uint32_t i = 0; i < reserveCount; i++)
vkDestroySemaphore(device, buf_get_value_at_typeof(&pool->semaphores, VkSemaphore, i), NULL);
buf_free(&pool->semaphores);
memset((void*)pool, 0, sizeof(pool));
free(pool);
}

VkSemaphore pvkSemaphoreFIFOPoolAcquire(PvkSemaphoreFIFOPool* pool, uint32_t* outIndex)
{
VkSemaphore semaphore = buf_get_value_at_typeof(&pool->semaphores, VkSemaphore, pool->acquiredIndex);
uint32_t reserveCount = (uint32_t)buf_get_capacity(&pool->semaphores);
if(outIndex != NULL)
*outIndex = pool->acquiredIndex;
pool->acquiredIndex = (pool->acquiredIndex + 1) % reserveCount;
return semaphore;
}

VkSemaphore pvkSemaphoreFIFOPoolRecreate(VkDevice device, PvkSemaphoreFIFOPool* pool, uint32_t index)
{
VkSemaphore* semaphore = buf_get_ptr_at_typeof(&pool->semaphores, VkSemaphore, index);
vkDestroySemaphore(device, *semaphore, NULL);
*semaphore = pvkCreateSemaphore(device);
return *semaphore;
}


static void recordCommandBuffers(u32 width, u32 height, VkCommandBuffer* commandBuffers,
VkClearValue* clearValues,
VkRenderPass renderPass,
Expand Down Expand Up @@ -400,22 +349,6 @@ static void recordCommandBuffers(u32 width, u32 height, VkCommandBuffer* command
}
}

static bool getAvailableFence(VkDevice device, VkFence* fences, uint32_t fenceCount, VkFence* outFence)
{
for(uint32_t i = 0; i < fenceCount; i++)
{
VkResult result = vkWaitForFences(device, 1, &fences[i], VK_TRUE, 0);
if(result == VK_SUCCESS)
{
PVK_CHECK(vkResetFences(device, 1, &fences[i]));
*outFence = fences[i];
return true;
}
else if(result != VK_TIMEOUT) PVK_CHECK(result);
}
return false;
}

int main()
{
VkInstance instance = pvkCreateVulkanInstanceWithExtensions(2, "VK_KHR_win32_surface", "VK_KHR_surface");
Expand Down Expand Up @@ -580,24 +513,21 @@ int main()
planeGeometry,
boxGeometry);

PvkSemaphoreFIFOPool* semaphorePool = pvkCreateSemaphoreFIFOPool(logicalGPU, 6);

VkFence fences[3];
for(uint32_t i = 0; i < 3; i++)
fences[i] = pvkCreateFence(logicalGPU, VK_FENCE_CREATE_SIGNALED_BIT);
PvkSemaphoreCircularPool* semaphorePool = pvkCreateSemaphoreCircularPool(logicalGPU, 6);
PvkFencePool* fencePool = pvkCreateFencePool(logicalGPU, 3);

float angle = 0;
/* Rendering & Presentation */
while(!pvkWindowShouldClose(window))
{
VkFence fence;
if(!getAvailableFence(logicalGPU, fences, 3, &fence))
if(!pvkFencePoolAcquire(logicalGPU, fencePool, &fence))
{
pvkWindowPollEvents(window);
continue;
}
uint32_t semaphoreIndex;
VkSemaphore imageAvailableSemaphore = pvkSemaphoreFIFOPoolAcquire(semaphorePool, &semaphoreIndex);
VkSemaphore imageAvailableSemaphore = pvkSemaphoreCircularPoolAcquire(semaphorePool, &semaphoreIndex);
uint32_t index;
while(!pvkAcquireNextImageKHR(logicalGPU, swapchain, UINT64_MAX, imageAvailableSemaphore, fence, &index))
{
Expand All @@ -619,9 +549,8 @@ int main()
vkDestroySwapchainKHR(logicalGPU, swapchain, NULL);
vkDestroySurfaceKHR(instance, surface, NULL);

imageAvailableSemaphore = pvkSemaphoreFIFOPoolRecreate(logicalGPU, semaphorePool, semaphoreIndex);
PVK_CHECK(vkWaitForFences(logicalGPU, 1, &fence, VK_TRUE, 0));
PVK_CHECK(vkResetFences(logicalGPU, 1, &fence));
imageAvailableSemaphore = pvkSemaphoreCircularPoolRecreate(logicalGPU, semaphorePool, semaphoreIndex);
pvkResetFences(logicalGPU, 1, &fence);

surface = pvkWindowCreateVulkanSurface(window, instance);
swapchain = pvkCreateSwapchain(logicalGPU, surface,
Expand Down Expand Up @@ -718,7 +647,7 @@ int main()
objectData->normalMatrix = pvkMat4Inverse(objectData->modelMatrix);
pvkUploadToMemory(logicalGPU, objectUniformBuffer.memory, objectData, sizeof(PvkObjectData));

VkSemaphore renderFinishSemaphore = pvkSemaphoreFIFOPoolAcquire(semaphorePool, NULL);
VkSemaphore renderFinishSemaphore = pvkSemaphoreCircularPoolAcquire(semaphorePool, NULL);
// execute commands
pvkSubmit(commandBuffers[index], graphicsQueue, imageAvailableSemaphore, renderFinishSemaphore, VK_NULL_HANDLE);

Expand All @@ -743,7 +672,7 @@ int main()
vkDestroySwapchainKHR(logicalGPU, swapchain, NULL);
vkDestroySurfaceKHR(instance, surface, NULL);

// pvkSemaphoreFIFOPoolReset(semaphorePool);
// pvkSemaphoreCircularPoolReset(semaphorePool);

surface = pvkWindowCreateVulkanSurface(window, instance);
swapchain = pvkCreateSwapchain(logicalGPU, surface,
Expand Down Expand Up @@ -840,10 +769,8 @@ int main()

PVK_CHECK(vkDeviceWaitIdle(logicalGPU));

PVK_CHECK(vkWaitForFences(logicalGPU, 3, fences, VK_TRUE, 0));
for(uint32_t i = 0; i < 3; i++)
vkDestroyFence(logicalGPU, fences[i], NULL);
pvkDestroySemaphoreFIFOPool(logicalGPU, semaphorePool);
pvkDestroyFencePool(logicalGPU, fencePool);
pvkDestroySemaphoreCircularPool(logicalGPU, semaphorePool);
delete(clearValues);
delete(objectData);
delete(camera);
Expand Down

0 comments on commit ed6aedf

Please sign in to comment.