Vulkan: Make image info available through ResourceInfo

The image info (layerCount, levelCount, sampleCount, extent, format,
type)  was previously only available through `ImageLayouts`. This info
is now also stored in `ResourceInfo`.

Storing this in `ResourceInfo` makes this info easily accessible from
`VkResourceRecord`s representing `VkImage`s and `VkImageView`s. This
simplifies upcoming changes to the image tracking and avoids the lock
protecting the `m_ImageLayouts` map.

To simplify this duplication, a new struct `ImageInfo` is added here to
hold the image info in both `ResourceInfo` and `ImageLayouts`.

Change-Id: I390cbba4c3ce7b0bd6f004521497c21bf4c1e97f
This commit is contained in:
Benson Joeris
2019-06-13 18:33:03 +01:00
committed by Baldur Karlsson
parent e66acc5429
commit aa62d20477
10 changed files with 167 additions and 135 deletions
+40 -36
View File
@@ -97,8 +97,10 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
VkResult vkr = VK_SUCCESS;
WrappedVkImage *im = (WrappedVkImage *)res;
const ResourceInfo &resInfo = *im->record->resInfo;
const ImageInfo &imageInfo = resInfo.imageInfo;
if(im->record->resInfo && im->record->resInfo->IsSparse())
if(resInfo.IsSparse())
{
// if the image is sparse we have to do a different kind of initial state prepare,
// to serialise out the page mapping. The fetching of memory is also different
@@ -133,8 +135,8 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
// 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);
if(IsBlockFormat(imageInfo.format))
bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, imageInfo.format, 0);
VkBufferCreateInfo bufInfo = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -147,23 +149,23 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
VkImage arrayIm = VK_NULL_HANDLE;
VkImage realim = im->real.As<VkImage>();
int numLayers = layout->layerCount;
int numLayers = imageInfo.layerCount;
if(layout->sampleCount > 1)
if(imageInfo.sampleCount > 1)
{
// first decompose to array
numLayers *= layout->sampleCount;
numLayers *= imageInfo.sampleCount;
VkImageCreateInfo arrayInfo = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
VK_IMAGE_TYPE_2D, layout->format, layout->extent, (uint32_t)layout->levelCount,
VK_IMAGE_TYPE_2D, imageInfo.format, imageInfo.extent, (uint32_t)imageInfo.levelCount,
(uint32_t)numLayers, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
VK_SHARING_MODE_EXCLUSIVE, 0, NULL, VK_IMAGE_LAYOUT_UNDEFINED,
};
if(IsDepthOrStencilFormat(layout->format))
if(IsDepthOrStencilFormat(imageInfo.format))
arrayInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
else
arrayInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
@@ -184,13 +186,13 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
// backing the array image only.
}
uint32_t planeCount = GetYUVPlaneCount(layout->format);
uint32_t planeCount = GetYUVPlaneCount(imageInfo.format);
uint32_t horizontalPlaneShift = 0;
uint32_t verticalPlaneShift = 0;
if(planeCount > 1)
{
switch(layout->format)
switch(imageInfo.format)
{
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
@@ -222,11 +224,11 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
}
}
VkFormat sizeFormat = GetDepthOnlyFormat(layout->format);
VkFormat sizeFormat = GetDepthOnlyFormat(imageInfo.format);
for(int a = 0; a < numLayers; a++)
{
for(int m = 0; m < layout->levelCount; m++)
for(int m = 0; m < imageInfo.levelCount; m++)
{
bufInfo.size = AlignUp(bufInfo.size, bufAlignment);
@@ -235,21 +237,21 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
// need to consider each plane aspect separately. We simplify the calculation by just
// aligning up the width to a multiple of 4, that ensures each plane will start at a
// multiple of 4 because the rowpitch must be a multiple of 4
bufInfo.size += GetByteSize(AlignUp4(layout->extent.width), layout->extent.height,
layout->extent.depth, sizeFormat, m);
bufInfo.size += GetByteSize(AlignUp4(imageInfo.extent.width), imageInfo.extent.height,
imageInfo.extent.depth, sizeFormat, m);
}
else
{
bufInfo.size += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, sizeFormat, m);
bufInfo.size += GetByteSize(imageInfo.extent.width, imageInfo.extent.height,
imageInfo.extent.depth, sizeFormat, m);
if(sizeFormat != layout->format)
if(sizeFormat != imageInfo.format)
{
// if there's stencil and depth, allocate space for stencil
bufInfo.size = AlignUp(bufInfo.size, bufAlignment);
bufInfo.size += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, VK_FORMAT_S8_UINT, m);
bufInfo.size += GetByteSize(imageInfo.extent.width, imageInfo.extent.height,
imageInfo.extent.depth, VK_FORMAT_S8_UINT, m);
}
}
}
@@ -284,11 +286,11 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
}
VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
if(IsStencilOnlyFormat(layout->format))
if(IsStencilOnlyFormat(imageInfo.format))
{
aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT;
}
else if(IsDepthOrStencilFormat(layout->format))
else if(IsDepthOrStencilFormat(imageInfo.format))
{
aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
}
@@ -311,10 +313,10 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
layout->queueFamilyIndex,
m_QueueFamilyIdx,
realim,
{aspectFlags, 0, (uint32_t)layout->levelCount, 0, (uint32_t)numLayers},
{aspectFlags, 0, (uint32_t)imageInfo.levelCount, 0, (uint32_t)numLayers},
};
if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT && !IsDepthOnlyFormat(layout->format))
if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT && !IsDepthOnlyFormat(imageInfo.format))
srcimBarrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
// update the real image layout into transfer-source
@@ -369,8 +371,9 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd));
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetDebugManager()->CopyTex2DMSToArray(Unwrap(arrayIm), realim, layout->extent,
layout->layerCount, layout->sampleCount, layout->format);
GetDebugManager()->CopyTex2DMSToArray(Unwrap(arrayIm), realim, imageInfo.extent,
imageInfo.layerCount, imageInfo.sampleCount,
imageInfo.format);
cmd = GetNextCmd();
@@ -393,9 +396,9 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
// loop over every slice/mip, copying it to the appropriate point in the buffer
for(int a = 0; a < numLayers; a++)
{
VkExtent3D extent = layout->extent;
VkExtent3D extent = imageInfo.extent;
for(int m = 0; m < layout->levelCount; m++)
for(int m = 0; m < imageInfo.levelCount; m++)
{
VkBufferImageCopy region = {
0,
@@ -425,8 +428,8 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
region.imageExtent.height >>= verticalPlaneShift;
}
bufOffset += GetPlaneByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, sizeFormat, m, i);
bufOffset += GetPlaneByteSize(imageInfo.extent.width, imageInfo.extent.height,
imageInfo.extent.depth, sizeFormat, m, i);
ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), realim,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(dstBuf),
@@ -439,13 +442,13 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
region.bufferOffset = bufOffset;
bufOffset += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, sizeFormat, m);
bufOffset += GetByteSize(imageInfo.extent.width, imageInfo.extent.height,
imageInfo.extent.depth, sizeFormat, m);
ObjDisp(d)->CmdCopyImageToBuffer(
Unwrap(cmd), realim, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(dstBuf), 1, &region);
if(sizeFormat != layout->format)
if(sizeFormat != imageInfo.format)
{
// if we removed stencil from the format, copy that separately now.
bufOffset = AlignUp(bufOffset, bufAlignment);
@@ -453,8 +456,8 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
bufOffset += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, VK_FORMAT_S8_UINT, m);
bufOffset += GetByteSize(imageInfo.extent.width, imageInfo.extent.height,
imageInfo.extent.depth, VK_FORMAT_S8_UINT, m);
ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), realim,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(dstBuf),
@@ -470,7 +473,8 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
}
RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= bufInfo.size, bufOffset,
readbackmem.size, layout->extent, layout->format, numLayers, layout->levelCount);
readbackmem.size, imageInfo.extent, imageInfo.format, numLayers,
imageInfo.levelCount);
// transfer back to whatever it was
srcimBarrier.oldLayout = srcimBarrier.newLayout;
@@ -1382,7 +1386,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
{
if(initial.tag == VkInitialContents::ClearColorImage)
{
VkFormat format = m_ImageLayouts[id].format;
VkFormat format = m_ImageLayouts[id].imageInfo.format;
if(IsBlockFormat(format) || IsYUVFormat(format))
{
+10 -7
View File
@@ -210,7 +210,7 @@ void VulkanResourceManager::RecordBarriers(std::vector<rdcpair<ResourceId, Image
if(nummips == VK_REMAINING_MIP_LEVELS)
{
if(it != layouts.end())
nummips = it->second.levelCount - t.subresourceRange.baseMipLevel;
nummips = it->second.imageInfo.levelCount - t.subresourceRange.baseMipLevel;
else
nummips = 1;
}
@@ -218,7 +218,7 @@ void VulkanResourceManager::RecordBarriers(std::vector<rdcpair<ResourceId, Image
if(numslices == VK_REMAINING_ARRAY_LAYERS)
{
if(it != layouts.end())
numslices = it->second.layerCount - t.subresourceRange.baseArrayLayer;
numslices = it->second.imageInfo.layerCount - t.subresourceRange.baseArrayLayer;
else
numslices = 1;
}
@@ -370,9 +370,10 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
for(auto it = states.begin(); it != states.end(); ++it)
{
ImageLayouts &layouts = it->second;
const ImageInfo &imageInfo = layouts.imageInfo;
if(layouts.subresourceStates.size() > 1 &&
layouts.subresourceStates.size() == size_t(layouts.layerCount * layouts.levelCount))
layouts.subresourceStates.size() == size_t(imageInfo.layerCount * imageInfo.levelCount))
{
VkImageLayout layout = layouts.subresourceStates[0].newLayout;
@@ -393,8 +394,8 @@ void VulkanResourceManager::SerialiseImageStates(SerialiserType &ser,
layouts.subresourceStates.end());
layouts.subresourceStates[0].subresourceRange.baseArrayLayer = 0;
layouts.subresourceStates[0].subresourceRange.baseMipLevel = 0;
layouts.subresourceStates[0].subresourceRange.layerCount = layouts.layerCount;
layouts.subresourceStates[0].subresourceRange.levelCount = layouts.levelCount;
layouts.subresourceStates[0].subresourceRange.layerCount = imageInfo.layerCount;
layouts.subresourceStates[0].subresourceRange.levelCount = imageInfo.levelCount;
}
}
}
@@ -538,12 +539,14 @@ void VulkanResourceManager::ApplyBarriers(uint32_t queueFamilyIndex,
if(t.dstQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED)
stit->second.queueFamilyIndex = queueFamilyIndex;
const ImageInfo &imageInfo = stit->second.imageInfo;
uint32_t nummips = t.subresourceRange.levelCount;
uint32_t numslices = t.subresourceRange.layerCount;
if(nummips == VK_REMAINING_MIP_LEVELS)
nummips = layouts[id].levelCount;
nummips = imageInfo.levelCount;
if(numslices == VK_REMAINING_ARRAY_LAYERS)
numslices = layouts[id].layerCount;
numslices = imageInfo.layerCount;
if(nummips == 0)
nummips = 1;
+4 -3
View File
@@ -164,6 +164,7 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
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;
CreateTexImageView(liveIm, iminfo, cfg.typeHint, texviews);
@@ -189,14 +190,14 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
int viewIndex = 0;
// if we're displaying the stencil, set up for stencil display
if(layouts.format == VK_FORMAT_S8_UINT ||
(IsStencilFormat(layouts.format) && !cfg.red && cfg.green))
if(imageInfo.format == VK_FORMAT_S8_UINT ||
(IsStencilFormat(imageInfo.format) && !cfg.red && cfg.green))
{
descSetBinding = 10;
displayformat |= TEXDISPLAY_UINT_TEX;
// for stencil we use view 1 as long as it's a depth-stencil texture
if(IsDepthAndStencilFormat(layouts.format))
if(IsDepthAndStencilFormat(imageInfo.format))
viewIndex = 1;
// rescale the range so that stencil seems to fit to 0-1
+1 -1
View File
@@ -1788,7 +1788,7 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip,
{
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid];
if(IsDepthAndStencilFormat(layouts.format))
if(IsDepthAndStencilFormat(layouts.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
+9 -5
View File
@@ -3075,9 +3075,11 @@ void VkResourceRecord::MarkBufferFrameReferenced(VkResourceRecord *buf, VkDevice
MarkMemoryFrameReferenced(buf->baseResource, buf->memOffset + offset, size, refType);
}
void VkResourceRecord::MarkBufferImageCopyFrameReferenced(
VkResourceRecord *buf, VkResourceRecord *img, const ImageLayouts &layout, uint32_t regionCount,
const VkBufferImageCopy *regions, FrameRefType bufRefType, FrameRefType imgRefType)
void VkResourceRecord::MarkBufferImageCopyFrameReferenced(VkResourceRecord *buf,
VkResourceRecord *img, uint32_t regionCount,
const VkBufferImageCopy *regions,
FrameRefType bufRefType,
FrameRefType imgRefType)
{
MarkResourceFrameReferenced(img->GetResourceID(), imgRefType);
MarkResourceFrameReferenced(img->baseResource, imgRefType);
@@ -3088,16 +3090,18 @@ void VkResourceRecord::MarkBufferImageCopyFrameReferenced(
// mark buffer just as read
MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read);
VkFormat imgFormat = img->resInfo->imageInfo.format;
for(uint32_t ri = 0; ri < regionCount; ri++)
{
const VkBufferImageCopy &region = regions[ri];
VkFormat regionFormat = layout.format;
VkFormat regionFormat = imgFormat;
uint32_t plane = 0;
switch(region.imageSubresource.aspectMask)
{
case VK_IMAGE_ASPECT_STENCIL_BIT: regionFormat = VK_FORMAT_S8_UINT; break;
case VK_IMAGE_ASPECT_DEPTH_BIT: regionFormat = GetDepthOnlyFormat(layout.format); break;
case VK_IMAGE_ASPECT_DEPTH_BIT: regionFormat = GetDepthOnlyFormat(imgFormat); break;
case VK_IMAGE_ASPECT_PLANE_1_BIT: plane = 1; break;
case VK_IMAGE_ASPECT_PLANE_2_BIT: plane = 2; break;
default: break;
+47 -26
View File
@@ -879,6 +879,39 @@ struct SwapchainInfo
uint32_t lastPresent;
};
struct ImageInfo
{
int layerCount = 0;
int levelCount = 0;
int sampleCount = 0;
VkExtent3D extent = {0, 0, 0};
VkFormat format = VK_FORMAT_UNDEFINED;
VkImageType imageType = VK_IMAGE_TYPE_MAX_ENUM;
ImageInfo() {}
ImageInfo(const VkImageCreateInfo &ci)
: layerCount(ci.arrayLayers),
levelCount(ci.mipLevels),
sampleCount((int)ci.samples),
extent(ci.extent),
format(ci.format),
imageType(ci.imageType)
{
}
ImageInfo(const SwapchainInfo &swapInfo)
: layerCount(swapInfo.arraySize),
levelCount(1),
sampleCount(1),
format(swapInfo.format),
imageType(VK_IMAGE_TYPE_2D)
{
extent.width = swapInfo.extent.width;
extent.height = swapInfo.extent.height;
extent.depth = 1;
}
};
DECLARE_REFLECTION_STRUCT(ImageInfo);
// these structs are allocated for images and buffers, then pointed to (non-owning) by views
struct ResourceInfo
{
@@ -903,6 +936,8 @@ struct ResourceInfo
// in order of width first, then height, then depth
rdcpair<VkDeviceMemory, VkDeviceSize> *pages[NUM_VK_IMAGE_ASPECTS];
ImageInfo imageInfo;
bool IsSparse() const { return pages[0] != NULL; }
void Update(uint32_t numBindings, const VkSparseMemoryBind *pBindings);
void Update(uint32_t numBindings, const VkSparseImageMemoryBind *pBindings);
@@ -1274,14 +1309,14 @@ struct ImageLayouts;
template <typename Compose>
FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, ResourceId img,
const ImageLayouts &layout, const ImageRange &range,
const ImageInfo &imageInfo, const ImageRange &range,
FrameRefType refType, Compose comp);
inline FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, ResourceId img,
const ImageLayouts &layout, const ImageRange &range,
const ImageInfo &imageInfo, const ImageRange &range,
FrameRefType refType)
{
return MarkImageReferenced(imgRefs, img, layout, range, refType, ComposeFrameRefs);
return MarkImageReferenced(imgRefs, img, imageInfo, range, refType, ComposeFrameRefs);
}
template <typename Compose>
@@ -1443,9 +1478,8 @@ public:
void MarkBufferFrameReferenced(VkResourceRecord *buf, VkDeviceSize offset, VkDeviceSize size,
FrameRefType refType);
void MarkBufferImageCopyFrameReferenced(VkResourceRecord *buf, VkResourceRecord *img,
const ImageLayouts &layout, uint32_t regionCount,
const VkBufferImageCopy *regions, FrameRefType bufRefType,
FrameRefType imgRefType);
uint32_t regionCount, const VkBufferImageCopy *regions,
FrameRefType bufRefType, FrameRefType imgRefType);
void MarkBufferViewFrameReferenced(VkResourceRecord *buf, FrameRefType refType);
// these are all disjoint, so only a record of the right type will have each
// Note some of these need to be deleted in the constructor, so we check the
@@ -1549,24 +1583,11 @@ public:
struct ImageLayouts
{
ImageLayouts()
: layerCount(1),
levelCount(1),
sampleCount(1),
format(VK_FORMAT_UNDEFINED),
imageType(VK_IMAGE_TYPE_MAX_ENUM)
{
extent.width = extent.height = extent.depth = 1;
}
uint32_t queueFamilyIndex = 0;
std::vector<ImageRegionState> subresourceStates;
int layerCount, levelCount, sampleCount;
VkExtent3D extent;
VkFormat format;
VkImageType imageType;
bool memoryBound = false;
VkImageLayout initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
ImageInfo imageInfo;
};
DECLARE_REFLECTION_STRUCT(ImageLayouts);
@@ -1598,7 +1619,7 @@ uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFor
template <typename Compose>
FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, ResourceId img,
const ImageLayouts &layout, const ImageRange &range,
const ImageInfo &imageInfo, const ImageRange &range,
FrameRefType refType, Compose comp)
{
if(refType == eFrameRef_None)
@@ -1606,11 +1627,11 @@ FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, Resourc
auto refs = imgRefs.find(img);
if(refs == imgRefs.end())
{
refs =
imgRefs
.insert(std::make_pair(img, ImgRefs(layout.imageType, FormatImageAspects(layout.format),
layout.levelCount, layout.layerCount, layout.extent)))
.first;
refs = imgRefs
.insert(std::make_pair(
img, ImgRefs(imageInfo.imageType, FormatImageAspects(imageInfo.format),
imageInfo.levelCount, imageInfo.layerCount, imageInfo.extent)))
.first;
}
return refs->second.Update(range, refType, comp);
}
+7 -1
View File
@@ -3423,6 +3423,12 @@ void DoSerialise(SerialiserType &ser, ImageLayouts &el)
SERIALISE_MEMBER(queueFamilyIndex);
}
SERIALISE_MEMBER(subresourceStates);
SERIALISE_MEMBER(imageInfo);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, ImageInfo &el)
{
SERIALISE_MEMBER(layerCount);
SERIALISE_MEMBER(levelCount);
SERIALISE_MEMBER(sampleCount);
@@ -7455,4 +7461,4 @@ INSTANTIATE_SERIALISE_TYPE(VkFenceGetWin32HandleInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkSurfaceCapabilitiesFullScreenExclusiveEXT);
INSTANTIATE_SERIALISE_TYPE(VkSurfaceFullScreenExclusiveInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkSurfaceFullScreenExclusiveWin32InfoEXT);
#endif
#endif
@@ -1770,8 +1770,8 @@ void WrappedVulkan::vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuff
record->AddChunk(scope.Get());
record->MarkBufferImageCopyFrameReferenced(GetRecord(srcBuffer), GetRecord(destImage),
m_ImageLayouts[GetResID(destImage)], regionCount,
pRegions, eFrameRef_Read, eFrameRef_PartialWrite);
regionCount, pRegions, eFrameRef_Read,
eFrameRef_PartialWrite);
}
}
@@ -1878,8 +1878,8 @@ void WrappedVulkan::vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImag
record->AddChunk(scope.Get());
record->MarkBufferImageCopyFrameReferenced(GetRecord(destBuffer), GetRecord(srcImage),
m_ImageLayouts[GetResID(srcImage)], regionCount,
pRegions, eFrameRef_CompleteWrite, eFrameRef_Read);
regionCount, pRegions, eFrameRef_CompleteWrite,
eFrameRef_Read);
}
}
@@ -1467,14 +1467,10 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
range.layerCount = CreateInfo.arrayLayers;
ImageLayouts &layouts = m_ImageLayouts[live];
layouts.imageInfo = ImageInfo(CreateInfo);
layouts.subresourceStates.clear();
layouts.layerCount = CreateInfo.arrayLayers;
layouts.sampleCount = (int)CreateInfo.samples;
layouts.levelCount = CreateInfo.mipLevels;
layouts.extent = CreateInfo.extent;
layouts.format = CreateInfo.format;
layouts.imageType = CreateInfo.imageType;
layouts.initialLayout = CreateInfo.initialLayout;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@@ -1621,6 +1617,13 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pImage);
record->AddChunk(chunk);
record->resInfo = new ResourceInfo();
ResourceInfo &resInfo = *record->resInfo;
resInfo.imageInfo = ImageInfo(*pCreateInfo);
// pre-populate memory requirements
ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(*pImage), &resInfo.memreqs);
bool isSparse = (pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT |
VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) != 0;
@@ -1646,14 +1649,8 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
// sure to fetch their contents even if we don't see any writes.
if(isSparse || isExternal)
{
record->resInfo = new ResourceInfo();
GetResourceManager()->MarkDirtyResource(id);
// pre-populate memory requirements
ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(*pImage),
&record->resInfo->memreqs);
// for external images, try creating a non-external version and take the worst case of
// memory requirements, in case the non-external one (as we will replay it) needs more
// memory or a stricter alignment
@@ -1679,16 +1676,15 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
if(mrq.size > 0)
{
RDCDEBUG("External image requires %llu bytes at %llu alignment, in %x memory types",
record->resInfo->memreqs.size, record->resInfo->memreqs.alignment,
record->resInfo->memreqs.memoryTypeBits);
resInfo.memreqs.size, resInfo.memreqs.alignment,
resInfo.memreqs.memoryTypeBits);
RDCDEBUG(
"Non-external version requires %llu bytes at %llu alignment, in %x memory types",
mrq.size, mrq.alignment, mrq.memoryTypeBits);
record->resInfo->memreqs.size = RDCMAX(record->resInfo->memreqs.size, mrq.size);
record->resInfo->memreqs.alignment =
RDCMAX(record->resInfo->memreqs.size, mrq.alignment);
record->resInfo->memreqs.memoryTypeBits &= mrq.memoryTypeBits;
resInfo.memreqs.size = RDCMAX(resInfo.memreqs.size, mrq.size);
resInfo.memreqs.alignment = RDCMAX(resInfo.memreqs.size, mrq.alignment);
resInfo.memreqs.memoryTypeBits &= mrq.memoryTypeBits;
}
}
else
@@ -1714,22 +1710,20 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
RDCASSERT(numreqs > 0);
record->resInfo->pagedim = reqs[0].formatProperties.imageGranularity;
record->resInfo->imgdim = pCreateInfo->extent;
record->resInfo->imgdim.width /= record->resInfo->pagedim.width;
record->resInfo->imgdim.height /= record->resInfo->pagedim.height;
record->resInfo->imgdim.depth /= record->resInfo->pagedim.depth;
resInfo.pagedim = reqs[0].formatProperties.imageGranularity;
resInfo.imgdim = pCreateInfo->extent;
resInfo.imgdim.width /= resInfo.pagedim.width;
resInfo.imgdim.height /= resInfo.pagedim.height;
resInfo.imgdim.depth /= resInfo.pagedim.depth;
uint32_t numpages = record->resInfo->imgdim.width * record->resInfo->imgdim.height *
record->resInfo->imgdim.depth;
uint32_t numpages = resInfo.imgdim.width * resInfo.imgdim.height * resInfo.imgdim.depth;
for(uint32_t i = 0; i < numreqs; i++)
{
// assume all page sizes are the same for all aspects
RDCASSERT(
record->resInfo->pagedim.width == reqs[i].formatProperties.imageGranularity.width &&
record->resInfo->pagedim.height == reqs[i].formatProperties.imageGranularity.height &&
record->resInfo->pagedim.depth == reqs[i].formatProperties.imageGranularity.depth);
RDCASSERT(resInfo.pagedim.width == reqs[i].formatProperties.imageGranularity.width &&
resInfo.pagedim.height == reqs[i].formatProperties.imageGranularity.height &&
resInfo.pagedim.depth == reqs[i].formatProperties.imageGranularity.depth);
int a = 0;
for(a = 0; a < NUM_VK_IMAGE_ASPECTS; a++)
@@ -1738,7 +1732,7 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
break;
}
record->resInfo->pages[a] = new rdcpair<VkDeviceMemory, VkDeviceSize>[numpages];
resInfo.pages[a] = new rdcpair<VkDeviceMemory, VkDeviceSize>[numpages];
}
}
else
@@ -1765,15 +1759,9 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
SCOPED_LOCK(m_ImageLayoutsLock);
layout = &m_ImageLayouts[id];
}
layout->imageInfo = ImageInfo(*pCreateInfo);
layout->layerCount = pCreateInfo->arrayLayers;
layout->levelCount = pCreateInfo->mipLevels;
layout->sampleCount = (int)pCreateInfo->samples;
layout->extent = pCreateInfo->extent;
layout->format = pCreateInfo->format;
layout->imageType = pCreateInfo->imageType;
layout->initialLayout = pCreateInfo->initialLayout;
layout->subresourceStates.clear();
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@@ -298,6 +298,9 @@ VkResult WrappedVulkan::vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR
record->AddParent(swaprecord);
record->resInfo = new ResourceInfo();
record->resInfo->imageInfo = ImageInfo(*swaprecord->swapInfo);
// note we add the chunk to the swap record, that way when the swapchain is created it will
// always create all of its images on replay. The image's record is kept around for
// reference tracking and any other chunks. Because it has a parent relationship on the
@@ -446,14 +449,15 @@ bool WrappedVulkan::Serialise_vkCreateSwapchainKHR(SerialiserType &ser, VkDevice
range.layerCount = CreateInfo.imageArrayLayers;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
m_ImageLayouts[liveId].extent = iminfo.extent;
m_ImageLayouts[liveId].format = iminfo.format;
m_ImageLayouts[liveId].imageType = iminfo.type;
m_ImageLayouts[liveId].memoryBound = true;
m_ImageLayouts[liveId].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
ImageLayouts &layouts = m_ImageLayouts[liveId];
m_ImageLayouts[liveId].subresourceStates.clear();
m_ImageLayouts[liveId].subresourceStates.push_back(ImageRegionState(
layouts.imageInfo = ImageInfo(swapinfo);
layouts.memoryBound = 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));
}
}
@@ -584,17 +588,18 @@ void WrappedVulkan::WrapAndProcessCreatedSwapchain(VkDevice device,
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
// fill out image info so we track resource state barriers
ImageLayouts *layout = NULL;
{
SCOPED_LOCK(m_ImageLayoutsLock);
m_ImageLayouts[imid].format = pCreateInfo->imageFormat;
m_ImageLayouts[imid].imageType = VK_IMAGE_TYPE_2D;
m_ImageLayouts[imid].memoryBound = true;
m_ImageLayouts[imid].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_ImageLayouts[imid].subresourceStates.clear();
m_ImageLayouts[imid].subresourceStates.push_back(ImageRegionState(
VK_QUEUE_FAMILY_IGNORED, range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED));
layout = &m_ImageLayouts[imid];
}
layout->imageInfo = GetRecord(images[i])->resInfo->imageInfo;
layout->memoryBound = true;
layout->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
layout->subresourceStates.clear();
layout->subresourceStates.push_back(ImageRegionState(
VK_QUEUE_FAMILY_IGNORED, range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED));
{
VkImageViewCreateInfo info = {