mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-23 22:25:55 +00:00
Add new image tracking to replay side
Change-Id: I67ef6b1f6fd9b84621ec6700a8260c24afb35a05
This commit is contained in:
committed by
Baldur Karlsson
parent
1d44386724
commit
cb66100840
@@ -360,89 +360,6 @@ void WrappedVulkan::FlushQ()
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedVulkan::TempTransition(VkImage image, VkImageLayout layout, VkAccessFlags access,
|
||||
rdcarray<VkImageMemoryBarrier> &setupBarriers,
|
||||
rdcarray<VkImageMemoryBarrier> &cleanupBarriers,
|
||||
bool &extQCleanup) const
|
||||
{
|
||||
ResourceId id = GetResID(image);
|
||||
|
||||
auto it = m_ImageLayouts.find(id);
|
||||
|
||||
if(it == m_ImageLayouts.end())
|
||||
{
|
||||
RDCERR("Can't find image layouts for image %s in TempTransition", ToStr(id).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
setupBarriers.clear();
|
||||
cleanupBarriers.clear();
|
||||
|
||||
const ImageLayouts &layouts = it->second;
|
||||
|
||||
VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
||||
|
||||
barrier.image = Unwrap(image);
|
||||
barrier.newLayout = layout;
|
||||
barrier.srcQueueFamilyIndex = layouts.queueFamilyIndex;
|
||||
barrier.dstQueueFamilyIndex = GetQueueFamilyIndex();
|
||||
|
||||
extQCleanup = true;
|
||||
|
||||
// if we're on the same queue, don't need to bother with queue acquire/release
|
||||
if(barrier.srcQueueFamilyIndex == barrier.dstQueueFamilyIndex)
|
||||
{
|
||||
barrier.srcQueueFamilyIndex = barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
extQCleanup = false;
|
||||
}
|
||||
|
||||
barrier.dstAccessMask = access;
|
||||
|
||||
for(const ImageRegionState ®ion : layouts.subresourceStates)
|
||||
{
|
||||
barrier.subresourceRange = region.subresourceRange;
|
||||
barrier.oldLayout = region.newLayout;
|
||||
barrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS | MakeAccessMask(barrier.oldLayout);
|
||||
SanitiseOldImageLayout(barrier.oldLayout);
|
||||
|
||||
setupBarriers.push_back(barrier);
|
||||
}
|
||||
|
||||
if(SeparateDepthStencil())
|
||||
CombineDepthStencilLayouts(setupBarriers);
|
||||
|
||||
cleanupBarriers = setupBarriers;
|
||||
for(VkImageMemoryBarrier &b : cleanupBarriers)
|
||||
{
|
||||
std::swap(b.srcQueueFamilyIndex, b.dstQueueFamilyIndex);
|
||||
std::swap(b.oldLayout, b.newLayout);
|
||||
SanitiseNewImageLayout(b.newLayout);
|
||||
b.srcAccessMask = access;
|
||||
b.dstAccessMask = VK_ACCESS_ALL_READ_BITS | MakeAccessMask(b.newLayout);
|
||||
}
|
||||
|
||||
// if we have some queue transfer to do, submit the release on the ext queue now (which is what we
|
||||
// defined above). The user will have to check the bool themselves and submit cleanupBarriers as
|
||||
// external after they're done and submitted on the main queue
|
||||
if(extQCleanup)
|
||||
{
|
||||
VkCommandBuffer extQCmd = GetExtQueueCmd(barrier.srcQueueFamilyIndex);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
VkResult vkr = ObjDisp(extQCmd)->BeginCommandBuffer(Unwrap(extQCmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
DoPipelineBarrier(extQCmd, setupBarriers.size(), setupBarriers.data());
|
||||
|
||||
vkr = ObjDisp(extQCmd)->EndCommandBuffer(Unwrap(extQCmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
SubmitAndFlushExtQueue(layouts.queueFamilyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
VkCommandBuffer WrappedVulkan::GetExtQueueCmd(uint32_t queueFamilyIdx) const
|
||||
{
|
||||
if(queueFamilyIdx >= m_ExternalQueues.size())
|
||||
@@ -2443,8 +2360,10 @@ ReplayStatus WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t sta
|
||||
|
||||
ApplyInitialContents();
|
||||
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
|
||||
SetDebugMessageSink(sink);
|
||||
}
|
||||
@@ -2661,6 +2580,19 @@ void WrappedVulkan::ApplyInitialContents()
|
||||
// actually apply the initial contents here
|
||||
GetResourceManager()->ApplyInitialContents();
|
||||
|
||||
for(auto it = m_ImageStates.begin(); it != m_ImageStates.end(); ++it)
|
||||
{
|
||||
if(GetResourceManager()->HasCurrentResource(it->first))
|
||||
{
|
||||
it->second.LockWrite()->ResetToOldState(m_cleanupImageBarriers, GetImageTransitionInfo());
|
||||
}
|
||||
else
|
||||
{
|
||||
it = m_ImageStates.erase(it);
|
||||
--it;
|
||||
}
|
||||
}
|
||||
|
||||
// likewise again to make sure the initial states are all applied
|
||||
cmd = GetNextCmd();
|
||||
|
||||
@@ -2673,7 +2605,10 @@ void WrappedVulkan::ApplyInitialContents()
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3168,8 +3103,10 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
ApplyInitialContents();
|
||||
VkMarkerRegion::End();
|
||||
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
}
|
||||
|
||||
m_State = CaptureState::ActiveReplaying;
|
||||
@@ -3287,7 +3224,10 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -577,7 +577,6 @@ private:
|
||||
} state;
|
||||
|
||||
std::map<ResourceId, ImageState> imageStates;
|
||||
rdcarray<rdcpair<ResourceId, ImageRegionState>> imgbarriers;
|
||||
|
||||
ResourceId pushDescriptorID[2][64];
|
||||
|
||||
@@ -763,9 +762,6 @@ private:
|
||||
std::map<ResourceId, LockingImageState> m_ImageStates;
|
||||
Threading::CriticalSection m_ImageStatesLock;
|
||||
|
||||
std::map<ResourceId, ImageLayouts> m_ImageLayouts;
|
||||
Threading::CriticalSection m_ImageLayoutsLock;
|
||||
|
||||
// find swapchain for an image
|
||||
std::map<RENDERDOC_WindowHandle, VkSwapchainKHR> m_SwapLookup;
|
||||
Threading::CriticalSection m_SwapLookupLock;
|
||||
@@ -931,10 +927,6 @@ private:
|
||||
int32_t messageCode, const char *pLayerPrefix,
|
||||
const char *pMessage, void *pUserData);
|
||||
void AddFrameTerminator(uint64_t queueMarkerTag);
|
||||
void ImageInitializationBarriers(ResourceId id, WrappedVkRes *live, InitPolicy policy,
|
||||
bool initialized, const ImgRefs *imgRefs,
|
||||
rdcarray<VkImageMemoryBarrier> &setupBarriers,
|
||||
rdcarray<VkImageMemoryBarrier> &cleanupBarriers) const;
|
||||
void SubmitExtQBarriers(const std::map<uint32_t, rdcarray<VkImageMemoryBarrier>> &extQBarriers);
|
||||
void SubmitExtQBarriers(uint32_t queueFamilyIndex,
|
||||
const rdcarray<VkImageMemoryBarrier> &queueFamilyBarriers);
|
||||
@@ -1028,10 +1020,6 @@ public:
|
||||
void SubmitSemaphores();
|
||||
void FlushQ();
|
||||
|
||||
void TempTransition(VkImage image, VkImageLayout layout, VkAccessFlags access,
|
||||
rdcarray<VkImageMemoryBarrier> &setupBarriers,
|
||||
rdcarray<VkImageMemoryBarrier> &cleanupBarriers, bool &extQCleanup) const;
|
||||
|
||||
bool SeparateDepthStencil() const { return m_SeparateDepthStencil; }
|
||||
VulkanRenderState &GetRenderState() { return m_RenderState; }
|
||||
void SetDrawcallCB(VulkanDrawcallCallback *cb) { m_DrawcallCallback = cb; }
|
||||
|
||||
@@ -881,22 +881,6 @@ void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height,
|
||||
|
||||
// need to update image layout into valid state
|
||||
|
||||
VkImageMemoryBarrier barrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(m_Custom.TexImg),
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, 1},
|
||||
};
|
||||
|
||||
m_pDriver->m_ImageLayouts[GetResID(m_Custom.TexImg)].subresourceStates[0].newLayout =
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkCommandBuffer cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
@@ -904,7 +888,10 @@ void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height,
|
||||
|
||||
ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
DoPipelineBarrier(cmd, 1, &barrier);
|
||||
m_pDriver->FindImageState(GetResID(m_Custom.TexImg))
|
||||
->InlineTransition(cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
@@ -86,7 +86,8 @@ public:
|
||||
|
||||
void PixelHistoryCopyPixel(VkCommandBuffer cmd, CopyPixelParams &p, size_t offset);
|
||||
|
||||
VkImageLayout GetImageLayout(ResourceId image, VkImageAspectFlags aspect, uint32_t mip);
|
||||
VkImageLayout GetImageLayout(ResourceId image, VkImageAspectFlagBits aspect, uint32_t mip,
|
||||
uint32_t slice);
|
||||
|
||||
const VulkanCreationInfo::Image &GetImageInfo(ResourceId img);
|
||||
|
||||
|
||||
@@ -1208,22 +1208,21 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool
|
||||
{
|
||||
ResourceId liveid = GetResourceManager()->GetLiveID(id);
|
||||
|
||||
if(m_ImageLayouts.find(liveid) == m_ImageLayouts.end())
|
||||
VkInitialContents::Tag tag = VkInitialContents::ClearColorImage;
|
||||
LockedImageStateRef state = FindImageState(liveid);
|
||||
if(!state)
|
||||
{
|
||||
RDCERR("Couldn't find image info for %llu", id);
|
||||
RDCERR("Couldn't find image info for %s", ToStr(id).c_str());
|
||||
GetResourceManager()->SetInitialContents(
|
||||
id, VkInitialContents(type, VkInitialContents::ClearColorImage));
|
||||
return;
|
||||
}
|
||||
else if(IsDepthOrStencilFormat(state->GetImageInfo().format))
|
||||
{
|
||||
tag = VkInitialContents::ClearDepthStencilImage;
|
||||
}
|
||||
|
||||
ImageLayouts &layouts = m_ImageLayouts[liveid];
|
||||
|
||||
if(!IsDepthOrStencilFormat(layouts.imageInfo.format))
|
||||
GetResourceManager()->SetInitialContents(
|
||||
id, VkInitialContents(type, VkInitialContents::ClearColorImage));
|
||||
else
|
||||
GetResourceManager()->SetInitialContents(
|
||||
id, VkInitialContents(type, VkInitialContents::ClearDepthStencilImage));
|
||||
GetResourceManager()->SetInitialContents(id, VkInitialContents(type, tag));
|
||||
}
|
||||
else if(type == eResDeviceMemory)
|
||||
{
|
||||
@@ -1235,121 +1234,6 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedVulkan::ImageInitializationBarriers(ResourceId id, WrappedVkRes *live, InitPolicy policy,
|
||||
bool initialized, const ImgRefs *imgRefs,
|
||||
rdcarray<VkImageMemoryBarrier> &setupBarriers,
|
||||
rdcarray<VkImageMemoryBarrier> &cleanupBarriers) const
|
||||
{
|
||||
// For each subresource that will be initialized (either copy or fill), create barriers that will
|
||||
// transition the subresource from UNDEFINED to TRANSFER_DST_OPTIMAL before the write (in
|
||||
// `setupBarriers`), and barriers to transition the subresource from TRANSFER_DST_OPTIMAL back to
|
||||
// the current layout (`cleanupBarriers`). `cleanupBarriers` will also transfer ownership back to
|
||||
// the correct queues, if necessary.
|
||||
const ImageLayouts &imageLayouts = m_ImageLayouts.at(id);
|
||||
|
||||
for(size_t si = 0; si < imageLayouts.subresourceStates.size(); si++)
|
||||
{
|
||||
VkImageMemoryBarrier barrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
ToUnwrappedHandle<VkImage>(live),
|
||||
imageLayouts.subresourceStates[si].subresourceRange,
|
||||
};
|
||||
|
||||
if(IsDepthAndStencilFormat(imageLayouts.imageInfo.format) && !SeparateDepthStencil())
|
||||
{
|
||||
if(barrier.subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
{
|
||||
// There will be a different subresourceState with DEPTH aspect, which is when we will
|
||||
// handle both the depth and stencil aspects.
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
VkImageMemoryBarrier revBarrier = barrier;
|
||||
revBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
revBarrier.newLayout = imageLayouts.subresourceStates[si].newLayout;
|
||||
SanitiseNewImageLayout(revBarrier.newLayout);
|
||||
|
||||
revBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
revBarrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS | MakeAccessMask(revBarrier.newLayout);
|
||||
if(imageLayouts.queueFamilyIndex != m_QueueFamilyIdx)
|
||||
{
|
||||
revBarrier.srcQueueFamilyIndex = m_QueueFamilyIdx;
|
||||
revBarrier.dstQueueFamilyIndex = imageLayouts.queueFamilyIndex;
|
||||
}
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
setupBarriers.push_back(barrier);
|
||||
cleanupBarriers.push_back(revBarrier);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IsDepthAndStencilFormat(imageLayouts.imageInfo.format) && SeparateDepthStencil())
|
||||
{
|
||||
// process as if we're looking at both aspects in a depth/stencil format whenever we see
|
||||
// either. If both are already separate, we need to transition them separately
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
|
||||
auto initReqs =
|
||||
imgRefs->SubresourceRangeInitReqs(barrier.subresourceRange, policy, initialized);
|
||||
for(auto initIt = initReqs.begin(); initIt != initReqs.end(); ++initIt)
|
||||
{
|
||||
barrier.subresourceRange = revBarrier.subresourceRange = initIt->first;
|
||||
InitReqType initReq = initIt->second;
|
||||
if(IsDepthAndStencilFormat(imageLayouts.imageInfo.format))
|
||||
{
|
||||
if(SeparateDepthStencil())
|
||||
{
|
||||
// conservatively set init requirements for both aspects whenever we see either aspect.
|
||||
barrier.subresourceRange.aspectMask = revBarrier.subresourceRange.aspectMask =
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
initReq =
|
||||
imgRefs->SubresourceRangeMaxInitReq(barrier.subresourceRange, policy, initialized);
|
||||
// but transition the original aspect. These barriers will be combined if identical
|
||||
barrier.subresourceRange.aspectMask = revBarrier.subresourceRange.aspectMask =
|
||||
imageLayouts.subresourceStates[si].subresourceRange.aspectMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(barrier.subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
{
|
||||
// There will be a different subresourceState with DEPTH aspect, which is when we will
|
||||
// handle both the depth and stencil aspects.
|
||||
continue;
|
||||
}
|
||||
else if(barrier.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
{
|
||||
barrier.subresourceRange.aspectMask = revBarrier.subresourceRange.aspectMask =
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
initReq =
|
||||
imgRefs->SubresourceRangeMaxInitReq(barrier.subresourceRange, policy, initialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(initReq != eInitReq_None)
|
||||
{
|
||||
setupBarriers.push_back(barrier);
|
||||
cleanupBarriers.push_back(revBarrier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint32_t, rdcarray<VkImageMemoryBarrier> > GetExtQBarriers(
|
||||
const rdcarray<VkImageMemoryBarrier> &barriers)
|
||||
{
|
||||
@@ -1466,22 +1350,25 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
ResourceId orig = GetResourceManager()->GetOriginalID(id);
|
||||
ImgRefs *imgRefs = GetResourceManager()->FindImgRefs(orig);
|
||||
|
||||
bool initialized = false;
|
||||
InitPolicy policy = GetResourceManager()->GetInitPolicy();
|
||||
|
||||
if(imgRefs)
|
||||
LockedImageStateRef state = FindImageState(id);
|
||||
if(!state)
|
||||
{
|
||||
initialized = imgRefs->initializedLiveRes == live;
|
||||
imgRefs->initializedLiveRes = live;
|
||||
RDCWARN("No image state found for image %s", ToStr(id).c_str());
|
||||
return;
|
||||
}
|
||||
ResourceId boundMemory = state->boundMemory;
|
||||
VkDeviceSize boundMemoryOffset = state->boundMemoryOffset;
|
||||
VkDeviceSize boundMemorySize = state->boundMemorySize;
|
||||
const ImageInfo &imageInfo = state->GetImageInfo();
|
||||
initialized = IsActiveReplaying(m_State);
|
||||
|
||||
ImageLayouts &layout = m_ImageLayouts[id];
|
||||
|
||||
if(initialized && layout.boundMemory != ResourceId())
|
||||
if(initialized && boundMemory != ResourceId())
|
||||
{
|
||||
ResourceId origMem = GetResourceManager()->GetOriginalID(layout.boundMemory);
|
||||
ResourceId origMem = GetResourceManager()->GetOriginalID(boundMemory);
|
||||
if(origMem != ResourceId())
|
||||
{
|
||||
MemRefs *memRefs = GetResourceManager()->FindMemRefs(origMem);
|
||||
@@ -1497,9 +1384,8 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto it = memRefs->rangeRefs.find(layout.boundMemoryOffset);
|
||||
it != memRefs->rangeRefs.end() &&
|
||||
it->start() < layout.boundMemoryOffset + layout.boundMemorySize;
|
||||
for(auto it = memRefs->rangeRefs.find(boundMemoryOffset);
|
||||
it != memRefs->rangeRefs.end() && it->start() < boundMemoryOffset + boundMemorySize;
|
||||
++it)
|
||||
{
|
||||
if(IncludesWrite(it->value()) ||
|
||||
@@ -1526,7 +1412,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
{
|
||||
if(initial.tag == VkInitialContents::ClearColorImage)
|
||||
{
|
||||
VkFormat format = layout.imageInfo.format;
|
||||
VkFormat format = imageInfo.format;
|
||||
|
||||
// can't clear these, so leave them alone.
|
||||
if(IsBlockFormat(format) || IsYUVFormat(format))
|
||||
@@ -1537,11 +1423,12 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
TempTransition(ToWrappedHandle<VkImage>(live), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, setupBarriers, cleanupBarriers, extQCleanup);
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
ImageBarrierSequence setupBarriers;
|
||||
state->DiscardContents();
|
||||
state->Transition(m_QueueFamilyIdx, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, setupBarriers, GetImageTransitionInfo());
|
||||
InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_setupImageBarriers.Merge(setupBarriers);
|
||||
|
||||
VkClearColorValue clearval = {};
|
||||
VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
@@ -1550,63 +1437,43 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
ObjDisp(cmd)->CmdClearColorImage(Unwrap(cmd), ToUnwrappedHandle<VkImage>(live),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1, &range);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
if(extQCleanup)
|
||||
{
|
||||
// ensure work is completed before we pass ownership back to original queue
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
|
||||
SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
#endif
|
||||
}
|
||||
else if(initial.tag == VkInitialContents::ClearDepthStencilImage)
|
||||
{
|
||||
VkFormat format = layout.imageInfo.format;
|
||||
|
||||
VkCommandBuffer cmd = GetNextCmd();
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
TempTransition(ToWrappedHandle<VkImage>(live), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, setupBarriers, cleanupBarriers, extQCleanup);
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
ImageBarrierSequence setupBarriers; // , cleanupBarriers;
|
||||
state->DiscardContents();
|
||||
state->Transition(m_QueueFamilyIdx, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, setupBarriers, GetImageTransitionInfo());
|
||||
InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_setupImageBarriers.Merge(setupBarriers);
|
||||
|
||||
VkClearDepthStencilValue clearval = {1.0f, 0};
|
||||
VkImageSubresourceRange range = {FormatImageAspects(format), 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
VK_REMAINING_ARRAY_LAYERS};
|
||||
VkImageSubresourceRange range = imageInfo.FullRange();
|
||||
|
||||
ObjDisp(cmd)->CmdClearDepthStencilImage(Unwrap(cmd), ToUnwrappedHandle<VkImage>(live),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1,
|
||||
&range);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
if(extQCleanup)
|
||||
{
|
||||
// ensure work is completed before we pass ownership back to original queue
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
|
||||
SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -1628,12 +1495,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
|
||||
VkFormat fmt = c.format;
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
TempTransition(ToWrappedHandle<VkImage>(live), VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
setupBarriers, cleanupBarriers, extQCleanup);
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
ImageBarrierSequence setupBarriers; // , cleanupBarriers;
|
||||
state->DiscardContents();
|
||||
state->Transition(m_QueueFamilyIdx, VK_IMAGE_LAYOUT_GENERAL, 0,
|
||||
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
setupBarriers, GetImageTransitionInfo());
|
||||
InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_setupImageBarriers.Merge(setupBarriers);
|
||||
|
||||
VkImage arrayIm = initial.img;
|
||||
|
||||
@@ -1649,22 +1517,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
if(extQCleanup)
|
||||
{
|
||||
// ensure work is completed before we pass ownership back to original queue
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
|
||||
SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -1719,17 +1578,11 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
}
|
||||
}
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
ImageInitializationBarriers(id, live, policy, initialized, imgRefs, setupBarriers,
|
||||
cleanupBarriers);
|
||||
if(SeparateDepthStencil())
|
||||
{
|
||||
CombineDepthStencilLayouts(setupBarriers);
|
||||
CombineDepthStencilLayouts(cleanupBarriers);
|
||||
}
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
|
||||
SubmitExtQBarriers(GetExtQBarriers(setupBarriers));
|
||||
ImageBarrierSequence setupBarriers;
|
||||
state->Transition(m_QueueFamilyIdx, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, setupBarriers, GetImageTransitionInfo());
|
||||
InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_setupImageBarriers.Merge(setupBarriers);
|
||||
|
||||
VkDeviceSize bufOffset = 0;
|
||||
|
||||
@@ -1781,9 +1634,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
bufOffset += GetPlaneByteSize(extent.width, extent.height, extent.depth, fmt, 0, i);
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
initReq = eInitReq_Copy;
|
||||
}
|
||||
else
|
||||
initReq = imgRefs->SubresourceRangeMaxInitReq(range, policy, initialized);
|
||||
{
|
||||
initReq = state->MaxInitReq(range, policy, initialized);
|
||||
}
|
||||
if(initReq == eInitReq_Copy)
|
||||
copyRegions.push_back(region);
|
||||
else if(initReq == eInitReq_Clear)
|
||||
@@ -1797,9 +1654,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
initReq = eInitReq_Copy;
|
||||
}
|
||||
else
|
||||
initReq = imgRefs->SubresourceRangeMaxInitReq(range, policy, initialized);
|
||||
{
|
||||
initReq = state->MaxInitReq(range, policy, initialized);
|
||||
}
|
||||
if(initReq == eInitReq_None)
|
||||
continue;
|
||||
|
||||
@@ -1838,9 +1699,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
bufOffset += GetByteSize(extent.width, extent.height, extent.depth, fmt, 0);
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
initReq = eInitReq_Copy;
|
||||
}
|
||||
else
|
||||
initReq = imgRefs->SubresourceRangeMaxInitReq(range, policy, initialized);
|
||||
{
|
||||
initReq = state->MaxInitReq(range, policy, initialized);
|
||||
}
|
||||
if(initReq == eInitReq_Copy)
|
||||
copyRegions.push_back(region);
|
||||
else if(initReq == eInitReq_Clear)
|
||||
@@ -1878,24 +1743,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
}
|
||||
}
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
std::map<uint32_t, rdcarray<VkImageMemoryBarrier> > extQBarriers =
|
||||
GetExtQBarriers(cleanupBarriers);
|
||||
if(extQBarriers.size() > 0)
|
||||
{
|
||||
// ensure work is completed before we pass ownership back to original queue
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
|
||||
SubmitExtQBarriers(extQBarriers);
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
#endif
|
||||
}
|
||||
else if(type == eResDeviceMemory)
|
||||
|
||||
@@ -285,6 +285,8 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hasLiveRes = HasLiveResource(Image);
|
||||
|
||||
ImageState imageState;
|
||||
|
||||
if(ser.VersionLess(0x11))
|
||||
@@ -294,7 +296,7 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
|
||||
ImageLayouts &ImageState = imageLayouts;
|
||||
SERIALISE_ELEMENT(ImageState);
|
||||
}
|
||||
if(IsReplayingAndReading())
|
||||
if(IsReplayingAndReading() && hasLiveRes)
|
||||
{
|
||||
if(imageLayouts.imageInfo.extent.depth > 1)
|
||||
imageLayouts.imageInfo.imageType = VK_IMAGE_TYPE_3D;
|
||||
@@ -317,7 +319,8 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
|
||||
subresourceStates.push_back(p);
|
||||
}
|
||||
|
||||
imageState.subresourceStates.FromArray(subresourceStates);
|
||||
if(!subresourceStates.empty())
|
||||
imageState.subresourceStates.FromArray(subresourceStates);
|
||||
imageState.maxRefType = eFrameRef_Unknown;
|
||||
}
|
||||
}
|
||||
@@ -327,7 +330,7 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
|
||||
::ImageState &ImageState = imageState;
|
||||
SERIALISE_ELEMENT(ImageState);
|
||||
}
|
||||
if(IsReplayingAndReading())
|
||||
if(IsReplayingAndReading() && hasLiveRes)
|
||||
{
|
||||
imageState.newQueueFamilyTransfers.clear();
|
||||
for(auto it = imageState.subresourceStates.begin();
|
||||
@@ -342,7 +345,7 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
|
||||
}
|
||||
}
|
||||
}
|
||||
if(HasLiveResource(Image))
|
||||
if(hasLiveRes)
|
||||
{
|
||||
ResourceId liveid = GetLiveID(Image);
|
||||
|
||||
@@ -878,15 +881,6 @@ MemRefs *VulkanResourceManager::FindMemRefs(ResourceId mem)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ImgRefs *VulkanResourceManager::FindImgRefs(ResourceId img)
|
||||
{
|
||||
auto it = m_ImgFrameRefs.find(img);
|
||||
if(it != m_ImgFrameRefs.end())
|
||||
return &it->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool VulkanResourceManager::Prepare_InitialState(WrappedVkRes *res)
|
||||
{
|
||||
return m_Core->Prepare_InitialState(res);
|
||||
|
||||
@@ -460,6 +460,5 @@ private:
|
||||
|
||||
WrappedVulkan *m_Core;
|
||||
std::map<ResourceId, MemRefs> m_MemFrameRefs;
|
||||
std::map<ResourceId, ImgRefs> m_ImgFrameRefs;
|
||||
InitPolicy m_InitPolicy = eInitPolicy_CopyAll;
|
||||
};
|
||||
|
||||
@@ -518,23 +518,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa
|
||||
|
||||
// need to update image layout into valid state
|
||||
|
||||
VkImageMemoryBarrier barrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(m_Overlay.Image),
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
|
||||
};
|
||||
|
||||
m_pDriver->m_ImageLayouts[GetResID(m_Overlay.Image)].subresourceStates[0].newLayout =
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
DoPipelineBarrier(cmd, 1, &barrier);
|
||||
m_pDriver->FindImageState(GetResID(m_Overlay.Image))
|
||||
->InlineTransition(
|
||||
cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
VkAttachmentDescription colDesc = {
|
||||
0,
|
||||
@@ -1290,21 +1277,16 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa
|
||||
attDescs[1].format = depthImageInfo.format;
|
||||
attDescs[0].samples = attDescs[1].samples = iminfo.samples;
|
||||
|
||||
rdcarray<ImageRegionState> &depthStates = m_pDriver->m_ImageLayouts[depthIm].subresourceStates;
|
||||
|
||||
for(ImageRegionState &ds : depthStates)
|
||||
{
|
||||
// find the state that overlaps the view's subresource range start. We assume all
|
||||
// subresources are correctly in the same state (as they should be) so we just need to find
|
||||
// the first match.
|
||||
if(ds.subresourceRange.baseArrayLayer <= depthViewInfo.range.baseArrayLayer &&
|
||||
ds.subresourceRange.baseArrayLayer + 1 > depthViewInfo.range.baseArrayLayer &&
|
||||
ds.subresourceRange.baseMipLevel <= depthViewInfo.range.baseMipLevel &&
|
||||
ds.subresourceRange.baseMipLevel + ds.subresourceRange.levelCount + 1 >
|
||||
depthViewInfo.range.baseMipLevel)
|
||||
LockedConstImageStateRef imState = m_pDriver->FindConstImageState(depthIm);
|
||||
if(imState)
|
||||
{
|
||||
attDescs[1].initialLayout = attDescs[1].finalLayout = ds.newLayout;
|
||||
break;
|
||||
// find the state that overlaps the view's subresource range start. We assume all
|
||||
// subresources are correctly in the same state (as they should be) so we just need to
|
||||
// find the first match.
|
||||
auto it = imState->subresourceStates.RangeBegin(depthViewInfo.range);
|
||||
if(it != imState->subresourceStates.end())
|
||||
attDescs[1].initialLayout = attDescs[1].finalLayout = it->state().newLayout;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2073,22 +2055,16 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa
|
||||
attDescs[1].format = depthImageInfo.format;
|
||||
attDescs[0].samples = attDescs[1].samples = iminfo.samples;
|
||||
|
||||
rdcarray<ImageRegionState> &depthStates =
|
||||
m_pDriver->m_ImageLayouts[depthIm].subresourceStates;
|
||||
|
||||
for(ImageRegionState &ds : depthStates)
|
||||
{
|
||||
// find the state that overlaps the view's subresource range start. We assume all
|
||||
// subresources are correctly in the same state (as they should be) so we just need to
|
||||
// find the first match.
|
||||
if(ds.subresourceRange.baseArrayLayer <= depthViewInfo.range.baseArrayLayer &&
|
||||
ds.subresourceRange.baseArrayLayer + 1 > depthViewInfo.range.baseArrayLayer &&
|
||||
ds.subresourceRange.baseMipLevel <= depthViewInfo.range.baseMipLevel &&
|
||||
ds.subresourceRange.baseMipLevel + ds.subresourceRange.levelCount + 1 >
|
||||
depthViewInfo.range.baseMipLevel)
|
||||
LockedConstImageStateRef imState = m_pDriver->FindConstImageState(depthIm);
|
||||
if(imState)
|
||||
{
|
||||
attDescs[1].initialLayout = attDescs[1].finalLayout = ds.newLayout;
|
||||
break;
|
||||
// find the state that overlaps the view's subresource range start. We assume all
|
||||
// subresources are correctly in the same state (as they should be) so we just need to
|
||||
// find the first match.
|
||||
auto it = imState->subresourceStates.RangeBegin(depthViewInfo.range);
|
||||
if(it != imState->subresourceStates.end())
|
||||
attDescs[1].initialLayout = attDescs[1].finalLayout = it->state().newLayout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1345,6 +1345,10 @@ bool VulkanDebugManager::PixelHistorySetupResources(PixelHistoryResources &resou
|
||||
vkr = m_pDriver->vkCreateImage(dev, &imgInfo, NULL, &colorImage);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkImage wrappedColorImage = colorImage;
|
||||
m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), wrappedColorImage);
|
||||
ImageState colorImageState = ImageState(wrappedColorImage, ImageInfo(imgInfo), eFrameRef_None);
|
||||
|
||||
VkMemoryRequirements colorImageMrq = {0};
|
||||
m_pDriver->vkGetImageMemoryRequirements(dev, colorImage, &colorImageMrq);
|
||||
|
||||
@@ -1355,6 +1359,10 @@ bool VulkanDebugManager::PixelHistorySetupResources(PixelHistoryResources &resou
|
||||
vkr = m_pDriver->vkCreateImage(dev, &imgInfo, NULL, &stencilImage);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkImage wrappedStencilImage = stencilImage;
|
||||
m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), wrappedStencilImage);
|
||||
ImageState stencilImageState = ImageState(wrappedStencilImage, ImageInfo(imgInfo), eFrameRef_None);
|
||||
|
||||
VkMemoryRequirements stencilImageMrq = {0};
|
||||
m_pDriver->vkGetImageMemoryRequirements(dev, stencilImage, &stencilImageMrq);
|
||||
VkDeviceSize offset = AlignUp(colorImageMrq.size, stencilImageMrq.alignment);
|
||||
@@ -1413,34 +1421,13 @@ bool VulkanDebugManager::PixelHistorySetupResources(PixelHistoryResources &resou
|
||||
vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkImageMemoryBarrier barriers[2] = {};
|
||||
barriers[0] = {};
|
||||
barriers[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barriers[0].srcAccessMask = 0;
|
||||
barriers[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
barriers[0].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
barriers[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barriers[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barriers[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barriers[0].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
barriers[0].image = Unwrap(colorImage);
|
||||
colorImageState.InlineTransition(
|
||||
cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
stencilImageState.InlineTransition(
|
||||
cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
barriers[1] = barriers[0];
|
||||
barriers[1].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
barriers[1].newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
barriers[1].subresourceRange = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0,
|
||||
1};
|
||||
barriers[1].image = Unwrap(stencilImage);
|
||||
|
||||
DoPipelineBarrier(cmd, 2, barriers);
|
||||
|
||||
{
|
||||
SCOPED_LOCK(m_pDriver->m_ImageLayoutsLock);
|
||||
m_pDriver->m_ImageLayouts[GetResID(colorImage)].subresourceStates[0].newLayout =
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
m_pDriver->m_ImageLayouts[GetResID(stencilImage)].subresourceStates[0].newLayout =
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
m_pDriver->SubmitCmds();
|
||||
@@ -1569,23 +1556,19 @@ void CreateOcclusionPool(WrappedVulkan *vk, uint32_t poolSize, VkQueryPool *pQue
|
||||
vk->FlushQ();
|
||||
}
|
||||
|
||||
VkImageLayout VulkanDebugManager::GetImageLayout(ResourceId image, VkImageAspectFlags aspect,
|
||||
uint32_t mip)
|
||||
VkImageLayout VulkanDebugManager::GetImageLayout(ResourceId image, VkImageAspectFlagBits aspect,
|
||||
uint32_t mip, uint32_t slice)
|
||||
{
|
||||
VkImageLayout imgLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
const ImageLayouts &imgLayouts = m_pDriver->m_ImageLayouts[image];
|
||||
for(const ImageRegionState &resState : imgLayouts.subresourceStates)
|
||||
auto state = m_pDriver->FindConstImageState(image);
|
||||
if(!state)
|
||||
{
|
||||
VkImageSubresourceRange range = resState.subresourceRange;
|
||||
|
||||
if((range.aspectMask & aspect) &&
|
||||
(mip >= range.baseMipLevel && mip < range.baseMipLevel + range.levelCount))
|
||||
{
|
||||
// Consider using the layer count
|
||||
imgLayout = resState.newLayout;
|
||||
}
|
||||
RDCERR("Could not find image state for %s", ToStr(image).c_str());
|
||||
return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
return imgLayout;
|
||||
if(state->GetImageInfo().extent.depth > 1)
|
||||
return state->GetImageLayout(aspect, mip, 0);
|
||||
else
|
||||
return state->GetImageLayout(aspect, mip, slice);
|
||||
}
|
||||
|
||||
void UpdateTestsFailed(const TestsFailedCallback *tfCb, uint32_t eventId, uint32_t eventFlags,
|
||||
@@ -1686,10 +1669,12 @@ rdcarray<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> even
|
||||
return history;
|
||||
|
||||
uint32_t mip = sub.mip;
|
||||
uint32_t slice = sub.slice;
|
||||
uint32_t sampleIdx = sub.sample;
|
||||
|
||||
// TODO: figure out correct aspect.
|
||||
VkImageLayout imgLayout = GetDebugManager()->GetImageLayout(target, VK_IMAGE_ASPECT_COLOR_BIT, mip);
|
||||
VkImageLayout imgLayout =
|
||||
GetDebugManager()->GetImageLayout(target, VK_IMAGE_ASPECT_COLOR_BIT, mip, slice);
|
||||
RDCASSERTNOTEQUAL(imgLayout, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
|
||||
// TODO: use the given type hint for typeless textures
|
||||
|
||||
@@ -145,10 +145,21 @@ bool VulkanReplay::RenderTexture(TextureDisplay cfg)
|
||||
NULL,
|
||||
};
|
||||
|
||||
return RenderTextureInternal(cfg, rpbegin, eTexDisplay_MipShift | eTexDisplay_BlendAlpha);
|
||||
LockedConstImageStateRef imageState = m_pDriver->FindConstImageState(cfg.resourceId);
|
||||
if(!imageState)
|
||||
{
|
||||
RDCWARN("Could not find image info for image %s", ToStr(cfg.resourceId).c_str());
|
||||
return false;
|
||||
}
|
||||
if(!imageState->isMemoryBound)
|
||||
return false;
|
||||
|
||||
return RenderTextureInternal(cfg, *imageState, rpbegin,
|
||||
eTexDisplay_MipShift | eTexDisplay_BlendAlpha);
|
||||
}
|
||||
|
||||
bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, int flags)
|
||||
bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, const ImageState &imageState,
|
||||
VkRenderPassBeginInfo rpbegin, int flags)
|
||||
{
|
||||
const bool blendAlpha = (flags & eTexDisplay_BlendAlpha) != 0;
|
||||
const bool mipShift = (flags & eTexDisplay_MipShift) != 0;
|
||||
@@ -159,14 +170,11 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
const VkDevDispatchTable *vt = ObjDisp(dev);
|
||||
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[cfg.resourceId];
|
||||
const ImageInfo &imageInfo = imageState.GetImageInfo();
|
||||
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[cfg.resourceId];
|
||||
TextureDisplayViews &texviews = m_TexRender.TextureViews[cfg.resourceId];
|
||||
VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle<VkImage>(cfg.resourceId);
|
||||
const ImageInfo &imageInfo = layouts.imageInfo;
|
||||
|
||||
if(!layouts.isMemoryBound)
|
||||
return false;
|
||||
|
||||
CreateTexImageView(liveIm, iminfo, cfg.typeCast, texviews);
|
||||
|
||||
@@ -481,12 +489,12 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
|
||||
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
m_pDriver->TempTransition(liveIm, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_SHADER_READ_BIT, setupBarriers, cleanupBarriers, extQCleanup);
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
|
||||
ImageBarrierSequence setupBarriers, cleanupBarriers;
|
||||
imageState.TempTransition(m_pDriver->GetQueueFamilyIndex(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT,
|
||||
setupBarriers, cleanupBarriers, m_pDriver->GetImageTransitionInfo());
|
||||
m_pDriver->InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(setupBarriers);
|
||||
{
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
@@ -556,21 +564,19 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
|
||||
vt->CmdEndRenderPass(Unwrap(cmd));
|
||||
}
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
m_pDriver->InlineCleanupImageBarriers(cmd, cleanupBarriers);
|
||||
vt->EndCommandBuffer(Unwrap(cmd));
|
||||
|
||||
if(extQCleanup)
|
||||
if(!cleanupBarriers.empty())
|
||||
{
|
||||
// ensure work is completed before we pass ownership back to original queue
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
m_pDriver->SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(cleanupBarriers);
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
m_pDriver->SubmitCmds();
|
||||
else
|
||||
{
|
||||
m_pDriver->SubmitCmds();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
@@ -296,7 +296,7 @@ rdcarray<ResourceId> VulkanReplay::GetTextures()
|
||||
{
|
||||
rdcarray<ResourceId> texs;
|
||||
|
||||
for(auto it = m_pDriver->m_ImageLayouts.begin(); it != m_pDriver->m_ImageLayouts.end(); ++it)
|
||||
for(auto it = m_pDriver->m_ImageStates.begin(); it != m_pDriver->m_ImageStates.end(); ++it)
|
||||
{
|
||||
// skip textures that aren't from the capture
|
||||
if(m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first)
|
||||
@@ -1849,9 +1849,9 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
|
||||
|
||||
// image layouts
|
||||
{
|
||||
m_VulkanPipelineState.images.resize(m_pDriver->m_ImageLayouts.size());
|
||||
size_t i = 0;
|
||||
for(auto it = m_pDriver->m_ImageLayouts.begin(); it != m_pDriver->m_ImageLayouts.end(); ++it)
|
||||
m_VulkanPipelineState.images.resize(m_pDriver->m_ImageStates.size());
|
||||
for(auto it = m_pDriver->m_ImageStates.begin(); it != m_pDriver->m_ImageStates.end(); ++it)
|
||||
{
|
||||
VKPipe::ImageData &img = m_VulkanPipelineState.images[i];
|
||||
|
||||
@@ -1860,14 +1860,16 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
|
||||
|
||||
img.resourceId = rm->GetOriginalID(it->first);
|
||||
|
||||
img.layouts.resize(it->second.subresourceStates.size());
|
||||
for(size_t l = 0; l < it->second.subresourceStates.size(); l++)
|
||||
LockedConstImageStateRef imState = it->second.LockRead();
|
||||
img.layouts.resize(imState->subresourceStates.size());
|
||||
auto subIt = imState->subresourceStates.begin();
|
||||
for(size_t l = 0; l < img.layouts.size(); ++l, ++subIt)
|
||||
{
|
||||
img.layouts[l].name = ToStr(it->second.subresourceStates[l].newLayout);
|
||||
img.layouts[l].baseMip = it->second.subresourceStates[l].subresourceRange.baseMipLevel;
|
||||
img.layouts[l].baseLayer = it->second.subresourceStates[l].subresourceRange.baseArrayLayer;
|
||||
img.layouts[l].numLayer = it->second.subresourceStates[l].subresourceRange.layerCount;
|
||||
img.layouts[l].numMip = it->second.subresourceStates[l].subresourceRange.levelCount;
|
||||
img.layouts[l].name = ToStr(subIt->state().newLayout);
|
||||
img.layouts[l].baseMip = subIt->range().baseMipLevel;
|
||||
img.layouts[l].numMip = subIt->range().levelCount;
|
||||
img.layouts[l].baseLayer = subIt->range().baseArrayLayer;
|
||||
img.layouts[l].numLayer = subIt->range().layerCount;
|
||||
}
|
||||
|
||||
if(img.layouts.empty())
|
||||
@@ -1965,6 +1967,14 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const S
|
||||
m_DebugWidth = m_DebugHeight = 1;
|
||||
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texture];
|
||||
LockedConstImageStateRef imageState = m_pDriver->FindConstImageState(texture);
|
||||
if(!imageState)
|
||||
{
|
||||
RDCWARN("Could not find image info for image %s", ToStr(texture).c_str());
|
||||
return;
|
||||
}
|
||||
if(!imageState->isMemoryBound)
|
||||
return;
|
||||
|
||||
bool isStencil = IsStencilFormat(iminfo.format);
|
||||
|
||||
@@ -2012,7 +2022,8 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const S
|
||||
&clearval,
|
||||
};
|
||||
|
||||
RenderTextureInternal(texDisplay, rpbegin, eTexDisplay_32Render | eTexDisplay_MipShift);
|
||||
RenderTextureInternal(texDisplay, *imageState, rpbegin,
|
||||
eTexDisplay_32Render | eTexDisplay_MipShift);
|
||||
}
|
||||
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
@@ -2114,9 +2125,15 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const S
|
||||
bool VulkanReplay::GetMinMax(ResourceId texid, const Subresource &sub, CompType typeCast,
|
||||
float *minval, float *maxval)
|
||||
{
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid];
|
||||
const ImageInfo *imageInfo = NULL;
|
||||
{
|
||||
LockedConstImageStateRef state = m_pDriver->FindConstImageState(texid);
|
||||
if(!state)
|
||||
return false;
|
||||
imageInfo = &state->GetImageInfo();
|
||||
}
|
||||
|
||||
if(IsDepthAndStencilFormat(layouts.imageInfo.format))
|
||||
if(IsDepthAndStencilFormat(imageInfo->format))
|
||||
{
|
||||
// for depth/stencil we need to run the code twice - once to fetch depth and once to fetch
|
||||
// stencil - since we can't process float depth and int stencil at the same time
|
||||
@@ -2154,12 +2171,15 @@ bool VulkanReplay::GetMinMax(ResourceId texid, const Subresource &sub, CompType
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
const VkDevDispatchTable *vt = ObjDisp(dev);
|
||||
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid];
|
||||
LockedConstImageStateRef state = m_pDriver->FindConstImageState(texid);
|
||||
if(!state)
|
||||
return false;
|
||||
bool isMemoryBound = state->isMemoryBound;
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid];
|
||||
TextureDisplayViews &texviews = m_TexRender.TextureViews[texid];
|
||||
VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle<VkImage>(texid);
|
||||
|
||||
if(!layouts.isMemoryBound)
|
||||
if(!isMemoryBound)
|
||||
return false;
|
||||
|
||||
if(!IsStencilFormat(iminfo.format))
|
||||
@@ -2339,11 +2359,6 @@ bool VulkanReplay::GetMinMax(ResourceId texid, const Subresource &sub, CompType
|
||||
|
||||
m_Histogram.m_HistogramUBO.Unmap();
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
m_pDriver->TempTransition(liveIm, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_SHADER_READ_BIT, setupBarriers, cleanupBarriers, extQCleanup);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
@@ -2351,7 +2366,12 @@ bool VulkanReplay::GetMinMax(ResourceId texid, const Subresource &sub, CompType
|
||||
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
ImageBarrierSequence setupBarriers, cleanupBarriers;
|
||||
state->TempTransition(m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_SHADER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
m_pDriver->GetImageTransitionInfo());
|
||||
m_pDriver->InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(setupBarriers);
|
||||
|
||||
int blocksX = (int)ceil(iminfo.extent.width / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK));
|
||||
int blocksY =
|
||||
@@ -2365,7 +2385,16 @@ bool VulkanReplay::GetMinMax(ResourceId texid, const Subresource &sub, CompType
|
||||
|
||||
vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
m_pDriver->InlineCleanupImageBarriers(cmd, cleanupBarriers);
|
||||
if(!cleanupBarriers.empty())
|
||||
{
|
||||
vt->EndCommandBuffer(Unwrap(cmd));
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(cleanupBarriers);
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
}
|
||||
|
||||
VkBufferMemoryBarrier tilebarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
@@ -2419,9 +2448,6 @@ bool VulkanReplay::GetMinMax(ResourceId texid, const Subresource &sub, CompType
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
if(extQCleanup)
|
||||
m_pDriver->SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
|
||||
Vec4f *minmax = (Vec4f *)m_Histogram.m_MinMaxReadback.Map(NULL);
|
||||
|
||||
minval[0] = minmax[0].x;
|
||||
@@ -2449,14 +2475,13 @@ bool VulkanReplay::GetHistogram(ResourceId texid, const Subresource &sub, CompTy
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
const VkDevDispatchTable *vt = ObjDisp(dev);
|
||||
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid];
|
||||
LockedConstImageStateRef state = m_pDriver->FindConstImageState(texid);
|
||||
if(!state->isMemoryBound)
|
||||
return false;
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid];
|
||||
TextureDisplayViews &texviews = m_TexRender.TextureViews[texid];
|
||||
VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle<VkImage>(texid);
|
||||
|
||||
if(!layouts.isMemoryBound)
|
||||
return false;
|
||||
|
||||
bool stencil = false;
|
||||
// detect if stencil is selected
|
||||
if(IsStencilFormat(iminfo.format) && !channels[0] && channels[1] && !channels[2] && !channels[3])
|
||||
@@ -2655,11 +2680,12 @@ bool VulkanReplay::GetHistogram(ResourceId texid, const Subresource &sub, CompTy
|
||||
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
m_pDriver->TempTransition(liveIm, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_READ_BIT,
|
||||
setupBarriers, cleanupBarriers, extQCleanup);
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
ImageBarrierSequence setupBarriers, cleanupBarriers;
|
||||
state->TempTransition(m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_ACCESS_SHADER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
m_pDriver->GetImageTransitionInfo());
|
||||
m_pDriver->InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(setupBarriers);
|
||||
|
||||
int blocksX = (int)ceil(iminfo.extent.width / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK));
|
||||
int blocksY =
|
||||
@@ -2676,7 +2702,16 @@ bool VulkanReplay::GetHistogram(ResourceId texid, const Subresource &sub, CompTy
|
||||
|
||||
vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
m_pDriver->InlineCleanupImageBarriers(cmd, cleanupBarriers);
|
||||
if(!cleanupBarriers.empty())
|
||||
{
|
||||
vt->EndCommandBuffer(Unwrap(cmd));
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(cleanupBarriers);
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
}
|
||||
|
||||
VkBufferMemoryBarrier tilebarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
@@ -2714,9 +2749,6 @@ bool VulkanReplay::GetHistogram(ResourceId texid, const Subresource &sub, CompTy
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
if(extQCleanup)
|
||||
m_pDriver->SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
|
||||
uint32_t *buckets = (uint32_t *)m_Histogram.m_HistogramReadback.Map(NULL);
|
||||
|
||||
histogram.assign(buckets, HGRAM_NUM_BUCKETS);
|
||||
@@ -2745,10 +2777,11 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
|
||||
const VulkanCreationInfo::Image &imInfo = m_pDriver->m_CreationInfo.m_Image[tex];
|
||||
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[tex];
|
||||
|
||||
if(!layouts.isMemoryBound)
|
||||
LockedConstImageStateRef lockedImage = m_pDriver->FindConstImageState(tex);
|
||||
if(!lockedImage || !lockedImage->isMemoryBound)
|
||||
return;
|
||||
const ImageState *srcImageState = &*lockedImage;
|
||||
ImageState tmpImageState;
|
||||
|
||||
VkMarkerRegion region(StringFormat::Fmt("GetTextureData(%u, %u, %u, remap=%d)", sub.mip,
|
||||
sub.slice, sub.sample, params.remap));
|
||||
@@ -2781,10 +2814,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
|
||||
VkImage srcImage = Unwrap(liveWrappedImage);
|
||||
VkImage tmpImage = VK_NULL_HANDLE;
|
||||
VkImage wrappedTmpImage = VK_NULL_HANDLE;
|
||||
VkDeviceMemory tmpMemory = VK_NULL_HANDLE;
|
||||
|
||||
uint32_t srcQueueIndex = layouts.queueFamilyIndex;
|
||||
|
||||
VkFramebuffer *tmpFB = NULL;
|
||||
VkImageView *tmpView = NULL;
|
||||
uint32_t numFBs = 0;
|
||||
@@ -2812,9 +2844,6 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
if(wasms && (isDepth || isStencil))
|
||||
resolve = false;
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> setupBarriers, cleanupBarriers;
|
||||
bool extQCleanup = false;
|
||||
|
||||
if(params.remap != RemapTexture::NoRemap)
|
||||
{
|
||||
int renderFlags = 0;
|
||||
@@ -2875,6 +2904,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
|
||||
// create render texture similar to readback texture
|
||||
vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage);
|
||||
wrappedTmpImage = tmpImage;
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), wrappedTmpImage);
|
||||
tmpImageState = ImageState(wrappedTmpImage, ImageInfo(imCreateInfo), eFrameRef_None);
|
||||
|
||||
VkMemoryRequirements mrq = {0};
|
||||
vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq);
|
||||
@@ -2890,21 +2922,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
vkr = vt->BindImageMemory(Unwrap(dev), tmpImage, tmpMemory, 0);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkImageMemoryBarrier dstimBarrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
tmpImage,
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS},
|
||||
};
|
||||
|
||||
// move tmp image into transfer destination layout
|
||||
DoPipelineBarrier(cmd, 1, &dstimBarrier);
|
||||
tmpImageState.InlineTransition(
|
||||
cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
// end this command buffer, the rendertexture below will use its own and we want to ensure
|
||||
// ordering
|
||||
@@ -3046,7 +3066,7 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
&clearval,
|
||||
};
|
||||
|
||||
RenderTextureInternal(texDisplay, rpbegin, renderFlags);
|
||||
RenderTextureInternal(texDisplay, *srcImageState, rpbegin, renderFlags);
|
||||
renderCount++;
|
||||
|
||||
// for textures with stencil, do another draw to copy the stencil
|
||||
@@ -3062,8 +3082,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
rpbegin.framebuffer = tmpFB[i + numFBs];
|
||||
|
||||
texDisplay.red = texDisplay.blue = texDisplay.alpha = false;
|
||||
RenderTextureInternal(texDisplay, rpbegin, (renderFlags & ~eTexDisplay_RemapFloat) |
|
||||
eTexDisplay_RemapUInt | eTexDisplay_GreenOnly);
|
||||
RenderTextureInternal(texDisplay, *srcImageState, rpbegin,
|
||||
(renderFlags & ~eTexDisplay_RemapFloat) | eTexDisplay_RemapUInt |
|
||||
eTexDisplay_GreenOnly);
|
||||
renderCount++;
|
||||
}
|
||||
}
|
||||
@@ -3072,7 +3093,7 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
m_DebugHeight = oldH;
|
||||
|
||||
srcImage = tmpImage;
|
||||
srcQueueIndex = m_pDriver->GetQueueFamilyIndex();
|
||||
srcImageState = &tmpImageState;
|
||||
|
||||
// fetch a new command buffer for copy & readback
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
@@ -3080,13 +3101,10 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
// ensure all writes happen before copy & readback
|
||||
dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
dstimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
|
||||
DoPipelineBarrier(cmd, 1, &dstimBarrier);
|
||||
tmpImageState.InlineTransition(cmd, m_pDriver->m_QueueFamilyIdx,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
// these have already been selected, don't need to fetch that subresource
|
||||
// when copying back to readback buffer
|
||||
@@ -3108,6 +3126,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
|
||||
// create resolve texture
|
||||
vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage);
|
||||
wrappedTmpImage = tmpImage;
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), wrappedTmpImage);
|
||||
tmpImageState = ImageState(wrappedTmpImage, ImageInfo(imCreateInfo), eFrameRef_None);
|
||||
|
||||
VkMemoryRequirements mrq = {0};
|
||||
vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq);
|
||||
@@ -3133,43 +3154,27 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
imCreateInfo.extent,
|
||||
};
|
||||
|
||||
m_pDriver->TempTransition(liveWrappedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
extQCleanup);
|
||||
|
||||
VkImageMemoryBarrier dstimBarrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
tmpImage,
|
||||
{imageAspects, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS},
|
||||
};
|
||||
|
||||
// move tmp image into transfer destination layout as well
|
||||
setupBarriers.push_back(dstimBarrier);
|
||||
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
tmpImageState.InlineTransition(
|
||||
cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
ImageBarrierSequence setupBarriers, cleanupBarriers;
|
||||
srcImageState->TempTransition(m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
m_pDriver->GetImageTransitionInfo());
|
||||
m_pDriver->InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(setupBarriers);
|
||||
|
||||
// resolve from live texture to resolve texture
|
||||
vt->CmdResolveImage(Unwrap(cmd), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tmpImage,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
|
||||
|
||||
dstimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
tmpImageState.InlineTransition(cmd, m_pDriver->m_QueueFamilyIdx,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
// wait for resolve to finish before copy to buffer
|
||||
cleanupBarriers.push_back(dstimBarrier);
|
||||
m_pDriver->InlineCleanupImageBarriers(cmd, cleanupBarriers);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
if(extQCleanup)
|
||||
if(!cleanupBarriers.empty())
|
||||
{
|
||||
// ensure this resolve happens before handing back the source image to the original queue
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
@@ -3178,10 +3183,7 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
// don't do our dest image barrier on the external queue
|
||||
cleanupBarriers.pop_back();
|
||||
|
||||
m_pDriver->SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(cleanupBarriers);
|
||||
|
||||
// fetch a new command buffer for remaining work
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
@@ -3189,9 +3191,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
srcImageState = &tmpImageState;
|
||||
|
||||
srcImage = tmpImage;
|
||||
srcQueueIndex = m_pDriver->GetQueueFamilyIndex();
|
||||
|
||||
// these have already been selected, don't need to fetch that subresource
|
||||
// when copying back to readback buffer
|
||||
@@ -3215,6 +3217,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
|
||||
// create resolve texture
|
||||
vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage);
|
||||
wrappedTmpImage = tmpImage;
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), wrappedTmpImage);
|
||||
tmpImageState = ImageState(wrappedTmpImage, ImageInfo(imCreateInfo), eFrameRef_None);
|
||||
|
||||
VkMemoryRequirements mrq = {0};
|
||||
vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq);
|
||||
@@ -3230,26 +3235,15 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
vkr = vt->BindImageMemory(Unwrap(dev), tmpImage, tmpMemory, 0);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
m_pDriver->TempTransition(liveWrappedImage, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_READ_BIT,
|
||||
setupBarriers, cleanupBarriers, extQCleanup);
|
||||
|
||||
VkImageMemoryBarrier dstimBarrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
tmpImage,
|
||||
{imageAspects, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS},
|
||||
};
|
||||
|
||||
// move tmp image into transfer destination layout
|
||||
setupBarriers.push_back(dstimBarrier);
|
||||
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
tmpImageState.InlineTransition(cmd, m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_GENERAL, 0,
|
||||
VK_ACCESS_SHADER_WRITE_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
ImageBarrierSequence setupBarriers, cleanupBarriers;
|
||||
srcImageState->TempTransition(m_pDriver->m_QueueFamilyIdx,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_SHADER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
m_pDriver->GetImageTransitionInfo());
|
||||
m_pDriver->InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(setupBarriers);
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
@@ -3265,18 +3259,13 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
// wait for copy to finish before copy to buffer
|
||||
dstimBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
tmpImageState.InlineTransition(cmd, m_pDriver->m_QueueFamilyIdx,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_SHADER_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, m_pDriver->GetImageTransitionInfo());
|
||||
|
||||
// wait for work to finish before copy to buffer
|
||||
cleanupBarriers.push_back(dstimBarrier);
|
||||
m_pDriver->InlineCleanupImageBarriers(cmd, cleanupBarriers);
|
||||
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
if(extQCleanup)
|
||||
if(!cleanupBarriers.empty())
|
||||
{
|
||||
// ensure this resolve happens before handing back the source image to the original queue
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
@@ -3285,10 +3274,7 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
// don't do our dest image barrier on the external queue
|
||||
cleanupBarriers.pop_back();
|
||||
|
||||
m_pDriver->SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(cleanupBarriers);
|
||||
|
||||
// fetch a new command buffer for remaining work
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
@@ -3298,27 +3284,22 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
}
|
||||
|
||||
srcImage = tmpImage;
|
||||
srcQueueIndex = m_pDriver->GetQueueFamilyIndex();
|
||||
|
||||
srcImageState = &tmpImageState;
|
||||
s.slice = s.slice * numSamples + s.sample;
|
||||
s.sample = 0;
|
||||
}
|
||||
|
||||
ImageBarrierSequence cleanupBarriers;
|
||||
|
||||
// if we have no tmpImage, we're copying directly from the real image
|
||||
if(tmpImage == VK_NULL_HANDLE)
|
||||
{
|
||||
m_pDriver->TempTransition(liveWrappedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
extQCleanup);
|
||||
|
||||
DoPipelineBarrier(cmd, setupBarriers.size(), setupBarriers.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
// no more setup/cleanup to do, we read from the real image above
|
||||
extQCleanup = false;
|
||||
setupBarriers.clear();
|
||||
cleanupBarriers.clear();
|
||||
ImageBarrierSequence setupBarriers;
|
||||
srcImageState->TempTransition(m_pDriver->m_QueueFamilyIdx, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, setupBarriers, cleanupBarriers,
|
||||
m_pDriver->GetImageTransitionInfo());
|
||||
m_pDriver->InlineSetupImageBarriers(cmd, setupBarriers);
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(setupBarriers);
|
||||
}
|
||||
|
||||
VkImageAspectFlags copyAspects = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
@@ -3435,6 +3416,30 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
readbackBuf, 1, copyregion);
|
||||
}
|
||||
|
||||
// if we have no tmpImage, we're copying directly from the real image
|
||||
if(tmpImage == VK_NULL_HANDLE)
|
||||
{
|
||||
m_pDriver->InlineCleanupImageBarriers(cmd, cleanupBarriers);
|
||||
|
||||
if(!cleanupBarriers.empty())
|
||||
{
|
||||
// ensure this resolve happens before handing back the source image to the original queue
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
m_pDriver->SubmitAndFlushImageStateBarriers(cleanupBarriers);
|
||||
|
||||
// fetch a new command buffer for remaining work
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
@@ -3447,10 +3452,6 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
dataSize,
|
||||
};
|
||||
|
||||
// do any cleanup needed
|
||||
if(!cleanupBarriers.empty())
|
||||
DoPipelineBarrier(cmd, cleanupBarriers.size(), cleanupBarriers.data());
|
||||
|
||||
// wait for copy to finish before reading back to host
|
||||
DoPipelineBarrier(cmd, 1, &bufBarrier);
|
||||
|
||||
@@ -3459,9 +3460,6 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
if(extQCleanup)
|
||||
m_pDriver->SubmitExtQBarriers(~0U, cleanupBarriers);
|
||||
|
||||
// map the buffer and copy to return buffer
|
||||
byte *pData = NULL;
|
||||
vkr = vt->MapMemory(Unwrap(dev), readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
|
||||
@@ -3577,6 +3575,7 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
|
||||
if(tmpImage != VK_NULL_HANDLE)
|
||||
{
|
||||
GetResourceManager()->ReleaseWrappedResource(wrappedTmpImage, true);
|
||||
vt->DestroyImage(Unwrap(dev), tmpImage, NULL);
|
||||
vt->FreeMemory(Unwrap(dev), tmpMemory, NULL);
|
||||
}
|
||||
@@ -3658,7 +3657,16 @@ ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid,
|
||||
&clearval,
|
||||
};
|
||||
|
||||
RenderTextureInternal(disp, rpbegin, eTexDisplay_MipShift);
|
||||
LockedConstImageStateRef imageState = m_pDriver->FindConstImageState(texid);
|
||||
if(!imageState)
|
||||
{
|
||||
RDCWARN("Could not find image info for image %s", ToStr(texid).c_str());
|
||||
return ResourceId();
|
||||
}
|
||||
if(!imageState->isMemoryBound)
|
||||
return ResourceId();
|
||||
|
||||
RenderTextureInternal(disp, *imageState, rpbegin, eTexDisplay_MipShift);
|
||||
|
||||
m_DebugWidth = oldW;
|
||||
m_DebugHeight = oldH;
|
||||
|
||||
@@ -426,7 +426,8 @@ private:
|
||||
|
||||
void RefreshDerivedReplacements();
|
||||
|
||||
bool RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, int flags);
|
||||
bool RenderTextureInternal(TextureDisplay cfg, const ImageState &imageState,
|
||||
VkRenderPassBeginInfo rpbegin, int flags);
|
||||
|
||||
bool GetMinMax(ResourceId texid, const Subresource &sub, CompType typeCast, bool stencil,
|
||||
float *minval, float *maxval);
|
||||
|
||||
@@ -453,7 +453,7 @@ bool WrappedVulkan::Serialise_vkCreateCommandPool(SerialiserType &ser, VkDevice
|
||||
// remap the queue family index
|
||||
CreateInfo.queueFamilyIndex = m_QueueRemapping[CreateInfo.queueFamilyIndex][0].family;
|
||||
|
||||
m_commandQueueFamilies[CmdPool] = CreateInfo.queueFamilyIndex;
|
||||
InsertCommandQueueFamily(CmdPool, CreateInfo.queueFamilyIndex);
|
||||
|
||||
VkResult ret = ObjDisp(device)->CreateCommandPool(Unwrap(device), &CreateInfo, NULL, &pool);
|
||||
|
||||
@@ -466,7 +466,7 @@ bool WrappedVulkan::Serialise_vkCreateCommandPool(SerialiserType &ser, VkDevice
|
||||
{
|
||||
ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool);
|
||||
GetResourceManager()->AddLiveResource(CmdPool, pool);
|
||||
m_commandQueueFamilies[live] = CreateInfo.queueFamilyIndex;
|
||||
InsertCommandQueueFamily(live, CreateInfo.queueFamilyIndex);
|
||||
}
|
||||
|
||||
AddResource(CmdPool, ResourceType::Pool, "Command Pool");
|
||||
@@ -561,13 +561,18 @@ bool WrappedVulkan::Serialise_vkAllocateCommandBuffers(SerialiserType &ser, VkDe
|
||||
{
|
||||
ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cmd);
|
||||
GetResourceManager()->AddLiveResource(CommandBuffer, cmd);
|
||||
|
||||
m_commandQueueFamilies[live] = m_commandQueueFamilies[GetResID(AllocateInfo.commandPool)];
|
||||
auto cmdQueueFamilyIt = m_commandQueueFamilies.find(GetResID(AllocateInfo.commandPool));
|
||||
if(cmdQueueFamilyIt == m_commandQueueFamilies.end())
|
||||
{
|
||||
RDCERR("Missing queue family for %s", ToStr(GetResID(AllocateInfo.commandPool)).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertCommandQueueFamily(CommandBuffer, cmdQueueFamilyIt->second);
|
||||
InsertCommandQueueFamily(live, cmdQueueFamilyIt->second);
|
||||
}
|
||||
}
|
||||
|
||||
m_commandQueueFamilies[CommandBuffer] =
|
||||
m_commandQueueFamilies[GetResID(AllocateInfo.commandPool)];
|
||||
|
||||
AddResource(CommandBuffer, ResourceType::CommandBuffer, "Command Buffer");
|
||||
DerivedResource(device, CommandBuffer);
|
||||
DerivedResource(AllocateInfo.commandPool, CommandBuffer);
|
||||
@@ -695,6 +700,16 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
auto cmdQueueFamilyIt = m_commandQueueFamilies.find(CommandBuffer);
|
||||
if(cmdQueueFamilyIt == m_commandQueueFamilies.end())
|
||||
{
|
||||
RDCERR("Unknown queue family for %s", ToStr(CommandBuffer).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertCommandQueueFamily(BakedCommandBuffer, cmdQueueFamilyIt->second);
|
||||
}
|
||||
|
||||
m_LastCmdBufferID = CommandBuffer;
|
||||
|
||||
// when loading, allocate a new resource ID for each push descriptor slot in this command buffer
|
||||
@@ -827,6 +842,7 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman
|
||||
// there's no issue with clashes here.
|
||||
m_RerecordCmds[BakedCommandBuffer] = cmd;
|
||||
m_RerecordCmds[m_LastCmdBufferID] = cmd;
|
||||
InsertCommandQueueFamily(GetResID(cmd), FindCommandQueueFamily(m_LastCmdBufferID));
|
||||
|
||||
m_RerecordCmdList.push_back({AllocateInfo.commandPool, cmd});
|
||||
|
||||
@@ -921,6 +937,8 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman
|
||||
}
|
||||
|
||||
ObjDisp(device)->BeginCommandBuffer(Unwrap(cmd), &unwrappedBeginInfo);
|
||||
InsertCommandQueueFamily(GetResourceManager()->GetLiveID(BakedCommandBuffer),
|
||||
FindCommandQueueFamily(BakedCommandBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1050,7 +1068,7 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(SerialiserType &ser, VkCommandB
|
||||
// subpass
|
||||
uint32_t &sub = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass;
|
||||
|
||||
rdcarray<rdcpair<ResourceId, ImageRegionState> > imgbarriers;
|
||||
std::map<ResourceId, ImageState> renderPassEndStates;
|
||||
|
||||
for(sub = m_RenderState.subpass + 1; sub < numSubpasses; sub++)
|
||||
{
|
||||
@@ -1059,51 +1077,43 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(SerialiserType &ser, VkCommandB
|
||||
rdcarray<VkImageMemoryBarrier> subpassBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
GetResourceManager()->RecordBarriers(
|
||||
imgbarriers, m_ImageLayouts, (uint32_t)subpassBarriers.size(), &subpassBarriers[0]);
|
||||
renderPassEndStates, FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)subpassBarriers.size(), subpassBarriers.data());
|
||||
}
|
||||
|
||||
rdcarray<VkImageMemoryBarrier> finalBarriers = GetImplicitRenderPassBarriers(~0U);
|
||||
|
||||
GetResourceManager()->RecordBarriers(imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)finalBarriers.size(), &finalBarriers[0]);
|
||||
GetResourceManager()->RecordBarriers(renderPassEndStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)finalBarriers.size(), finalBarriers.data());
|
||||
|
||||
ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer));
|
||||
|
||||
// undo any implicit transitions we just went through, so that we can pretend that the
|
||||
// image stayed in the same layout as it was when we stopped partially replaying.
|
||||
rdcarray<VkImageMemoryBarrier> revertBarriers;
|
||||
|
||||
for(auto it = imgbarriers.begin(); it != imgbarriers.end(); ++it)
|
||||
for(auto it = renderPassEndStates.begin(); it != renderPassEndStates.end(); ++it)
|
||||
{
|
||||
VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
||||
barrier.srcAccessMask = VK_ACCESS_ALL_READ_BITS | VK_ACCESS_ALL_WRITE_BITS;
|
||||
barrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS | VK_ACCESS_ALL_WRITE_BITS;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = Unwrap(GetResourceManager()->GetCurrentHandle<VkImage>(it->first));
|
||||
|
||||
// go from the layout we ended up in, to the layout we started in
|
||||
barrier.oldLayout = it->second.newLayout;
|
||||
barrier.newLayout = it->second.oldLayout;
|
||||
|
||||
barrier.subresourceRange = it->second.subresourceRange;
|
||||
|
||||
if(barrier.oldLayout != barrier.newLayout &&
|
||||
barrier.newLayout != VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
ResourceId id = it->first;
|
||||
ImageState &endState = it->second;
|
||||
LockedConstImageStateRef current = FindConstImageState(id);
|
||||
if(!current)
|
||||
{
|
||||
SanitiseOldImageLayout(barrier.oldLayout);
|
||||
SanitiseNewImageLayout(barrier.newLayout);
|
||||
|
||||
revertBarriers.push_back(barrier);
|
||||
RDCERR("Unknown image %s", ToStr(id).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageBarrierSequence barriers;
|
||||
endState.Transition(*current, VK_ACCESS_ALL_WRITE_BITS, VK_ACCESS_ALL_READ_BITS,
|
||||
barriers, GetImageTransitionInfo());
|
||||
InlineCleanupImageBarriers(commandBuffer, barriers);
|
||||
if(!barriers.empty())
|
||||
{
|
||||
// This should not happen, because the cleanup barriers are just image layout
|
||||
// transitions, no queue family transitions
|
||||
RDCERR("Partial RenderPass replay cleanup barriers could not all be inlined");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!revertBarriers.empty())
|
||||
{
|
||||
if(SeparateDepthStencil())
|
||||
CombineDepthStencilLayouts(revertBarriers);
|
||||
|
||||
DoPipelineBarrier(commandBuffer, revertBarriers.size(), revertBarriers.data());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1327,12 +1337,12 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman
|
||||
}
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
if(m_FirstEventID == m_LastEventID)
|
||||
GetResourceManager()->ApplyBarriers(
|
||||
m_QueueFamilyIdx, m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts);
|
||||
UpdateImageStates(m_BakedCmdBufferInfo[cmd].imageStates);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1389,7 +1399,8 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddEvent();
|
||||
@@ -1529,7 +1540,8 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass(SerialiserType &ser, VkCommandBuf
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
@@ -1545,7 +1557,8 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass(SerialiserType &ser, VkCommandBuf
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddEvent();
|
||||
@@ -1623,7 +1636,8 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandB
|
||||
}
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
@@ -1641,7 +1655,8 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandB
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers(~0U);
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddImplicitResolveResourceUsage(~0U);
|
||||
@@ -1801,12 +1816,12 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass2(SerialiserType &ser,
|
||||
}
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
if(m_FirstEventID == m_LastEventID)
|
||||
GetResourceManager()->ApplyBarriers(
|
||||
m_QueueFamilyIdx, m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts);
|
||||
UpdateImageStates(m_BakedCmdBufferInfo[cmd].imageStates);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1864,7 +1879,8 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass2(SerialiserType &ser,
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddEvent();
|
||||
@@ -2021,7 +2037,8 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass2(SerialiserType &ser, VkCommandBu
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
@@ -2038,7 +2055,8 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass2(SerialiserType &ser, VkCommandBu
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddEvent();
|
||||
@@ -2135,7 +2153,8 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand
|
||||
}
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
@@ -2146,7 +2165,8 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand
|
||||
rdcarray<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers(~0U);
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddEvent();
|
||||
@@ -2962,14 +2982,25 @@ bool WrappedVulkan::Serialise_vkCmdPipelineBarrier(
|
||||
if(commandBuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
FindCommandQueueFamily(m_LastCmdBufferID),
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
// now sanitise layouts before passing to vulkan
|
||||
for(VkImageMemoryBarrier &barrier : imgBarriers)
|
||||
{
|
||||
SanitiseOldImageLayout(barrier.oldLayout);
|
||||
SanitiseNewImageLayout(barrier.newLayout);
|
||||
if(!IsLoading(m_State) && barrier.oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED)
|
||||
{
|
||||
// This is a transition from PRENITIALIZED, but we've already done this barrier once (when
|
||||
// loading); Since we couldn't transition back to PREINITIALIZED, we instead left the
|
||||
// image in GENERAL.
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SanitiseReplayImageLayout(barrier.oldLayout);
|
||||
}
|
||||
SanitiseReplayImageLayout(barrier.newLayout);
|
||||
}
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
@@ -3372,9 +3403,9 @@ bool WrappedVulkan::Serialise_vkCmdExecuteCommands(SerialiserType &ser, VkComman
|
||||
// merge barriers into parent command buffer
|
||||
for(uint32_t i = 0; i < commandBufferCount; i++)
|
||||
{
|
||||
GetResourceManager()->MergeBarriers(
|
||||
m_BakedCmdBufferInfo[GetResID(commandBuffer)].imgbarriers,
|
||||
m_BakedCmdBufferInfo[GetResID(pCommandBuffers[i])].imgbarriers);
|
||||
ImageState::Merge(m_BakedCmdBufferInfo[GetResID(commandBuffer)].imageStates,
|
||||
m_BakedCmdBufferInfo[GetResID(pCommandBuffers[i])].imageStates,
|
||||
GetImageTransitionInfo());
|
||||
}
|
||||
|
||||
// append deferred indirect copies
|
||||
@@ -3588,9 +3619,8 @@ bool WrappedVulkan::Serialise_vkCmdExecuteCommands(SerialiserType &ser, VkComman
|
||||
#endif
|
||||
rerecordedCmds.push_back(Unwrap(cmd));
|
||||
|
||||
GetResourceManager()->MergeBarriers(
|
||||
m_BakedCmdBufferInfo[GetResID(commandBuffer)].imgbarriers,
|
||||
m_BakedCmdBufferInfo[rerecord].imgbarriers);
|
||||
ImageState::Merge(m_BakedCmdBufferInfo[GetResID(commandBuffer)].imageStates,
|
||||
m_BakedCmdBufferInfo[rerecord].imageStates, GetImageTransitionInfo());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -268,9 +268,7 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(SerialiserType &ser, VkQueue queue,
|
||||
|
||||
BakedCmdBufferInfo &cmdBufInfo = m_BakedCmdBufferInfo[cmd];
|
||||
|
||||
GetResourceManager()->ApplyBarriers(m_CreationInfo.m_Queue[GetResID(queue)],
|
||||
m_BakedCmdBufferInfo[liveCmd].imgbarriers,
|
||||
m_ImageLayouts);
|
||||
UpdateImageStates(m_BakedCmdBufferInfo[liveCmd].imageStates);
|
||||
|
||||
rdcstr name = StringFormat::Fmt("=> %s[%u]: vkBeginCommandBuffer(%s)", basename.c_str(),
|
||||
c, ToStr(cmd).c_str());
|
||||
@@ -400,9 +398,7 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(SerialiserType &ser, VkQueue queue,
|
||||
#endif
|
||||
rerecordedCmds.push_back(Unwrap(cmd));
|
||||
|
||||
GetResourceManager()->ApplyBarriers(m_CreationInfo.m_Queue[GetResID(queue)],
|
||||
m_BakedCmdBufferInfo[rerecord].imgbarriers,
|
||||
m_ImageLayouts);
|
||||
UpdateImageStates(m_BakedCmdBufferInfo[rerecord].imageStates);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1011,11 +1011,20 @@ bool WrappedVulkan::Serialise_vkBindImageMemory(SerialiserType &ser, VkDevice de
|
||||
|
||||
ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(image), Unwrap(memory), memoryOffset);
|
||||
|
||||
ImageLayouts &layout = m_ImageLayouts[GetResID(image)];
|
||||
layout.isMemoryBound = true;
|
||||
layout.boundMemory = GetResID(memory);
|
||||
layout.boundMemoryOffset = memoryOffset;
|
||||
layout.boundMemorySize = mrq.size;
|
||||
{
|
||||
LockedImageStateRef state = FindImageState(GetResID(image));
|
||||
if(!state)
|
||||
{
|
||||
RDCERR("Binding memory for unknown image %s", ToStr(GetResID(image)).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
state->isMemoryBound = true;
|
||||
state->boundMemory = GetResID(memory);
|
||||
state->boundMemoryOffset = memoryOffset;
|
||||
state->boundMemorySize = mrq.size;
|
||||
}
|
||||
}
|
||||
|
||||
GetResourceDesc(memOrigId).derivedResources.push_back(resOrigId);
|
||||
GetResourceDesc(resOrigId).parentResources.push_back(memOrigId);
|
||||
@@ -1071,7 +1080,13 @@ VkResult WrappedVulkan::vkBindImageMemory(VkDevice device, VkImage image, VkDevi
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ImageLayouts[GetResID(image)].isMemoryBound = true;
|
||||
{
|
||||
LockedImageStateRef state = FindImageState(GetResID(image));
|
||||
if(!state)
|
||||
RDCERR("Binding memory to unknown image %s", ToStr(GetResID(image)).c_str());
|
||||
else
|
||||
state->isMemoryBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1551,39 +1566,13 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
|
||||
|
||||
m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
|
||||
|
||||
VkImageSubresourceRange range;
|
||||
range.baseMipLevel = range.baseArrayLayer = 0;
|
||||
range.levelCount = CreateInfo.mipLevels;
|
||||
range.layerCount = CreateInfo.arrayLayers;
|
||||
|
||||
ImageLayouts &layouts = m_ImageLayouts[live];
|
||||
layouts.imageInfo = ImageInfo(CreateInfo);
|
||||
|
||||
layouts.subresourceStates.clear();
|
||||
|
||||
layouts.initialLayout = CreateInfo.initialLayout;
|
||||
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
if(IsDepthOnlyFormat(CreateInfo.format))
|
||||
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
else if(IsStencilOnlyFormat(CreateInfo.format))
|
||||
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
else if(IsDepthOrStencilFormat(CreateInfo.format))
|
||||
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
// if we don't support separate depth/stencil, track both aspects together
|
||||
if(!SeparateDepthStencil() && IsDepthAndStencilFormat(CreateInfo.format))
|
||||
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
layouts.subresourceStates.push_back(ImageRegionState(
|
||||
VK_QUEUE_FAMILY_IGNORED, range, UNKNOWN_PREV_IMG_LAYOUT, CreateInfo.initialLayout));
|
||||
|
||||
// if we do support separate depth stencil, add a separate stencil aspect tracker
|
||||
if(SeparateDepthStencil() && IsDepthAndStencilFormat(CreateInfo.format))
|
||||
bool inserted = false;
|
||||
auto state = InsertImageState(img, live, CreateInfo, eFrameRef_Unknown, &inserted);
|
||||
if(!inserted)
|
||||
{
|
||||
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
layouts.subresourceStates.push_back(ImageRegionState(
|
||||
VK_QUEUE_FAMILY_IGNORED, range, UNKNOWN_PREV_IMG_LAYOUT, CreateInfo.initialLayout));
|
||||
// Image state already existed.
|
||||
state->wrappedHandle = img;
|
||||
*state = state->InitialState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2121,11 +2110,21 @@ bool WrappedVulkan::Serialise_vkBindImageMemory2(SerialiserType &ser, VkDevice d
|
||||
if(!ok)
|
||||
return false;
|
||||
|
||||
ImageLayouts &imageLayouts = m_ImageLayouts[GetResID(bindInfo.image)];
|
||||
imageLayouts.isMemoryBound = true;
|
||||
imageLayouts.boundMemory = GetResID(bindInfo.memory);
|
||||
imageLayouts.boundMemoryOffset = bindInfo.memoryOffset;
|
||||
imageLayouts.boundMemorySize = mrq.size;
|
||||
{
|
||||
ResourceId id = GetResID(bindInfo.image);
|
||||
LockedImageStateRef state = FindImageState(id);
|
||||
if(!state)
|
||||
{
|
||||
RDCERR("Binding memory for unknown image %s", ToStr(id).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
state->isMemoryBound = true;
|
||||
state->boundMemory = GetResID(bindInfo.memory);
|
||||
state->boundMemoryOffset = bindInfo.memoryOffset;
|
||||
state->boundMemorySize = mrq.size;
|
||||
}
|
||||
}
|
||||
|
||||
GetResourceDesc(memOrigId).derivedResources.push_back(resOrigId);
|
||||
GetResourceDesc(resOrigId).parentResources.push_back(memOrigId);
|
||||
@@ -2193,7 +2192,13 @@ VkResult WrappedVulkan::vkBindImageMemory2(VkDevice device, uint32_t bindInfoCou
|
||||
else
|
||||
{
|
||||
for(uint32_t i = 0; i < bindInfoCount; i++)
|
||||
m_ImageLayouts[GetResID(pBindInfos[i].image)].isMemoryBound = true;
|
||||
{
|
||||
LockedImageStateRef state = FindImageState(GetResID(pBindInfos[i].image));
|
||||
if(!state)
|
||||
state->isMemoryBound = true;
|
||||
else
|
||||
RDCERR("Binding memory to unknown image %s", ToStr(GetResID(pBindInfos[i].image)).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -841,8 +841,9 @@ bool WrappedVulkan::Serialise_vkCmdWaitEvents(
|
||||
}
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), &imgBarriers[0]);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imageStates,
|
||||
m_commandQueueFamilies[cmd], (uint32_t)imgBarriers.size(),
|
||||
&imgBarriers[0]);
|
||||
|
||||
if(commandBuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
|
||||
@@ -441,22 +441,11 @@ bool WrappedVulkan::Serialise_vkCreateSwapchainKHR(SerialiserType &ser, VkDevice
|
||||
|
||||
m_CreationInfo.m_Names[liveId] = StringFormat::Fmt("Presentable Image %u", i);
|
||||
|
||||
VkImageSubresourceRange range;
|
||||
range.baseMipLevel = range.baseArrayLayer = 0;
|
||||
range.levelCount = 1;
|
||||
range.layerCount = CreateInfo.imageArrayLayers;
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
ImageLayouts &layouts = m_ImageLayouts[liveId];
|
||||
|
||||
layouts.imageInfo = swapinfo.imageInfo;
|
||||
|
||||
layouts.isMemoryBound = true;
|
||||
layouts.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
layouts.subresourceStates.clear();
|
||||
layouts.subresourceStates.push_back(ImageRegionState(
|
||||
VK_QUEUE_FAMILY_IGNORED, range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED));
|
||||
{
|
||||
LockedImageStateRef state =
|
||||
InsertImageState(im, liveId, ImageInfo(swapinfo.imageInfo), eFrameRef_Unknown);
|
||||
state->isMemoryBound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user