Fixes in examples: support swapchain image count change on resize, fix multiple validation layer errors on resize and quit, multiview now supports resize/fullscreen, computecloth deltaT now based on frame time, multisampling recreates attachments on resize, P key now pauses computeparticles, descriptorsets, and pushdescriptors
This commit is contained in:
parent
cb343c329a
commit
121612857c
10 changed files with 148 additions and 65 deletions
|
|
@ -101,6 +101,7 @@ public:
|
||||||
~VulkanExample()
|
~VulkanExample()
|
||||||
{
|
{
|
||||||
// Graphics
|
// Graphics
|
||||||
|
graphics.indices.destroy();
|
||||||
graphics.uniformBuffer.destroy();
|
graphics.uniformBuffer.destroy();
|
||||||
vkDestroyPipeline(device, graphics.pipelines.cloth, nullptr);
|
vkDestroyPipeline(device, graphics.pipelines.cloth, nullptr);
|
||||||
vkDestroyPipeline(device, graphics.pipelines.sphere, nullptr);
|
vkDestroyPipeline(device, graphics.pipelines.sphere, nullptr);
|
||||||
|
|
@ -670,13 +671,13 @@ public:
|
||||||
void updateComputeUBO()
|
void updateComputeUBO()
|
||||||
{
|
{
|
||||||
if (!paused) {
|
if (!paused) {
|
||||||
compute.ubo.deltaT = 0.000005f;
|
//compute.ubo.deltaT = 0.000005f;
|
||||||
// todo: base on frametime
|
// todo: base on frametime
|
||||||
//compute.ubo.deltaT = frameTimer * 0.0075f;
|
compute.ubo.deltaT = frameTimer * 0.0015f;
|
||||||
|
|
||||||
if (simulateWind) {
|
if (simulateWind) {
|
||||||
std::default_random_engine rndEngine(benchmark.active ? 0 : (unsigned)time(nullptr));
|
std::default_random_engine rndEngine(benchmark.active ? 0 : (unsigned)time(nullptr));
|
||||||
std::uniform_real_distribution<float> rd(1.0f, 6.0f);
|
std::uniform_real_distribution<float> rd(1.0f, 30.0f);
|
||||||
compute.ubo.gravity.x = cos(glm::radians(-timer * 360.0f)) * (rd(rndEngine) - rd(rndEngine));
|
compute.ubo.gravity.x = cos(glm::radians(-timer * 360.0f)) * (rd(rndEngine) - rd(rndEngine));
|
||||||
compute.ubo.gravity.z = sin(glm::radians(timer * 360.0f)) * (rd(rndEngine) - rd(rndEngine));
|
compute.ubo.gravity.z = sin(glm::radians(timer * 360.0f)) * (rd(rndEngine) - rd(rndEngine));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -620,6 +620,13 @@ public:
|
||||||
// Semaphore for compute & graphics sync
|
// Semaphore for compute & graphics sync
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &graphics.semaphore));
|
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &graphics.semaphore));
|
||||||
|
|
||||||
|
// Signal the semaphore
|
||||||
|
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = &graphics.semaphore;
|
||||||
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareCompute()
|
void prepareCompute()
|
||||||
|
|
@ -736,13 +743,6 @@ public:
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
||||||
|
|
||||||
// Signal the semaphore
|
|
||||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
|
||||||
submitInfo.pSignalSemaphores = &compute.semaphore;
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
|
||||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
|
||||||
|
|
||||||
// Build a single command buffer containing the compute dispatch commands
|
// Build a single command buffer containing the compute dispatch commands
|
||||||
buildComputeCommandBuffer();
|
buildComputeCommandBuffer();
|
||||||
|
|
||||||
|
|
@ -841,6 +841,20 @@ public:
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
|
// Wait for rendering finished
|
||||||
|
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
|
|
||||||
|
// Submit compute commands
|
||||||
|
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
||||||
|
computeSubmitInfo.commandBufferCount = 1;
|
||||||
|
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||||
|
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||||
|
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||||
|
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
||||||
|
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||||
|
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||||
|
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||||
|
|
||||||
VulkanExampleBase::prepareFrame();
|
VulkanExampleBase::prepareFrame();
|
||||||
|
|
||||||
VkPipelineStageFlags graphicsWaitStageMasks[] = { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
VkPipelineStageFlags graphicsWaitStageMasks[] = { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
|
|
@ -858,20 +872,6 @@ public:
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
|
||||||
VulkanExampleBase::submitFrame();
|
VulkanExampleBase::submitFrame();
|
||||||
|
|
||||||
// Wait for rendering finished
|
|
||||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
|
||||||
|
|
||||||
// Submit compute commands
|
|
||||||
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
|
||||||
computeSubmitInfo.commandBufferCount = 1;
|
|
||||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
|
||||||
computeSubmitInfo.waitSemaphoreCount = 1;
|
|
||||||
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
|
||||||
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
|
||||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
|
||||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ public:
|
||||||
vkDestroyPipeline(device, graphics.pipeline, nullptr);
|
vkDestroyPipeline(device, graphics.pipeline, nullptr);
|
||||||
vkDestroyPipelineLayout(device, graphics.pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, graphics.pipelineLayout, nullptr);
|
||||||
vkDestroyDescriptorSetLayout(device, graphics.descriptorSetLayout, nullptr);
|
vkDestroyDescriptorSetLayout(device, graphics.descriptorSetLayout, nullptr);
|
||||||
|
vkDestroySemaphore(device, graphics.semaphore, nullptr);
|
||||||
|
|
||||||
// Compute
|
// Compute
|
||||||
compute.storageBuffer.destroy();
|
compute.storageBuffer.destroy();
|
||||||
|
|
@ -551,6 +552,13 @@ public:
|
||||||
// Semaphore for compute & graphics sync
|
// Semaphore for compute & graphics sync
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &graphics.semaphore));
|
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &graphics.semaphore));
|
||||||
|
|
||||||
|
// Signal the semaphore
|
||||||
|
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = &graphics.semaphore;
|
||||||
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareCompute()
|
void prepareCompute()
|
||||||
|
|
@ -636,13 +644,6 @@ public:
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
||||||
|
|
||||||
// Signal the semaphore
|
|
||||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
|
||||||
submitInfo.pSignalSemaphores = &compute.semaphore;
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
|
||||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
|
||||||
|
|
||||||
// Build a single command buffer containing the compute dispatch commands
|
// Build a single command buffer containing the compute dispatch commands
|
||||||
buildComputeCommandBuffer();
|
buildComputeCommandBuffer();
|
||||||
|
|
||||||
|
|
@ -716,7 +717,7 @@ public:
|
||||||
|
|
||||||
void updateUniformBuffers()
|
void updateUniformBuffers()
|
||||||
{
|
{
|
||||||
compute.ubo.deltaT = frameTimer * 2.5f;
|
compute.ubo.deltaT = paused ? 0.0f : frameTimer * 2.5f;
|
||||||
if (!attachToCursor)
|
if (!attachToCursor)
|
||||||
{
|
{
|
||||||
compute.ubo.destX = sin(glm::radians(timer * 360.0f)) * 0.75f;
|
compute.ubo.destX = sin(glm::radians(timer * 360.0f)) * 0.75f;
|
||||||
|
|
@ -735,6 +736,20 @@ public:
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
|
// Wait for rendering finished
|
||||||
|
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
|
|
||||||
|
// Submit compute commands
|
||||||
|
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
||||||
|
computeSubmitInfo.commandBufferCount = 1;
|
||||||
|
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||||
|
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||||
|
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||||
|
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
||||||
|
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||||
|
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||||
|
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||||
|
|
||||||
VulkanExampleBase::prepareFrame();
|
VulkanExampleBase::prepareFrame();
|
||||||
|
|
||||||
VkPipelineStageFlags graphicsWaitStageMasks[] = { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
VkPipelineStageFlags graphicsWaitStageMasks[] = { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
|
|
@ -752,21 +767,6 @@ public:
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
|
||||||
VulkanExampleBase::submitFrame();
|
VulkanExampleBase::submitFrame();
|
||||||
|
|
||||||
// Wait for rendering finished
|
|
||||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
|
||||||
|
|
||||||
// Submit compute commands
|
|
||||||
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
|
||||||
computeSubmitInfo.commandBufferCount = 1;
|
|
||||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
|
||||||
computeSubmitInfo.waitSemaphoreCount = 1;
|
|
||||||
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
|
||||||
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
|
||||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
|
||||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
|
|
|
||||||
|
|
@ -362,7 +362,7 @@ public:
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
draw();
|
draw();
|
||||||
if (animate) {
|
if (animate && !paused) {
|
||||||
cubes[0].rotation.x += 2.5f * frameTimer;
|
cubes[0].rotation.x += 2.5f * frameTimer;
|
||||||
if (cubes[0].rotation.x > 360.0f)
|
if (cubes[0].rotation.x > 360.0f)
|
||||||
cubes[0].rotation.x -= 360.0f;
|
cubes[0].rotation.x -= 360.0f;
|
||||||
|
|
@ -370,7 +370,7 @@ public:
|
||||||
if (cubes[1].rotation.x > 360.0f)
|
if (cubes[1].rotation.x > 360.0f)
|
||||||
cubes[1].rotation.x -= 360.0f;
|
cubes[1].rotation.x -= 360.0f;
|
||||||
}
|
}
|
||||||
if ((camera.updated) || (animate)) {
|
if ((camera.updated) || (animate && !paused)) {
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,11 +180,23 @@ public:
|
||||||
for (auto i = 0; i < attachments.size(); i++) {
|
for (auto i = 0; i < attachments.size(); i++) {
|
||||||
clearAttachment(&attachments[i].color);
|
clearAttachment(&attachments[i].color);
|
||||||
clearAttachment(&attachments[i].depth);
|
clearAttachment(&attachments[i].depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SRS - Recreate attachments and descriptors in case number of swapchain images has changed on resize
|
||||||
|
attachments.resize(swapChain.imageCount);
|
||||||
|
for (auto i = 0; i < attachments.size(); i++) {
|
||||||
createAttachment(colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &attachments[i].color);
|
createAttachment(colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &attachments[i].color);
|
||||||
createAttachment(depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, &attachments[i].depth);
|
createAttachment(depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, &attachments[i].depth);
|
||||||
// Since the framebuffers/attachments are referred in the descriptor sets, these need to be updated too
|
|
||||||
updateAttachmentReadDescriptors(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayouts.attachmentWrite, nullptr);
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayouts.attachmentRead, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentWrite, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentRead, nullptr);
|
||||||
|
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
||||||
|
|
||||||
|
// Since the framebuffers/attachments are referred in the descriptor sets, these need to be updated on resize
|
||||||
|
setupDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView views[3];
|
VkImageView views[3];
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ public:
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
VkDescriptorSet descriptorSet;
|
VkDescriptorSet descriptorSet;
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
|
VkExtent2D attachmentSize;
|
||||||
|
|
||||||
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
|
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
|
||||||
{
|
{
|
||||||
|
|
@ -200,6 +201,8 @@ public:
|
||||||
{
|
{
|
||||||
// Overrides the virtual function of the base class
|
// Overrides the virtual function of the base class
|
||||||
|
|
||||||
|
attachmentSize = { width, height };
|
||||||
|
|
||||||
std::array<VkAttachmentDescription, 3> attachments = {};
|
std::array<VkAttachmentDescription, 3> attachments = {};
|
||||||
|
|
||||||
// Multisampled attachment that we render to
|
// Multisampled attachment that we render to
|
||||||
|
|
@ -290,6 +293,20 @@ public:
|
||||||
{
|
{
|
||||||
// Overrides the virtual function of the base class
|
// Overrides the virtual function of the base class
|
||||||
|
|
||||||
|
// SRS - If the window is resized, the MSAA attachments need to be released and recreated
|
||||||
|
if (attachmentSize.width != width || attachmentSize.height != height)
|
||||||
|
{
|
||||||
|
attachmentSize = { width, height };
|
||||||
|
|
||||||
|
// Destroy MSAA target
|
||||||
|
vkDestroyImage(device, multisampleTarget.color.image, nullptr);
|
||||||
|
vkDestroyImageView(device, multisampleTarget.color.view, nullptr);
|
||||||
|
vkFreeMemory(device, multisampleTarget.color.memory, nullptr);
|
||||||
|
vkDestroyImage(device, multisampleTarget.depth.image, nullptr);
|
||||||
|
vkDestroyImageView(device, multisampleTarget.depth.view, nullptr);
|
||||||
|
vkFreeMemory(device, multisampleTarget.depth.memory, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
std::array<VkImageView, 3> attachments;
|
std::array<VkImageView, 3> attachments;
|
||||||
|
|
||||||
setupMultisampleTarget();
|
setupMultisampleTarget();
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ public:
|
||||||
vkDestroySampler(device, multiviewPass.sampler, nullptr);
|
vkDestroySampler(device, multiviewPass.sampler, nullptr);
|
||||||
vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr);
|
vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr);
|
||||||
|
|
||||||
|
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(multiviewPass.commandBuffers.size()), multiviewPass.commandBuffers.data());
|
||||||
vkDestroySemaphore(device, multiviewPass.semaphore, nullptr);
|
vkDestroySemaphore(device, multiviewPass.semaphore, nullptr);
|
||||||
for (auto& fence : multiviewPass.waitFences) {
|
for (auto& fence : multiviewPass.waitFences) {
|
||||||
vkDestroyFence(device, fence, nullptr);
|
vkDestroyFence(device, fence, nullptr);
|
||||||
|
|
@ -337,6 +338,9 @@ public:
|
||||||
|
|
||||||
void buildCommandBuffers()
|
void buildCommandBuffers()
|
||||||
{
|
{
|
||||||
|
if (resized)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
View display
|
View display
|
||||||
*/
|
*/
|
||||||
|
|
@ -392,11 +396,6 @@ public:
|
||||||
Multiview layered attachment scene rendering
|
Multiview layered attachment scene rendering
|
||||||
*/
|
*/
|
||||||
|
|
||||||
multiviewPass.commandBuffers.resize(drawCmdBuffers.size());
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
|
||||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, multiviewPass.commandBuffers.data()));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
||||||
|
|
||||||
|
|
@ -467,6 +466,11 @@ public:
|
||||||
*/
|
*/
|
||||||
VkDescriptorSetAllocateInfo allocateInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
VkDescriptorSetAllocateInfo allocateInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocateInfo, &descriptorSet));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocateInfo, &descriptorSet));
|
||||||
|
updateDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDescriptors()
|
||||||
|
{
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor),
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &multiviewPass.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &multiviewPass.descriptor),
|
||||||
|
|
@ -669,6 +673,11 @@ public:
|
||||||
prepareUniformBuffers();
|
prepareUniformBuffers();
|
||||||
prepareDescriptors();
|
prepareDescriptors();
|
||||||
preparePipelines();
|
preparePipelines();
|
||||||
|
|
||||||
|
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||||
|
multiviewPass.commandBuffers.resize(drawCmdBuffers.size());
|
||||||
|
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, multiviewPass.commandBuffers.data()));
|
||||||
|
|
||||||
buildCommandBuffers();
|
buildCommandBuffers();
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo = vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
VkFenceCreateInfo fenceCreateInfo = vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||||
|
|
@ -680,6 +689,45 @@ public:
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SRS - Recreate and update Multiview resources when window size has changed
|
||||||
|
virtual void windowResized()
|
||||||
|
{
|
||||||
|
vkDestroyImageView(device, multiviewPass.color.view, nullptr);
|
||||||
|
vkDestroyImage(device, multiviewPass.color.image, nullptr);
|
||||||
|
vkFreeMemory(device, multiviewPass.color.memory, nullptr);
|
||||||
|
vkDestroyImageView(device, multiviewPass.depth.view, nullptr);
|
||||||
|
vkDestroyImage(device, multiviewPass.depth.image, nullptr);
|
||||||
|
vkFreeMemory(device, multiviewPass.depth.memory, nullptr);
|
||||||
|
|
||||||
|
vkDestroyRenderPass(device, multiviewPass.renderPass, nullptr);
|
||||||
|
vkDestroySampler(device, multiviewPass.sampler, nullptr);
|
||||||
|
vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr);
|
||||||
|
|
||||||
|
prepareMultiview();
|
||||||
|
updateDescriptors();
|
||||||
|
|
||||||
|
// SRS - Recreate Multiview command buffers in case number of swapchain images has changed on resize
|
||||||
|
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(multiviewPass.commandBuffers.size()), multiviewPass.commandBuffers.data());
|
||||||
|
|
||||||
|
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||||
|
multiviewPass.commandBuffers.resize(drawCmdBuffers.size());
|
||||||
|
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, multiviewPass.commandBuffers.data()));
|
||||||
|
|
||||||
|
resized = false;
|
||||||
|
buildCommandBuffers();
|
||||||
|
|
||||||
|
// SRS - Recreate Multiview fences in case number of swapchain images has changed on resize
|
||||||
|
for (auto& fence : multiviewPass.waitFences) {
|
||||||
|
vkDestroyFence(device, fence, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceCreateInfo = vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||||
|
multiviewPass.waitFences.resize(multiviewPass.commandBuffers.size());
|
||||||
|
for (auto& fence : multiviewPass.waitFences) {
|
||||||
|
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void render()
|
virtual void render()
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ public:
|
||||||
memcpy(cube.uniformBuffer.mapped, &cube.modelMat, sizeof(glm::mat4));
|
memcpy(cube.uniformBuffer.mapped, &cube.modelMat, sizeof(glm::mat4));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animate) {
|
if (animate && !paused) {
|
||||||
cubes[0].rotation.x += 2.5f * frameTimer;
|
cubes[0].rotation.x += 2.5f * frameTimer;
|
||||||
if (cubes[0].rotation.x > 360.0f)
|
if (cubes[0].rotation.x > 360.0f)
|
||||||
cubes[0].rotation.x -= 360.0f;
|
cubes[0].rotation.x -= 360.0f;
|
||||||
|
|
@ -323,7 +323,7 @@ public:
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
draw();
|
draw();
|
||||||
if (animate) {
|
if (animate && !paused) {
|
||||||
cubes[0].rotation.x += 2.5f * frameTimer;
|
cubes[0].rotation.x += 2.5f * frameTimer;
|
||||||
if (cubes[0].rotation.x > 360.0f)
|
if (cubes[0].rotation.x > 360.0f)
|
||||||
cubes[0].rotation.x -= 360.0f;
|
cubes[0].rotation.x -= 360.0f;
|
||||||
|
|
|
||||||
|
|
@ -901,7 +901,9 @@ public:
|
||||||
|
|
||||||
virtual void windowResized()
|
virtual void windowResized()
|
||||||
{
|
{
|
||||||
updateTextOverlay();
|
// SRS - Recreate text overlay resources in case number of swapchain images has changed on resize
|
||||||
|
delete textOverlay;
|
||||||
|
prepareTextOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(__ANDROID__)
|
#if !defined(__ANDROID__)
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,9 @@ public:
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample()
|
||||||
{
|
{
|
||||||
|
// SRS - Ensure all operations on the device have finished before destroying resources
|
||||||
|
vkDeviceWaitIdle(device);
|
||||||
|
|
||||||
// Clean up used Vulkan resources
|
// Clean up used Vulkan resources
|
||||||
// Note: Inherited destructor cleans up resources stored in base class
|
// Note: Inherited destructor cleans up resources stored in base class
|
||||||
vkDestroyPipeline(device, pipeline, nullptr);
|
vkDestroyPipeline(device, pipeline, nullptr);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue