mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 06:56:40 +00:00
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:
committed by
Baldur Karlsson
parent
e66acc5429
commit
aa62d20477
@@ -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, ®ion);
|
||||
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ®ion = 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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user