diff --git a/renderdoc/driver/vulkan/imgrefs_tests.cpp b/renderdoc/driver/vulkan/imgrefs_tests.cpp index b081506d4..54165f1cb 100644 --- a/renderdoc/driver/vulkan/imgrefs_tests.cpp +++ b/renderdoc/driver/vulkan/imgrefs_tests.cpp @@ -38,49 +38,51 @@ TEST_CASE("Test ImgRefs type", "[imgrefs]") SECTION("unsplit") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 0); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == 0); }; SECTION("split aspect") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(true, false, false); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 1); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == 1); }; SECTION("split levels") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(false, true, false); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 2); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == 2); }; SECTION("split layers") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(false, false, true); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 5); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == 5); }; SECTION("split aspect and levels") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(true, true, false); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 11 + 2); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == 11 + 2); }; SECTION("split aspect and layers") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(true, false, true); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 17 + 5); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == 17 + 5); }; SECTION("split levels and layers") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(false, true, true); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 2 * 17 + 5); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == + 2 * 17 + 5); }; SECTION("split aspect and levels and layers") { ImgRefs imgRefs(ImageInfo(VK_FORMAT_D16_UNORM_S8_UINT, {100, 100, 1}, 11, 17, 1)); imgRefs.Split(true, true, true); - CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 11 * 17 + 2 * 17 + 5); + CHECK(imgRefs.SubresourceIndex(imgRefs.AspectIndex(VK_IMAGE_ASPECT_STENCIL_BIT), 2, 5) == + 11 * 17 + 2 * 17 + 5); }; SECTION("update unsplit") { diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index cbc55156d..7f43a1760 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -1375,6 +1375,19 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + ResourceId orig = GetResourceManager()->GetOriginalID(id); + ImgRefs *imgRefs = NULL; + bool initialized = false; + if(GetResourceManager()->OptimizeInitialState()) + { + imgRefs = GetResourceManager()->FindImgRefs(orig); + if(imgRefs) + { + initialized = imgRefs->initializedLiveRes == live; + imgRefs->initializedLiveRes = live; + } + } + if(initial.tag == VkInitialContents::Sparse) { Apply_SparseInitialState((WrappedVkImage *)live, initial); @@ -1882,6 +1895,24 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten SubmitAndFlushExtQueue(dstimBarrier.srcQueueFamilyIndex); } + std::vector copyRegions; + std::vector clearRegions; + +#define INIT_REGION() \ + if(!initialized) \ + { \ + copyRegions.push_back(region); \ + } \ + else \ + { \ + InitReqType initReq = imgRefs->SubresourceInitReq( \ + imgRefs->AspectIndex((VkImageAspectFlagBits)region.imageSubresource.aspectMask), m, a); \ + if(initReq == eInitReq_Reset) \ + copyRegions.push_back(region); \ + else if(initReq == eInitReq_Clear) \ + clearRegions.push_back(ImageRange(region.imageSubresource)); \ + } + // copy each slice/mip individually for(int a = 0; a < m_CreationInfo.m_Image[id].arrayLayers; a++) { @@ -1919,8 +1950,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten bufOffset += GetPlaneByteSize(extent.width, extent.height, extent.depth, fmt, 0, i); - ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle(live), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + INIT_REGION(); } } else @@ -1934,8 +1964,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten // pass 0 for mip since we've already pre-downscaled extent bufOffset += GetByteSize(extent.width, extent.height, extent.depth, sizeFormat, 0); - ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle(live), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + INIT_REGION(); if(sizeFormat != fmt) { @@ -1947,8 +1976,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten bufOffset += GetByteSize(extent.width, extent.height, extent.depth, VK_FORMAT_S8_UINT, 0); - ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle(live), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + INIT_REGION(); } } @@ -1959,6 +1987,32 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten } } +#undef INIT_REGION + + if(copyRegions.size() > 0) + ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle(live), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (uint32_t)copyRegions.size(), copyRegions.data()); + + if(clearRegions.size() > 0) + { + if(IsDepthOrStencilFormat(fmt)) + { + VkClearDepthStencilValue val = {0, 0}; + ObjDisp(cmd)->CmdClearDepthStencilImage(Unwrap(cmd), ToHandle(live), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &val, + (uint32_t)clearRegions.size(), clearRegions.data()); + } + else + { + VkClearColorValue val; + memset(&val, 0, sizeof(val)); + ObjDisp(cmd)->CmdClearColorImage(Unwrap(cmd), ToHandle(live), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &val, + (uint32_t)clearRegions.size(), clearRegions.data()); + } + } + // update the live image layout back dstimBarrier.oldLayout = dstimBarrier.newLayout; diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index 74e1fc260..d765cc5d3 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -2930,7 +2930,7 @@ int ImgRefs::GetAspectCount() const return aspectCount; } -int ImgRefs::SubresourceIndex(VkImageAspectFlagBits aspect, int level, int layer) const +int ImgRefs::AspectIndex(VkImageAspectFlagBits aspect) const { int aspectIndex = 0; if(areAspectsSplit) @@ -2943,7 +2943,7 @@ int ImgRefs::SubresourceIndex(VkImageAspectFlagBits aspect, int level, int layer ++aspectIndex; } } - return SubresourceIndex(aspectIndex, level, layer); + return aspectIndex; } int ImgRefs::SubresourceIndex(int aspectIndex, int level, int layer) const diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 1adcfcc34..c1692829c 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -1078,6 +1078,20 @@ struct ImageRange layerCount(range.layerCount) { } + ImageRange(const VkBufferImageCopy &range) + : aspectMask(range.imageSubresource.aspectMask), + baseMipLevel(range.imageSubresource.mipLevel), + levelCount(1), + baseArrayLayer(range.imageSubresource.baseArrayLayer), + layerCount(range.imageSubresource.layerCount), + offset(range.imageOffset), + extent(range.imageExtent) + { + } + inline operator VkImageSubresourceRange() const + { + return {aspectMask, baseMipLevel, levelCount, baseArrayLayer, layerCount}; + } VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM; uint32_t baseMipLevel = 0; uint32_t levelCount = VK_REMAINING_MIP_LEVELS; @@ -1115,16 +1129,20 @@ struct ImgRefs // Depth slices of 3D views are treated as array layers this->imageInfo.layerCount = imageInfo.extent.depth; } - int SubresourceIndex(VkImageAspectFlagBits aspect, int level, int layer) const; + int AspectIndex(VkImageAspectFlagBits aspect) const; int SubresourceIndex(int aspectIndex, int level, int layer) const; - inline FrameRefType SubresourceRef(VkImageAspectFlagBits aspect, int level, int layer) const - { - return rangeRefs[SubresourceIndex(aspect, level, layer)]; - } inline FrameRefType SubresourceRef(int aspectIndex, int level, int layer) const { return rangeRefs[SubresourceIndex(aspectIndex, level, layer)]; } + inline InitReqType SubresourceInitReq(int aspectIndex, int level, int layer) const + { + return InitReq(SubresourceRef(aspectIndex, level, layer)); + } + inline InitReqType SubresourceInitReq(int aspectIndex, int level, int layer, bool initialized) const + { + return InitReq(SubresourceRef(aspectIndex, level, layer)); + } void Split(bool splitAspects, bool splitLevels, bool splitLayers); template FrameRefType Update(ImageRange range, FrameRefType refType, Compose comp);