Size readback buffer for initial states based on what we need

* No need to base readback buffer on image memory requirements which
  could be packed tighter than our requirements for readback (e.g. depth
  and stencil combined formats)
This commit is contained in:
baldurk
2016-07-13 16:49:10 +02:00
parent bf707845d1
commit a7dc5f207f
+18 -14
View File
@@ -1030,9 +1030,10 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
layout = &m_ImageLayouts[im->id];
}
// get requirements to allocate memory large enough for all slices/mips
VkMemoryRequirements immrq = {0};
ObjDisp(d)->GetImageMemoryRequirements(Unwrap(d), im->real.As<VkImage>(), &immrq);
// must ensure offset remains valid. Must be multiple of block size, or 4, depending on format
VkDeviceSize bufAlignment = 4;
if(IsBlockFormat(layout->format))
bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, layout->format, 0);
VkDeviceMemory readbackmem = VK_NULL_HANDLE;
@@ -1040,10 +1041,21 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
NULL,
0,
immrq.size,
0,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
};
for(int a = 0; a < layout->layerCount; a++)
{
for(int m = 0; m < layout->levelCount; m++)
{
bufInfo.size = AlignUp(bufInfo.size, bufAlignment);
bufInfo.size += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, layout->format, m);
}
}
// since this is very short lived, it is not wrapped
VkBuffer dstBuf;
@@ -1111,11 +1123,6 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
VkDeviceSize bufOffset = 0;
// must ensure offset remains valid. Must be multiple of block size, or 4, depending on format
VkDeviceSize bufAlignment = 4;
if(IsBlockFormat(layout->format))
bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, layout->format, 0);
// loop over every slice/mip, copying it to the appropriate point in the buffer
for(int a = 0; a < layout->layerCount; a++)
{
@@ -1151,8 +1158,8 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
}
}
RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= mrq.size, bufOffset, mrq.size,
layout->extent, layout->format, layout->layerCount, layout->levelCount);
RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= bufInfo.size, bufOffset,
mrq.size, layout->extent, layout->format, layout->layerCount, layout->levelCount);
// transfer back to whatever it was
srcimBarrier.oldLayout = srcimBarrier.newLayout;
@@ -1706,9 +1713,6 @@ bool WrappedVulkan::Serialise_InitialState(ResourceId resid, WrappedVkRes *)
}
}
RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= mrq.size, bufOffset, mrq.size,
imInfo.extent, imInfo.format, imInfo.arrayLayers, imInfo.mipLevels);
vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd));
RDCASSERTEQUAL(vkr, VK_SUCCESS);