From 390ae40e83cc78ba2ef5ff6f040310eb7fb6e139 Mon Sep 17 00:00:00 2001 From: niki Date: Thu, 11 Aug 2022 16:11:06 +0200 Subject: [PATCH] vulkan: cut down on number of cmd buffers Until now we've used a command buffer for every swap chain image, however it makes more sense to just have a command buffer for every frame in flight, since we won't be ever recording more than that. This makes it more in line with the data transfer command buffers, which are also just created per frame in flight. This should make more sense. --- src/modules/graphics/vulkan/Graphics.cpp | 48 ++++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index bff4881ac..ce73fd059 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -103,7 +103,7 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d rect.rect.extent.width = static_cast(currentViewportWidth); rect.rect.extent.height = static_cast(currentViewportHeight); - vkCmdClearAttachments(commandBuffers[imageIndex], 1, &attachment, 1, &rect); + vkCmdClearAttachments(commandBuffers[currentFrame], 1, &attachment, 1, &rect); } void Graphics::clear(const std::vector& colors, OptionalInt stencil, OptionalDouble depth) { @@ -125,7 +125,7 @@ void Graphics::clear(const std::vector& colors, OptionalInt sten rect.rect.extent.width = static_cast(currentViewportWidth); rect.rect.extent.height = static_cast(currentViewportHeight); - vkCmdClearAttachments(commandBuffers[imageIndex], static_cast(attachments.size()), attachments.data(), 1, &rect); + vkCmdClearAttachments(commandBuffers[currentFrame], static_cast(attachments.size()), attachments.data(), 1, &rect); } void Graphics::present(void* screenshotCallbackdata) { @@ -143,7 +143,7 @@ void Graphics::present(void* screenshotCallbackdata) { imagesInFlight[imageIndex] = inFlightFences[currentFrame]; // all data transfers should happen before any draw calls. - std::vector submitCommandbuffers = { dataTransferCommandBuffers.at(currentFrame), commandBuffers.at(imageIndex) }; + std::vector submitCommandbuffers = { dataTransferCommandBuffers.at(currentFrame), commandBuffers.at(currentFrame) }; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -374,14 +374,14 @@ Graphics::RendererInfo Graphics::getRendererInfo() const { void Graphics::draw(const DrawCommand& cmd) { prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode); - vkCmdDraw(commandBuffers.at(imageIndex), static_cast(cmd.vertexCount), static_cast(cmd.instanceCount), static_cast(cmd.vertexStart), 0); + vkCmdDraw(commandBuffers.at(currentFrame), static_cast(cmd.vertexCount), static_cast(cmd.instanceCount), static_cast(cmd.vertexStart), 0); } void Graphics::draw(const DrawIndexedCommand& cmd) { prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode); - vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType)); - vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(cmd.indexCount), static_cast(cmd.instanceCount), 0, 0, 0); + vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType)); + vkCmdDrawIndexed(commandBuffers.at(currentFrame), static_cast(cmd.indexCount), static_cast(cmd.instanceCount), 0, 0, 0); } void Graphics::drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) { @@ -390,14 +390,14 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes& attribute prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES, CULL_BACK); - vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16)); + vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16)); int baseVertex = start * 4; for (int quadindex = 0; quadindex < count; quadindex += MAX_QUADS_PER_DRAW) { int quadcount = std::min(MAX_QUADS_PER_DRAW, count - quadindex); - vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(quadcount * 6), 1, 0, baseVertex, 0); + vkCmdDrawIndexed(commandBuffers.at(currentFrame), static_cast(quadcount * 6), 1, 0, baseVertex, 0); baseVertex += quadcount * 4; } } @@ -503,14 +503,14 @@ void Graphics::startRecordingGraphicsCommands() { beginInfo.flags = 0; beginInfo.pInheritanceInfo = nullptr; - if (vkBeginCommandBuffer(commandBuffers.at(imageIndex), &beginInfo) != VK_SUCCESS) { + if (vkBeginCommandBuffer(commandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS) { throw love::Exception("failed to begin recording command buffer"); } if (vkBeginCommandBuffer(dataTransferCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS) { throw love::Exception("failed to begin recording data transfer command buffer"); } - Vulkan::cmdTransitionImageLayout(commandBuffers.at(imageIndex), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); startRenderPass(nullptr, swapChainExtent.width, swapChainExtent.height); @@ -520,9 +520,9 @@ void Graphics::startRecordingGraphicsCommands() { void Graphics::endRecordingGraphicsCommands() { endRenderPass(); - Vulkan::cmdTransitionImageLayout(commandBuffers.at(imageIndex), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); - if (vkEndCommandBuffer(commandBuffers.at(imageIndex)) != VK_SUCCESS) { + if (vkEndCommandBuffer(commandBuffers.at(currentFrame)) != VK_SUCCESS) { throw love::Exception("failed to record command buffer"); } if (vkEndCommandBuffer(dataTransferCommandBuffers.at(currentFrame)) != VK_SUCCESS) { @@ -1175,8 +1175,8 @@ void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindi ensureGraphicsPipelineConfiguration(configuration); - configuration.shader->cmdPushDescriptorSets(commandBuffers.at(imageIndex), static_cast(currentFrame)); - vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, static_cast(bufferVector.size()), bufferVector.data(), offsets.data()); + configuration.shader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), static_cast(currentFrame)); + vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast(bufferVector.size()), bufferVector.data(), offsets.data()); } void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) { @@ -1210,19 +1210,19 @@ void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) { currentViewportHeight = (float)h; if (renderTargetTexture) { - Vulkan::cmdTransitionImageLayout(commandBuffers.at(imageIndex), (VkImage)texture->getHandle(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), (VkImage)texture->getHandle(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } - vkCmdBeginRendering(commandBuffers.at(imageIndex), &renderingInfo); + vkCmdBeginRendering(commandBuffers.at(currentFrame), &renderingInfo); currentGraphicsPipeline = VK_NULL_HANDLE; } void Graphics::endRenderPass() { - vkCmdEndRendering(commandBuffers.at(imageIndex)); + vkCmdEndRendering(commandBuffers.at(currentFrame)); if (renderTargetTexture) { - Vulkan::cmdTransitionImageLayout(commandBuffers.at(imageIndex), (VkImage)renderTargetTexture->getHandle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), (VkImage)renderTargetTexture->getHandle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); renderTargetTexture = nullptr; } } @@ -1239,7 +1239,7 @@ VkSampler Graphics::createSampler(const SamplerState& samplerState) { samplerInfo.addressModeV = Vulkan::getWrapMode(samplerState.wrapV); samplerInfo.addressModeW = Vulkan::getWrapMode(samplerState.wrapW); samplerInfo.anisotropyEnable = VK_TRUE; - samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy; // fixme: samplerState.maxAnisotropy + samplerInfo.maxAnisotropy = static_cast(samplerState.maxAnisotropy); samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; samplerInfo.unnormalizedCoordinates = VK_FALSE; if (samplerState.depthSampleMode.hasValue) { @@ -1399,13 +1399,13 @@ void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration auto it = graphicsPipelines.find(configuration); if (it != graphicsPipelines.end()) { if (it->second != currentGraphicsPipeline) { - vkCmdBindPipeline(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second); + vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second); currentGraphicsPipeline = it->second; } } else { VkPipeline pipeline = createGraphicsPipeline(configuration); graphicsPipelines.insert({configuration, pipeline}); - vkCmdBindPipeline(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); currentGraphicsPipeline = pipeline; } } @@ -1424,14 +1424,14 @@ void Graphics::createCommandPool() { } void Graphics::createCommandBuffers() { - commandBuffers.resize(swapChainImages.size()); + commandBuffers.resize(MAX_FRAMES_IN_FLIGHT); dataTransferCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT); VkCommandBufferAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.commandPool = commandPool; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandBufferCount = (uint32_t)commandBuffers.size(); + allocInfo.commandBufferCount = (uint32_t)MAX_FRAMES_IN_FLIGHT; if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) { throw love::Exception("failed to allocate command buffers"); @@ -1498,7 +1498,7 @@ void Graphics::cleanup() { vkDestroyFence(device, inFlightFences[i], nullptr); } - vkFreeCommandBuffers(device, commandPool, static_cast(commandBuffers.size()), commandBuffers.data()); + vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, commandBuffers.data()); vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, dataTransferCommandBuffers.data()); for (auto const& p : samplers) {