mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-13 02:56:59 +00:00
More precise memory tracking for vkCmdCopyImageToBuffer
This change tracks the exact memory regions of the buffer accessed in `vkCmdCopyBufferToImage` and `vkCmdCopyImageToBuffer`. In the case of `vkCmdCopyImageToBuffer`, using the exact memory regions allows the buffer write to be treated as a `CompleteWrite` (instead of `PartialWrite`).
This commit is contained in:
committed by
Baldur Karlsson
parent
d6b706b132
commit
a7b21ae2d2
@@ -1702,32 +1702,42 @@ uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFor
|
||||
return GetByteSize(Width, Height, Depth, Format, mip);
|
||||
}
|
||||
|
||||
struct TexelShape
|
||||
// The shape of blocks in (a plane of) an image format.
|
||||
// Non-block formats are considered to have 1x1 blocks.
|
||||
// For some planar formats, the block shape depends on the plane--
|
||||
// e.g. VK_FORMAT_G8_B8R8_2PLANE_422_UNORM has 8 bits per 1x1 block in plane 0, but 16 bits per 1x1
|
||||
// block in plane 1.
|
||||
struct BlockShape
|
||||
{
|
||||
// the width of a block, in texels (or 1 for non-block formats)
|
||||
uint32_t width;
|
||||
|
||||
// the height of a block, in texels (or 1 for non-block formats)
|
||||
uint32_t height;
|
||||
|
||||
// the number of bytes used to encode the block
|
||||
uint32_t bytes;
|
||||
};
|
||||
|
||||
TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
BlockShape GetBlockShape(VkFormat Format, uint32_t plane)
|
||||
{
|
||||
switch(Format)
|
||||
{
|
||||
case VK_FORMAT_R64G64B64A64_UINT:
|
||||
case VK_FORMAT_R64G64B64A64_SINT:
|
||||
case VK_FORMAT_R64G64B64A64_SFLOAT: return TexelShape{1, 1, 32};
|
||||
case VK_FORMAT_R64G64B64A64_SFLOAT: return {1, 1, 32};
|
||||
case VK_FORMAT_R64G64B64_UINT:
|
||||
case VK_FORMAT_R64G64B64_SINT:
|
||||
case VK_FORMAT_R64G64B64_SFLOAT: return TexelShape{1, 1, 24};
|
||||
case VK_FORMAT_R64G64B64_SFLOAT: return {1, 1, 24};
|
||||
case VK_FORMAT_R32G32B32A32_UINT:
|
||||
case VK_FORMAT_R32G32B32A32_SINT:
|
||||
case VK_FORMAT_R32G32B32A32_SFLOAT:
|
||||
case VK_FORMAT_R64G64_UINT:
|
||||
case VK_FORMAT_R64G64_SINT:
|
||||
case VK_FORMAT_R64G64_SFLOAT: return TexelShape{1, 1, 16};
|
||||
case VK_FORMAT_R64G64_SFLOAT: return {1, 1, 16};
|
||||
case VK_FORMAT_R32G32B32_UINT:
|
||||
case VK_FORMAT_R32G32B32_SINT:
|
||||
case VK_FORMAT_R32G32B32_SFLOAT: return TexelShape{1, 1, 12};
|
||||
case VK_FORMAT_R32G32B32_SFLOAT: return {1, 1, 12};
|
||||
case VK_FORMAT_R16G16B16A16_UNORM:
|
||||
case VK_FORMAT_R16G16B16A16_SNORM:
|
||||
case VK_FORMAT_R16G16B16A16_USCALED:
|
||||
@@ -1740,15 +1750,15 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_R32G32_SFLOAT:
|
||||
case VK_FORMAT_R64_UINT:
|
||||
case VK_FORMAT_R64_SINT:
|
||||
case VK_FORMAT_R64_SFLOAT: return TexelShape{1, 1, 8};
|
||||
case VK_FORMAT_R64_SFLOAT: return {1, 1, 8};
|
||||
case VK_FORMAT_R16G16B16_UNORM:
|
||||
case VK_FORMAT_R16G16B16_SNORM:
|
||||
case VK_FORMAT_R16G16B16_USCALED:
|
||||
case VK_FORMAT_R16G16B16_SSCALED:
|
||||
case VK_FORMAT_R16G16B16_UINT:
|
||||
case VK_FORMAT_R16G16B16_SINT:
|
||||
case VK_FORMAT_R16G16B16_SFLOAT: return TexelShape{1, 1, 6};
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT: return TexelShape{1, 1, 8};
|
||||
case VK_FORMAT_R16G16B16_SFLOAT: return {1, 1, 6};
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT: return {1, 1, 8};
|
||||
case VK_FORMAT_R8G8B8_UNORM:
|
||||
case VK_FORMAT_R8G8B8_SNORM:
|
||||
case VK_FORMAT_R8G8B8_USCALED:
|
||||
@@ -1762,7 +1772,7 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_B8G8R8_SSCALED:
|
||||
case VK_FORMAT_B8G8R8_UINT:
|
||||
case VK_FORMAT_B8G8R8_SINT:
|
||||
case VK_FORMAT_B8G8R8_SRGB: return TexelShape{1, 1, 3};
|
||||
case VK_FORMAT_B8G8R8_SRGB: return {1, 1, 3};
|
||||
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
|
||||
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
@@ -1810,8 +1820,8 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_X8_D24_UNORM_PACK32:
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
case VK_FORMAT_D32_SFLOAT:
|
||||
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: return TexelShape{1, 1, 4};
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT: return TexelShape{1, 1, 4};
|
||||
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: return {1, 1, 4};
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT: return {1, 1, 4};
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
case VK_FORMAT_R8G8_SNORM:
|
||||
case VK_FORMAT_R8G8_USCALED:
|
||||
@@ -1833,7 +1843,7 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
case VK_FORMAT_B5G6R5_UNORM_PACK16:
|
||||
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||
case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return TexelShape{1, 1, 2};
|
||||
case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return {1, 1, 2};
|
||||
case VK_FORMAT_R4G4_UNORM_PACK8:
|
||||
case VK_FORMAT_R8_UNORM:
|
||||
case VK_FORMAT_R8_SNORM:
|
||||
@@ -1842,7 +1852,7 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_R8_UINT:
|
||||
case VK_FORMAT_R8_SINT:
|
||||
case VK_FORMAT_R8_SRGB:
|
||||
case VK_FORMAT_S8_UINT: return TexelShape{1, 1, 1};
|
||||
case VK_FORMAT_S8_UINT: return {1, 1, 1};
|
||||
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
|
||||
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
|
||||
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
|
||||
@@ -1856,7 +1866,7 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
|
||||
case VK_FORMAT_EAC_R11_UNORM_BLOCK:
|
||||
case VK_FORMAT_EAC_R11_SNORM_BLOCK: return TexelShape{4, 4, 8};
|
||||
case VK_FORMAT_EAC_R11_SNORM_BLOCK: return {4, 4, 8};
|
||||
case VK_FORMAT_BC2_UNORM_BLOCK:
|
||||
case VK_FORMAT_BC2_SRGB_BLOCK:
|
||||
case VK_FORMAT_BC3_UNORM_BLOCK:
|
||||
@@ -1868,44 +1878,44 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_BC7_UNORM_BLOCK:
|
||||
case VK_FORMAT_BC7_SRGB_BLOCK:
|
||||
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
|
||||
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: return TexelShape{4, 4, 16};
|
||||
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: return {4, 4, 16};
|
||||
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: return TexelShape{4, 4, 16};
|
||||
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: return {4, 4, 16};
|
||||
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: return TexelShape{5, 4, 16};
|
||||
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: return {5, 4, 16};
|
||||
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: return TexelShape{5, 5, 16};
|
||||
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: return {5, 5, 16};
|
||||
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: return TexelShape{6, 5, 16};
|
||||
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: return {6, 5, 16};
|
||||
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: return TexelShape{6, 6, 16};
|
||||
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: return {6, 6, 16};
|
||||
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: return TexelShape{8, 5, 16};
|
||||
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: return {8, 5, 16};
|
||||
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: return TexelShape{8, 6, 16};
|
||||
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: return {8, 6, 16};
|
||||
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: return TexelShape{8, 8, 16};
|
||||
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: return {8, 8, 16};
|
||||
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: return TexelShape{10, 5, 16};
|
||||
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: return {10, 5, 16};
|
||||
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: return TexelShape{10, 6, 16};
|
||||
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: return {10, 6, 16};
|
||||
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: return TexelShape{10, 8, 16};
|
||||
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: return {10, 8, 16};
|
||||
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: return TexelShape{10, 10, 16};
|
||||
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: return {10, 10, 16};
|
||||
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: return TexelShape{12, 10, 16};
|
||||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: return {12, 10, 16};
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: return TexelShape{12, 12, 16};
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: return {12, 12, 16};
|
||||
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return TexelShape{8, 4, 8};
|
||||
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return {8, 4, 8};
|
||||
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
|
||||
return TexelShape{4, 4, 8};
|
||||
return {4, 4, 8};
|
||||
|
||||
/*
|
||||
* YUV planar/packed subsampled textures.
|
||||
@@ -1987,33 +1997,33 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_B8G8R8G8_422_UNORM:
|
||||
// 4:2:2 packed 8-bit, so 1 byte per pixel for luma and 1 byte per pixel for chroma (2 chroma
|
||||
// samples, with 50% subsampling = 1 byte per pixel)
|
||||
return TexelShape{2, 1, 4};
|
||||
return {2, 1, 4};
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return TexelShape{1, 1, 1};
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return {1, 1, 1};
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
|
||||
if(plane == 0)
|
||||
return TexelShape{1, 1, 1};
|
||||
return {1, 1, 1};
|
||||
else if(plane == 1)
|
||||
return TexelShape{1, 1, 2};
|
||||
return {1, 1, 2};
|
||||
else
|
||||
RDCERR("Invalid plane %d in 2-plane format", plane);
|
||||
case VK_FORMAT_R10X6_UNORM_PACK16:
|
||||
case VK_FORMAT_R12X4_UNORM_PACK16:
|
||||
// basically just 16-bit format with only top 10-bits used
|
||||
// 10-bit and 12-bit formats are stored identically to 16-bit formats
|
||||
return TexelShape{1, 1, 2};
|
||||
return {1, 1, 2};
|
||||
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
// just a 16-bit format with only top N-bits used
|
||||
// 10-bit and 12-bit formats are stored identically to 16-bit formats
|
||||
return TexelShape{1, 1, 4};
|
||||
return {1, 1, 4};
|
||||
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
|
||||
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
|
||||
// just a 16-bit format with only top N-bits used
|
||||
// 10-bit and 12-bit formats are stored identically to 16-bit formats
|
||||
return TexelShape{1, 1, 8};
|
||||
return {1, 1, 8};
|
||||
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
|
||||
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
|
||||
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
|
||||
@@ -2022,7 +2032,7 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_B16G16R16G16_422_UNORM:
|
||||
// 10-bit and 12-bit formats are stored identically to 16-bit formats
|
||||
// 4:2:2 packed 16-bit
|
||||
return TexelShape{2, 1, 8};
|
||||
return {2, 1, 8};
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
|
||||
@@ -2031,7 +2041,7 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return TexelShape{1, 1, 2};
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return {1, 1, 2};
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
|
||||
@@ -2039,14 +2049,17 @@ TexelShape GetTexelShape(VkFormat Format, uint32_t plane)
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
|
||||
if(plane == 0)
|
||||
return TexelShape{1, 1, 2};
|
||||
return {1, 1, 2};
|
||||
else if(plane == 1)
|
||||
return TexelShape{1, 1, 4};
|
||||
return {1, 1, 4};
|
||||
else
|
||||
RDCERR("Invalid plane %d in 2-plane format", plane);
|
||||
default: RDCERR("Unrecognised Vulkan Format: %d", Format); return TexelShape{};
|
||||
default: RDCERR("Unrecognised Vulkan Format: %d", Format);
|
||||
}
|
||||
|
||||
return BlockShape();
|
||||
}
|
||||
|
||||
ResourceFormat MakeResourceFormat(VkFormat fmt)
|
||||
{
|
||||
ResourceFormat ret;
|
||||
@@ -3401,6 +3414,100 @@ 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)
|
||||
{
|
||||
MarkResourceFrameReferenced(img->GetResourceID(), imgRefType);
|
||||
MarkResourceFrameReferenced(img->baseResource, imgRefType);
|
||||
|
||||
// mark buffer just as read
|
||||
MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read);
|
||||
|
||||
for(uint32_t ri = 0; ri < regionCount; ri++)
|
||||
{
|
||||
const VkBufferImageCopy ®ion = regions[ri];
|
||||
|
||||
VkFormat regionFormat = layout.format;
|
||||
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_PLANE_1_BIT: plane = 1; break;
|
||||
case VK_IMAGE_ASPECT_PLANE_2_BIT: plane = 2; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// The shape of the texel blocks;
|
||||
// non-block formats are treated as having 1x1 blocks
|
||||
BlockShape blockShape = GetBlockShape(regionFormat, plane);
|
||||
|
||||
// width of copied region, in blocks
|
||||
uint32_t widthInBlocks = (region.imageExtent.width + blockShape.width - 1) / blockShape.width;
|
||||
|
||||
// width of copied region, in bytes (in the buffer);
|
||||
uint32_t widthInBytes = blockShape.bytes * widthInBlocks;
|
||||
|
||||
// height of copied region, in blocks
|
||||
uint32_t heightInBlocks = (region.imageExtent.height + blockShape.height - 1) / blockShape.height;
|
||||
|
||||
// total number of depth slices to be copied.
|
||||
uint32_t sliceCount = region.imageExtent.depth * region.imageSubresource.layerCount;
|
||||
|
||||
// stride_y: number of bytes in the buffer between the start of one row of
|
||||
// blocks and the next. The buffer may have space for more blocks per row than
|
||||
// are actually being copied (specified by bufferRowLength).
|
||||
uint32_t stride_y;
|
||||
if(region.bufferRowLength == 0)
|
||||
stride_y = widthInBytes;
|
||||
else
|
||||
stride_y = blockShape.bytes * region.bufferRowLength;
|
||||
|
||||
// stride_z: number of bytes in the buffer between the start of one depth
|
||||
// slice and the next. The buffer may have space for more rows per slice
|
||||
// than are actually being copied (specified by bufferImageHeight).
|
||||
uint32_t stride_z;
|
||||
if(region.bufferImageHeight == 0)
|
||||
stride_z = stride_y * heightInBlocks;
|
||||
else
|
||||
stride_z = stride_y * region.bufferImageHeight;
|
||||
|
||||
// memory offset of the first byte to be copied to/from the buffer
|
||||
VkDeviceSize startRegion = buf->memOffset + region.bufferOffset;
|
||||
|
||||
if(stride_z == widthInBytes * heightInBlocks)
|
||||
{
|
||||
// no gaps between slices nor between rows; single copy for entire region
|
||||
MarkMemoryFrameReferenced(buf->baseResource, startRegion,
|
||||
widthInBytes * heightInBlocks * sliceCount, bufRefType);
|
||||
}
|
||||
else if(stride_y == widthInBytes)
|
||||
{
|
||||
// gaps between slices, but no gaps between rows; separate copies per slice
|
||||
for(uint32_t z = 0; z < sliceCount; z++)
|
||||
{
|
||||
VkDeviceSize startSlice = startRegion + z * stride_z;
|
||||
MarkMemoryFrameReferenced(buf->baseResource, startSlice, widthInBytes * heightInBlocks,
|
||||
bufRefType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// gaps between rows; separate copies for each row in each slice
|
||||
for(uint32_t z = 0; z < sliceCount; z++)
|
||||
{
|
||||
VkDeviceSize startSlice = startRegion + z * stride_z;
|
||||
for(uint32_t y = 0; y < heightInBlocks; y++)
|
||||
{
|
||||
VkDeviceSize startRow = startSlice + y * stride_y;
|
||||
MarkMemoryFrameReferenced(buf->baseResource, startRow, widthInBytes, bufRefType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VkResourceRecord::MarkBufferViewFrameReferenced(VkResourceRecord *bufView, FrameRefType refType)
|
||||
{
|
||||
// mark the VkBufferView and VkBuffer as read
|
||||
|
||||
@@ -1075,6 +1075,7 @@ inline FrameRefType MarkMemoryReferenced(std::map<ResourceId, MemRefs> &memRefs,
|
||||
}
|
||||
|
||||
struct DescUpdateTemplate;
|
||||
struct ImageLayouts;
|
||||
|
||||
struct VkResourceRecord : public ResourceRecord
|
||||
{
|
||||
@@ -1206,6 +1207,10 @@ public:
|
||||
FrameRefType refType);
|
||||
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);
|
||||
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
|
||||
|
||||
@@ -1769,16 +1769,9 @@ void WrappedVulkan::vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuff
|
||||
regionCount, pRegions);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
|
||||
record->MarkResourceFrameReferenced(GetResID(srcBuffer), eFrameRef_Read);
|
||||
record->MarkResourceFrameReferenced(GetRecord(srcBuffer)->baseResource, eFrameRef_Read);
|
||||
record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_PartialWrite);
|
||||
record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read);
|
||||
record->cmdInfo->dirtied.insert(GetResID(destImage));
|
||||
if(GetRecord(srcBuffer)->resInfo)
|
||||
record->cmdInfo->sparse.insert(GetRecord(srcBuffer)->resInfo);
|
||||
if(GetRecord(destImage)->resInfo)
|
||||
record->cmdInfo->sparse.insert(GetRecord(destImage)->resInfo);
|
||||
record->MarkBufferImageCopyFrameReferenced(GetRecord(srcBuffer), GetRecord(destImage),
|
||||
m_ImageLayouts[GetResID(destImage)], regionCount,
|
||||
pRegions, eFrameRef_Read, eFrameRef_PartialWrite);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1884,20 +1877,9 @@ void WrappedVulkan::vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImag
|
||||
regionCount, pRegions);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read);
|
||||
record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read);
|
||||
|
||||
VkResourceRecord *buf = GetRecord(destBuffer);
|
||||
|
||||
// mark buffer just as read, and memory behind as write & dirtied
|
||||
record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read);
|
||||
record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_PartialWrite);
|
||||
if(buf->baseResource != ResourceId())
|
||||
record->cmdInfo->dirtied.insert(buf->baseResource);
|
||||
if(GetRecord(srcImage)->resInfo)
|
||||
record->cmdInfo->sparse.insert(GetRecord(srcImage)->resInfo);
|
||||
if(buf->resInfo)
|
||||
record->cmdInfo->sparse.insert(buf->resInfo);
|
||||
record->MarkBufferImageCopyFrameReferenced(GetRecord(destBuffer), GetRecord(srcImage),
|
||||
m_ImageLayouts[GetResID(srcImage)], regionCount,
|
||||
pRegions, eFrameRef_CompleteWrite, eFrameRef_Read);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user