Skip to content

Commit ae2aca5

Browse files
committed
Dynamic Uniform Buffers
1 parent 54afe28 commit ae2aca5

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

src/main.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ VulkanPipeline modelPipeline;
4646
VkDescriptorSetLayout modelDescriptorSetLayout;
4747
VkDescriptorPool modelDescriptorPool;
4848
VkDescriptorSet modelDescriptorSets[FRAMES_IN_FLIGHT];
49+
uint64_t singleElementSize;
4950
VulkanBuffer modelUniformBuffers[FRAMES_IN_FLIGHT];
5051

5152
VkQueryPool timestampQueryPools[FRAMES_IN_FLIGHT];
@@ -239,7 +240,7 @@ void initApplication(SDL_Window* window) {
239240

240241
{
241242
VkDescriptorPoolSize poolSizes[] = {
242-
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, FRAMES_IN_FLIGHT},
243+
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, FRAMES_IN_FLIGHT},
243244
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, FRAMES_IN_FLIGHT},
244245
};
245246
VkDescriptorPoolCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
@@ -249,11 +250,13 @@ void initApplication(SDL_Window* window) {
249250
VKA(vkCreateDescriptorPool(context->device, &createInfo, 0, &modelDescriptorPool));
250251
}
251252
for(uint32_t i = 0; i < FRAMES_IN_FLIGHT; ++i) {
252-
createBuffer(context, &modelUniformBuffers[i], sizeof(glm::mat4)*2, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
253+
uint64_t minUniformAlignment = context->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
254+
singleElementSize = ALIGN_UP_POW2(sizeof(glm::mat4)*2, minUniformAlignment);
255+
createBuffer(context, &modelUniformBuffers[i], singleElementSize*2, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
253256
}
254257
{
255258
VkDescriptorSetLayoutBinding bindings[] = {
256-
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, 0},
259+
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT, 0},
257260
{1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler},
258261
};
259262
VkDescriptorSetLayoutCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
@@ -275,7 +278,7 @@ void initApplication(SDL_Window* window) {
275278
descriptorWrites[0].dstSet = modelDescriptorSets[i];
276279
descriptorWrites[0].dstBinding = 0;
277280
descriptorWrites[0].descriptorCount = 1;
278-
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
281+
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
279282
descriptorWrites[0].pBufferInfo = &bufferInfo;
280283
descriptorWrites[1] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};
281284
descriptorWrites[1].dstSet = modelDescriptorSets[i];
@@ -480,13 +483,17 @@ void renderApplication() {
480483
VKA(vkWaitForFences(context->device, 1, &fences[frameIndex], VK_TRUE, UINT64_MAX));
481484

482485
VkResult result = VK(vkAcquireNextImageKHR(context->device, swapchain.swapchain, UINT64_MAX, acquireSemaphores[frameIndex], 0, &imageIndex));
483-
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
486+
if(result == VK_ERROR_OUT_OF_DATE_KHR) {
487+
// ImGui still expects us to call render so we still do this here
488+
ImGui::Render();
484489
// Swapchain is out of date
485490
recreateSwapchain();
486491
return;
487492
} else {
488493
VKA(vkResetFences(context->device, 1, &fences[frameIndex]));
489-
ASSERT_VULKAN(result);
494+
if(result != VK_SUBOPTIMAL_KHR) {
495+
ASSERT_VULKAN(result);
496+
}
490497
}
491498

492499
// Query timestamps
@@ -496,7 +503,7 @@ void renderApplication() {
496503
double frameGpuBegin = double(timestamps[0]) * context->physicalDeviceProperties.limits.timestampPeriod * 1e-6;
497504
double frameGpuEnd = double(timestamps[1]) * context->physicalDeviceProperties.limits.timestampPeriod * 1e-6;
498505
frameGpuAvg = frameGpuAvg * 0.95 + (frameGpuEnd - frameGpuBegin) * 0.05;
499-
LOG_INFO("GPU frametime: ", frameGpuAvg, "ms");
506+
//LOG_INFO("GPU frametime: ", frameGpuAvg, "ms");
500507
}
501508

502509
VKA(vkResetCommandPool(context->device, commandPools[frameIndex], 0));
@@ -535,7 +542,7 @@ void renderApplication() {
535542
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, spritePipeline.pipelineLayout, 0, 1, &spriteDescriptorSet, 0, 0);
536543
vkCmdDrawIndexed(commandBuffer, ARRAY_COUNT(indexData), 1, 0, 0, 0);
537544
#else
538-
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 3.0f));
545+
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 2.0f));
539546
glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(100.0f));
540547
glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), -time, glm::vec3(0.0f, 1.0f, 0.0f));
541548
glm::mat4 modelMatrix = translationMatrix * scaleMatrix * rotationMatrix;
@@ -547,14 +554,30 @@ void renderApplication() {
547554
VK(vkMapMemory(context->device, modelUniformBuffers[frameIndex].memory, 0, sizeof(glm::mat4)*2, 0, &mapped));
548555
memcpy(mapped, &modelViewProj, sizeof(modelViewProj));
549556
memcpy(((uint8_t*)mapped)+sizeof(glm::mat4), &modelView, sizeof(modelView));
550-
VK(vkUnmapMemory(context->device, modelUniformBuffers[frameIndex].memory));
551557

552558
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, modelPipeline.pipeline);
553559
VkDeviceSize offset = 0;
554560
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &model.vertexBuffer.buffer, &offset);
555561
vkCmdBindIndexBuffer(commandBuffer, model.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16);
556-
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, modelPipeline.pipelineLayout, 0, 1, &modelDescriptorSets[frameIndex], 0, 0);
562+
uint32_t dynamicOffset = 0;
563+
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, modelPipeline.pipelineLayout, 0, 1, &modelDescriptorSets[frameIndex], 1, &dynamicOffset);
564+
vkCmdDrawIndexed(commandBuffer, model.numIndices, 1, 0, 0, 0);
565+
566+
567+
// Second instance
568+
modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 5.0f)) * scaleMatrix * rotationMatrix;
569+
modelViewProj = camera.viewProj * modelMatrix;
570+
modelView = camera.view * modelMatrix;
571+
572+
mapped = ((uint8_t*)mapped) + singleElementSize;
573+
memcpy(mapped, &modelViewProj, sizeof(modelViewProj));
574+
memcpy(((uint8_t*)mapped)+sizeof(glm::mat4), &modelView, sizeof(modelView));
575+
576+
dynamicOffset = singleElementSize;
577+
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, modelPipeline.pipelineLayout, 0, 1, &modelDescriptorSets[frameIndex], 1, &dynamicOffset);
557578
vkCmdDrawIndexed(commandBuffer, model.numIndices, 1, 0, 0, 0);
579+
580+
VK(vkUnmapMemory(context->device, modelUniformBuffers[frameIndex].memory));
558581
#endif
559582

560583
ImGui::Render();

src/vulkan_base/vulkan_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#endif
1616

1717
#define ARRAY_COUNT(array) (sizeof(array) / sizeof((array)[0]))
18+
#define ALIGN_UP_POW2(x, p) (((x)+(p) - 1) &~((p) - 1))
1819

1920
struct VulkanQueue {
2021
VkQueue queue;

0 commit comments

Comments
 (0)