diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index 74e35a282..66a8aa86a 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -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 diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 08151d882..df1ae6c86 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -1075,6 +1075,7 @@ inline FrameRefType MarkMemoryReferenced(std::map &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 diff --git a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp index 2b0a51607..604e2a619 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp @@ -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); } }