void VulkanRenderManager::Submit(int frame, bool triggerFence) { FrameData &frameData = frameData_[frame]; if (frameData.hasInitCommands) { VkResult res = vkEndCommandBuffer(frameData.initCmd); _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res)); } VkResult res = vkEndCommandBuffer(frameData.mainCmd); _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res)); VkCommandBuffer cmdBufs[2]; int numCmdBufs = 0; if (frameData.hasInitCommands) { cmdBufs[numCmdBufs++] = frameData.initCmd; frameData.hasInitCommands = false; if (splitSubmit_) { // Send the init commands off separately. Used this once to confirm that the cause of a device loss was in the init cmdbuf. VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; submit_info.commandBufferCount = (uint32_t)numCmdBufs; submit_info.pCommandBuffers = cmdBufs; res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE); if (res == VK_ERROR_DEVICE_LOST) { _assert_msg_(G3D, false, "Lost the Vulkan device!"); } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res)); } numCmdBufs = 0; } } cmdBufs[numCmdBufs++] = frameData.mainCmd; VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; if (triggerFence && !frameData.skipSwap) { submit_info.waitSemaphoreCount = 1; submit_info.pWaitSemaphores = &acquireSemaphore_; VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submit_info.pWaitDstStageMask = waitStage; } submit_info.commandBufferCount = (uint32_t)numCmdBufs; submit_info.pCommandBuffers = cmdBufs; if (triggerFence && !frameData.skipSwap) { submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &renderingCompleteSemaphore_; } res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFence ? frameData.fence : VK_NULL_HANDLE); if (res == VK_ERROR_DEVICE_LOST) { _assert_msg_(G3D, false, "Lost the Vulkan device!"); } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res)); } // When !triggerFence, we notify after syncing with Vulkan. if (useThread_ && triggerFence) { VLOG("PULL: Frame %d.readyForFence = true", frame); std::unique_lock<std::mutex> lock(frameData.push_mutex); frameData.readyForFence = true; frameData.push_condVar.notify_all(); } }
void VulkanWindow::EndRender() const { vkCmdEndRenderPass ( mVulkanRenderer.GetCommandBuffer() ); if ( VkResult result = vkEndCommandBuffer ( mVulkanRenderer.GetCommandBuffer() ) ) { std::cout << GetVulkanResultString ( result ) << " " << __func__ << " " << __LINE__ << " " << std::endl; } VkSubmitInfo submit_info{}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.waitSemaphoreCount = 0; submit_info.pWaitSemaphores = nullptr; submit_info.pWaitDstStageMask = nullptr; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &mVulkanRenderer.GetCommandBuffer(); submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &mVulkanRenderer.GetSignalSemaphore(); if ( VkResult result = vkQueueSubmit ( mVulkanRenderer.GetQueue(), 1, &submit_info, VK_NULL_HANDLE ) ) { std::cout << GetVulkanResultString ( result ) << " " << __func__ << " " << __LINE__ << " " << std::endl; } std::array<VkResult, 1> result_array{ { VkResult::VK_SUCCESS } }; VkPresentInfoKHR present_info{}; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.waitSemaphoreCount = 1; present_info.pWaitSemaphores = &mVulkanRenderer.GetSignalSemaphore(); present_info.swapchainCount = 1; present_info.pSwapchains = &mVkSwapchainKHR; present_info.pImageIndices = &mActiveImageIndex; present_info.pResults = result_array.data(); if ( VkResult result = vkQueuePresentKHR ( mVulkanRenderer.GetQueue(), &present_info ) ) { std::cout << GetVulkanResultString ( result ) << " " << __func__ << " " << __LINE__ << " " << std::endl; } }
void VkContext::EndDrawBuffer(VkCommandBuffer cmdBuffer, VkImage image) { VkImageSubresourceRange subresourceRange = {}; subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; subresourceRange.baseArrayLayer = 0; subresourceRange.layerCount = 1; VkImageMemoryBarrier memoryBarrier = {}; memoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; memoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; memoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; memoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; memoryBarrier.srcQueueFamilyIndex = queueIndex; memoryBarrier.dstQueueFamilyIndex = queueIndex; memoryBarrier.image = image; memoryBarrier.subresourceRange = subresourceRange; // Change image layout to present vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &memoryBarrier); // End command buffer CheckVkResult(vkEndCommandBuffer(cmdBuffer)); }
void op3d::Engine::createCommandBuffers() { if (commandBuffers.size() > 0) { vkFreeCommandBuffers(device, commandBufferManager.getCommandPool(), commandBuffers.size(), commandBuffers.data()); } commandBuffers.resize(swapChainFramebuffers.size()); VkCommandBufferAllocateInfo allocInfo = {}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.commandPool = commandBufferManager.getCommandPool(); allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.commandBufferCount = (uint32_t)commandBuffers.size(); if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) { throw std::runtime_error("failed to allocate command buffers!"); } for (std::size_t i = 0; i < commandBuffers.size(); i++) { VkCommandBufferBeginInfo beginInfo = {}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; vkBeginCommandBuffer(commandBuffers[i], &beginInfo); VkRenderPassBeginInfo renderPassInfo = {}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.renderPass = renderPass; renderPassInfo.framebuffer = swapChainFramebuffers[i]; renderPassInfo.renderArea.offset = {0, 0}; renderPassInfo.renderArea.extent = swapChain.getExtent(); std::array <VkClearValue, 2> clearValues = {}; clearValues[0].color = { 0.0f, 0.0f, 0.0f, 1.0f }; clearValues[1].depthStencil = { 1.0f, 0 }; renderPassInfo.clearValueCount = clearValues.size(); renderPassInfo.pClearValues = clearValues.data(); vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); VkBuffer vertexBuffers[] = {vertexBuffer}; VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets); vkCmdBindIndexBuffer(commandBuffers[i], indexBuffer, 0, VK_INDEX_TYPE_UINT16); vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); vkCmdDrawIndexed(commandBuffers[i], indices.size(), 1, 0, 0, 0); vkCmdEndRenderPass(commandBuffers[i]); if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) { throw std::runtime_error("failed to record command buffer!"); } } }
/** * Finish command buffer recording and submit it to a queue * * @param commandBuffer Command buffer to flush * @param queue Queue to submit the command buffer to * @param free (Optional) Free the command buffer once it has been submitted (Defaults to true) * * @note The queue that the command buffer is submitted to must be from the same family index as the pool it was allocated from * @note Uses a fence to ensure command buffer has finished executing */ void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free = true) { if (commandBuffer == VK_NULL_HANDLE) { return; } VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); VkSubmitInfo submitInfo = vkTools::initializers::submitInfo(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffer; // Create fence to ensure that the command buffer has finished executing VkFenceCreateInfo fenceInfo = vkTools::initializers::fenceCreateInfo(VK_FLAGS_NONE); VkFence fence; VK_CHECK_RESULT(vkCreateFence(logicalDevice, &fenceInfo, nullptr, &fence)); // Submit to the queue VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence)); // Wait for the fence to signal that command buffer has finished executing VK_CHECK_RESULT(vkWaitForFences(logicalDevice, 1, &fence, VK_TRUE, DEFAULT_FENCE_TIMEOUT)); vkDestroyFence(logicalDevice, fence, nullptr); if (free) { vkFreeCommandBuffers(logicalDevice, commandPool, 1, &commandBuffer); } }
void VulkanBase::submitPostPresentBarrier(VkImage image) { VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); vkTools::checkResult(vkBeginCommandBuffer(postPresentCmdBuffer, &cmdBufInfo)); VkImageMemoryBarrier postPresentBarrier = vkTools::initializers::imageMemoryBarrier(); postPresentBarrier.srcAccessMask = 0; postPresentBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; postPresentBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; postPresentBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; postPresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; postPresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; postPresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; postPresentBarrier.image = image; vkCmdPipelineBarrier( postPresentCmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, // No memory barriers, 0, nullptr, // No buffer barriers, 1, &postPresentBarrier); vkTools::checkResult(vkEndCommandBuffer(postPresentCmdBuffer)); VkSubmitInfo submitInfo = vkTools::initializers::submitInfo(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &postPresentCmdBuffer; vkTools::checkResult(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); }
static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) { VkResult err; VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); check_vk_result(err); ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; { err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking check_vk_result(err); err = vkResetFences(g_Device, 1, &fd->Fence); check_vk_result(err); } { err = vkResetCommandPool(g_Device, fd->CommandPool, 0); check_vk_result(err); VkCommandBufferBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; err = vkBeginCommandBuffer(fd->CommandBuffer, &info); check_vk_result(err); } { VkRenderPassBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.renderPass = wd->RenderPass; info.framebuffer = wd->Framebuffer[wd->FrameIndex]; info.renderArea.extent.width = wd->Width; info.renderArea.extent.height = wd->Height; info.clearValueCount = 1; info.pClearValues = &wd->ClearValue; vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } // Record Imgui Draw Data and draw funcs into command buffer ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); { VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; info.waitSemaphoreCount = 1; info.pWaitSemaphores = &image_acquired_semaphore; info.pWaitDstStageMask = &wait_stage; info.commandBufferCount = 1; info.pCommandBuffers = &fd->CommandBuffer; info.signalSemaphoreCount = 1; info.pSignalSemaphores = &fd->RenderCompleteSemaphore; err = vkEndCommandBuffer(fd->CommandBuffer); check_vk_result(err); err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); check_vk_result(err); } }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; clearValues[0].color = defaultClearColor; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vkTools::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; VkResult err; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; err = vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo); assert(!err); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vkTools::initializers::viewport( (float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vkTools::initializers::rect2D( width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid); VkDeviceSize offsets[1] = { 0 }; // Bind mesh vertex buffer vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &mesh.vertices.buf, offsets); // Bind mesh index buffer vkCmdBindIndexBuffer(drawCmdBuffers[i], mesh.indices.buf, 0, VK_INDEX_TYPE_UINT32); // Render mesh vertex buffer using it's indices vkCmdDrawIndexed(drawCmdBuffers[i], mesh.indices.count, 1, 0, 0, 0); vkCmdEndRenderPass(drawCmdBuffers[i]); err = vkEndCommandBuffer(drawCmdBuffers[i]); assert(!err); } }
void Shadow::CookCmdBuffer(const Scene& scene) { // COMMAND BUFFER auto drawTriangleCmdBufferAllocInfo = vkstruct<VkCommandBufferAllocateInfo>(); drawTriangleCmdBufferAllocInfo.commandPool = mCmdPool; drawTriangleCmdBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; drawTriangleCmdBufferAllocInfo.commandBufferCount = 1u; gVkLastRes = vkAllocateCommandBuffers(gDevice.VkHandle(), &drawTriangleCmdBufferAllocInfo, &mCmdBuffer); VKFN_LAST_RES_SUCCESS_OR_QUIT(vkAllocateCommandBuffers); auto framebufferCreateInfo = vkstruct<VkFramebufferCreateInfo>(); framebufferCreateInfo.flags = 0; framebufferCreateInfo.renderPass = mRenderPass; framebufferCreateInfo.attachmentCount = 1u; framebufferCreateInfo.pAttachments = &mDepthImage.view; framebufferCreateInfo.width = static_cast<u32>(SHADOWMAP_RES); framebufferCreateInfo.height = static_cast<u32>(SHADOWMAP_RES); framebufferCreateInfo.layers = 1u; gVkLastRes = vkCreateFramebuffer(gDevice.VkHandle(), &framebufferCreateInfo, nullptr, &mFramebuffer); VKFN_LAST_RES_SUCCESS_OR_QUIT(vkCreateFramebuffer); VkClearValue clearDepthStencilValue; clearDepthStencilValue.depthStencil = { 1.f, 0 }; auto renderPassBeginInfo = vkstruct<VkRenderPassBeginInfo>(); renderPassBeginInfo.renderPass = mRenderPass; renderPassBeginInfo.framebuffer = mFramebuffer; renderPassBeginInfo.renderArea = { { 0, 0 },{ SHADOWMAP_RES, SHADOWMAP_RES } }; renderPassBeginInfo.clearValueCount = 1u; renderPassBeginInfo.pClearValues = &clearDepthStencilValue; auto cmdBufferBeginInfo = vkstruct<VkCommandBufferBeginInfo>(); cmdBufferBeginInfo.flags = 0; // REGISTER COMMAND BUFFER gVkLastRes = vkBeginCommandBuffer(mCmdBuffer, &cmdBufferBeginInfo); VKFN_LAST_RES_SUCCESS_OR_QUIT(vkBeginCommandBuffer); // TRANSITION RENDERTARGET FROM PRESENTABLE TO RENDERABLE LAYOUT + Initial transition from UNDEFINED layout vkCmdBeginRenderPass(mCmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(mCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, mPipeline); vkCmdBindDescriptorSets(mCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, mPipelineLayout, 0u, GlobalDescriptorSets::CB_COUNT, GlobalDescriptorSets::descriptorSets, 0u, nullptr); scene.BindDrawingToCmdBuffer(mCmdBuffer); vkCmdEndRenderPass(mCmdBuffer); gVkLastRes = vkEndCommandBuffer(mCmdBuffer); VKFN_LAST_RES_SUCCESS_OR_QUIT(vkEndCommandBuffer); }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; clearValues[0].color = defaultClearColor; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); VkDeviceSize offsets[1] = { 0 }; // Skybox if (displaySkybox) { vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.skybox, 0, NULL); vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &models.skybox.vertices.buffer, offsets); vkCmdBindIndexBuffer(drawCmdBuffers[i], models.skybox.indices.buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.skybox); vkCmdDrawIndexed(drawCmdBuffers[i], models.skybox.indexCount, 1, 0, 0, 0); } // 3D object vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.object, 0, NULL); vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &models.objects[models.objectIndex].vertices.buffer, offsets); vkCmdBindIndexBuffer(drawCmdBuffers[i], models.objects[models.objectIndex].indices.buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.reflect); vkCmdDrawIndexed(drawCmdBuffers[i], models.objects[models.objectIndex].indexCount, 1, 0, 0, 0); drawUI(drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]); VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; clearValues[0].color = { {0.5f, 0.5f, 0.5f, 0.0f} }; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vkTools::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vkTools::initializers::viewport(splitScreen ? (float)width / 2.0f : (float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdSetLineWidth(drawCmdBuffers[i], 1.0f); vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); VkDeviceSize offsets[1] = { 0 }; vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &meshes.object.vertices.buf, offsets); vkCmdBindIndexBuffer(drawCmdBuffers[i], meshes.object.indices.buf, 0, VK_INDEX_TYPE_UINT32); if (splitScreen) { vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLeft); vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); viewport.x = float(width) / 2; } vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineRight); vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); vkCmdEndRenderPass(drawCmdBuffers[i]); VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } }
void VkeDrawCall::initDrawCommands(const uint32_t inCount, const uint32_t inCommandIndex){ VkPipelineLayout layout = m_renderer->getPipelineLayout(); VkPipeline pipeline = m_renderer->getPipeline(); VkDescriptorSet sceneDescriptor = m_renderer->getSceneDescriptorSet(); VkDescriptorSet *textureDescriptors = m_renderer->getTextureDescriptorSets(); VkBuffer sceneIndirectBuffer = m_renderer->getSceneIndirectBuffer(); VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = dc->getDefaultQueue(); VulkanAppContext *ctxt = VulkanAppContext::GetInstance(); vkResetCommandBuffer(m_draw_command[inCommandIndex], 0); VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; VKA_CHECK_ERROR(vkBeginCommandBuffer(m_draw_command[inCommandIndex], &cmdBeginInfo), "Could not begin command buffer.\n"); vkCmdBindPipeline(m_draw_command[inCommandIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); VkeVBO *theVBO = ctxt->getVBO(); VkeIBO *theIBO = ctxt->getIBO(); theVBO->bind(&m_draw_command[inCommandIndex]); theIBO->bind(&m_draw_command[inCommandIndex]); VkDescriptorSet sets[3] = { sceneDescriptor, textureDescriptors[0], m_transform_descriptor_set }; vkCmdBindDescriptorSets(m_draw_command[inCommandIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 3, sets, 0, NULL); vkCmdDrawIndexedIndirect(m_draw_command[inCommandIndex], sceneIndirectBuffer, 0, inCount, sizeof(VkDrawIndexedIndirectCommand)); vkCmdDraw(m_draw_command[inCommandIndex], 1, 1, 0, 0); vkEndCommandBuffer(m_draw_command[inCommandIndex]); /* Lock mutex to update generated call count. */ //std::lock_guard<std::mutex> lk(m_renderer->getSecondaryCmdBufferMutex()); /* Increment the generated call count */ m_renderer->incrementDrawCallsGenerated(); }
static void vulkan_raster_font_flush(vulkan_raster_t *font) { const struct vk_draw_triangles call = { font->vk->pipelines.font, &font->texture_optimal, font->vk->samplers.mipmap_linear, &font->vk->mvp, sizeof(font->vk->mvp), &font->range, font->vertices, }; if(font->needs_update) { VkCommandBuffer staging; VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; VkCommandBufferAllocateInfo cmd_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmd_info.commandPool = font->vk->staging_pool; cmd_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; cmd_info.commandBufferCount = 1; vkAllocateCommandBuffers(font->vk->context->device, &cmd_info, &staging); begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; vkBeginCommandBuffer(staging, &begin_info); vulkan_copy_staging_to_dynamic(font->vk, staging, &font->texture_optimal, &font->texture); vkEndCommandBuffer(staging); #ifdef HAVE_THREADS slock_lock(font->vk->context->queue_lock); #endif submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &staging; vkQueueSubmit(font->vk->context->queue, 1, &submit_info, VK_NULL_HANDLE); vkQueueWaitIdle(font->vk->context->queue); #ifdef HAVE_THREADS slock_unlock(font->vk->context->queue_lock); #endif vkFreeCommandBuffers(font->vk->context->device, font->vk->staging_pool, 1, &staging); font->needs_update = false; } vulkan_draw_triangles(font->vk, &call); }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; clearValues[0].color = defaultClearColor; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vkTools::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; VkResult err; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; err = vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo); assert(!err); // The primary command buffer does not contain any rendering commands // These are stored (and retrieved) from the secondary command buffers vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); // Execute secondary command buffers for (auto& renderThread : renderThreads) { // todo : Make sure threads are finished before accessing their command buffers vkCmdExecuteCommands(drawCmdBuffers[i], 1, &renderThread.cmdBuffers[i]); } vkCmdEndRenderPass(drawCmdBuffers[i]); VkImageMemoryBarrier prePresentBarrier = vkTools::prePresentBarrier(swapChain.buffers[i].image); vkCmdPipelineBarrier( drawCmdBuffers[i], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FLAGS_NONE, 0, nullptr, 0, nullptr, 1, &prePresentBarrier); err = vkEndCommandBuffer(drawCmdBuffers[i]); assert(!err); } }
void HookGui::HGWidgetShader::EndRender() { // End the render pass vkCmdEndRenderPass(m_CommandBuffer); // End the command buffer record if (vkEndCommandBuffer(m_CommandBuffer) != VK_SUCCESS) { throw std::runtime_error("failed to record command buffer!"); } }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; clearValues[0].color = defaultClearColor; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { renderPassBeginInfo.framebuffer = frameBuffers[i]; VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); VkDeviceSize offsets[1] = { 0 }; vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &vertexBuffer.buffer, offsets); vkCmdBindIndexBuffer(drawCmdBuffers[i], indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); // Render multiple objects using different model matrices by dynamically offsetting into one uniform buffer for (uint32_t j = 0; j < OBJECT_INSTANCES; j++) { // One dynamic offset per dynamic descriptor to offset into the ubo containing all model matrices uint32_t dynamicOffset = j * static_cast<uint32_t>(dynamicAlignment); // Bind the descriptor set for rendering a mesh using the dynamic offset vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 1, &dynamicOffset); vkCmdDrawIndexed(drawCmdBuffers[i], indexCount, 1, 0, 0, 0); } vkCmdEndRenderPass(drawCmdBuffers[i]); VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } }
/** * Update the command buffers to reflect text changes */ void updateCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.extent.width = *frameBufferWidth; renderPassBeginInfo.renderArea.extent.height = *frameBufferHeight; // None of the attachments will be cleared renderPassBeginInfo.clearValueCount = 0; renderPassBeginInfo.pClearValues = nullptr; for (size_t i = 0; i < cmdBuffers.size(); ++i) { renderPassBeginInfo.framebuffer = *frameBuffers[i]; VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuffers[i], &cmdBufInfo)); if (vks::debugmarker::active) { vks::debugmarker::beginRegion(cmdBuffers[i], "Text overlay", glm::vec4(1.0f, 0.94f, 0.3f, 1.0f)); } vkCmdBeginRenderPass(cmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vks::initializers::viewport((float)*frameBufferWidth, (float)*frameBufferHeight, 0.0f, 1.0f); vkCmdSetViewport(cmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vks::initializers::rect2D(*frameBufferWidth, *frameBufferHeight, 0, 0); vkCmdSetScissor(cmdBuffers[i], 0, 1, &scissor); vkCmdBindPipeline(cmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); vkCmdBindDescriptorSets(cmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); VkDeviceSize offsets = 0; vkCmdBindVertexBuffers(cmdBuffers[i], 0, 1, &vertexBuffer.buffer, &offsets); vkCmdBindVertexBuffers(cmdBuffers[i], 1, 1, &vertexBuffer.buffer, &offsets); for (uint32_t j = 0; j < numLetters; j++) { vkCmdDraw(cmdBuffers[i], 4, 1, j * 4, 0); } vkCmdEndRenderPass(cmdBuffers[i]); if (vks::debugmarker::active) { vks::debugmarker::endRegion(cmdBuffers[i]); } VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuffers[i])); } }
void buildComputeCommandBuffer() { VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();; vkBeginCommandBuffer(computeCmdBuffer, &cmdBufInfo); vkCmdBindPipeline(computeCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelines.compute); vkCmdBindDescriptorSets(computeCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout, 0, 1, &computeDescriptorSet, 0, 0); vkCmdDispatch(computeCmdBuffer, PARTICLE_COUNT / 16, 1, 1); vkEndCommandBuffer(computeCmdBuffer); }
void Renderer::_EndSingleTimeCommands(VkCommandPool pool, VkCommandBuffer commandBuffer) { ErrorCheck(vkEndCommandBuffer(commandBuffer)); VkSubmitInfo submit_info {}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &commandBuffer; ErrorCheck(vkQueueSubmit(_queue, 1, &submit_info, VK_NULL_HANDLE)); ErrorCheck(vkQueueWaitIdle(_queue)); vkFreeCommandBuffers(_device, pool, 1, &commandBuffer); }
void VkApp::endSingleTimeCommands(VkCommandBuffer commandBuffer){ vkEndCommandBuffer(commandBuffer); VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffer; vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); vkQueueWaitIdle(graphicsQueue); vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer); }
/*! * \brief Finishes initializing all previously recorded objects * * Submits internal vulkan command buffer */ bool rSceneBase::endInitObject() { if ( !vInitializingObjects ) { eLOG( "beginInitObject was NOT called on secene ", vName_str ); return false; } vkEndCommandBuffer( vInitBuff_vk ); VkSubmitInfo lInfo = {}; lInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; lInfo.pNext = nullptr; lInfo.waitSemaphoreCount = 0; lInfo.pWaitSemaphores = nullptr; lInfo.pWaitDstStageMask = nullptr; lInfo.commandBufferCount = 1; lInfo.pCommandBuffers = &vInitBuff_vk; lInfo.signalSemaphoreCount = 0; lInfo.pSignalSemaphores = nullptr; auto lFence = vWorldPtr->createFence(); VkResult lRes; { std::lock_guard<std::mutex> lLock( vWorldPtr->getInitPtr()->getQueueMutex( vInitQueue_vk ) ); lRes = vkQueueSubmit( vInitQueue_vk, 1, &lInfo, lFence ); } if ( lRes ) { eLOG( "'vkQueueSubmit' returned ", uEnum2Str::toStr( lRes ) ); vInitObjs.clear(); vObjectsInit_MUT.unlock(); return false; } lRes = vkWaitForFences( vWorldPtr->getDevice(), 1, &lFence, VK_TRUE, UINT64_MAX ); if ( lRes ) { eLOG( "'vkQueueSubmit' returned ", uEnum2Str::toStr( lRes ) ); } for ( auto &i : vInitObjs ) i->finishData(); vkDestroyFence( vWorldPtr->getDevice(), lFence, nullptr ); vkFreeCommandBuffers( vWorldPtr->getDevice(), vInitPool_vk, 1, &vInitBuff_vk ); vInitObjs.clear(); vInitializingObjects = false; vObjectsInit_MUT.unlock(); return true; }
void VulkanRenderManager::StopThread() { if (useThread_ && run_) { run_ = false; // Stop the thread. for (int i = 0; i < vulkan_->GetInflightFrames(); i++) { auto &frameData = frameData_[i]; { std::unique_lock<std::mutex> lock(frameData.push_mutex); frameData.push_condVar.notify_all(); } { std::unique_lock<std::mutex> lock(frameData.pull_mutex); frameData.pull_condVar.notify_all(); } } thread_.join(); ILOG("Vulkan submission thread joined. Frame=%d", vulkan_->GetCurFrame()); // Eat whatever has been queued up for this frame if anything. Wipe(); // Wait for any fences to finish and be resignaled, so we don't have sync issues. // Also clean out any queued data, which might refer to things that might not be valid // when we restart... for (int i = 0; i < vulkan_->GetInflightFrames(); i++) { auto &frameData = frameData_[i]; _assert_(!frameData.readyForRun); _assert_(frameData.steps.empty()); if (frameData.hasInitCommands) { // Clear 'em out. This can happen on restart sometimes. vkEndCommandBuffer(frameData.initCmd); frameData.hasInitCommands = false; } frameData.readyForRun = false; for (size_t i = 0; i < frameData.steps.size(); i++) { delete frameData.steps[i]; } frameData.steps.clear(); std::unique_lock<std::mutex> lock(frameData.push_mutex); while (!frameData.readyForFence) { VLOG("PUSH: Waiting for frame[%d].readyForFence = 1 (stop)", i); frameData.push_condVar.wait(lock); } } } else { ILOG("Vulkan submission thread was already stopped."); } }
void flush_command_buffer() { VkResult err; if (_vulkan_command_buffer == VK_NULL_HANDLE) { return; } err = vkEndCommandBuffer(_vulkan_command_buffer); assert(!err); const VkCommandBuffer command_buffers[] = { _vulkan_command_buffer }; VkFence nullFence = VK_NULL_HANDLE; /* typedef struct VkSubmitInfo { VkStructureType sType; const void* pNext; uint32_t waitSemaphoreCount; const VkSemaphore* pWaitSemaphores; const VkPipelineStageFlags* pWaitDstStageMask; uint32_t commandBufferCount; const VkCommandBuffer* pCommandBuffers; uint32_t signalSemaphoreCount; const VkSemaphore* pSignalSemaphores; } VkSubmitInfo; */ VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO, NULL, 0, NULL, NULL, 1, command_buffers, 0, NULL }; err = vkQueueSubmit(_vulkan_queue, 1, &submit_info, nullFence); assert(!err); err = vkQueueWaitIdle(_vulkan_queue); assert(!err); vkFreeCommandBuffers(_vulkan_device, _vulkan_command_pool, 1, command_buffers); _vulkan_command_buffer = VK_NULL_HANDLE; }
void RHI_CommandList::End() { if (!m_is_recording) return; vkCmdEndRenderPass(CMD_BUFFER_VK); auto result = vkEndCommandBuffer(CMD_BUFFER_VK); if (result != VK_SUCCESS) { LOGF_ERROR("Failed to end command buffer, %s.", Vulkan_Common::result_to_string(result)); return; } m_is_recording = false; }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; clearValues[0].color = { { 1.0f, 1.0f, 1.0f, 1.0f } }; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { renderPassBeginInfo.framebuffer = frameBuffers[i]; VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); const VkDeviceSize offsets[1] = { 0 }; vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &scene.vertices.buffer, offsets); vkCmdBindIndexBuffer(drawCmdBuffers[i], scene.indices.buffer, 0, VK_INDEX_TYPE_UINT32); for (auto node : scene.nodes) { renderNode(node, drawCmdBuffers[i]); } drawUI(drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]); VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } }
void CommandBufferManager::SubmitCommandBuffer(bool submit_on_worker_thread, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkSwapchainKHR present_swap_chain, uint32_t present_image_index) { FrameResources& resources = m_frame_resources[m_current_frame]; // Fire fence tracking callbacks. This can't happen on the worker thread. // We invoke these before submitting so that any last-minute commands can be added. for (const auto& iter : m_fence_point_callbacks) iter.second.first(resources.command_buffers[1], resources.fence); // End the current command buffer. for (VkCommandBuffer command_buffer : resources.command_buffers) { VkResult res = vkEndCommandBuffer(command_buffer); if (res != VK_SUCCESS) { LOG_VULKAN_ERROR(res, "vkEndCommandBuffer failed: "); PanicAlert("Failed to end command buffer"); } } // This command buffer now has commands, so can't be re-used without waiting. resources.needs_fence_wait = true; // Submitting off-thread? if (m_use_threaded_submission && submit_on_worker_thread) { // Push to the pending submit queue. { std::lock_guard<std::mutex> guard(m_pending_submit_lock); m_pending_submits.push_back({m_current_frame, wait_semaphore, signal_semaphore, present_swap_chain, present_image_index}); } // Wake up the worker thread for a single iteration. m_submit_loop->Wakeup(); } else { // Pass through to normal submission path. SubmitCommandBuffer(m_current_frame, wait_semaphore, signal_semaphore, present_swap_chain, present_image_index); } }
void vkeGameRendererDynamic::initTerrainCommand(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = dc->getDefaultQueue(); uint32_t cmdID = 1021; VkResult rslt; for (uint32_t i = 0; i < 2; ++i){ if (m_terrain_command[i] != VK_NULL_HANDLE){ vkFreeCommandBuffers(device->getVKDevice(), queue->getCommandPool(), 1, &m_terrain_command[i]); m_terrain_command[i] = VK_NULL_HANDLE; } { VkCommandBufferAllocateInfo cmdBufInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmdBufInfo.commandBufferCount = 1; cmdBufInfo.commandPool = queue->getCommandPool(); cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; rslt = vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, &m_terrain_command[i]); VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; rslt = vkBeginCommandBuffer(m_terrain_command[i], &cmdBeginInfo); vkCmdBindPipeline(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_quad_pipeline); vkCmdBindDescriptorSets(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_quad_pipeline_layout, 0, 1, &m_quad_descriptor_set, 0, NULL); m_screen_quad.bind(&m_terrain_command[i]); m_screen_quad.draw(&m_terrain_command[i]); vkCmdBindPipeline(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_terrain_pipeline); vkCmdBindDescriptorSets(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_terrain_pipeline_layout, 0, 1, &m_terrain_descriptor_set, 0, NULL); m_terrain_quad.bind(&m_terrain_command[i]); m_terrain_quad.draw(&m_terrain_command[i]);/**/ vkEndCommandBuffer(m_terrain_command[i]); } } }
void CommandBufferManager::SubmitCommandBuffer(bool submit_on_worker_thread, bool wait_for_completion, VkSwapchainKHR present_swap_chain, uint32_t present_image_index) { // End the current command buffer. FrameResources& resources = m_frame_resources[m_current_frame]; for (VkCommandBuffer command_buffer : resources.command_buffers) { VkResult res = vkEndCommandBuffer(command_buffer); if (res != VK_SUCCESS) { LOG_VULKAN_ERROR(res, "vkEndCommandBuffer failed: "); PanicAlert("Failed to end command buffer"); } } // Grab the semaphore before submitting command buffer either on-thread or off-thread. // This prevents a race from occurring where a second command buffer is executed // before the worker thread has woken and executed the first one yet. m_submit_semaphore.Wait(); // Submitting off-thread? if (m_use_threaded_submission && submit_on_worker_thread && !wait_for_completion) { // Push to the pending submit queue. { std::lock_guard<std::mutex> guard(m_pending_submit_lock); m_pending_submits.push_back({present_swap_chain, present_image_index, m_current_frame}); } // Wake up the worker thread for a single iteration. m_submit_loop->Wakeup(); } else { // Pass through to normal submission path. SubmitCommandBuffer(m_current_frame, present_swap_chain, present_image_index); if (wait_for_completion) WaitForCommandBufferCompletion(m_current_frame); } // Switch to next cmdbuffer. BeginCommandBuffer(); }
void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VkClearValue clearValues[3]; // Clear to a white background for higher contrast clearValues[0].color = { { 1.0f, 1.0f, 1.0f, 1.0f } }; clearValues[1].color = { { 1.0f, 1.0f, 1.0f, 1.0f } }; clearValues[2].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.extent.width = width; renderPassBeginInfo.renderArea.extent.height = height; renderPassBeginInfo.clearValueCount = 3; renderPassBeginInfo.pClearValues = clearValues; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, useSampleShading ? pipelines.MSAASampleShading : pipelines.MSAA); VkDeviceSize offsets[1] = { 0 }; vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &models.example.vertices.buffer, offsets); vkCmdBindIndexBuffer(drawCmdBuffers[i], models.example.indices.buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdDrawIndexed(drawCmdBuffers[i], models.example.indexCount, 1, 0, 0, 0); vkCmdEndRenderPass(drawCmdBuffers[i]); VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } }
void VkHelper::endSingleTimeCommandBuffer(VkDevice device, VkCommandPool cmdPool, VkQueue queue, VkCommandBuffer cmdBuffer) { if (vkEndCommandBuffer(cmdBuffer) != VK_SUCCESS) std::runtime_error("ERROR: Command buffer end failed."); VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.pNext = VK_NULL_HANDLE; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuffer; if (vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) std::runtime_error("ERROR: Submission to the queue failed."); vkQueueWaitIdle(queue); vkFreeCommandBuffers(device, cmdPool, 1, &cmdBuffer); }