Hello again.
I got one more report from the validation layers.
I can’t reset my commandbuffers because they are still in use --> Error
I can’t find a way to fix this. There are a lot of examples without resetting commandbuffers out there, but none with it.
That makes it hard for me.
Fences are created with the VK_FENCE_CREATE_SIGNALED_BIT flag.
The code (function order == execution order):
void DCRHI::BuildCommandBuffers()
{
VkCommandBufferBeginInfo cmdBufInfo = {};
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdBufInfo.pNext = VK_NULL_HANDLE;
VkClearValue clearValues[2];
clearValues[0].color = { { 0.2f, 0.0f, 0.2f, 1.0f } };
clearValues[1].depthStencil = { 1.0f, 0 };
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = VK_NULL_HANDLE;
renderPassBeginInfo.renderPass = DCINTERNAL::g_renderpass.GetRenderPass();
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = DCINTERNAL::g_swapchain.GetSwapchainWidth();
renderPassBeginInfo.renderArea.extent.height = DCINTERNAL::g_swapchain.GetSwapchainHeight();
renderPassBeginInfo.clearValueCount = 2;
renderPassBeginInfo.pClearValues = clearValues;
// some special stuff
DCScene* scene = nullptr;
scene = DCSceneManager::GetSceneByIndex(0);
DCHierarchy& hierarchy = scene->GetHierarchy();
std::vector<DCEntity*> entities = hierarchy.GetEntitiesByName("Camera");
DCEntity* cameraEntity = entities[0];
Camera* cam = cameraEntity->GetComponent<Camera>();
// prepares all meshRenderers for rendering
for (uint32_t ii = 0; ii < m_renderables.size(); ii++)
{
m_renderables[ii]->PrepareRenderer(*cam);
}
for (uint32_t i = 0; i < 2; i++)
{
VkResult result;
// wait for the sync fence to ensure the commandBuffer is not in use on rendering
result = vkWaitForFences(DCINTERNAL::g_devices[0].GetDevice(), 1, &m_waitFences[m_currentBuffer], VK_TRUE, UINT64_MAX);
// error. Command buffer still in use
result = vkResetCommandBuffer(m_commandBuffers[i]->GetCommandBuffer(), VkCommandBufferResetFlagBits::VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
// Set target frame
renderPassBeginInfo.framebuffer = DCINTERNAL::g_swapchain.GetFramebuffers().GetFramebuffer(i);
this->GetCommandBuffer(i).BeginCommandBuffer(VkCommandBufferUsageFlagBits::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
// Startes the first sub pass specified in our default render pass setup
// by the base class. This will clear the color and depth attachment
vkCmdBeginRenderPass(this->GetCommandBuffer(i).GetCommandBuffer(), &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
// Update the dynamic viewport
VkViewport viewport = {};
viewport.width = (float)DCINTERNAL::g_swapchain.GetSwapchainWidth();
viewport.height = (float)DCINTERNAL::g_swapchain.GetSwapchainHeight();
viewport.minDepth = (float)0.0f;
viewport.maxDepth = (float)1.0f;
vkCmdSetViewport(this->GetCommandBuffer(i).GetCommandBuffer(), 0, 1, &viewport);
// Update the dynamic viewport
VkRect2D scissor = {};
scissor.extent.width = (float)DCINTERNAL::g_swapchain.GetSwapchainWidth();
scissor.extent.height = (float)DCINTERNAL::g_swapchain.GetSwapchainHeight();
scissor.offset.x = 0;
scissor.offset.y = 0;
vkCmdSetScissor(this->GetCommandBuffer(i).GetCommandBuffer(), 0, 1, &scissor);
for (uint32_t ii = m_renderables.size() - 1; ii >= 0; ii--)
{
m_renderables[ii]->Render(this->GetCommandBuffer(i));
if (ii == 0)
break;
}
vkCmdEndRenderPass(this->GetCommandBuffer(i).GetCommandBuffer());
vkEndCommandBuffer(this->GetCommandBuffer(i).GetCommandBuffer());
}
}
void DCRHI::SubmitToQueue()
{
VkResult result;
// get the next image in the swapchain (back/front buffer)
result = DCINTERNAL::g_swapchain.AcquireNextImage(m_semPresentComplete, &m_currentBuffer);
// use a fence to wait until the command buffer has finished execution before using it again
result = vkWaitForFences(DCINTERNAL::g_devices[0].GetDevice(), 1, &m_waitFences[m_currentBuffer], VK_TRUE, UINT64_MAX);
result = vkResetFences(DCINTERNAL::g_devices[0].GetDevice(), 1, &m_waitFences[m_currentBuffer]);
// pipeline stage at which the queue submission will wait
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
// the submit info structure specifies a command buffer queue submission batch
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pWaitDstStageMask = &waitStageMask;
submitInfo.pWaitSemaphores = &m_semPresentComplete;
submitInfo.waitSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &m_semRenderComplete;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pCommandBuffers = &this->GetCommandBuffer(m_currentBuffer).GetCommandBuffer();
submitInfo.commandBufferCount = 1;
vkQueueSubmit(DCINTERNAL::g_swapchain.GetQueue(), 1, &submitInfo, m_waitFences[m_currentBuffer]);
}
void DCRHI::render()
{
DCINTERNAL::g_swapchain.QueuePresent(DCINTERNAL::g_swapchain.GetQueue() , m_currentBuffer, m_semRenderComplete);
}
Thank you!