From 44a6a8164104dd7d8f6655beac8e09bfadbc1431 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 31 Mar 2024 17:56:36 -0300 Subject: [PATCH] vulkan: improve depth/stencil texture support. --- src/modules/graphics/vulkan/Graphics.cpp | 33 ++++++++++------ src/modules/graphics/vulkan/Graphics.h | 2 +- src/modules/graphics/vulkan/Texture.cpp | 50 +++++++++++------------- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 4ab2d3b71..b28ed9c40 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1884,15 +1884,15 @@ VkSurfaceFormatKHR Graphics::chooseSwapSurfaceFormat(const std::vector> transitionImages; + std::vector> transitionImages; for (const auto &color : rts.colors) { - configuration.colorViews.push_back(dynamic_cast(color.texture)->getRenderTargetView(color.mipmap, color.slice)); - transitionImages.push_back({ (VkImage)color.texture->getHandle(), color.texture->getPixelFormat() }); + auto tex = (Texture*)color.texture; + configuration.colorViews.push_back(tex->getRenderTargetView(color.mipmap, color.slice)); + VkImageLayout imagelayout = tex->getImageLayout(); + if (imagelayout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + transitionImages.push_back({ (VkImage)tex->getHandle(), tex->getPixelFormat(), imagelayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }); } if (rts.depthStencil.texture != nullptr) - configuration.staticData.depthView = dynamic_cast(rts.depthStencil.texture)->getRenderTargetView(rts.depthStencil.mipmap, rts.depthStencil.slice); + { + auto tex = (Texture*)rts.depthStencil.texture; + configuration.staticData.depthView = tex->getRenderTargetView(rts.depthStencil.mipmap, rts.depthStencil.slice); + VkImageLayout imagelayout = tex->getImageLayout(); + if (imagelayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) + transitionImages.push_back({ (VkImage)tex->getHandle(), tex->getPixelFormat(), imagelayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }); + } configuration.staticData.width = static_cast(pixelw); configuration.staticData.height = static_cast(pixelh); @@ -2450,8 +2459,8 @@ void Graphics::startRenderPass() renderPassState.framebufferConfiguration.staticData.renderPass = renderPassState.beginInfo.renderPass; renderPassState.beginInfo.framebuffer = getFramebuffer(renderPassState.framebufferConfiguration); - for (const auto &[image, format] : renderPassState.transitionImages) - Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, format, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + for (const auto &[image, format, imageLayout, renderLayout] : renderPassState.transitionImages) + Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, format, imageLayout, renderLayout); vkCmdBeginRenderPass(commandBuffers.at(currentFrame), &renderPassState.beginInfo, VK_SUBPASS_CONTENTS_INLINE); } @@ -2462,8 +2471,8 @@ void Graphics::endRenderPass() vkCmdEndRenderPass(commandBuffers.at(currentFrame)); - for (const auto &[image, format] : renderPassState.transitionImages) - Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, format, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + for (const auto &[image, format, imageLayout, renderLayout] : renderPassState.transitionImages) + Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, format, renderLayout, imageLayout); for (auto &colorAttachment : renderPassState.renderPassConfiguration.colorAttachments) colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 2e77b4ea7..df8f80b24 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -236,7 +236,7 @@ struct RenderpassState RenderPassConfiguration renderPassConfiguration{}; FramebufferConfiguration framebufferConfiguration{}; VkPipeline pipeline = VK_NULL_HANDLE; - std::vector> transitionImages; + std::vector> transitionImages; uint32_t numColorAttachments = 0; float width = 0.0f; float height = 0.0f; diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index e5241fe7f..693bf38ca 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -151,12 +151,16 @@ bool Texture::loadVolatile() auto commandBuffer = vgfx->getCommandBufferForDataTransfer(); - if (isPixelFormatDepthStencil(format)) - imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - else if (computeWrite) + if (computeWrite) imageLayout = VK_IMAGE_LAYOUT_GENERAL; - else + else if (readable) imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + else if (renderTarget && isPixelFormatDepthStencil(format)) + imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + else if (renderTarget) + imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + else // TODO: is there a better layout for this situation? + imageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, format, VK_IMAGE_LAYOUT_UNDEFINED, imageLayout, @@ -383,40 +387,32 @@ void Texture::clear() range.baseArrayLayer = 0; range.layerCount = VK_REMAINING_ARRAY_LAYERS; - if (imageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + VkImageLayout clearLayout = imageLayout == VK_IMAGE_LAYOUT_GENERAL ? imageLayout : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + if (clearLayout != imageLayout) { Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, format, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS); - - auto clearColor = getClearColor(this, ColorD(0, 0, 0, 0)); - - vkCmdClearColorImage(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range); - - Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, format, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + imageLayout, clearLayout, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS); } - else if (imageLayout == VK_IMAGE_LAYOUT_GENERAL) - { - auto clearColor = getClearColor(this, ColorD(0, 0, 0, 0)); - vkCmdClearColorImage(commandBuffer, textureImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &range); - } - else + if (isPixelFormatDepthStencil(format)) { - Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, format, - imageLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS); - VkClearDepthStencilValue depthStencilColor{}; depthStencilColor.depth = 0.0f; depthStencilColor.stencil = 0; + vkCmdClearDepthStencilImage(commandBuffer, textureImage, clearLayout, &depthStencilColor, 1, &range); + } + else + { + auto clearColor = getClearColor(this, ColorD(0, 0, 0, 0)); + vkCmdClearColorImage(commandBuffer, textureImage, clearLayout, &clearColor, 1, &range); + } - vkCmdClearDepthStencilImage(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilColor, 1, &range); - + if (clearLayout != imageLayout) + { Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, format, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout, + clearLayout, imageLayout, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS); } }