Fix a bug for 3D texture comparison in e2e CopyTests

When we are copying data, we need to offset "rowsPerImage" rows
for each depth slice, even though this is a partial copy whose
copy height is less than rowsPerImage.

In addition, when we copy the original data into expected buffer
for comparison, we don't pack data for T2B copy and T2T copy. We
don't remove paddings during copy. So I renames PackTextureData
to CopyTextureData. For B2T copy, we do pack data. Right now we
name it CopyXXXX and we pack the data during some copies, it is
understandable. But if we name it PackXXXX but don't pack data
sometimes, it is weird. In addition, for B2T copy, we pack the
data, so I shorten the buffer size we allocated for comparison.

This change also renames "slice" to "layer" if it includes multiple
depth slices and actually means a layer, but keep slice as slice if
it means an array layer or a depth slice for different cases.

Bug: dawn:547
Change-Id: I6d82e6c25f50bd4c988b1f65f85b24ad1c191d01
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/53501
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
Yunchao He 2021-06-07 17:32:43 +00:00 committed by Dawn LUCI CQ
parent 6fb11ffa40
commit 9df00a3e9a
1 changed files with 32 additions and 25 deletions

View File

@ -106,17 +106,19 @@ class CopyTests : public DawnTest {
utils::RequiredBytesInCopy(bytesPerRow, rowsPerImage, copyExtent, format); utils::RequiredBytesInCopy(bytesPerRow, rowsPerImage, copyExtent, format);
return {totalDataSize, 0, bytesPerRow, rowsPerImage}; return {totalDataSize, 0, bytesPerRow, rowsPerImage};
} }
static void PackTextureData(uint32_t bytesPerTexelBlock, static void CopyTextureData(uint32_t bytesPerTexelBlock,
const void* srcData, const void* srcData,
uint32_t widthInBlocks, uint32_t widthInBlocks,
uint32_t heightInBlocks, uint32_t heightInBlocks,
uint32_t depthInBlocks, uint32_t depthInBlocks,
uint32_t srcBytesPerRow, uint32_t srcBytesPerRow,
uint32_t srcRowsPerImage,
void* dstData, void* dstData,
uint32_t dstBytesPerRow) { uint32_t dstBytesPerRow,
uint32_t dstRowsPerImage) {
for (unsigned int z = 0; z < depthInBlocks; ++z) { for (unsigned int z = 0; z < depthInBlocks; ++z) {
uint32_t srcDepthOffset = z * srcBytesPerRow * heightInBlocks; uint32_t srcDepthOffset = z * srcBytesPerRow * srcRowsPerImage;
uint32_t dstDepthOffset = z * dstBytesPerRow * heightInBlocks; uint32_t dstDepthOffset = z * dstBytesPerRow * dstRowsPerImage;
for (unsigned int y = 0; y < heightInBlocks; ++y) { for (unsigned int y = 0; y < heightInBlocks; ++y) {
memcpy(static_cast<uint8_t*>(dstData) + dstDepthOffset + y * dstBytesPerRow, memcpy(static_cast<uint8_t*>(dstData) + dstDepthOffset + y * dstBytesPerRow,
static_cast<const uint8_t*>(srcData) + srcDepthOffset + y * srcBytesPerRow, static_cast<const uint8_t*>(srcData) + srcDepthOffset + y * srcBytesPerRow,
@ -195,24 +197,25 @@ class CopyTests_T2B : public CopyTests {
} }
const wgpu::Extent3D copySizePerLayer = {copySize.width, copySize.height, copyDepth}; const wgpu::Extent3D copySizePerLayer = {copySize.width, copySize.height, copyDepth};
// Texels in single slice. // Texels in single layer.
const uint32_t texelCountInCopyRegion = utils::GetTexelCountInCopyRegion( const uint32_t texelCountInCopyRegion = utils::GetTexelCountInCopyRegion(
bufferSpec.bytesPerRow, bufferSpec.rowsPerImage, copySizePerLayer, textureSpec.format); bufferSpec.bytesPerRow, bufferSpec.rowsPerImage, copySizePerLayer, textureSpec.format);
const uint32_t maxArrayLayer = textureSpec.copyOrigin.z + copyLayer; const uint32_t maxArrayLayer = textureSpec.copyOrigin.z + copyLayer;
std::vector<RGBA8> expected(texelCountInCopyRegion); std::vector<RGBA8> expected(texelCountInCopyRegion);
for (uint32_t slice = textureSpec.copyOrigin.z; slice < maxArrayLayer; ++slice) { for (uint32_t layer = textureSpec.copyOrigin.z; layer < maxArrayLayer; ++layer) {
// Pack the data used to create the upload buffer in the specified copy region to have // Copy the data used to create the upload buffer in the specified copy region to have
// the same format as the expected buffer data. // the same format as the expected buffer data.
std::fill(expected.begin(), expected.end(), RGBA8()); std::fill(expected.begin(), expected.end(), RGBA8());
const uint32_t texelIndexOffset = copyLayout.texelBlocksPerImage * slice; const uint32_t texelIndexOffset = copyLayout.texelBlocksPerImage * layer;
const uint32_t expectedTexelArrayDataStartIndex = const uint32_t expectedTexelArrayDataStartIndex =
texelIndexOffset + (textureSpec.copyOrigin.x + texelIndexOffset + (textureSpec.copyOrigin.x +
textureSpec.copyOrigin.y * copyLayout.texelBlocksPerRow); textureSpec.copyOrigin.y * copyLayout.texelBlocksPerRow);
PackTextureData(bytesPerTexel, CopyTextureData(bytesPerTexel,
textureArrayData.data() + expectedTexelArrayDataStartIndex, textureArrayData.data() + expectedTexelArrayDataStartIndex,
copySize.width, copySize.height, copyDepth, copyLayout.bytesPerRow, copySize.width, copySize.height, copyDepth, copyLayout.bytesPerRow,
expected.data(), bufferSpec.bytesPerRow); copyLayout.rowsPerImage, expected.data(), bufferSpec.bytesPerRow,
bufferSpec.rowsPerImage);
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer, EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer,
bufferOffset, static_cast<uint32_t>(expected.size())) bufferOffset, static_cast<uint32_t>(expected.size()))
@ -222,7 +225,7 @@ class CopyTests_T2B : public CopyTests {
<< textureSpec.copyOrigin.y + copySize.height << ", " << textureSpec.copyOrigin.y + copySize.height << ", "
<< textureSpec.copyOrigin.z + copySize.depthOrArrayLayers << ")) from " << textureSpec.copyOrigin.z + copySize.depthOrArrayLayers << ")) from "
<< textureSpec.textureSize.width << " x " << textureSpec.textureSize.height << textureSpec.textureSize.width << " x " << textureSpec.textureSize.height
<< " texture at mip level " << textureSpec.copyLevel << " layer " << slice << " to " << " texture at mip level " << textureSpec.copyLevel << " layer " << layer << " to "
<< bufferSpec.size << "-byte buffer with offset " << bufferOffset << bufferSpec.size << "-byte buffer with offset " << bufferOffset
<< " and bytes per row " << bufferSpec.bytesPerRow << std::endl; << " and bytes per row " << bufferSpec.bytesPerRow << std::endl;
@ -288,16 +291,19 @@ class CopyTests_B2T : public CopyTests {
} }
uint64_t bufferOffset = bufferSpec.offset; uint64_t bufferOffset = bufferSpec.offset;
const uint32_t texelCountLastLayer = const uint32_t blockWidth = utils::GetTextureFormatBlockWidth(textureSpec.format);
copyDepth * (copyLayout.texelBlocksPerRow * (copyLayout.mipSize.height - 1) + const uint32_t blockHeight = utils::GetTextureFormatBlockHeight(textureSpec.format);
copyLayout.mipSize.width); const uint32_t texelCountPerLayer = copyDepth * (copyLayout.mipSize.width / blockWidth) *
(copyLayout.mipSize.height / blockHeight) *
bytesPerTexel;
for (uint32_t layer = 0; layer < copyLayer; ++layer) { for (uint32_t layer = 0; layer < copyLayer; ++layer) {
// Pack the data used to create the buffer in the specified copy region to have the same // Copy and pack the data used to create the buffer in the specified copy region to have
// format as the expected texture data. // the same format as the expected texture data.
std::vector<RGBA8> expected(texelCountLastLayer); std::vector<RGBA8> expected(texelCountPerLayer);
PackTextureData(bytesPerTexel, bufferData.data() + bufferOffset / bytesPerTexel, CopyTextureData(bytesPerTexel, bufferData.data() + bufferOffset / bytesPerTexel,
copySize.width, copySize.height, copyDepth, bufferSpec.bytesPerRow, copySize.width, copySize.height, copyDepth, bufferSpec.bytesPerRow,
expected.data(), copySize.width * bytesPerTexel); bufferSpec.rowsPerImage, expected.data(),
copySize.width * bytesPerTexel, copySize.height);
EXPECT_TEXTURE_EQ(expected.data(), texture, EXPECT_TEXTURE_EQ(expected.data(), texture,
{textureSpec.copyOrigin.x, textureSpec.copyOrigin.y, {textureSpec.copyOrigin.x, textureSpec.copyOrigin.y,
@ -442,10 +448,11 @@ class CopyTests_T2T : public CopyTests {
dstSpec.copyOrigin.y * dstDataCopyLayout.mipSize.width) * dstSpec.copyOrigin.y * dstDataCopyLayout.mipSize.width) *
bytesPerTexel; bytesPerTexel;
// Do the T2T "copy" on the CPU side to get the expected texel value at the // Do the T2T "copy" on the CPU side to get the expected texel value at the
PackTextureData( CopyTextureData(bytesPerTexel, &srcTextureCopyData[srcTexelDataOffset],
bytesPerTexel, &srcTextureCopyData[srcTexelDataOffset], copySize.width, copySize.width, copySize.height, copyDepth,
copySize.height, copyDepth, srcDataCopyLayout.bytesPerRow, srcDataCopyLayout.bytesPerRow, srcDataCopyLayout.rowsPerImage,
&expectedDstDataPerSlice[expectedDstDataOffset], dstDataCopyLayout.bytesPerRow); &expectedDstDataPerSlice[expectedDstDataOffset],
dstDataCopyLayout.bytesPerRow, dstDataCopyLayout.rowsPerImage);
// Compare the content of the destination texture at the (dstSpec.copyOrigin.z + // Compare the content of the destination texture at the (dstSpec.copyOrigin.z +
// slice)-th layer to its expected data after the copy (the outputBuffer contains // slice)-th layer to its expected data after the copy (the outputBuffer contains
@ -1043,7 +1050,7 @@ TEST_P(CopyTests_T2B, Texture3DSubRegion) {
textureSpec.textureSize = {kWidth, kHeight, kDepth}; textureSpec.textureSize = {kWidth, kHeight, kDepth};
DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth), DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth),
{kWidth, kHeight, kCopyDepth}, wgpu::TextureDimension::e3D); {kWidth / 2, kHeight / 2, kCopyDepth}, wgpu::TextureDimension::e3D);
} }
TEST_P(CopyTests_T2B, Texture3DNoSplitRowDataWithEmptyFirstRow) { TEST_P(CopyTests_T2B, Texture3DNoSplitRowDataWithEmptyFirstRow) {
@ -1626,7 +1633,7 @@ TEST_P(CopyTests_B2T, Texture3DSubRegion) {
textureSpec.textureSize = {kWidth, kHeight, kDepth}; textureSpec.textureSize = {kWidth, kHeight, kDepth};
DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth), DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth),
{kWidth, kHeight, kCopyDepth}, wgpu::TextureDimension::e3D); {kWidth / 2, kHeight / 2, kCopyDepth}, wgpu::TextureDimension::e3D);
} }
TEST_P(CopyTests_B2T, Texture3DNoSplitRowDataWithEmptyFirstRow) { TEST_P(CopyTests_B2T, Texture3DNoSplitRowDataWithEmptyFirstRow) {