From b02dbdc1b525b3c1f16d7d8111acb405e2b23e1c Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Feb 2025 18:31:58 +0000 Subject: [PATCH] Add RP normalisation option --- renderdoc/driver/vulkan/vk_core.h | 2 + renderdoc/driver/vulkan/vk_debug.cpp | 3 +- .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 241 ++++++++++++------ .../driver/vulkan/wrappers/vk_misc_funcs.cpp | 110 +++++--- 4 files changed, 229 insertions(+), 127 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 772e4eca6..745f477a8 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -1051,6 +1051,8 @@ private: void AddImplicitResolveResourceUsage(uint32_t subpass = 0); rdcarray GetImplicitRenderPassBarriers(uint32_t subpass = 0); rdcstr MakeRenderPassOpString(bool store); + void ApplyRPStoreDiscards(VkCommandBuffer commandBuffer, VkRect2D renderArea, + ResourceId currentRP, const rdcarray &attachments); void ApplyRPLoadDiscards(VkCommandBuffer commandBuffer, VkRect2D renderArea); RDCDriver GetFrameCaptureDriver() { return RDCDriver::Vulkan; } diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 2836b7605..42eb4c034 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -2376,7 +2376,8 @@ void VulkanDebugManager::FillWithDiscardPattern(VkCommandBuffer cmd, DiscardType : (VkAccessFlags)VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dstimBarrier.dstAccessMask = VK_ACCESS_ALL_WRITE_BITS | VK_ACCESS_ALL_READ_BITS; - DoPipelineBarrier(cmd, 1, &dstimBarrier); + if(curLayout != VK_IMAGE_LAYOUT_UNDEFINED) + DoPipelineBarrier(cmd, 1, &dstimBarrier); m_pDriver->GetCmdRenderState().BindPipeline(m_pDriver, cmd, VulkanRenderState::BindInitial, false); diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index e779ebeb7..c0a05d725 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -30,6 +30,7 @@ RDOC_DEBUG_CONFIG( bool, Vulkan_Debug_VerboseCommandRecording, false, "Add verbose logging around recording and submission of command buffers in vulkan."); +RDOC_EXTERN_CONFIG(bool, Vulkan_Hack_DisableRPRobustness); static rdcstr ToHumanStr(const VkAttachmentLoadOp &el) { @@ -768,6 +769,64 @@ void WrappedVulkan::ApplyRPLoadDiscards(VkCommandBuffer commandBuffer, VkRect2D } } +void WrappedVulkan::ApplyRPStoreDiscards(VkCommandBuffer commandBuffer, VkRect2D renderArea, + ResourceId currentRP, + const rdcarray &attachments) +{ + const VulkanCreationInfo::RenderPass &rpinfo = m_CreationInfo.m_RenderPass[currentRP]; + + for(size_t i = 0; i < attachments.size(); i++) + { + if(!rpinfo.attachments[i].used) + continue; + + const VulkanCreationInfo::ImageView &viewInfo = m_CreationInfo.m_ImageView[attachments[i]]; + VkImage image = GetResourceManager()->GetCurrentHandle(viewInfo.image); + + VkImageLayout layout = rpinfo.attachments[i].finalLayout; + + if(Vulkan_Hack_DisableRPRobustness()) + layout = VK_IMAGE_LAYOUT_UNDEFINED; + + if(IsStencilFormat(viewInfo.format)) + { + // check to see if stencil and depth store ops are different and apply them + // individually here + const bool depthDontCareStore = + (rpinfo.attachments[i].storeOp == VK_ATTACHMENT_STORE_OP_DONT_CARE); + const bool stencilDontCareStore = + (rpinfo.attachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_DONT_CARE); + + // if they're both don't care then we can do a simple discard clear + if(depthDontCareStore && stencilDontCareStore) + { + GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, + image, layout, viewInfo.range, renderArea); + } + else + { + // otherwise only don't care the appropriate aspects + VkImageSubresourceRange range = viewInfo.range; + + range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + if(depthDontCareStore && (viewInfo.range.aspectMask & range.aspectMask) != 0) + GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, + image, layout, range, renderArea); + + range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + if(stencilDontCareStore && (viewInfo.range.aspectMask & range.aspectMask) != 0) + GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, + image, layout, range, renderArea); + } + } + else if(rpinfo.attachments[i].storeOp == VK_ATTACHMENT_STORE_OP_DONT_CARE) + { + GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, image, + layout, viewInfo.range, renderArea); + } + } +} + // Command pool functions template @@ -2274,58 +2333,7 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandB if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest && !m_FeedbackRPs.contains(currentRP)) { - const VulkanCreationInfo::RenderPass &rpinfo = m_CreationInfo.m_RenderPass[currentRP]; - - for(size_t i = 0; i < attachments.size(); i++) - { - if(!rpinfo.attachments[i].used) - continue; - - const VulkanCreationInfo::ImageView &viewInfo = - m_CreationInfo.m_ImageView[attachments[i]]; - VkImage image = GetResourceManager()->GetCurrentHandle(viewInfo.image); - - if(IsStencilFormat(viewInfo.format)) - { - // check to see if stencil and depth store ops are different and apply them - // individually here - const bool depthDontCareStore = - (rpinfo.attachments[i].storeOp == VK_ATTACHMENT_STORE_OP_DONT_CARE); - const bool stencilDontCareStore = - (rpinfo.attachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_DONT_CARE); - - // if they're both don't care then we can do a simple discard clear - if(depthDontCareStore && stencilDontCareStore) - { - GetDebugManager()->FillWithDiscardPattern( - commandBuffer, DiscardType::RenderPassStore, image, - rpinfo.attachments[i].finalLayout, viewInfo.range, renderArea); - } - else - { - // otherwise only don't care the appropriate aspects - VkImageSubresourceRange range = viewInfo.range; - - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - if(depthDontCareStore && (viewInfo.range.aspectMask & range.aspectMask) != 0) - GetDebugManager()->FillWithDiscardPattern( - commandBuffer, DiscardType::RenderPassStore, image, - rpinfo.attachments[i].finalLayout, range, renderArea); - - range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; - if(stencilDontCareStore && (viewInfo.range.aspectMask & range.aspectMask) != 0) - GetDebugManager()->FillWithDiscardPattern( - commandBuffer, DiscardType::RenderPassStore, image, - rpinfo.attachments[i].finalLayout, range, renderArea); - } - } - else if(rpinfo.attachments[i].storeOp == VK_ATTACHMENT_STORE_OP_DONT_CARE) - { - GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, - image, rpinfo.attachments[i].finalLayout, - viewInfo.range, renderArea); - } - } + ApplyRPStoreDiscards(commandBuffer, renderArea, currentRP, attachments); } GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[m_LastCmdBufferID].imageStates, @@ -2339,6 +2347,14 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandB m_BakedCmdBufferInfo[m_LastCmdBufferID].renderPassOpen = false; m_BakedCmdBufferInfo[m_LastCmdBufferID].endBarriers.append(GetImplicitRenderPassBarriers(~0U)); + + ResourceId currentRP = GetCmdRenderState().GetRenderPass(); + + if(Vulkan_Hack_DisableRPRobustness() && !m_FeedbackRPs.contains(currentRP)) + { + ApplyRPStoreDiscards(commandBuffer, GetCmdRenderState().renderArea, currentRP, + GetCmdRenderState().GetFramebufferAttachments()); + } } } else @@ -2942,7 +2958,6 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand rdcarray attachments; VkRect2D renderArea; - const VulkanCreationInfo::RenderPass &rpinfo = m_CreationInfo.m_RenderPass[currentRP]; { VulkanRenderState &renderstate = GetCmdRenderState(); @@ -2968,20 +2983,7 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest && !m_FeedbackRPs.contains(currentRP)) { - for(size_t i = 0; i < attachments.size(); i++) - { - const VulkanCreationInfo::ImageView &viewInfo = - m_CreationInfo.m_ImageView[attachments[i]]; - VkImage image = GetResourceManager()->GetCurrentHandle(viewInfo.image); - - if(rpinfo.attachments[i].storeOp == VK_ATTACHMENT_STORE_OP_DONT_CARE && - rpinfo.attachments[i].used) - { - GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, - image, rpinfo.attachments[i].finalLayout, - viewInfo.range, renderArea); - } - } + ApplyRPStoreDiscards(commandBuffer, renderArea, currentRP, attachments); } GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[m_LastCmdBufferID].imageStates, @@ -3010,6 +3012,13 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand stateOffsets[i] = fragmentDensityOffsetStruct->pFragmentDensityOffsets[i]; } } + + ResourceId currentRP = GetCmdRenderState().GetRenderPass(); + if(Vulkan_Hack_DisableRPRobustness() && !m_FeedbackRPs.contains(currentRP)) + { + ApplyRPStoreDiscards(commandBuffer, GetCmdRenderState().renderArea, currentRP, + GetCmdRenderState().GetFramebufferAttachments()); + } } } else @@ -7305,24 +7314,36 @@ bool WrappedVulkan::Serialise_vkCmdBeginRendering(SerialiserType &ser, VkCommand // effects of that are never user-visible. if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest) { - for(uint32_t i = 0; i < unwrappedInfo->colorAttachmentCount + 2; i++) + if(Vulkan_Hack_DisableRPRobustness()) { - VkRenderingAttachmentInfo *att = - (VkRenderingAttachmentInfo *)unwrappedInfo->pColorAttachments + i; + static bool warned = false; - if(i == unwrappedInfo->colorAttachmentCount) - att = (VkRenderingAttachmentInfo *)unwrappedInfo->pDepthAttachment; - else if(i == unwrappedInfo->colorAttachmentCount + 1) - att = (VkRenderingAttachmentInfo *)unwrappedInfo->pStencilAttachment; + if(!warned) + RDCWARN("RP attachment normalisation not applied!"); - if(!att) - continue; + warned = true; + } + else + { + for(uint32_t i = 0; i < unwrappedInfo->colorAttachmentCount + 2; i++) + { + VkRenderingAttachmentInfo *att = + (VkRenderingAttachmentInfo *)unwrappedInfo->pColorAttachments + i; - if(att->storeOp != VK_ATTACHMENT_STORE_OP_NONE) - att->storeOp = VK_ATTACHMENT_STORE_OP_STORE; + if(i == unwrappedInfo->colorAttachmentCount) + att = (VkRenderingAttachmentInfo *)unwrappedInfo->pDepthAttachment; + else if(i == unwrappedInfo->colorAttachmentCount + 1) + att = (VkRenderingAttachmentInfo *)unwrappedInfo->pStencilAttachment; - if(att->loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + if(!att) + continue; + + if(att->storeOp != VK_ATTACHMENT_STORE_OP_NONE) + att->storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + if(att->loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) + att->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + } } } @@ -7550,14 +7571,14 @@ bool WrappedVulkan::Serialise_vkCmdEndRendering(SerialiserType &ser, VkCommandBu if(IsActiveReplaying(m_State)) { + VulkanRenderState &renderstate = GetCmdRenderState(); + + bool suspending = (renderstate.dynamicRendering.flags & VK_RENDERING_SUSPENDING_BIT) != 0; + if(InRerecordRange(m_LastCmdBufferID)) { commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); - VulkanRenderState &renderstate = GetCmdRenderState(); - - bool suspending = (renderstate.dynamicRendering.flags & VK_RENDERING_SUSPENDING_BIT) != 0; - if(ShouldUpdateRenderpassActive(m_LastCmdBufferID, true)) { m_BakedCmdBufferInfo[m_LastCmdBufferID].renderPassOpen = false; @@ -7648,6 +7669,58 @@ bool WrappedVulkan::Serialise_vkCmdEndRendering(SerialiserType &ser, VkCommandBu ObjDisp(commandBuffer)->CmdEndRendering(Unwrap(commandBuffer)); m_BakedCmdBufferInfo[m_LastCmdBufferID].renderPassOpen = false; + + // only do discards when not suspending! + if(Vulkan_Hack_DisableRPRobustness() && !suspending) + { + rdcarray dynAtts = renderstate.dynamicRendering.color; + dynAtts.push_back(renderstate.dynamicRendering.depth); + + size_t depthIdx = dynAtts.size() - 1; + size_t stencilIdx = ~0U; + VkImageAspectFlags depthAspects = VK_IMAGE_ASPECT_DEPTH_BIT; + + // if we have different images attached, or different store ops, treat stencil separately + if(renderstate.dynamicRendering.stencil.imageView != VK_NULL_HANDLE && + (renderstate.dynamicRendering.depth.imageView != + renderstate.dynamicRendering.stencil.imageView || + renderstate.dynamicRendering.depth.storeOp != + renderstate.dynamicRendering.stencil.storeOp)) + { + dynAtts.push_back(renderstate.dynamicRendering.stencil); + stencilIdx = dynAtts.size() - 1; + } + // otherwise if the same image is bound and the storeOp is the same then include it + else if(renderstate.dynamicRendering.stencil.imageView != VK_NULL_HANDLE) + { + depthAspects |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + + for(size_t i = 0; i < dynAtts.size(); i++) + { + if(dynAtts[i].imageView == VK_NULL_HANDLE) + continue; + + const VulkanCreationInfo::ImageView &viewInfo = + m_CreationInfo.m_ImageView[GetResID(dynAtts[i].imageView)]; + VkImage image = GetResourceManager()->GetCurrentHandle(viewInfo.image); + + if(dynAtts[i].storeOp == VK_ATTACHMENT_STORE_OP_DONT_CARE) + { + VkImageSubresourceRange range = viewInfo.range; + + if(i == depthIdx) + range.aspectMask = depthAspects; + + if(i == stencilIdx) + range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + + GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassStore, + image, VK_IMAGE_LAYOUT_UNDEFINED, range, + renderstate.renderArea); + } + } + } } } else diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index fbdccf465..bf9152498 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -24,6 +24,11 @@ #include "../vk_core.h" #include "../vk_debug.h" +#include "core/settings.h" + +RDOC_CONFIG( + bool, Vulkan_Hack_DisableRPNormalisation, false, + "Disable default behaviour to normalise renderpasses to be more consistent and debuggable."); static void PatchSeparateStencil(VkAttachmentDescription &att, const VkAttachmentReference *ref) { @@ -1041,28 +1046,35 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(SerialiserType &ser, VkDevice d VkAttachmentDescription *att = (VkAttachmentDescription *)CreateInfo.pAttachments; for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++) { - if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE) - att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE) - att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - - if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest) + if(Vulkan_Hack_DisableRPNormalisation()) { - if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + RDCWARN("RP attachment normalisation not applied!"); + } + else + { + if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE) + att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE) + att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD && - att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest) { - att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; - } + if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) + att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) + att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD && - att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) - { - att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD && + att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + { + att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + } + + if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD && + att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + { + att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + } } } @@ -1124,6 +1136,21 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(SerialiserType &ser, VkDevice d att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; if(att[i].stencilLoadOp != VK_ATTACHMENT_LOAD_OP_NONE) att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + + if(Vulkan_Hack_DisableRPNormalisation()) + { + if((att[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || + att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD) && + att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + { + att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + } + + if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE) + att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE) + att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + } } VkRenderPassCreateInfo loadInfo = CreateInfo; @@ -1295,36 +1322,35 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass2(SerialiserType &ser, VkDevice VkAttachmentDescription2 *att = (VkAttachmentDescription2 *)CreateInfo.pAttachments; for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++) { - if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE) - att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE) - att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - - if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest) + if(Vulkan_Hack_DisableRPNormalisation()) { - if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + RDCWARN("RP attachment normalisation not applied!"); } - - if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest) + else { - if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE) + att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE) + att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD && - att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest) { - att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; - } + if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) + att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE) + att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD && - att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) - { - att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD && + att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + { + att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + } + + if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD && + att[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) + { + att[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + } } }