Deprecate BufferCopyView.rowPitch/imageHeight -> bytesPerRow/rowsPerImage

Bug: dawn:22

Change-Id: Ib4d93a73a6c40326d180f569fd51216c2d87df1e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20201
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Corentin Wallez 2020-04-24 10:02:43 +00:00 committed by Commit Bot service account
parent c244f53921
commit cdf2d8de77
29 changed files with 505 additions and 301 deletions

View File

@ -215,8 +215,10 @@
"members": [ "members": [
{"name": "buffer", "type": "buffer"}, {"name": "buffer", "type": "buffer"},
{"name": "offset", "type": "uint64_t", "default": 0}, {"name": "offset", "type": "uint64_t", "default": 0},
{"name": "row pitch", "type": "uint32_t"}, {"name": "row pitch", "type": "uint32_t", "default": 0},
{"name": "image height", "type": "uint32_t"} {"name": "image height", "type": "uint32_t", "default": 0},
{"name": "bytes per row", "type": "uint32_t", "default": 0},
{"name": "rows per image", "type": "uint32_t", "default": 0}
] ]
}, },
"buffer descriptor": { "buffer descriptor": {

View File

@ -32,7 +32,7 @@ static constexpr uint32_t kMaxVertexBuffers = 16u;
static constexpr uint32_t kMaxVertexBufferStride = 2048u; static constexpr uint32_t kMaxVertexBufferStride = 2048u;
static constexpr uint32_t kNumStages = 3; static constexpr uint32_t kNumStages = 3;
static constexpr uint32_t kMaxColorAttachments = 4u; static constexpr uint32_t kMaxColorAttachments = 4u;
static constexpr uint32_t kTextureRowPitchAlignment = 256u; static constexpr uint32_t kTextureBytesPerRowAlignment = 256u;
// Dynamic buffer offsets require offset to be divisible by 256 // Dynamic buffer offsets require offset to be divisible by 256
static constexpr uint64_t kMinDynamicBufferOffsetAlignment = 256u; static constexpr uint64_t kMinDynamicBufferOffsetAlignment = 256u;
// Max numbers of dynamic uniform buffers // Max numbers of dynamic uniform buffers

View File

@ -110,16 +110,16 @@ namespace dawn_native {
return {}; return {};
} }
MaybeError ValidateImageHeight(const Format& format, MaybeError ValidateRowsPerImage(const Format& format,
uint32_t imageHeight, uint32_t rowsPerImage,
uint32_t copyHeight) { uint32_t copyHeight) {
if (imageHeight < copyHeight) { if (rowsPerImage < copyHeight) {
return DAWN_VALIDATION_ERROR("Image height must not be less than the copy height."); return DAWN_VALIDATION_ERROR("rowsPerImage must not be less than the copy height.");
} }
if (imageHeight % format.blockHeight != 0) { if (rowsPerImage % format.blockHeight != 0) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"Image height must be a multiple of compressed texture format block width"); "rowsPerImage must be a multiple of compressed texture format block width");
} }
return {}; return {};
@ -180,37 +180,37 @@ namespace dawn_native {
MaybeError ComputeTextureCopyBufferSize(const Format& textureFormat, MaybeError ComputeTextureCopyBufferSize(const Format& textureFormat,
const Extent3D& copySize, const Extent3D& copySize,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t imageHeight, uint32_t rowsPerImage,
uint32_t* bufferSize) { uint32_t* bufferSize) {
ASSERT(imageHeight >= copySize.height); ASSERT(rowsPerImage >= copySize.height);
uint32_t blockByteSize = textureFormat.blockByteSize; uint32_t blockByteSize = textureFormat.blockByteSize;
uint32_t blockWidth = textureFormat.blockWidth; uint32_t blockWidth = textureFormat.blockWidth;
uint32_t blockHeight = textureFormat.blockHeight; uint32_t blockHeight = textureFormat.blockHeight;
// TODO(cwallez@chromium.org): check for overflows // TODO(cwallez@chromium.org): check for overflows
uint32_t slicePitch = rowPitch * imageHeight / blockWidth; uint32_t slicePitch = bytesPerRow * rowsPerImage / blockWidth;
uint32_t sliceSize = rowPitch * (copySize.height / blockHeight - 1) + uint32_t sliceSize = bytesPerRow * (copySize.height / blockHeight - 1) +
(copySize.width / blockWidth) * blockByteSize; (copySize.width / blockWidth) * blockByteSize;
*bufferSize = (slicePitch * (copySize.depth - 1)) + sliceSize; *bufferSize = (slicePitch * (copySize.depth - 1)) + sliceSize;
return {}; return {};
} }
uint32_t ComputeDefaultRowPitch(const Format& format, uint32_t width) { uint32_t ComputeDefaultBytesPerRow(const Format& format, uint32_t width) {
return width / format.blockWidth * format.blockByteSize; return width / format.blockWidth * format.blockByteSize;
} }
MaybeError ValidateRowPitch(const Format& format, MaybeError ValidateBytesPerRow(const Format& format,
const Extent3D& copySize, const Extent3D& copySize,
uint32_t rowPitch) { uint32_t bytesPerRow) {
if (rowPitch % kTextureRowPitchAlignment != 0) { if (bytesPerRow % kTextureBytesPerRowAlignment != 0) {
return DAWN_VALIDATION_ERROR("Row pitch must be a multiple of 256"); return DAWN_VALIDATION_ERROR("bytesPerRow must be a multiple of 256");
} }
if (rowPitch < copySize.width / format.blockWidth * format.blockByteSize) { if (bytesPerRow < copySize.width / format.blockWidth * format.blockByteSize) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"Row pitch must not be less than the number of bytes per row"); "bytesPerRow must not be less than the number of bytes per row");
} }
return {}; return {};
@ -483,6 +483,40 @@ namespace dawn_native {
return {}; return {};
} }
// TODO(dawn:22): Remove this once users bytesPerRow/rowsPerImage
ResultOrError<BufferCopyView> FixBufferCopyView(DeviceBase* device,
const BufferCopyView* original) {
BufferCopyView fixed = *original;
if (fixed.rowPitch != 0) {
if (fixed.bytesPerRow != 0) {
return DAWN_VALIDATION_ERROR(
"Cannot use rowPitch and bytesPerRow at the same time");
} else {
device->EmitDeprecationWarning(
"BufferCopyView::rowPitch is deprecated, use BufferCopyView::bytesPerRow "
"instead");
fixed.bytesPerRow = fixed.rowPitch;
fixed.rowPitch = 0;
}
}
if (fixed.imageHeight != 0) {
if (fixed.rowsPerImage != 0) {
return DAWN_VALIDATION_ERROR(
"Cannot use imageHeight and rowsPerImage at the same time");
} else {
device->EmitDeprecationWarning(
"BufferCopyView::imageHeight is deprecated, use "
"BufferCopyView::rowsPerImage instead");
fixed.rowsPerImage = fixed.imageHeight;
fixed.imageHeight = 0;
}
}
return fixed;
}
} // namespace } // namespace
CommandEncoder::CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor*) CommandEncoder::CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor*)
@ -629,32 +663,36 @@ namespace dawn_native {
const TextureCopyView* destination, const TextureCopyView* destination,
const Extent3D* copySize) { const Extent3D* copySize) {
mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(source->buffer)); // TODO(dawn:22): Remove this once users bytesPerRow/rowsPerImage
BufferCopyView fixedSource;
DAWN_TRY_ASSIGN(fixedSource, FixBufferCopyView(GetDevice(), source));
DAWN_TRY(GetDevice()->ValidateObject(fixedSource.buffer));
DAWN_TRY(GetDevice()->ValidateObject(destination->texture)); DAWN_TRY(GetDevice()->ValidateObject(destination->texture));
CopyBufferToTextureCmd* copy = CopyBufferToTextureCmd* copy =
allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture); allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
copy->source.buffer = source->buffer; copy->source.buffer = fixedSource.buffer;
copy->source.offset = source->offset; copy->source.offset = fixedSource.offset;
copy->destination.texture = destination->texture; copy->destination.texture = destination->texture;
copy->destination.origin = destination->origin; copy->destination.origin = destination->origin;
copy->copySize = *copySize; copy->copySize = *copySize;
copy->destination.mipLevel = destination->mipLevel; copy->destination.mipLevel = destination->mipLevel;
copy->destination.arrayLayer = destination->arrayLayer; copy->destination.arrayLayer = destination->arrayLayer;
if (source->rowPitch == 0) { if (fixedSource.bytesPerRow == 0) {
copy->source.rowPitch = copy->source.bytesPerRow =
ComputeDefaultRowPitch(destination->texture->GetFormat(), copySize->width); ComputeDefaultBytesPerRow(destination->texture->GetFormat(), copySize->width);
} else { } else {
copy->source.rowPitch = source->rowPitch; copy->source.bytesPerRow = fixedSource.bytesPerRow;
} }
if (source->imageHeight == 0) { if (fixedSource.rowsPerImage == 0) {
copy->source.imageHeight = copySize->height; copy->source.rowsPerImage = copySize->height;
} else { } else {
copy->source.imageHeight = source->imageHeight; copy->source.rowsPerImage = fixedSource.rowsPerImage;
} }
if (GetDevice()->IsValidationEnabled()) { if (GetDevice()->IsValidationEnabled()) {
mTopLevelBuffers.insert(source->buffer); mTopLevelBuffers.insert(fixedSource.buffer);
mTopLevelTextures.insert(destination->texture); mTopLevelTextures.insert(destination->texture);
} }
return {}; return {};
@ -665,8 +703,12 @@ namespace dawn_native {
const BufferCopyView* destination, const BufferCopyView* destination,
const Extent3D* copySize) { const Extent3D* copySize) {
mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
// TODO(dawn:22): Remove this once users bytesPerRow/rowsPerImage
BufferCopyView fixedDestination;
DAWN_TRY_ASSIGN(fixedDestination, FixBufferCopyView(GetDevice(), destination));
DAWN_TRY(GetDevice()->ValidateObject(source->texture)); DAWN_TRY(GetDevice()->ValidateObject(source->texture));
DAWN_TRY(GetDevice()->ValidateObject(destination->buffer)); DAWN_TRY(GetDevice()->ValidateObject(fixedDestination.buffer));
CopyTextureToBufferCmd* copy = CopyTextureToBufferCmd* copy =
allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer); allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
@ -675,23 +717,23 @@ namespace dawn_native {
copy->copySize = *copySize; copy->copySize = *copySize;
copy->source.mipLevel = source->mipLevel; copy->source.mipLevel = source->mipLevel;
copy->source.arrayLayer = source->arrayLayer; copy->source.arrayLayer = source->arrayLayer;
copy->destination.buffer = destination->buffer; copy->destination.buffer = fixedDestination.buffer;
copy->destination.offset = destination->offset; copy->destination.offset = fixedDestination.offset;
if (destination->rowPitch == 0) { if (fixedDestination.bytesPerRow == 0) {
copy->destination.rowPitch = copy->destination.bytesPerRow =
ComputeDefaultRowPitch(source->texture->GetFormat(), copySize->width); ComputeDefaultBytesPerRow(source->texture->GetFormat(), copySize->width);
} else { } else {
copy->destination.rowPitch = destination->rowPitch; copy->destination.bytesPerRow = fixedDestination.bytesPerRow;
} }
if (destination->imageHeight == 0) { if (fixedDestination.rowsPerImage == 0) {
copy->destination.imageHeight = copySize->height; copy->destination.rowsPerImage = copySize->height;
} else { } else {
copy->destination.imageHeight = destination->imageHeight; copy->destination.rowsPerImage = fixedDestination.rowsPerImage;
} }
if (GetDevice()->IsValidationEnabled()) { if (GetDevice()->IsValidationEnabled()) {
mTopLevelTextures.insert(source->texture); mTopLevelTextures.insert(source->texture);
mTopLevelBuffers.insert(destination->buffer); mTopLevelBuffers.insert(fixedDestination.buffer);
} }
return {}; return {};
}); });
@ -825,20 +867,21 @@ namespace dawn_native {
DAWN_TRY( DAWN_TRY(
ValidateTextureSampleCountInCopyCommands(copy->destination.texture.Get())); ValidateTextureSampleCountInCopyCommands(copy->destination.texture.Get()));
DAWN_TRY(ValidateImageHeight(copy->destination.texture->GetFormat(), DAWN_TRY(ValidateRowsPerImage(copy->destination.texture->GetFormat(),
copy->source.imageHeight, copy->copySize.height)); copy->source.rowsPerImage,
copy->copySize.height));
DAWN_TRY(ValidateImageOrigin(copy->destination.texture->GetFormat(), DAWN_TRY(ValidateImageOrigin(copy->destination.texture->GetFormat(),
copy->destination.origin)); copy->destination.origin));
DAWN_TRY(ValidateImageCopySize(copy->destination.texture->GetFormat(), DAWN_TRY(ValidateImageCopySize(copy->destination.texture->GetFormat(),
copy->copySize)); copy->copySize));
uint32_t bufferCopySize = 0; uint32_t bufferCopySize = 0;
DAWN_TRY(ValidateRowPitch(copy->destination.texture->GetFormat(), DAWN_TRY(ValidateBytesPerRow(copy->destination.texture->GetFormat(),
copy->copySize, copy->source.rowPitch)); copy->copySize, copy->source.bytesPerRow));
DAWN_TRY(ComputeTextureCopyBufferSize( DAWN_TRY(ComputeTextureCopyBufferSize(
copy->destination.texture->GetFormat(), copy->copySize, copy->destination.texture->GetFormat(), copy->copySize,
copy->source.rowPitch, copy->source.imageHeight, &bufferCopySize)); copy->source.bytesPerRow, copy->source.rowsPerImage, &bufferCopySize));
DAWN_TRY(ValidateCopySizeFitsInTexture(copy->destination, copy->copySize)); DAWN_TRY(ValidateCopySizeFitsInTexture(copy->destination, copy->copySize));
DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->source, bufferCopySize)); DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->source, bufferCopySize));
@ -858,20 +901,20 @@ namespace dawn_native {
DAWN_TRY(ValidateTextureSampleCountInCopyCommands(copy->source.texture.Get())); DAWN_TRY(ValidateTextureSampleCountInCopyCommands(copy->source.texture.Get()));
DAWN_TRY(ValidateImageHeight(copy->source.texture->GetFormat(), DAWN_TRY(ValidateRowsPerImage(copy->source.texture->GetFormat(),
copy->destination.imageHeight, copy->destination.rowsPerImage,
copy->copySize.height)); copy->copySize.height));
DAWN_TRY(ValidateImageOrigin(copy->source.texture->GetFormat(), DAWN_TRY(ValidateImageOrigin(copy->source.texture->GetFormat(),
copy->source.origin)); copy->source.origin));
DAWN_TRY( DAWN_TRY(
ValidateImageCopySize(copy->source.texture->GetFormat(), copy->copySize)); ValidateImageCopySize(copy->source.texture->GetFormat(), copy->copySize));
uint32_t bufferCopySize = 0; uint32_t bufferCopySize = 0;
DAWN_TRY(ValidateRowPitch(copy->source.texture->GetFormat(), copy->copySize, DAWN_TRY(ValidateBytesPerRow(copy->source.texture->GetFormat(), copy->copySize,
copy->destination.rowPitch)); copy->destination.bytesPerRow));
DAWN_TRY(ComputeTextureCopyBufferSize( DAWN_TRY(ComputeTextureCopyBufferSize(
copy->source.texture->GetFormat(), copy->copySize, copy->source.texture->GetFormat(), copy->copySize,
copy->destination.rowPitch, copy->destination.imageHeight, copy->destination.bytesPerRow, copy->destination.rowsPerImage,
&bufferCopySize)); &bufferCopySize));
DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize)); DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize));

View File

@ -93,9 +93,9 @@ namespace dawn_native {
struct BufferCopy { struct BufferCopy {
Ref<BufferBase> buffer; Ref<BufferBase> buffer;
uint64_t offset; // Bytes uint64_t offset;
uint32_t rowPitch; // Bytes uint32_t bytesPerRow;
uint32_t imageHeight; // Texels uint32_t rowsPerImage;
}; };
struct TextureCopy { struct TextureCopy {

View File

@ -564,7 +564,7 @@ namespace dawn_native { namespace d3d12 {
auto copySplit = ComputeTextureCopySplit( auto copySplit = ComputeTextureCopySplit(
copy->destination.origin, copy->copySize, texture->GetFormat(), copy->destination.origin, copy->copySize, texture->GetFormat(),
copy->source.offset, copy->source.rowPitch, copy->source.imageHeight); copy->source.offset, copy->source.bytesPerRow, copy->source.rowsPerImage);
D3D12_TEXTURE_COPY_LOCATION textureLocation = D3D12_TEXTURE_COPY_LOCATION textureLocation =
ComputeTextureCopyLocationForTexture(texture, copy->destination.mipLevel, ComputeTextureCopyLocationForTexture(texture, copy->destination.mipLevel,
@ -576,7 +576,7 @@ namespace dawn_native { namespace d3d12 {
D3D12_TEXTURE_COPY_LOCATION bufferLocation = D3D12_TEXTURE_COPY_LOCATION bufferLocation =
ComputeBufferLocationForCopyTextureRegion( ComputeBufferLocationForCopyTextureRegion(
texture, buffer->GetD3D12Resource().Get(), info.bufferSize, texture, buffer->GetD3D12Resource().Get(), info.bufferSize,
copySplit.offset, copy->source.rowPitch); copySplit.offset, copy->source.bytesPerRow);
D3D12_BOX sourceRegion = D3D12_BOX sourceRegion =
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize); ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
@ -601,8 +601,8 @@ namespace dawn_native { namespace d3d12 {
TextureCopySplit copySplit = ComputeTextureCopySplit( TextureCopySplit copySplit = ComputeTextureCopySplit(
copy->source.origin, copy->copySize, texture->GetFormat(), copy->source.origin, copy->copySize, texture->GetFormat(),
copy->destination.offset, copy->destination.rowPitch, copy->destination.offset, copy->destination.bytesPerRow,
copy->destination.imageHeight); copy->destination.rowsPerImage);
D3D12_TEXTURE_COPY_LOCATION textureLocation = D3D12_TEXTURE_COPY_LOCATION textureLocation =
ComputeTextureCopyLocationForTexture(texture, copy->source.mipLevel, ComputeTextureCopyLocationForTexture(texture, copy->source.mipLevel,
@ -614,7 +614,7 @@ namespace dawn_native { namespace d3d12 {
D3D12_TEXTURE_COPY_LOCATION bufferLocation = D3D12_TEXTURE_COPY_LOCATION bufferLocation =
ComputeBufferLocationForCopyTextureRegion( ComputeBufferLocationForCopyTextureRegion(
texture, buffer->GetD3D12Resource().Get(), info.bufferSize, texture, buffer->GetD3D12Resource().Get(), info.bufferSize,
copySplit.offset, copy->destination.rowPitch); copySplit.offset, copy->destination.bytesPerRow);
D3D12_BOX sourceRegion = D3D12_BOX sourceRegion =
ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize); ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize);

View File

@ -23,15 +23,15 @@ namespace dawn_native { namespace d3d12 {
namespace { namespace {
Origin3D ComputeTexelOffsets(const Format& format, Origin3D ComputeTexelOffsets(const Format& format,
uint32_t offset, uint32_t offset,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t slicePitch) { uint32_t slicePitch) {
uint32_t byteOffsetX = offset % rowPitch; uint32_t byteOffsetX = offset % bytesPerRow;
offset -= byteOffsetX; offset -= byteOffsetX;
uint32_t byteOffsetY = offset % slicePitch; uint32_t byteOffsetY = offset % slicePitch;
uint32_t byteOffsetZ = offset - byteOffsetY; uint32_t byteOffsetZ = offset - byteOffsetY;
return {byteOffsetX / format.blockByteSize * format.blockWidth, return {byteOffsetX / format.blockByteSize * format.blockWidth,
byteOffsetY / rowPitch * format.blockHeight, byteOffsetZ / slicePitch}; byteOffsetY / bytesPerRow * format.blockHeight, byteOffsetZ / slicePitch};
} }
} // namespace } // namespace
@ -39,11 +39,11 @@ namespace dawn_native { namespace d3d12 {
Extent3D copySize, Extent3D copySize,
const Format& format, const Format& format,
uint64_t offset, uint64_t offset,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t imageHeight) { uint32_t rowsPerImage) {
TextureCopySplit copy; TextureCopySplit copy;
ASSERT(rowPitch % format.blockByteSize == 0); ASSERT(bytesPerRow % format.blockByteSize == 0);
uint64_t alignedOffset = uint64_t alignedOffset =
offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1); offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1);
@ -69,16 +69,16 @@ namespace dawn_native { namespace d3d12 {
ASSERT(alignedOffset < offset); ASSERT(alignedOffset < offset);
ASSERT(offset - alignedOffset < D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); ASSERT(offset - alignedOffset < D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
uint32_t slicePitch = rowPitch * (imageHeight / format.blockHeight); uint32_t slicePitch = bytesPerRow * (rowsPerImage / format.blockHeight);
Origin3D texelOffset = ComputeTexelOffsets( Origin3D texelOffset = ComputeTexelOffsets(
format, static_cast<uint32_t>(offset - alignedOffset), rowPitch, slicePitch); format, static_cast<uint32_t>(offset - alignedOffset), bytesPerRow, slicePitch);
uint32_t copyBytesPerRowPitch = copySize.width / format.blockWidth * format.blockByteSize; uint32_t copyBytesPerRowPitch = copySize.width / format.blockWidth * format.blockByteSize;
uint32_t byteOffsetInRowPitch = texelOffset.x / format.blockWidth * format.blockByteSize; uint32_t byteOffsetInRowPitch = texelOffset.x / format.blockWidth * format.blockByteSize;
if (copyBytesPerRowPitch + byteOffsetInRowPitch <= rowPitch) { if (copyBytesPerRowPitch + byteOffsetInRowPitch <= bytesPerRow) {
// The region's rows fit inside the row pitch. In this case, extend the width of the // The region's rows fit inside the bytes per row. In this case, extend the width of the
// PlacedFootprint and copy the buffer with an offset location // PlacedFootprint and copy the buffer with an offset location
// |<--------------- row pitch --------------->| // |<------------- bytes per row ------------->|
// //
// |-------------------------------------------| // |-------------------------------------------|
// | | // | |
@ -107,14 +107,14 @@ namespace dawn_native { namespace d3d12 {
copy.copies[0].bufferOffset = texelOffset; copy.copies[0].bufferOffset = texelOffset;
copy.copies[0].bufferSize.width = copySize.width + texelOffset.x; copy.copies[0].bufferSize.width = copySize.width + texelOffset.x;
copy.copies[0].bufferSize.height = imageHeight + texelOffset.y; copy.copies[0].bufferSize.height = rowsPerImage + texelOffset.y;
copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z; copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z;
return copy; return copy;
} }
// The region's rows straddle the row pitch. Split the copy into two copies // The region's rows straddle the bytes per row. Split the copy into two copies
// |<--------------- row pitch --------------->| // |<------------- bytes per row ------------->|
// //
// |-------------------------------------------| // |-------------------------------------------|
// | | // | |
@ -151,15 +151,15 @@ namespace dawn_native { namespace d3d12 {
copy.copies[0].textureOffset = origin; copy.copies[0].textureOffset = origin;
ASSERT(rowPitch > byteOffsetInRowPitch); ASSERT(bytesPerRow > byteOffsetInRowPitch);
uint32_t texelsPerRow = rowPitch / format.blockByteSize * format.blockWidth; uint32_t texelsPerRow = bytesPerRow / format.blockByteSize * format.blockWidth;
copy.copies[0].copySize.width = texelsPerRow - texelOffset.x; copy.copies[0].copySize.width = texelsPerRow - texelOffset.x;
copy.copies[0].copySize.height = copySize.height; copy.copies[0].copySize.height = copySize.height;
copy.copies[0].copySize.depth = copySize.depth; copy.copies[0].copySize.depth = copySize.depth;
copy.copies[0].bufferOffset = texelOffset; copy.copies[0].bufferOffset = texelOffset;
copy.copies[0].bufferSize.width = texelsPerRow; copy.copies[0].bufferSize.width = texelsPerRow;
copy.copies[0].bufferSize.height = imageHeight + texelOffset.y; copy.copies[0].bufferSize.height = rowsPerImage + texelOffset.y;
copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z; copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z;
copy.copies[1].textureOffset.x = origin.x + copy.copies[0].copySize.width; copy.copies[1].textureOffset.x = origin.x + copy.copies[0].copySize.width;
@ -175,7 +175,7 @@ namespace dawn_native { namespace d3d12 {
copy.copies[1].bufferOffset.y = texelOffset.y + format.blockHeight; copy.copies[1].bufferOffset.y = texelOffset.y + format.blockHeight;
copy.copies[1].bufferOffset.z = texelOffset.z; copy.copies[1].bufferOffset.z = texelOffset.z;
copy.copies[1].bufferSize.width = copy.copies[1].copySize.width; copy.copies[1].bufferSize.width = copy.copies[1].copySize.width;
copy.copies[1].bufferSize.height = imageHeight + texelOffset.y + format.blockHeight; copy.copies[1].bufferSize.height = rowsPerImage + texelOffset.y + format.blockHeight;
copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z; copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z;
return copy; return copy;

View File

@ -47,8 +47,8 @@ namespace dawn_native { namespace d3d12 {
Extent3D copySize, Extent3D copySize,
const Format& format, const Format& format,
uint64_t offset, uint64_t offset,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t imageHeight); uint32_t rowsPerImage);
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12
#endif // DAWNNATIVE_D3D12_TEXTURECOPYSPLITTER_H_ #endif // DAWNNATIVE_D3D12_TEXTURECOPYSPLITTER_H_

View File

@ -691,10 +691,10 @@ namespace dawn_native { namespace d3d12 {
} else { } else {
// TODO(natlee@microsoft.com): test compressed textures are cleared // TODO(natlee@microsoft.com): test compressed textures are cleared
// create temp buffer with clear color to copy to the texture image // create temp buffer with clear color to copy to the texture image
uint32_t rowPitch = uint32_t bytesPerRow =
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize, Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize,
kTextureRowPitchAlignment); kTextureBytesPerRowAlignment);
uint64_t bufferSize64 = rowPitch * (GetSize().height / GetFormat().blockHeight); uint64_t bufferSize64 = bytesPerRow * (GetSize().height / GetFormat().blockHeight);
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) { if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
} }
@ -711,7 +711,7 @@ namespace dawn_native { namespace d3d12 {
// compute d3d12 texture copy locations for texture and buffer // compute d3d12 texture copy locations for texture and buffer
Extent3D copySize = GetMipLevelVirtualSize(level); Extent3D copySize = GetMipLevelVirtualSize(level);
TextureCopySplit copySplit = ComputeTextureCopySplit( TextureCopySplit copySplit = ComputeTextureCopySplit(
{0, 0, 0}, copySize, GetFormat(), uploadHandle.startOffset, rowPitch, 0); {0, 0, 0}, copySize, GetFormat(), uploadHandle.startOffset, bytesPerRow, 0);
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount;
++layer) { ++layer) {
@ -729,7 +729,7 @@ namespace dawn_native { namespace d3d12 {
D3D12_TEXTURE_COPY_LOCATION bufferLocation = D3D12_TEXTURE_COPY_LOCATION bufferLocation =
ComputeBufferLocationForCopyTextureRegion( ComputeBufferLocationForCopyTextureRegion(
this, ToBackend(uploadHandle.stagingBuffer)->GetResource(), this, ToBackend(uploadHandle.stagingBuffer)->GetResource(),
info.bufferSize, copySplit.offset, rowPitch); info.bufferSize, copySplit.offset, bytesPerRow);
D3D12_BOX sourceRegion = D3D12_BOX sourceRegion =
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize); ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);

View File

@ -335,14 +335,14 @@ namespace dawn_native { namespace metal {
Extent3D virtualSizeAtLevel, Extent3D virtualSizeAtLevel,
uint64_t bufferSize, uint64_t bufferSize,
uint64_t bufferOffset, uint64_t bufferOffset,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t imageHeight) { uint32_t rowsPerImage) {
TextureBufferCopySplit copy; TextureBufferCopySplit copy;
// When copying textures from/to an unpacked buffer, the Metal validation layer doesn't // When copying textures from/to an unpacked buffer, the Metal validation layer doesn't
// compute the correct range when checking if the buffer is big enough to contain the // compute the correct range when checking if the buffer is big enough to contain the
// data for the whole copy. Instead of looking at the position of the last texel in the // data for the whole copy. Instead of looking at the position of the last texel in the
// buffer, it computes the volume of the 3D box with rowPitch * (imageHeight / // buffer, it computes the volume of the 3D box with bytesPerRow * (rowsPerImage /
// format.blockHeight) * copySize.depth. For example considering the pixel buffer below // format.blockHeight) * copySize.depth. For example considering the pixel buffer below
// where in memory, each row data (D) of the texture is followed by some padding data // where in memory, each row data (D) of the texture is followed by some padding data
// (P): // (P):
@ -356,8 +356,8 @@ namespace dawn_native { namespace metal {
// We work around this limitation by detecting when Metal would complain and copy the // We work around this limitation by detecting when Metal would complain and copy the
// last image and row separately using tight sourceBytesPerRow or sourceBytesPerImage. // last image and row separately using tight sourceBytesPerRow or sourceBytesPerImage.
uint32_t rowPitchCountPerImage = imageHeight / textureFormat.blockHeight; uint32_t dataRowsPerImage = rowsPerImage / textureFormat.blockHeight;
uint32_t bytesPerImage = rowPitch * rowPitchCountPerImage; uint32_t bytesPerImage = bytesPerRow * dataRowsPerImage;
// Metal validation layer requires that if the texture's pixel format is a compressed // Metal validation layer requires that if the texture's pixel format is a compressed
// format, the sourceSize must be a multiple of the pixel format's block size or be // format, the sourceSize must be a multiple of the pixel format's block size or be
@ -377,7 +377,7 @@ namespace dawn_native { namespace metal {
if (!needWorkaround) { if (!needWorkaround) {
copy.count = 1; copy.count = 1;
copy.copies[0].bufferOffset = bufferOffset; copy.copies[0].bufferOffset = bufferOffset;
copy.copies[0].bytesPerRow = rowPitch; copy.copies[0].bytesPerRow = bytesPerRow;
copy.copies[0].bytesPerImage = bytesPerImage; copy.copies[0].bytesPerImage = bytesPerImage;
copy.copies[0].textureOrigin = MakeMTLOrigin(origin); copy.copies[0].textureOrigin = MakeMTLOrigin(origin);
copy.copies[0].copyExtent = copy.copies[0].copyExtent =
@ -390,7 +390,7 @@ namespace dawn_native { namespace metal {
// Doing all the copy except the last image. // Doing all the copy except the last image.
if (copyExtent.depth > 1) { if (copyExtent.depth > 1) {
copy.copies[copy.count].bufferOffset = currentOffset; copy.copies[copy.count].bufferOffset = currentOffset;
copy.copies[copy.count].bytesPerRow = rowPitch; copy.copies[copy.count].bytesPerRow = bytesPerRow;
copy.copies[copy.count].bytesPerImage = bytesPerImage; copy.copies[copy.count].bytesPerImage = bytesPerImage;
copy.copies[copy.count].textureOrigin = MakeMTLOrigin(origin); copy.copies[copy.count].textureOrigin = MakeMTLOrigin(origin);
copy.copies[copy.count].copyExtent = MTLSizeMake( copy.copies[copy.count].copyExtent = MTLSizeMake(
@ -406,8 +406,8 @@ namespace dawn_native { namespace metal {
uint32_t copyBlockRowCount = copyExtent.height / textureFormat.blockHeight; uint32_t copyBlockRowCount = copyExtent.height / textureFormat.blockHeight;
if (copyBlockRowCount > 1) { if (copyBlockRowCount > 1) {
copy.copies[copy.count].bufferOffset = currentOffset; copy.copies[copy.count].bufferOffset = currentOffset;
copy.copies[copy.count].bytesPerRow = rowPitch; copy.copies[copy.count].bytesPerRow = bytesPerRow;
copy.copies[copy.count].bytesPerImage = rowPitch * (copyBlockRowCount - 1); copy.copies[copy.count].bytesPerImage = bytesPerRow * (copyBlockRowCount - 1);
copy.copies[copy.count].textureOrigin = copy.copies[copy.count].textureOrigin =
MTLOriginMake(origin.x, origin.y, origin.z + copyExtent.depth - 1); MTLOriginMake(origin.x, origin.y, origin.z + copyExtent.depth - 1);
@ -418,7 +418,7 @@ namespace dawn_native { namespace metal {
++copy.count; ++copy.count;
// Update offset to copy to the last row. // Update offset to copy to the last row.
currentOffset += (copyBlockRowCount - 1) * rowPitch; currentOffset += (copyBlockRowCount - 1) * bytesPerRow;
} }
// Doing the last row copy with the exact number of bytes in last row. // Doing the last row copy with the exact number of bytes in last row.
@ -752,7 +752,7 @@ namespace dawn_native { namespace metal {
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(dst.mipLevel); Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(dst.mipLevel);
TextureBufferCopySplit splittedCopies = ComputeTextureBufferCopySplit( TextureBufferCopySplit splittedCopies = ComputeTextureBufferCopySplit(
dst.origin, copySize, texture->GetFormat(), virtualSizeAtLevel, dst.origin, copySize, texture->GetFormat(), virtualSizeAtLevel,
buffer->GetSize(), src.offset, src.rowPitch, src.imageHeight); buffer->GetSize(), src.offset, src.bytesPerRow, src.rowsPerImage);
for (uint32_t i = 0; i < splittedCopies.count; ++i) { for (uint32_t i = 0; i < splittedCopies.count; ++i) {
const TextureBufferCopySplit::CopyInfo& copyInfo = splittedCopies.copies[i]; const TextureBufferCopySplit::CopyInfo& copyInfo = splittedCopies.copies[i];
@ -782,7 +782,7 @@ namespace dawn_native { namespace metal {
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(src.mipLevel); Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(src.mipLevel);
TextureBufferCopySplit splittedCopies = ComputeTextureBufferCopySplit( TextureBufferCopySplit splittedCopies = ComputeTextureBufferCopySplit(
src.origin, copySize, texture->GetFormat(), virtualSizeAtLevel, src.origin, copySize, texture->GetFormat(), virtualSizeAtLevel,
buffer->GetSize(), dst.offset, dst.rowPitch, dst.imageHeight); buffer->GetSize(), dst.offset, dst.bytesPerRow, dst.rowsPerImage);
for (uint32_t i = 0; i < splittedCopies.count; ++i) { for (uint32_t i = 0; i < splittedCopies.count; ++i) {
const TextureBufferCopySplit::CopyInfo& copyInfo = splittedCopies.copies[i]; const TextureBufferCopySplit::CopyInfo& copyInfo = splittedCopies.copies[i];

View File

@ -490,9 +490,10 @@ namespace dawn_native { namespace opengl {
gl.BindTexture(target, texture->GetHandle()); gl.BindTexture(target, texture->GetHandle());
const Format& formatInfo = texture->GetFormat(); const Format& formatInfo = texture->GetFormat();
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, gl.PixelStorei(
src.rowPitch / formatInfo.blockByteSize * formatInfo.blockWidth); GL_UNPACK_ROW_LENGTH,
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.imageHeight); src.bytesPerRow / formatInfo.blockByteSize * formatInfo.blockWidth);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage);
if (formatInfo.isCompressed) { if (formatInfo.isCompressed) {
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, formatInfo.blockByteSize); gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, formatInfo.blockByteSize);
@ -592,8 +593,8 @@ namespace dawn_native { namespace opengl {
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle()); gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
gl.PixelStorei(GL_PACK_ROW_LENGTH, gl.PixelStorei(GL_PACK_ROW_LENGTH,
dst.rowPitch / texture->GetFormat().blockByteSize); dst.bytesPerRow / texture->GetFormat().blockByteSize);
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.imageHeight); gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage);
ASSERT(copySize.depth == 1 && src.origin.z == 0); ASSERT(copySize.depth == 1 && src.origin.z == 0);
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset)); void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, copySize.height, gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, copySize.height,

View File

@ -286,17 +286,17 @@ namespace dawn_native { namespace opengl {
} else { } else {
// TODO(natlee@microsoft.com): test compressed textures are cleared // TODO(natlee@microsoft.com): test compressed textures are cleared
// create temp buffer with clear color to copy to the texture image // create temp buffer with clear color to copy to the texture image
ASSERT(kTextureRowPitchAlignment % GetFormat().blockByteSize == 0); ASSERT(kTextureBytesPerRowAlignment % GetFormat().blockByteSize == 0);
uint32_t rowPitch = uint32_t bytesPerRow =
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize, Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize,
kTextureRowPitchAlignment); kTextureBytesPerRowAlignment);
// Make sure that we are not rounding // Make sure that we are not rounding
ASSERT(rowPitch % GetFormat().blockByteSize == 0); ASSERT(bytesPerRow % GetFormat().blockByteSize == 0);
ASSERT(GetSize().height % GetFormat().blockHeight == 0); ASSERT(GetSize().height % GetFormat().blockHeight == 0);
dawn_native::BufferDescriptor descriptor; dawn_native::BufferDescriptor descriptor;
descriptor.size = rowPitch * (GetSize().height / GetFormat().blockHeight); descriptor.size = bytesPerRow * (GetSize().height / GetFormat().blockHeight);
if (descriptor.size > std::numeric_limits<uint32_t>::max()) { if (descriptor.size > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
} }
@ -317,7 +317,7 @@ namespace dawn_native { namespace opengl {
// Bind buffer and texture, and make the buffer to texture copy // Bind buffer and texture, and make the buffer to texture copy
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
(rowPitch / GetFormat().blockByteSize) * GetFormat().blockWidth); (bytesPerRow / GetFormat().blockByteSize) * GetFormat().blockWidth);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, srcBuffer->GetHandle()); gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, srcBuffer->GetHandle());

View File

@ -329,9 +329,9 @@ namespace dawn_native { namespace vulkan {
BufferCopy tempBufferCopy; BufferCopy tempBufferCopy;
tempBufferCopy.buffer = tempBuffer.Get(); tempBufferCopy.buffer = tempBuffer.Get();
tempBufferCopy.imageHeight = copySize.height; tempBufferCopy.rowsPerImage = copySize.height;
tempBufferCopy.offset = 0; tempBufferCopy.offset = 0;
tempBufferCopy.rowPitch = copySize.width / format.blockWidth * format.blockByteSize; tempBufferCopy.bytesPerRow = copySize.width / format.blockWidth * format.blockByteSize;
VkCommandBuffer commands = recordingContext->commandBuffer; VkCommandBuffer commands = recordingContext->commandBuffer;
VkImage srcImage = ToBackend(srcCopy.texture)->GetHandle(); VkImage srcImage = ToBackend(srcCopy.texture)->GetHandle();

View File

@ -721,10 +721,10 @@ namespace dawn_native { namespace vulkan {
} else { } else {
// TODO(natlee@microsoft.com): test compressed textures are cleared // TODO(natlee@microsoft.com): test compressed textures are cleared
// create temp buffer with clear color to copy to the texture image // create temp buffer with clear color to copy to the texture image
uint32_t rowPitch = uint32_t bytesPerRow =
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize, Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize,
kTextureRowPitchAlignment); kTextureBytesPerRowAlignment);
uint64_t bufferSize64 = rowPitch * (GetSize().height / GetFormat().blockHeight); uint64_t bufferSize64 = bytesPerRow * (GetSize().height / GetFormat().blockHeight);
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) { if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
} }
@ -737,9 +737,9 @@ namespace dawn_native { namespace vulkan {
// compute the buffer image copy to set the clear region of entire texture // compute the buffer image copy to set the clear region of entire texture
dawn_native::BufferCopy bufferCopy; dawn_native::BufferCopy bufferCopy;
bufferCopy.imageHeight = 0; bufferCopy.rowsPerImage = 0;
bufferCopy.offset = uploadHandle.startOffset; bufferCopy.offset = uploadHandle.startOffset;
bufferCopy.rowPitch = rowPitch; bufferCopy.bytesPerRow = bytesPerRow;
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
Extent3D copySize = GetMipLevelVirtualSize(level); Extent3D copySize = GetMipLevelVirtualSize(level);

View File

@ -75,9 +75,9 @@ namespace dawn_native { namespace vulkan {
region.bufferOffset = bufferCopy.offset; region.bufferOffset = bufferCopy.offset;
// In Vulkan the row length is in texels while it is in bytes for Dawn // In Vulkan the row length is in texels while it is in bytes for Dawn
const Format& format = texture->GetFormat(); const Format& format = texture->GetFormat();
ASSERT(bufferCopy.rowPitch % format.blockByteSize == 0); ASSERT(bufferCopy.bytesPerRow % format.blockByteSize == 0);
region.bufferRowLength = bufferCopy.rowPitch / format.blockByteSize * format.blockWidth; region.bufferRowLength = bufferCopy.bytesPerRow / format.blockByteSize * format.blockWidth;
region.bufferImageHeight = bufferCopy.imageHeight; region.bufferImageHeight = bufferCopy.rowsPerImage;
region.imageSubresource.aspectMask = texture->GetVkAspectMask(); region.imageSubresource.aspectMask = texture->GetVkAspectMask();
region.imageSubresource.mipLevel = textureCopy.mipLevel; region.imageSubresource.mipLevel = textureCopy.mipLevel;

View File

@ -796,7 +796,7 @@ std::ostringstream& DawnTestBase::AddBufferExpectation(const char* file,
deferred.readbackOffset = readback.offset; deferred.readbackOffset = readback.offset;
deferred.size = size; deferred.size = size;
deferred.rowBytes = size; deferred.rowBytes = size;
deferred.rowPitch = size; deferred.bytesPerRow = size;
deferred.expectation.reset(expectation); deferred.expectation.reset(expectation);
mDeferredExpectations.push_back(std::move(deferred)); mDeferredExpectations.push_back(std::move(deferred));
@ -815,8 +815,8 @@ std::ostringstream& DawnTestBase::AddTextureExpectation(const char* file,
uint32_t slice, uint32_t slice,
uint32_t pixelSize, uint32_t pixelSize,
detail::Expectation* expectation) { detail::Expectation* expectation) {
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
uint32_t size = rowPitch * (height - 1) + width * pixelSize; uint32_t size = bytesPerRow * (height - 1) + width * pixelSize;
auto readback = ReserveReadback(size); auto readback = ReserveReadback(size);
@ -825,7 +825,7 @@ std::ostringstream& DawnTestBase::AddTextureExpectation(const char* file,
wgpu::TextureCopyView textureCopyView = wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(texture, level, slice, {x, y, 0}); utils::CreateTextureCopyView(texture, level, slice, {x, y, 0});
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(readback.buffer, readback.offset, rowPitch, 0); utils::CreateBufferCopyView(readback.buffer, readback.offset, bytesPerRow, 0);
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
@ -841,7 +841,7 @@ std::ostringstream& DawnTestBase::AddTextureExpectation(const char* file,
deferred.readbackOffset = readback.offset; deferred.readbackOffset = readback.offset;
deferred.size = size; deferred.size = size;
deferred.rowBytes = width * pixelSize; deferred.rowBytes = width * pixelSize;
deferred.rowPitch = rowPitch; deferred.bytesPerRow = bytesPerRow;
deferred.expectation.reset(expectation); deferred.expectation.reset(expectation);
mDeferredExpectations.push_back(std::move(deferred)); mDeferredExpectations.push_back(std::move(deferred));
@ -929,15 +929,16 @@ void DawnTestBase::ResolveExpectations() {
uint32_t size; uint32_t size;
std::vector<char> packedData; std::vector<char> packedData;
if (expectation.rowBytes != expectation.rowPitch) { if (expectation.rowBytes != expectation.bytesPerRow) {
DAWN_ASSERT(expectation.rowPitch > expectation.rowBytes); DAWN_ASSERT(expectation.bytesPerRow > expectation.rowBytes);
uint32_t rowCount = uint32_t rowCount =
(expectation.size + expectation.rowPitch - 1) / expectation.rowPitch; (expectation.size + expectation.bytesPerRow - 1) / expectation.bytesPerRow;
uint32_t packedSize = rowCount * expectation.rowBytes; uint32_t packedSize = rowCount * expectation.rowBytes;
packedData.resize(packedSize); packedData.resize(packedSize);
for (uint32_t r = 0; r < rowCount; ++r) { for (uint32_t r = 0; r < rowCount; ++r) {
for (uint32_t i = 0; i < expectation.rowBytes; ++i) { for (uint32_t i = 0; i < expectation.rowBytes; ++i) {
packedData[i + r * expectation.rowBytes] = data[i + r * expectation.rowPitch]; packedData[i + r * expectation.rowBytes] =
data[i + r * expectation.bytesPerRow];
} }
} }
data = packedData.data(); data = packedData.data();

View File

@ -302,7 +302,7 @@ class DawnTestBase {
uint64_t readbackOffset; uint64_t readbackOffset;
uint64_t size; uint64_t size;
uint32_t rowBytes; uint32_t rowBytes;
uint32_t rowPitch; uint32_t bytesPerRow;
std::unique_ptr<detail::Expectation> expectation; std::unique_ptr<detail::Expectation> expectation;
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316
// Use unique_ptr because of missing move/copy constructors on std::basic_ostringstream // Use unique_ptr because of missing move/copy constructors on std::basic_ostringstream

View File

@ -158,7 +158,7 @@ class ComparisonSamplerTest : public DawnTest {
wgpu::BufferCopyView bufferCopyView = { wgpu::BufferCopyView bufferCopyView = {
.buffer = mTextureUploadBuffer, .buffer = mTextureUploadBuffer,
.offset = 0, .offset = 0,
.rowPitch = kTextureRowPitchAlignment, .rowPitch = kTextureBytesPerRowAlignment,
.imageHeight = 1, .imageHeight = 1,
}; };
wgpu::TextureCopyView textureCopyView = { wgpu::TextureCopyView textureCopyView = {

View File

@ -28,8 +28,8 @@ struct CopyConfig {
uint32_t viewMipmapLevel = 0; uint32_t viewMipmapLevel = 0;
uint32_t viewArrayLayer = 0; uint32_t viewArrayLayer = 0;
uint32_t bufferOffset = 0; uint32_t bufferOffset = 0;
uint32_t rowPitchAlignment = kTextureRowPitchAlignment; uint32_t bytesPerRowAlignment = kTextureBytesPerRowAlignment;
uint32_t imageHeight = 0; uint32_t rowsPerImage = 0;
}; };
class CompressedTextureBCFormatTest : public DawnTest { class CompressedTextureBCFormatTest : public DawnTest {
@ -52,7 +52,7 @@ class CompressedTextureBCFormatTest : public DawnTest {
const CopyConfig& copyConfig) { const CopyConfig& copyConfig) {
ASSERT(IsBCFormatSupported()); ASSERT(IsBCFormatSupported());
// Compute the upload buffer size with rowPitchAlignment and the copy region. // Compute the upload buffer size with bytesPerRowAlignment and the copy region.
const wgpu::Extent3D textureSize = copyConfig.textureDescriptor.size; const wgpu::Extent3D textureSize = copyConfig.textureDescriptor.size;
uint32_t actualWidthAtLevel = textureSize.width >> copyConfig.viewMipmapLevel; uint32_t actualWidthAtLevel = textureSize.width >> copyConfig.viewMipmapLevel;
uint32_t actualHeightAtLevel = textureSize.height >> copyConfig.viewMipmapLevel; uint32_t actualHeightAtLevel = textureSize.height >> copyConfig.viewMipmapLevel;
@ -61,8 +61,8 @@ class CompressedTextureBCFormatTest : public DawnTest {
uint32_t copyHeightInBlockAtLevel = uint32_t copyHeightInBlockAtLevel =
(actualHeightAtLevel + kBCBlockHeightInTexels - 1) / kBCBlockHeightInTexels; (actualHeightAtLevel + kBCBlockHeightInTexels - 1) / kBCBlockHeightInTexels;
uint32_t bufferRowPitchInBytes = 0; uint32_t bufferRowPitchInBytes = 0;
if (copyConfig.rowPitchAlignment != 0) { if (copyConfig.bytesPerRowAlignment != 0) {
bufferRowPitchInBytes = copyConfig.rowPitchAlignment; bufferRowPitchInBytes = copyConfig.bytesPerRowAlignment;
} else { } else {
bufferRowPitchInBytes = bufferRowPitchInBytes =
copyWidthInBlockAtLevel * copyWidthInBlockAtLevel *
@ -89,7 +89,7 @@ class CompressedTextureBCFormatTest : public DawnTest {
device, uploadData.data(), uploadBufferSize, wgpu::BufferUsage::CopySrc); device, uploadData.data(), uploadBufferSize, wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(stagingBuffer, copyConfig.bufferOffset, utils::CreateBufferCopyView(stagingBuffer, copyConfig.bufferOffset,
copyConfig.rowPitchAlignment, copyConfig.imageHeight); copyConfig.bytesPerRowAlignment, copyConfig.rowsPerImage);
wgpu::TextureCopyView textureCopyView = wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(bcCompressedTexture, copyConfig.viewMipmapLevel, utils::CreateTextureCopyView(bcCompressedTexture, copyConfig.viewMipmapLevel,
copyConfig.viewArrayLayer, copyConfig.copyOrigin3D); copyConfig.viewArrayLayer, copyConfig.copyOrigin3D);
@ -488,7 +488,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyIntoSubRegion) {
} }
} }
// Test using rowPitch == 0 in the copies with BC formats works correctly. // Test using bytesPerRow == 0 in the copies with BC formats works correctly.
TEST_P(CompressedTextureBCFormatTest, CopyWithZeroRowPitch) { TEST_P(CompressedTextureBCFormatTest, CopyWithZeroRowPitch) {
// TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan // TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan
// bots. // bots.
@ -504,11 +504,11 @@ TEST_P(CompressedTextureBCFormatTest, CopyWithZeroRowPitch) {
config.textureDescriptor.size.height = 8; config.textureDescriptor.size.height = 8;
config.textureDescriptor.size.depth = 1; config.textureDescriptor.size.depth = 1;
config.rowPitchAlignment = 0; config.bytesPerRowAlignment = 0;
for (wgpu::TextureFormat format : kBCFormats) { for (wgpu::TextureFormat format : kBCFormats) {
config.textureDescriptor.format = format; config.textureDescriptor.format = format;
config.textureDescriptor.size.width = kTextureRowPitchAlignment / config.textureDescriptor.size.width = kTextureBytesPerRowAlignment /
CompressedFormatBlockSizeInBytes(format) * CompressedFormatBlockSizeInBytes(format) *
kBCBlockWidthInTexels; kBCBlockWidthInTexels;
config.copyExtent3D = config.textureDescriptor.size; config.copyExtent3D = config.textureDescriptor.size;
@ -870,7 +870,7 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetAndExtentFitRowPitch) {
config.textureDescriptor.format = format; config.textureDescriptor.format = format;
const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format); const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format);
const uint32_t blockCountPerRowPitch = config.rowPitchAlignment / blockSizeInBytes; const uint32_t blockCountPerRowPitch = config.bytesPerRowAlignment / blockSizeInBytes;
config.bufferOffset = (blockCountPerRowPitch - blockCountPerRow) * blockSizeInBytes; config.bufferOffset = (blockCountPerRowPitch - blockCountPerRow) * blockSizeInBytes;
@ -879,7 +879,7 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetAndExtentFitRowPitch) {
} }
// Test the special case of the B2T copies on the D3D12 backend that the buffer offset exceeds the // Test the special case of the B2T copies on the D3D12 backend that the buffer offset exceeds the
// slice pitch (slicePitch = rowPitch * (imageHeightInTexels / blockHeightInTexels)). On D3D12 // slice pitch (slicePitch = bytesPerRow * (rowsPerImage / blockHeightInTexels)). On D3D12
// backend the texelOffset.y will be greater than 0 after calcuting the texelOffset in the function // backend the texelOffset.y will be greater than 0 after calcuting the texelOffset in the function
// ComputeTexelOffsets(). // ComputeTexelOffsets().
TEST_P(CompressedTextureBCFormatTest, BufferOffsetExceedsSlicePitch) { TEST_P(CompressedTextureBCFormatTest, BufferOffsetExceedsSlicePitch) {
@ -900,16 +900,16 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetExceedsSlicePitch) {
const wgpu::Extent3D textureSizeLevel0 = config.textureDescriptor.size; const wgpu::Extent3D textureSizeLevel0 = config.textureDescriptor.size;
const uint32_t blockCountPerRow = textureSizeLevel0.width / kBCBlockWidthInTexels; const uint32_t blockCountPerRow = textureSizeLevel0.width / kBCBlockWidthInTexels;
const uint32_t slicePitchInBytes = const uint32_t slicePitchInBytes =
config.rowPitchAlignment * (textureSizeLevel0.height / kBCBlockHeightInTexels); config.bytesPerRowAlignment * (textureSizeLevel0.height / kBCBlockHeightInTexels);
for (wgpu::TextureFormat format : kBCFormats) { for (wgpu::TextureFormat format : kBCFormats) {
config.textureDescriptor.format = format; config.textureDescriptor.format = format;
const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format); const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format);
const uint32_t blockCountPerRowPitch = config.rowPitchAlignment / blockSizeInBytes; const uint32_t blockCountPerRowPitch = config.bytesPerRowAlignment / blockSizeInBytes;
config.bufferOffset = (blockCountPerRowPitch - blockCountPerRow) * blockSizeInBytes + config.bufferOffset = (blockCountPerRowPitch - blockCountPerRow) * blockSizeInBytes +
config.rowPitchAlignment + slicePitchInBytes; config.bytesPerRowAlignment + slicePitchInBytes;
TestCopyRegionIntoBCFormatTextures(config); TestCopyRegionIntoBCFormatTextures(config);
} }
@ -940,7 +940,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWithBufferOffsetAndExtentExceedRowPitc
config.textureDescriptor.format = format; config.textureDescriptor.format = format;
const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format); const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format);
const uint32_t blockCountPerRowPitch = config.rowPitchAlignment / blockSizeInBytes; const uint32_t blockCountPerRowPitch = config.bytesPerRowAlignment / blockSizeInBytes;
config.bufferOffset = config.bufferOffset =
(blockCountPerRowPitch - blockCountPerRow + kExceedRowBlockCount) * blockSizeInBytes; (blockCountPerRowPitch - blockCountPerRow + kExceedRowBlockCount) * blockSizeInBytes;
@ -949,7 +949,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWithBufferOffsetAndExtentExceedRowPitc
} }
// Test the special case of the B2T copies on the D3D12 backend that the slicePitch is equal to the // Test the special case of the B2T copies on the D3D12 backend that the slicePitch is equal to the
// rowPitch. On D3D12 backend the texelOffset.z will be greater than 0 after calcuting the // bytesPerRow. On D3D12 backend the texelOffset.z will be greater than 0 after calcuting the
// texelOffset in the function ComputeTexelOffsets(). // texelOffset in the function ComputeTexelOffsets().
TEST_P(CompressedTextureBCFormatTest, RowPitchEqualToSlicePitch) { TEST_P(CompressedTextureBCFormatTest, RowPitchEqualToSlicePitch) {
// TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan // TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan
@ -964,13 +964,13 @@ TEST_P(CompressedTextureBCFormatTest, RowPitchEqualToSlicePitch) {
config.copyExtent3D = config.textureDescriptor.size; config.copyExtent3D = config.textureDescriptor.size;
const uint32_t blockCountPerRow = config.textureDescriptor.size.width / kBCBlockWidthInTexels; const uint32_t blockCountPerRow = config.textureDescriptor.size.width / kBCBlockWidthInTexels;
const uint32_t slicePitchInBytes = config.rowPitchAlignment; const uint32_t slicePitchInBytes = config.bytesPerRowAlignment;
for (wgpu::TextureFormat format : kBCFormats) { for (wgpu::TextureFormat format : kBCFormats) {
config.textureDescriptor.format = format; config.textureDescriptor.format = format;
const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format); const uint32_t blockSizeInBytes = CompressedFormatBlockSizeInBytes(format);
const uint32_t blockCountPerRowPitch = config.rowPitchAlignment / blockSizeInBytes; const uint32_t blockCountPerRowPitch = config.bytesPerRowAlignment / blockSizeInBytes;
config.bufferOffset = config.bufferOffset =
(blockCountPerRowPitch - blockCountPerRow) * blockSizeInBytes + slicePitchInBytes; (blockCountPerRowPitch - blockCountPerRow) * blockSizeInBytes + slicePitchInBytes;
@ -997,7 +997,7 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeight) {
config.textureDescriptor.size = {8, 8, 1}; config.textureDescriptor.size = {8, 8, 1};
config.copyExtent3D = config.textureDescriptor.size; config.copyExtent3D = config.textureDescriptor.size;
config.imageHeight = config.textureDescriptor.size.height * 2; config.rowsPerImage = config.textureDescriptor.size.height * 2;
for (wgpu::TextureFormat format : kBCFormats) { for (wgpu::TextureFormat format : kBCFormats) {
config.textureDescriptor.format = format; config.textureDescriptor.format = format;
@ -1040,7 +1040,7 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeightAndClampedCopyExtent) {
config.copyExtent3D = {kCopyWidthAtLevel, kCopyHeightAtLevel, 1}; config.copyExtent3D = {kCopyWidthAtLevel, kCopyHeightAtLevel, 1};
config.imageHeight = kCopyHeightAtLevel * 2; config.rowsPerImage = kCopyHeightAtLevel * 2;
for (wgpu::TextureFormat format : kBCFormats) { for (wgpu::TextureFormat format : kBCFormats) {
config.textureDescriptor.format = format; config.textureDescriptor.format = format;

View File

@ -37,7 +37,7 @@ class CopyTests : public DawnTest {
struct BufferSpec { struct BufferSpec {
uint64_t size; uint64_t size;
uint64_t offset; uint64_t offset;
uint32_t rowPitch; uint32_t bytesPerRow;
}; };
static void FillTextureData(uint32_t width, static void FillTextureData(uint32_t width,
@ -56,8 +56,8 @@ class CopyTests : public DawnTest {
} }
BufferSpec MinimumBufferSpec(uint32_t width, uint32_t height) { BufferSpec MinimumBufferSpec(uint32_t width, uint32_t height) {
uint32_t rowPitch = Align(width * kBytesPerTexel, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(width * kBytesPerTexel, kTextureBytesPerRowAlignment);
return { rowPitch * (height - 1) + width * kBytesPerTexel, 0, rowPitch }; return {bytesPerRow * (height - 1) + width * kBytesPerTexel, 0, bytesPerRow};
} }
static void PackTextureData(const RGBA8* srcData, uint32_t width, uint32_t height, uint32_t srcTexelsPerRow, RGBA8* dstData, uint32_t dstTexelsPerRow) { static void PackTextureData(const RGBA8* srcData, uint32_t width, uint32_t height, uint32_t srcTexelsPerRow, RGBA8* dstData, uint32_t dstTexelsPerRow) {
@ -90,8 +90,8 @@ class CopyTests_T2B : public CopyTests {
uint32_t width = textureSpec.width >> textureSpec.level; uint32_t width = textureSpec.width >> textureSpec.level;
uint32_t height = textureSpec.height >> textureSpec.level; uint32_t height = textureSpec.height >> textureSpec.level;
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(kBytesPerTexel * width, kTextureBytesPerRowAlignment);
uint32_t texelsPerRow = rowPitch / kBytesPerTexel; uint32_t texelsPerRow = bytesPerRow / kBytesPerTexel;
uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width; uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width;
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
@ -99,7 +99,7 @@ class CopyTests_T2B : public CopyTests {
std::vector<std::vector<RGBA8>> textureArrayData(textureSpec.arraySize); std::vector<std::vector<RGBA8>> textureArrayData(textureSpec.arraySize);
for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) { for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) {
textureArrayData[slice].resize(texelCountPerLayer); textureArrayData[slice].resize(texelCountPerLayer);
FillTextureData(width, height, rowPitch / kBytesPerTexel, slice, FillTextureData(width, height, bytesPerRow / kBytesPerTexel, slice,
textureArrayData[slice].data()); textureArrayData[slice].data());
// Create an upload buffer and use it to populate the current slice of the texture in `level` mip level // Create an upload buffer and use it to populate the current slice of the texture in `level` mip level
@ -108,16 +108,17 @@ class CopyTests_T2B : public CopyTests {
static_cast<uint32_t>(sizeof(RGBA8) * textureArrayData[slice].size()), static_cast<uint32_t>(sizeof(RGBA8) * textureArrayData[slice].size()),
wgpu::BufferUsage::CopySrc); wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(uploadBuffer, 0, bytesPerRow, 0);
wgpu::TextureCopyView textureCopyView = wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(texture, textureSpec.level, slice, {0, 0, 0}); utils::CreateTextureCopyView(texture, textureSpec.level, slice, {0, 0, 0});
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};
encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize); encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);
} }
// Create a buffer of size `size * textureSpec.arrayLayer` and populate it with empty data (0,0,0,0) // Create a buffer of size `size * textureSpec.arrayLayer` and populate it with empty
// Note: Prepopulating the buffer with empty data ensures that there is not random data in the expectation // data (0,0,0,0) Note: Prepopulating the buffer with empty data ensures that there is
// and helps ensure that the padding due to the row pitch is not modified by the copy // not random data in the expectation and helps ensure that the padding due to the bytes
// per row is not modified by the copy
wgpu::BufferDescriptor bufDescriptor; wgpu::BufferDescriptor bufDescriptor;
bufDescriptor.size = bufferSpec.size * textureSpec.arraySize; bufDescriptor.size = bufferSpec.size * textureSpec.arraySize;
bufDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst; bufDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
@ -128,11 +129,12 @@ class CopyTests_T2B : public CopyTests {
uint64_t bufferOffset = bufferSpec.offset; uint64_t bufferOffset = bufferSpec.offset;
for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) { for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) {
// Copy the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] from the `level` mip into the buffer at `offset + bufferSpec.size * slice` and `rowPitch` // Copy the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] from the `level`
// mip into the buffer at `offset + bufferSpec.size * slice` and `bytesPerRow`
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView( wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
texture, textureSpec.level, slice, {textureSpec.x, textureSpec.y, 0}); texture, textureSpec.level, slice, {textureSpec.x, textureSpec.y, 0});
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(buffer, bufferOffset, bufferSpec.rowPitch, 0); utils::CreateBufferCopyView(buffer, bufferOffset, bufferSpec.bytesPerRow, 0);
wgpu::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1}; wgpu::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1};
encoder.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, &copySize); encoder.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, &copySize);
bufferOffset += bufferSpec.size; bufferOffset += bufferSpec.size;
@ -142,22 +144,28 @@ class CopyTests_T2B : public CopyTests {
queue.Submit(1, &commands); queue.Submit(1, &commands);
bufferOffset = bufferSpec.offset; bufferOffset = bufferSpec.offset;
std::vector<RGBA8> expected(bufferSpec.rowPitch / kBytesPerTexel * (textureSpec.copyHeight - 1) + textureSpec.copyWidth); std::vector<RGBA8> expected(bufferSpec.bytesPerRow / kBytesPerTexel *
(textureSpec.copyHeight - 1) +
textureSpec.copyWidth);
for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) { for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) {
// Pack the data used to create the upload buffer in the specified copy region to have the same format as the expected buffer data. // Pack the data used to create the upload buffer in the specified copy region to have the same format as the expected buffer data.
std::fill(expected.begin(), expected.end(), RGBA8()); std::fill(expected.begin(), expected.end(), RGBA8());
PackTextureData( PackTextureData(
&textureArrayData[slice][textureSpec.x + textureSpec.y * (rowPitch / kBytesPerTexel)], &textureArrayData[slice][textureSpec.x +
textureSpec.copyWidth, textureSpec.y * (bytesPerRow / kBytesPerTexel)],
textureSpec.copyHeight, textureSpec.copyWidth, textureSpec.copyHeight, bytesPerRow / kBytesPerTexel,
rowPitch / kBytesPerTexel, expected.data(), bufferSpec.bytesPerRow / kBytesPerTexel);
expected.data(),
bufferSpec.rowPitch / kBytesPerTexel);
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer, bufferOffset, static_cast<uint32_t>(expected.size())) << EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()),
"Texture to Buffer copy failed copying region [(" << textureSpec.x << ", " << textureSpec.y << "), (" << textureSpec.x + textureSpec.copyWidth << ", " << textureSpec.y + textureSpec.copyHeight << buffer, bufferOffset,
")) from " << textureSpec.width << " x " << textureSpec.height << " texture at mip level " << textureSpec.level << " layer " << slice << static_cast<uint32_t>(expected.size()))
" to " << bufDescriptor.size << "-byte buffer with offset " << bufferOffset << " and row pitch " << bufferSpec.rowPitch << std::endl; << "Texture to Buffer copy failed copying region [(" << textureSpec.x << ", "
<< textureSpec.y << "), (" << textureSpec.x + textureSpec.copyWidth << ", "
<< textureSpec.y + textureSpec.copyHeight << ")) from " << textureSpec.width
<< " x " << textureSpec.height << " texture at mip level " << textureSpec.level
<< " layer " << slice << " to " << bufDescriptor.size
<< "-byte buffer with offset " << bufferOffset << " and bytes per row "
<< bufferSpec.bytesPerRow << std::endl;
bufferOffset += bufferSpec.size; bufferOffset += bufferSpec.size;
} }
@ -205,14 +213,15 @@ protected:
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
// Create an upload buffer filled with empty data and use it to populate the `level` mip of the texture // Create an upload buffer filled with empty data and use it to populate the `level` mip of
// Note: Prepopulating the texture with empty data ensures that there is not random data in the expectation // the texture Note: Prepopulating the texture with empty data ensures that there is not
// and helps ensure that the padding due to the row pitch is not modified by the copy // random data in the expectation and helps ensure that the padding due to the bytes per row
// is not modified by the copy
{ {
uint32_t width = textureSpec.width >> textureSpec.level; uint32_t width = textureSpec.width >> textureSpec.level;
uint32_t height = textureSpec.height >> textureSpec.level; uint32_t height = textureSpec.height >> textureSpec.level;
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(kBytesPerTexel * width, kTextureBytesPerRowAlignment);
uint32_t texelsPerRow = rowPitch / kBytesPerTexel; uint32_t texelsPerRow = bytesPerRow / kBytesPerTexel;
uint32_t texelCount = texelsPerRow * (height - 1) + width; uint32_t texelCount = texelsPerRow * (height - 1) + width;
std::vector<RGBA8> emptyData(texelCount); std::vector<RGBA8> emptyData(texelCount);
@ -220,17 +229,18 @@ protected:
device, emptyData.data(), static_cast<uint32_t>(sizeof(RGBA8) * emptyData.size()), device, emptyData.data(), static_cast<uint32_t>(sizeof(RGBA8) * emptyData.size()),
wgpu::BufferUsage::CopySrc); wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(uploadBuffer, 0, bytesPerRow, 0);
wgpu::TextureCopyView textureCopyView = wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(texture, textureSpec.level, 0, {0, 0, 0}); utils::CreateTextureCopyView(texture, textureSpec.level, 0, {0, 0, 0});
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};
encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize); encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);
} }
// Copy to the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] at the `level` mip from the buffer at the specified `offset` and `rowPitch` // Copy to the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] at the `level` mip
// from the buffer at the specified `offset` and `bytesPerRow`
{ {
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(buffer, bufferSpec.offset, bufferSpec.rowPitch, 0); utils::CreateBufferCopyView(buffer, bufferSpec.offset, bufferSpec.bytesPerRow, 0);
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView( wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
texture, textureSpec.level, 0, {textureSpec.x, textureSpec.y, 0}); texture, textureSpec.level, 0, {textureSpec.x, textureSpec.y, 0});
wgpu::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1}; wgpu::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1};
@ -241,15 +251,23 @@ protected:
queue.Submit(1, &commands); queue.Submit(1, &commands);
// Pack the data used to create the buffer in the specified copy region to have the same format as the expected texture data. // Pack the data used to create the buffer in the specified copy region to have the same format as the expected texture data.
uint32_t rowPitch = Align(kBytesPerTexel * textureSpec.copyWidth, kTextureRowPitchAlignment); uint32_t bytesPerRow =
std::vector<RGBA8> expected(rowPitch / kBytesPerTexel * (textureSpec.copyHeight - 1) + textureSpec.copyWidth); Align(kBytesPerTexel * textureSpec.copyWidth, kTextureBytesPerRowAlignment);
PackTextureData(&bufferData[bufferSpec.offset / kBytesPerTexel], textureSpec.copyWidth, textureSpec.copyHeight, bufferSpec.rowPitch / kBytesPerTexel, expected.data(), textureSpec.copyWidth); std::vector<RGBA8> expected(bytesPerRow / kBytesPerTexel * (textureSpec.copyHeight - 1) +
textureSpec.copyWidth);
PackTextureData(&bufferData[bufferSpec.offset / kBytesPerTexel], textureSpec.copyWidth,
textureSpec.copyHeight, bufferSpec.bytesPerRow / kBytesPerTexel,
expected.data(), textureSpec.copyWidth);
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, textureSpec.x, textureSpec.y, textureSpec.copyWidth, textureSpec.copyHeight, textureSpec.level, 0) << EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, textureSpec.x, textureSpec.y,
"Buffer to Texture copy failed copying " textureSpec.copyWidth, textureSpec.copyHeight, textureSpec.level, 0)
<< bufferSpec.size << "-byte buffer with offset " << bufferSpec.offset << " and row pitch " << bufferSpec.rowPitch << " to [(" << "Buffer to Texture copy failed copying " << bufferSpec.size
<< textureSpec.x << ", " << textureSpec.y << "), (" << textureSpec.x + textureSpec.copyWidth << ", " << textureSpec.y + textureSpec.copyHeight << << "-byte buffer with offset " << bufferSpec.offset << " and bytes per row "
")) region of " << textureSpec.width << " x " << textureSpec.height << " texture at mip level " << textureSpec.level << std::endl; << bufferSpec.bytesPerRow << " to [(" << textureSpec.x << ", " << textureSpec.y
<< "), (" << textureSpec.x + textureSpec.copyWidth << ", "
<< textureSpec.y + textureSpec.copyHeight << ")) region of " << textureSpec.width
<< " x " << textureSpec.height << " texture at mip level " << textureSpec.level
<< std::endl;
} }
@ -302,14 +320,14 @@ class CopyTests_T2T : public CopyTests {
// `level` mip level // `level` mip level
uint32_t width = srcSpec.width >> srcSpec.level; uint32_t width = srcSpec.width >> srcSpec.level;
uint32_t height = srcSpec.height >> srcSpec.level; uint32_t height = srcSpec.height >> srcSpec.level;
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(kBytesPerTexel * width, kTextureBytesPerRowAlignment);
uint32_t texelsPerRow = rowPitch / kBytesPerTexel; uint32_t texelsPerRow = bytesPerRow / kBytesPerTexel;
uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width; uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width;
std::vector<std::vector<RGBA8>> textureArrayData(srcSpec.arraySize); std::vector<std::vector<RGBA8>> textureArrayData(srcSpec.arraySize);
for (uint32_t slice = 0; slice < srcSpec.arraySize; ++slice) { for (uint32_t slice = 0; slice < srcSpec.arraySize; ++slice) {
textureArrayData[slice].resize(texelCountPerLayer); textureArrayData[slice].resize(texelCountPerLayer);
FillTextureData(width, height, rowPitch / kBytesPerTexel, slice, FillTextureData(width, height, bytesPerRow / kBytesPerTexel, slice,
textureArrayData[slice].data()); textureArrayData[slice].data());
wgpu::Buffer uploadBuffer = utils::CreateBufferFromData( wgpu::Buffer uploadBuffer = utils::CreateBufferFromData(
@ -317,7 +335,7 @@ class CopyTests_T2T : public CopyTests {
static_cast<uint32_t>(sizeof(RGBA8) * textureArrayData[slice].size()), static_cast<uint32_t>(sizeof(RGBA8) * textureArrayData[slice].size()),
wgpu::BufferUsage::CopySrc); wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(uploadBuffer, 0, bytesPerRow, 0);
wgpu::TextureCopyView textureCopyView = wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(srcTexture, srcSpec.level, slice, {0, 0, 0}); utils::CreateTextureCopyView(srcTexture, srcSpec.level, slice, {0, 0, 0});
wgpu::Extent3D bufferCopySize = {width, height, 1}; wgpu::Extent3D bufferCopySize = {width, height, 1};
@ -327,12 +345,12 @@ class CopyTests_T2T : public CopyTests {
// Create an upload buffer filled with empty data and use it to populate the `level` mip of // Create an upload buffer filled with empty data and use it to populate the `level` mip of
// the texture. Note: Prepopulating the texture with empty data ensures that there is not // the texture. Note: Prepopulating the texture with empty data ensures that there is not
// random data in the expectation and helps ensure that the padding due to the row pitch is // random data in the expectation and helps ensure that the padding due to the bytes per row
// not modified by the copy // is not modified by the copy
{ {
uint32_t dstWidth = dstSpec.width >> dstSpec.level; uint32_t dstWidth = dstSpec.width >> dstSpec.level;
uint32_t dstHeight = dstSpec.height >> dstSpec.level; uint32_t dstHeight = dstSpec.height >> dstSpec.level;
uint32_t dstRowPitch = Align(kBytesPerTexel * dstWidth, kTextureRowPitchAlignment); uint32_t dstRowPitch = Align(kBytesPerTexel * dstWidth, kTextureBytesPerRowAlignment);
uint32_t dstTexelsPerRow = dstRowPitch / kBytesPerTexel; uint32_t dstTexelsPerRow = dstRowPitch / kBytesPerTexel;
uint32_t dstTexelCount = dstTexelsPerRow * (dstHeight - 1) + dstWidth; uint32_t dstTexelCount = dstTexelsPerRow * (dstHeight - 1) + dstWidth;
@ -361,11 +379,11 @@ class CopyTests_T2T : public CopyTests {
wgpu::CommandBuffer commands = encoder.Finish(); wgpu::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands); queue.Submit(1, &commands);
std::vector<RGBA8> expected(rowPitch / kBytesPerTexel * (copy.height - 1) + copy.width); std::vector<RGBA8> expected(bytesPerRow / kBytesPerTexel * (copy.height - 1) + copy.width);
for (uint32_t slice = 0; slice < srcSpec.arraySize; ++slice) { for (uint32_t slice = 0; slice < srcSpec.arraySize; ++slice) {
std::fill(expected.begin(), expected.end(), RGBA8()); std::fill(expected.begin(), expected.end(), RGBA8());
PackTextureData( PackTextureData(
&textureArrayData[slice][srcSpec.x + srcSpec.y * (rowPitch / kBytesPerTexel)], &textureArrayData[slice][srcSpec.x + srcSpec.y * (bytesPerRow / kBytesPerTexel)],
copy.width, copy.height, texelsPerRow, expected.data(), copy.width); copy.width, copy.height, texelsPerRow, expected.data(), copy.width);
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, dstSpec.x, dstSpec.y, copy.width, EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, dstSpec.x, dstSpec.y, copy.width,
@ -486,7 +504,8 @@ TEST_P(CopyTests_T2B, OffsetBufferUnaligned) {
} }
} }
// Test that copying without a 512-byte aligned buffer offset that is greater than the row pitch works // Test that copying without a 512-byte aligned buffer offset that is greater than the bytes per row
// works
TEST_P(CopyTests_T2B, OffsetBufferUnalignedSmallRowPitch) { TEST_P(CopyTests_T2B, OffsetBufferUnalignedSmallRowPitch) {
constexpr uint32_t kWidth = 32; constexpr uint32_t kWidth = 32;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
@ -498,25 +517,26 @@ TEST_P(CopyTests_T2B, OffsetBufferUnalignedSmallRowPitch) {
} }
} }
// Test that copying with a greater row pitch than needed on a 256-byte aligned texture works // Test that copying with a greater bytes per row than needed on a 256-byte aligned texture works
TEST_P(CopyTests_T2B, RowPitchAligned) { TEST_P(CopyTests_T2B, RowPitchAligned) {
constexpr uint32_t kWidth = 256; constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight); BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
for (unsigned int i = 1; i < 4; ++i) { for (unsigned int i = 1; i < 4; ++i) {
bufferSpec.rowPitch += 256; bufferSpec.bytesPerRow += 256;
bufferSpec.size += 256 * kHeight; bufferSpec.size += 256 * kHeight;
DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec); DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec);
} }
} }
// Test that copying with a greater row pitch than needed on a texture that is not 256-byte aligned works // Test that copying with a greater bytes per row than needed on a texture that is not 256-byte
// aligned works
TEST_P(CopyTests_T2B, RowPitchUnaligned) { TEST_P(CopyTests_T2B, RowPitchUnaligned) {
constexpr uint32_t kWidth = 259; constexpr uint32_t kWidth = 259;
constexpr uint32_t kHeight = 127; constexpr uint32_t kHeight = 127;
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight); BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
for (unsigned int i = 1; i < 4; ++i) { for (unsigned int i = 1; i < 4; ++i) {
bufferSpec.rowPitch += 256; bufferSpec.bytesPerRow += 256;
bufferSpec.size += 256 * kHeight; bufferSpec.size += 256 * kHeight;
DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec); DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec);
} }
@ -647,7 +667,8 @@ TEST_P(CopyTests_B2T, OffsetBufferUnaligned) {
} }
} }
// Test that copying without a 512-byte aligned buffer offset that is greater than the row pitch works // Test that copying without a 512-byte aligned buffer offset that is greater than the bytes per row
// works
TEST_P(CopyTests_B2T, OffsetBufferUnalignedSmallRowPitch) { TEST_P(CopyTests_B2T, OffsetBufferUnalignedSmallRowPitch) {
constexpr uint32_t kWidth = 32; constexpr uint32_t kWidth = 32;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
@ -659,25 +680,26 @@ TEST_P(CopyTests_B2T, OffsetBufferUnalignedSmallRowPitch) {
} }
} }
// Test that copying with a greater row pitch than needed on a 256-byte aligned texture works // Test that copying with a greater bytes per row than needed on a 256-byte aligned texture works
TEST_P(CopyTests_B2T, RowPitchAligned) { TEST_P(CopyTests_B2T, RowPitchAligned) {
constexpr uint32_t kWidth = 256; constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128; constexpr uint32_t kHeight = 128;
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight); BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
for (unsigned int i = 1; i < 4; ++i) { for (unsigned int i = 1; i < 4; ++i) {
bufferSpec.rowPitch += 256; bufferSpec.bytesPerRow += 256;
bufferSpec.size += 256 * kHeight; bufferSpec.size += 256 * kHeight;
DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec); DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec);
} }
} }
// Test that copying with a greater row pitch than needed on a texture that is not 256-byte aligned works // Test that copying with a greater bytes per row than needed on a texture that is not 256-byte
// aligned works
TEST_P(CopyTests_B2T, RowPitchUnaligned) { TEST_P(CopyTests_B2T, RowPitchUnaligned) {
constexpr uint32_t kWidth = 259; constexpr uint32_t kWidth = 259;
constexpr uint32_t kHeight = 127; constexpr uint32_t kHeight = 127;
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight); BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
for (unsigned int i = 1; i < 4; ++i) { for (unsigned int i = 1; i < 4; ++i) {
bufferSpec.rowPitch += 256; bufferSpec.bytesPerRow += 256;
bufferSpec.size += 256 * kHeight; bufferSpec.size += 256 * kHeight;
DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec); DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec);
} }

View File

@ -19,6 +19,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h" #include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h" #include "utils/WGPUHelpers.h"
@ -364,6 +365,136 @@ TEST_P(DeprecationTests, ShaderModuleInlinedCodeStateTracking) {
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&renderPipelineDesc)); ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&renderPipelineDesc));
} }
// Tests for BufferCopyView.rowPitch/imageHeight -> bytesPerRow/rowsPerImage
class BufferCopyViewDeprecationTests : public DeprecationTests {
protected:
void TestSetUp() override {
DeprecationTests::TestSetUp();
wgpu::BufferDescriptor bufferDesc = {
.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst,
.size = kTextureBytesPerRowAlignment * 2,
};
buffer = device.CreateBuffer(&bufferDesc);
wgpu::TextureDescriptor textureDesc = {
.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst,
.size = {2, 2, 1},
.format = wgpu::TextureFormat::RGBA8Unorm,
};
texture = device.CreateTexture(&textureDesc);
}
enum CopyType {
B2T,
T2B,
};
void DoCopy(CopyType type, const wgpu::BufferCopyView& bufferView) {
wgpu::TextureCopyView textureCopyView = {
.texture = texture,
.mipLevel = 0,
.arrayLayer = 0,
.origin = {0, 0},
};
wgpu::Extent3D copySize = {2, 2, 1};
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
switch (type) {
case B2T:
encoder.CopyBufferToTexture(&bufferView, &textureCopyView, &copySize);
break;
case T2B:
encoder.CopyTextureToBuffer(&textureCopyView, &bufferView, &copySize);
break;
}
encoder.Finish();
}
wgpu::Buffer buffer;
wgpu::Texture texture;
};
// Test that using rowPitch produces a deprecation warning.
TEST_P(BufferCopyViewDeprecationTests, RowPitchIsDeprecated) {
wgpu::BufferCopyView view = {
.buffer = buffer,
.rowPitch = 256,
};
EXPECT_DEPRECATION_WARNING(DoCopy(B2T, view));
EXPECT_DEPRECATION_WARNING(DoCopy(T2B, view));
}
// Test that using imageHeight produces a deprecation warning.
TEST_P(BufferCopyViewDeprecationTests, ImageHeightIsDeprecated) {
wgpu::BufferCopyView view = {
.buffer = buffer,
.imageHeight = 2,
.bytesPerRow = 256,
};
EXPECT_DEPRECATION_WARNING(DoCopy(B2T, view));
EXPECT_DEPRECATION_WARNING(DoCopy(T2B, view));
}
// Test that using both rowPitch and bytesPerRow produces a validation error.
TEST_P(BufferCopyViewDeprecationTests, BothRowPitchAndBytesPerRowIsInvalid) {
wgpu::BufferCopyView view = {
.buffer = buffer,
.rowPitch = 256,
.bytesPerRow = 256,
};
ASSERT_DEVICE_ERROR(DoCopy(B2T, view));
ASSERT_DEVICE_ERROR(DoCopy(T2B, view));
}
// Test that using both imageHeight and rowsPerImage produces a validation error.
TEST_P(BufferCopyViewDeprecationTests, BothImageHeightAndRowsPerImageIsInvalid) {
wgpu::BufferCopyView view = {
.buffer = buffer,
.imageHeight = 2,
.bytesPerRow = 256,
.rowsPerImage = 2,
};
ASSERT_DEVICE_ERROR(DoCopy(B2T, view));
ASSERT_DEVICE_ERROR(DoCopy(T2B, view));
}
// Test that rowPitch is correctly taken into account for validation
TEST_P(BufferCopyViewDeprecationTests, RowPitchTakenIntoAccountForValidation) {
wgpu::BufferCopyView view = {
.buffer = buffer,
.rowPitch = 256,
};
EXPECT_DEPRECATION_WARNING(DoCopy(B2T, view));
EXPECT_DEPRECATION_WARNING(DoCopy(T2B, view));
view.rowPitch = 128;
ASSERT_DEVICE_ERROR(EXPECT_DEPRECATION_WARNING(DoCopy(B2T, view)));
ASSERT_DEVICE_ERROR(EXPECT_DEPRECATION_WARNING(DoCopy(T2B, view)));
}
// Test that imageHeight is correctly taken into account for validation
TEST_P(BufferCopyViewDeprecationTests, ImageHeightTakenIntoAccountForValidation) {
wgpu::BufferCopyView view = {
.buffer = buffer,
.imageHeight = 2,
.bytesPerRow = 256,
};
EXPECT_DEPRECATION_WARNING(DoCopy(B2T, view));
EXPECT_DEPRECATION_WARNING(DoCopy(T2B, view));
view.imageHeight = 1;
ASSERT_DEVICE_ERROR(EXPECT_DEPRECATION_WARNING(DoCopy(B2T, view)));
ASSERT_DEVICE_ERROR(EXPECT_DEPRECATION_WARNING(DoCopy(T2B, view)));
}
DAWN_INSTANTIATE_TEST(BufferCopyViewDeprecationTests,
D3D12Backend(),
MetalBackend(),
NullBackend(),
OpenGLBackend(),
VulkanBackend());
DAWN_INSTANTIATE_TEST(DeprecationTests, DAWN_INSTANTIATE_TEST(DeprecationTests,
D3D12Backend(), D3D12Backend(),
MetalBackend(), MetalBackend(),

View File

@ -98,7 +98,7 @@ protected:
wgpu::Texture texture = device.CreateTexture(&descriptor); wgpu::Texture texture = device.CreateTexture(&descriptor);
// Create a 2x2 checkerboard texture, with black in the top left and bottom right corners. // Create a 2x2 checkerboard texture, with black in the top left and bottom right corners.
const uint32_t rowPixels = kTextureRowPitchAlignment / sizeof(RGBA8); const uint32_t rowPixels = kTextureBytesPerRowAlignment / sizeof(RGBA8);
RGBA8 data[rowPixels * 2]; RGBA8 data[rowPixels * 2];
data[0] = data[rowPixels + 1] = RGBA8::kBlack; data[0] = data[rowPixels + 1] = RGBA8::kBlack;
data[1] = data[rowPixels] = RGBA8::kWhite; data[1] = data[rowPixels] = RGBA8::kWhite;

View File

@ -117,9 +117,9 @@ protected:
// Create a texture with pixel = (0, 0, 0, level * 10 + layer + 1) at level `level` and // Create a texture with pixel = (0, 0, 0, level * 10 + layer + 1) at level `level` and
// layer `layer`. // layer `layer`.
static_assert((kTextureRowPitchAlignment % sizeof(RGBA8)) == 0, static_assert((kTextureBytesPerRowAlignment % sizeof(RGBA8)) == 0,
"Texture row pitch alignment must be a multiple of sizeof(RGBA8)."); "Texture bytes per row alignment must be a multiple of sizeof(RGBA8).");
constexpr uint32_t kPixelsPerRowPitch = kTextureRowPitchAlignment / sizeof(RGBA8); constexpr uint32_t kPixelsPerRowPitch = kTextureBytesPerRowAlignment / sizeof(RGBA8);
ASSERT_LE(textureWidthLevel0, kPixelsPerRowPitch); ASSERT_LE(textureWidthLevel0, kPixelsPerRowPitch);
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
@ -135,7 +135,7 @@ protected:
wgpu::Buffer stagingBuffer = utils::CreateBufferFromData( wgpu::Buffer stagingBuffer = utils::CreateBufferFromData(
device, data.data(), data.size() * sizeof(RGBA8), wgpu::BufferUsage::CopySrc); device, data.data(), data.size() * sizeof(RGBA8), wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = wgpu::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(stagingBuffer, 0, kTextureRowPitchAlignment, 0); utils::CreateBufferCopyView(stagingBuffer, 0, kTextureBytesPerRowAlignment, 0);
wgpu::TextureCopyView textureCopyView = wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(mTexture, level, layer, {0, 0, 0}); utils::CreateTextureCopyView(mTexture, level, layer, {0, 0, 0});
wgpu::Extent3D copySize = {texWidth, texHeight, 1}; wgpu::Extent3D copySize = {texWidth, texHeight, 1};
@ -514,9 +514,10 @@ class TextureViewRenderingTest : public DawnTest {
// Check if the right pixels (Green) have been written into the right part of the texture. // Check if the right pixels (Green) have been written into the right part of the texture.
uint32_t textureViewWidth = textureWidthLevel0 >> textureViewBaseLevel; uint32_t textureViewWidth = textureWidthLevel0 >> textureViewBaseLevel;
uint32_t textureViewHeight = textureHeightLevel0 >> textureViewBaseLevel; uint32_t textureViewHeight = textureHeightLevel0 >> textureViewBaseLevel;
uint32_t rowPitch = Align(kBytesPerTexel * textureWidthLevel0, kTextureRowPitchAlignment); uint32_t bytesPerRow =
Align(kBytesPerTexel * textureWidthLevel0, kTextureBytesPerRowAlignment);
uint32_t expectedDataSize = uint32_t expectedDataSize =
rowPitch / kBytesPerTexel * (textureWidthLevel0 - 1) + textureHeightLevel0; bytesPerRow / kBytesPerTexel * (textureWidthLevel0 - 1) + textureHeightLevel0;
constexpr RGBA8 kExpectedPixel(0, 255, 0, 255); constexpr RGBA8 kExpectedPixel(0, 255, 0, 255);
std::vector<RGBA8> expected(expectedDataSize, kExpectedPixel); std::vector<RGBA8> expected(expectedDataSize, kExpectedPixel);
EXPECT_TEXTURE_RGBA8_EQ( EXPECT_TEXTURE_RGBA8_EQ(

View File

@ -638,13 +638,13 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClear) {
wgpu::Texture texture = device.CreateTexture(&descriptor); wgpu::Texture texture = device.CreateTexture(&descriptor);
// Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy // Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy
uint32_t rowPitch = Align(kSize * kFormatBlockByteSize, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(kSize * kFormatBlockByteSize, kTextureBytesPerRowAlignment);
uint32_t bufferSize = rowPitch * kSize; uint32_t bufferSize = bytesPerRow * kSize;
std::vector<uint8_t> data(bufferSize, 100); std::vector<uint8_t> data(bufferSize, 100);
wgpu::Buffer bufferDst = utils::CreateBufferFromData( wgpu::Buffer bufferDst = utils::CreateBufferFromData(
device, data.data(), static_cast<uint32_t>(data.size()), wgpu::BufferUsage::CopySrc); device, data.data(), static_cast<uint32_t>(data.size()), wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(bufferDst, 0, rowPitch, 0); wgpu::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(bufferDst, 0, bytesPerRow, 0);
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0}); wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
wgpu::Extent3D copySize = {kSize, kSize, 1}; wgpu::Extent3D copySize = {kSize, kSize, 1};
@ -669,12 +669,13 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClearUnalignedSize) {
wgpu::Texture texture = device.CreateTexture(&descriptor); wgpu::Texture texture = device.CreateTexture(&descriptor);
// Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy // Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy
uint32_t rowPitch = Align(kUnalignedSize * kFormatBlockByteSize, kTextureRowPitchAlignment); uint32_t bytesPerRow =
uint32_t bufferSize = rowPitch * kUnalignedSize; Align(kUnalignedSize * kFormatBlockByteSize, kTextureBytesPerRowAlignment);
uint32_t bufferSize = bytesPerRow * kUnalignedSize;
std::vector<uint8_t> data(bufferSize, 100); std::vector<uint8_t> data(bufferSize, 100);
wgpu::Buffer bufferDst = utils::CreateBufferFromData( wgpu::Buffer bufferDst = utils::CreateBufferFromData(
device, data.data(), static_cast<uint32_t>(data.size()), wgpu::BufferUsage::CopySrc); device, data.data(), static_cast<uint32_t>(data.size()), wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(bufferDst, 0, rowPitch, 0); wgpu::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(bufferDst, 0, bytesPerRow, 0);
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0}); wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
wgpu::Extent3D copySize = {kUnalignedSize, kUnalignedSize, 1}; wgpu::Extent3D copySize = {kUnalignedSize, kUnalignedSize, 1};

View File

@ -39,8 +39,8 @@ namespace {
struct BufferSpec { struct BufferSpec {
uint64_t offset; uint64_t offset;
uint32_t rowPitch; uint32_t bytesPerRow;
uint32_t imageHeight; uint32_t rowsPerImage;
}; };
// Check that each copy region fits inside the buffer footprint // Check that each copy region fits inside the buffer footprint
@ -123,14 +123,14 @@ namespace {
for (uint32_t i = 0; i < copySplit.count; ++i) { for (uint32_t i = 0; i < copySplit.count; ++i) {
const auto& copy = copySplit.copies[i]; const auto& copy = copySplit.copies[i];
uint32_t rowPitchInTexels = uint32_t bytesPerRowInTexels =
bufferSpec.rowPitch / textureSpec.texelBlockSizeInBytes * texelsPerBlock; bufferSpec.bytesPerRow / textureSpec.texelBlockSizeInBytes * texelsPerBlock;
uint32_t slicePitchInTexels = uint32_t slicePitchInTexels =
rowPitchInTexels * (bufferSpec.imageHeight / textureSpec.blockHeight); bytesPerRowInTexels * (bufferSpec.rowsPerImage / textureSpec.blockHeight);
uint32_t absoluteTexelOffset = uint32_t absoluteTexelOffset =
copySplit.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock + copySplit.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock +
copy.bufferOffset.x / textureSpec.blockWidth * texelsPerBlock + copy.bufferOffset.x / textureSpec.blockWidth * texelsPerBlock +
copy.bufferOffset.y / textureSpec.blockHeight * rowPitchInTexels + copy.bufferOffset.y / textureSpec.blockHeight * bytesPerRowInTexels +
copy.bufferOffset.z * slicePitchInTexels; copy.bufferOffset.z * slicePitchInTexels;
ASSERT(absoluteTexelOffset >= ASSERT(absoluteTexelOffset >=
@ -140,8 +140,8 @@ namespace {
bufferSpec.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock; bufferSpec.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock;
uint32_t z = relativeTexelOffset / slicePitchInTexels; uint32_t z = relativeTexelOffset / slicePitchInTexels;
uint32_t y = (relativeTexelOffset % slicePitchInTexels) / rowPitchInTexels; uint32_t y = (relativeTexelOffset % slicePitchInTexels) / bytesPerRowInTexels;
uint32_t x = relativeTexelOffset % rowPitchInTexels; uint32_t x = relativeTexelOffset % bytesPerRowInTexels;
ASSERT_EQ(copy.textureOffset.x - textureSpec.x, x); ASSERT_EQ(copy.textureOffset.x - textureSpec.x, x);
ASSERT_EQ(copy.textureOffset.y - textureSpec.y, y); ASSERT_EQ(copy.textureOffset.y - textureSpec.y, y);
@ -167,8 +167,8 @@ namespace {
} }
std::ostream& operator<<(std::ostream& os, const BufferSpec& bufferSpec) { std::ostream& operator<<(std::ostream& os, const BufferSpec& bufferSpec) {
os << "BufferSpec(" << bufferSpec.offset << ", " << bufferSpec.rowPitch << ", " os << "BufferSpec(" << bufferSpec.offset << ", " << bufferSpec.bytesPerRow << ", "
<< bufferSpec.imageHeight << ")"; << bufferSpec.rowsPerImage << ")";
return os; return os;
} }
@ -217,43 +217,44 @@ namespace {
{64, 48, 16, 1024, 1024, 1, 16, 4, 4}, {64, 48, 16, 1024, 1024, 1, 16, 4, 4},
}; };
// Define base buffer sizes to work with: some offsets aligned, some unaligned. rowPitch is the minimum required // Define base buffer sizes to work with: some offsets aligned, some unaligned. bytesPerRow is
// the minimum required
std::array<BufferSpec, 13> BaseBufferSpecs(const TextureSpec& textureSpec) { std::array<BufferSpec, 13> BaseBufferSpecs(const TextureSpec& textureSpec) {
uint32_t rowPitch = uint32_t bytesPerRow = Align(textureSpec.texelBlockSizeInBytes * textureSpec.width,
Align(textureSpec.texelBlockSizeInBytes * textureSpec.width, kTextureRowPitchAlignment); kTextureBytesPerRowAlignment);
auto alignNonPow2 = [](uint32_t value, uint32_t size) -> uint32_t { auto alignNonPow2 = [](uint32_t value, uint32_t size) -> uint32_t {
return value == 0 ? 0 : ((value - 1) / size + 1) * size; return value == 0 ? 0 : ((value - 1) / size + 1) * size;
}; };
return { return {
BufferSpec{alignNonPow2(0, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(0, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(512, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(512, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height * 2}, textureSpec.height * 2},
BufferSpec{alignNonPow2(32, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(32, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height * 2}, textureSpec.height * 2},
BufferSpec{alignNonPow2(31, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(31, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(257, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(257, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(511, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(511, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(513, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(513, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height}, textureSpec.height},
BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), rowPitch, BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), bytesPerRow,
textureSpec.height * 2}, textureSpec.height * 2},
}; };
} }
@ -280,7 +281,7 @@ class CopySplitTest : public testing::Test {
TextureCopySplit copySplit = ComputeTextureCopySplit( TextureCopySplit copySplit = ComputeTextureCopySplit(
{textureSpec.x, textureSpec.y, textureSpec.z}, {textureSpec.x, textureSpec.y, textureSpec.z},
{textureSpec.width, textureSpec.height, textureSpec.depth}, fakeFormat, {textureSpec.width, textureSpec.height, textureSpec.depth}, fakeFormat,
bufferSpec.offset, bufferSpec.rowPitch, bufferSpec.imageHeight); bufferSpec.offset, bufferSpec.bytesPerRow, bufferSpec.rowsPerImage);
ValidateCopySplit(textureSpec, bufferSpec, copySplit); ValidateCopySplit(textureSpec, bufferSpec, copySplit);
return copySplit; return copySplit;
} }
@ -418,9 +419,9 @@ TEST_F(CopySplitTest, BufferOffset) {
TEST_F(CopySplitTest, RowPitch) { TEST_F(CopySplitTest, RowPitch) {
for (TextureSpec textureSpec : kBaseTextureSpecs) { for (TextureSpec textureSpec : kBaseTextureSpecs) {
for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) { for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
uint32_t baseRowPitch = bufferSpec.rowPitch; uint32_t baseRowPitch = bufferSpec.bytesPerRow;
for (uint32_t i = 0; i < 5; ++i) { for (uint32_t i = 0; i < 5; ++i) {
bufferSpec.rowPitch = baseRowPitch + i * 256; bufferSpec.bytesPerRow = baseRowPitch + i * 256;
TextureCopySplit copySplit = DoTest(textureSpec, bufferSpec); TextureCopySplit copySplit = DoTest(textureSpec, bufferSpec);
if (HasFatalFailure()) { if (HasFatalFailure()) {
@ -437,9 +438,9 @@ TEST_F(CopySplitTest, RowPitch) {
TEST_F(CopySplitTest, ImageHeight) { TEST_F(CopySplitTest, ImageHeight) {
for (TextureSpec textureSpec : kBaseTextureSpecs) { for (TextureSpec textureSpec : kBaseTextureSpecs) {
for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) { for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
uint32_t baseImageHeight = bufferSpec.imageHeight; uint32_t baseImageHeight = bufferSpec.rowsPerImage;
for (uint32_t i = 0; i < 5; ++i) { for (uint32_t i = 0; i < 5; ++i) {
bufferSpec.imageHeight = baseImageHeight + i * 256; bufferSpec.rowsPerImage = baseImageHeight + i * 256;
TextureCopySplit copySplit = DoTest(textureSpec, bufferSpec); TextureCopySplit copySplit = DoTest(textureSpec, bufferSpec);
if (HasFatalFailure()) { if (HasFatalFailure()) {

View File

@ -68,8 +68,8 @@ class CopyCommandTest : public ValidationTest {
uint32_t depth, uint32_t depth,
wgpu::TextureFormat format = wgpu::TextureFormat::RGBA8Unorm) { wgpu::TextureFormat format = wgpu::TextureFormat::RGBA8Unorm) {
uint32_t bytesPerPixel = TextureFormatPixelSize(format); uint32_t bytesPerPixel = TextureFormatPixelSize(format);
uint32_t rowPitch = Align(width * bytesPerPixel, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(width * bytesPerPixel, kTextureBytesPerRowAlignment);
return (rowPitch * (height - 1) + width * bytesPerPixel) * depth; return (bytesPerRow * (height - 1) + width * bytesPerPixel) * depth;
} }
void ValidateExpectation(wgpu::CommandEncoder encoder, utils::Expectation expectation) { void ValidateExpectation(wgpu::CommandEncoder encoder, utils::Expectation expectation) {
@ -291,7 +291,7 @@ TEST_F(CopyCommandTest_B2T, Success) {
{0, 0, 0}, {1, 1, 1}); {0, 0, 0}, {1, 1, 1});
} }
// Copies with a 256-byte aligned row pitch but unaligned texture region // Copies with a 256-byte aligned bytes per row but unaligned texture region
{ {
// Unaligned region // Unaligned region
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
@ -336,16 +336,16 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnBuffer) {
TestB2TCopy(utils::Expectation::Failure, source, 4, 256, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, source, 4, 256, 0, destination, 0, 0, {0, 0, 0},
{4, 4, 1}); {4, 4, 1});
// OOB on the buffer because (row pitch * (height - 1) + width * bytesPerPixel) * depth // OOB on the buffer because (bytes per row * (height - 1) + width * bytesPerPixel) * depth
// overflows // overflows
TestB2TCopy(utils::Expectation::Failure, source, 0, 512, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, source, 0, 512, 0, destination, 0, 0, {0, 0, 0},
{4, 3, 1}); {4, 3, 1});
// Not OOB on the buffer although row pitch * height overflows // Not OOB on the buffer although bytes per row * height overflows
// but (row pitch * (height - 1) + width * bytesPerPixel) * depth does not overflow // but (bytes per row * (height - 1) + width * bytesPerPixel) * depth does not overflow
{ {
uint32_t sourceBufferSize = BufferSizeForTextureCopy(7, 3, 1); uint32_t sourceBufferSize = BufferSizeForTextureCopy(7, 3, 1);
ASSERT_TRUE(256 * 3 > sourceBufferSize) << "row pitch * height should overflow buffer"; ASSERT_TRUE(256 * 3 > sourceBufferSize) << "bytes per row * height should overflow buffer";
wgpu::Buffer sourceBuffer = CreateBuffer(sourceBufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer sourceBuffer = CreateBuffer(sourceBufferSize, wgpu::BufferUsage::CopySrc);
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
@ -420,15 +420,15 @@ TEST_F(CopyCommandTest_B2T, IncorrectRowPitch) {
wgpu::Texture destination = Create2DTexture(128, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::Texture destination = Create2DTexture(128, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm,
wgpu::TextureUsage::CopyDst); wgpu::TextureUsage::CopyDst);
// Default row pitch is not 256-byte aligned // Default bytes per row is not 256-byte aligned
TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 0, 0, {0, 0, 0},
{3, 4, 1}); {3, 4, 1});
// Row pitch is not 256-byte aligned // bytes per row is not 256-byte aligned
TestB2TCopy(utils::Expectation::Failure, source, 0, 128, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, source, 0, 128, 0, destination, 0, 0, {0, 0, 0},
{4, 4, 1}); {4, 4, 1});
// Row pitch is less than width * bytesPerPixel // bytes per row is less than width * bytesPerPixel
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, 0, {0, 0, 0}, TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
{65, 1, 1}); {65, 1, 1});
} }
@ -626,7 +626,7 @@ TEST_F(CopyCommandTest_T2B, Success) {
bufferSize - 4, 256, 0, {1, 1, 1}); bufferSize - 4, 256, 0, {1, 1, 1});
} }
// Copies with a 256-byte aligned row pitch but unaligned texture region // Copies with a 256-byte aligned bytes per row but unaligned texture region
{ {
// Unaligned region // Unaligned region
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, destination, 0, 256, 0, TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, destination, 0, 256, 0,
@ -695,16 +695,17 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnBuffer) {
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 4, 256, 0, TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 4, 256, 0,
{4, 4, 1}); {4, 4, 1});
// OOB on the buffer because (row pitch * (height - 1) + width * bytesPerPixel) * depth // OOB on the buffer because (bytes per row * (height - 1) + width * bytesPerPixel) * depth
// overflows // overflows
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 512, 0, TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 512, 0,
{4, 3, 1}); {4, 3, 1});
// Not OOB on the buffer although row pitch * height overflows // Not OOB on the buffer although bytes per row * height overflows
// but (row pitch * (height - 1) + width * bytesPerPixel) * depth does not overflow // but (bytes per row * (height - 1) + width * bytesPerPixel) * depth does not overflow
{ {
uint32_t destinationBufferSize = BufferSizeForTextureCopy(7, 3, 1); uint32_t destinationBufferSize = BufferSizeForTextureCopy(7, 3, 1);
ASSERT_TRUE(256 * 3 > destinationBufferSize) << "row pitch * height should overflow buffer"; ASSERT_TRUE(256 * 3 > destinationBufferSize)
<< "bytes per row * height should overflow buffer";
wgpu::Buffer destinationBuffer = wgpu::Buffer destinationBuffer =
CreateBuffer(destinationBufferSize, wgpu::BufferUsage::CopyDst); CreateBuffer(destinationBufferSize, wgpu::BufferUsage::CopyDst);
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, destinationBuffer, 0, 256, TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, destinationBuffer, 0, 256,
@ -752,15 +753,15 @@ TEST_F(CopyCommandTest_T2B, IncorrectRowPitch) {
wgpu::TextureUsage::CopyDst); wgpu::TextureUsage::CopyDst);
wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc); wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
// Default row pitch is not 256-byte aligned // Default bytes per row is not 256-byte aligned
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 256, 0, TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 256, 0,
{3, 4, 1}); {3, 4, 1});
// Row pitch is not 256-byte aligned // bytes per row is not 256-byte aligned
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 257, 0, TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 257, 0,
{4, 4, 1}); {4, 4, 1});
// Row pitch is less than width * bytesPerPixel // bytes per row is less than width * bytesPerPixel
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 256, 0, TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 256, 0,
{65, 1, 1}); {65, 1, 1});
} }
@ -1198,16 +1199,16 @@ class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest {
wgpu::Buffer buffer, wgpu::Buffer buffer,
uint64_t bufferOffset, uint64_t bufferOffset,
uint32_t bufferRowPitch, uint32_t bufferRowPitch,
uint32_t imageHeight, uint32_t rowsPerImage,
wgpu::Texture texture, wgpu::Texture texture,
uint32_t level, uint32_t level,
uint32_t arraySlice, uint32_t arraySlice,
wgpu::Origin3D origin, wgpu::Origin3D origin,
wgpu::Extent3D extent3D) { wgpu::Extent3D extent3D) {
TestB2TCopy(expectation, buffer, bufferOffset, bufferRowPitch, imageHeight, texture, level, TestB2TCopy(expectation, buffer, bufferOffset, bufferRowPitch, rowsPerImage, texture, level,
arraySlice, origin, extent3D); arraySlice, origin, extent3D);
TestT2BCopy(expectation, texture, level, arraySlice, origin, buffer, bufferOffset, TestT2BCopy(expectation, texture, level, arraySlice, origin, buffer, bufferOffset,
bufferRowPitch, imageHeight, extent3D); bufferRowPitch, rowsPerImage, extent3D);
} }
void TestBothT2TCopies(utils::Expectation expectation, void TestBothT2TCopies(utils::Expectation expectation,
@ -1336,7 +1337,7 @@ TEST_F(CopyCommandTest_CompressedTextureFormats, RowPitch) {
} }
} }
// Tests to verify that imageHeight must be a multiple of the compressed texture block height in // Tests to verify that rowsPerImage must be a multiple of the compressed texture block height in
// buffer-to-texture or texture-to-buffer copies with compressed texture formats. // buffer-to-texture or texture-to-buffer copies with compressed texture formats.
TEST_F(CopyCommandTest_CompressedTextureFormats, ImageHeight) { TEST_F(CopyCommandTest_CompressedTextureFormats, ImageHeight) {
wgpu::Buffer buffer = wgpu::Buffer buffer =
@ -1345,14 +1346,14 @@ TEST_F(CopyCommandTest_CompressedTextureFormats, ImageHeight) {
for (wgpu::TextureFormat bcFormat : kBCFormats) { for (wgpu::TextureFormat bcFormat : kBCFormats) {
wgpu::Texture texture = Create2DTexture(bcFormat); wgpu::Texture texture = Create2DTexture(bcFormat);
// Valid usages of imageHeight in B2T and T2B copies with compressed texture formats. // Valid usages of rowsPerImage in B2T and T2B copies with compressed texture formats.
{ {
constexpr uint32_t kValidImageHeight = 8; constexpr uint32_t kValidImageHeight = 8;
TestBothTBCopies(utils::Expectation::Success, buffer, 0, 256, kValidImageHeight, TestBothTBCopies(utils::Expectation::Success, buffer, 0, 256, kValidImageHeight,
texture, 0, 0, {0, 0, 0}, {4, 4, 1}); texture, 0, 0, {0, 0, 0}, {4, 4, 1});
} }
// Failures on invalid imageHeight. // Failures on invalid rowsPerImage.
{ {
constexpr uint32_t kInvalidImageHeight = 3; constexpr uint32_t kInvalidImageHeight = 3;
TestBothTBCopies(utils::Expectation::Failure, buffer, 0, 256, kInvalidImageHeight, TestBothTBCopies(utils::Expectation::Failure, buffer, 0, 256, kInvalidImageHeight,

View File

@ -536,8 +536,8 @@ namespace dawn_native { namespace vulkan {
wgpu::BufferCopyView copyDst; wgpu::BufferCopyView copyDst;
copyDst.buffer = copyDstBuffer; copyDst.buffer = copyDstBuffer;
copyDst.offset = 0; copyDst.offset = 0;
copyDst.rowPitch = 256; copyDst.bytesPerRow = 256;
copyDst.imageHeight = 0; copyDst.rowsPerImage = 0;
wgpu::Extent3D copySize = {1, 1, 1}; wgpu::Extent3D copySize = {1, 1, 1};
@ -588,8 +588,8 @@ namespace dawn_native { namespace vulkan {
wgpu::BufferCopyView copySrc; wgpu::BufferCopyView copySrc;
copySrc.buffer = copySrcBuffer; copySrc.buffer = copySrcBuffer;
copySrc.offset = 0; copySrc.offset = 0;
copySrc.rowPitch = 256; copySrc.bytesPerRow = 256;
copySrc.imageHeight = 0; copySrc.rowsPerImage = 0;
wgpu::TextureCopyView copyDst; wgpu::TextureCopyView copyDst;
copyDst.texture = secondDeviceWrappedTexture; copyDst.texture = secondDeviceWrappedTexture;
@ -787,8 +787,8 @@ namespace dawn_native { namespace vulkan {
// Draw a non-trivial picture // Draw a non-trivial picture
uint32_t width = 640, height = 480, pixelSize = 4; uint32_t width = 640, height = 480, pixelSize = 4;
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
uint32_t size = rowPitch * (height - 1) + width * pixelSize; uint32_t size = bytesPerRow * (height - 1) + width * pixelSize;
unsigned char data[size]; unsigned char data[size];
for (uint32_t row = 0; row < height; row++) { for (uint32_t row = 0; row < height; row++) {
for (uint32_t col = 0; col < width; col++) { for (uint32_t col = 0; col < width; col++) {
@ -808,7 +808,7 @@ namespace dawn_native { namespace vulkan {
wgpu::Buffer copySrcBuffer = wgpu::Buffer copySrcBuffer =
utils::CreateBufferFromData(secondDevice, data, size, wgpu::BufferUsage::CopySrc); utils::CreateBufferFromData(secondDevice, data, size, wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView copySrc = wgpu::BufferCopyView copySrc =
utils::CreateBufferCopyView(copySrcBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(copySrcBuffer, 0, bytesPerRow, 0);
wgpu::TextureCopyView copyDst = wgpu::TextureCopyView copyDst =
utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0}); utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0});
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};
@ -836,7 +836,7 @@ namespace dawn_native { namespace vulkan {
wgpu::TextureCopyView copySrc = wgpu::TextureCopyView copySrc =
utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0}); utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0});
wgpu::BufferCopyView copyDst = wgpu::BufferCopyView copyDst =
utils::CreateBufferCopyView(copyDstBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(copyDstBuffer, 0, bytesPerRow, 0);
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};

View File

@ -676,8 +676,8 @@ namespace dawn_native { namespace vulkan {
wgpu::BufferCopyView copyDst; wgpu::BufferCopyView copyDst;
copyDst.buffer = copyDstBuffer; copyDst.buffer = copyDstBuffer;
copyDst.offset = 0; copyDst.offset = 0;
copyDst.rowPitch = 256; copyDst.bytesPerRow = 256;
copyDst.imageHeight = 0; copyDst.rowsPerImage = 0;
wgpu::Extent3D copySize = {1, 1, 1}; wgpu::Extent3D copySize = {1, 1, 1};
@ -732,8 +732,8 @@ namespace dawn_native { namespace vulkan {
wgpu::BufferCopyView copySrc; wgpu::BufferCopyView copySrc;
copySrc.buffer = copySrcBuffer; copySrc.buffer = copySrcBuffer;
copySrc.offset = 0; copySrc.offset = 0;
copySrc.rowPitch = 256; copySrc.bytesPerRow = 256;
copySrc.imageHeight = 0; copySrc.rowsPerImage = 0;
wgpu::TextureCopyView copyDst; wgpu::TextureCopyView copyDst;
copyDst.texture = secondDeviceWrappedTexture; copyDst.texture = secondDeviceWrappedTexture;
@ -961,8 +961,8 @@ namespace dawn_native { namespace vulkan {
// Draw a non-trivial picture // Draw a non-trivial picture
uint32_t width = 640, height = 480, pixelSize = 4; uint32_t width = 640, height = 480, pixelSize = 4;
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment); uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
uint32_t size = rowPitch * (height - 1) + width * pixelSize; uint32_t size = bytesPerRow * (height - 1) + width * pixelSize;
unsigned char data[size]; unsigned char data[size];
for (uint32_t row = 0; row < height; row++) { for (uint32_t row = 0; row < height; row++) {
for (uint32_t col = 0; col < width; col++) { for (uint32_t col = 0; col < width; col++) {
@ -982,7 +982,7 @@ namespace dawn_native { namespace vulkan {
wgpu::Buffer copySrcBuffer = wgpu::Buffer copySrcBuffer =
utils::CreateBufferFromData(secondDevice, data, size, wgpu::BufferUsage::CopySrc); utils::CreateBufferFromData(secondDevice, data, size, wgpu::BufferUsage::CopySrc);
wgpu::BufferCopyView copySrc = wgpu::BufferCopyView copySrc =
utils::CreateBufferCopyView(copySrcBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(copySrcBuffer, 0, bytesPerRow, 0);
wgpu::TextureCopyView copyDst = wgpu::TextureCopyView copyDst =
utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0}); utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0});
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};
@ -1010,7 +1010,7 @@ namespace dawn_native { namespace vulkan {
wgpu::TextureCopyView copySrc = wgpu::TextureCopyView copySrc =
utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0}); utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0});
wgpu::BufferCopyView copyDst = wgpu::BufferCopyView copyDst =
utils::CreateBufferCopyView(copyDstBuffer, 0, rowPitch, 0); utils::CreateBufferCopyView(copyDstBuffer, 0, bytesPerRow, 0);
wgpu::Extent3D copySize = {width, height, 1}; wgpu::Extent3D copySize = {width, height, 1};

View File

@ -235,13 +235,13 @@ namespace utils {
wgpu::BufferCopyView CreateBufferCopyView(wgpu::Buffer buffer, wgpu::BufferCopyView CreateBufferCopyView(wgpu::Buffer buffer,
uint64_t offset, uint64_t offset,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t imageHeight) { uint32_t rowsPerImage) {
wgpu::BufferCopyView bufferCopyView; wgpu::BufferCopyView bufferCopyView;
bufferCopyView.buffer = buffer; bufferCopyView.buffer = buffer;
bufferCopyView.offset = offset; bufferCopyView.offset = offset;
bufferCopyView.rowPitch = rowPitch; bufferCopyView.bytesPerRow = bytesPerRow;
bufferCopyView.imageHeight = imageHeight; bufferCopyView.rowsPerImage = rowsPerImage;
return bufferCopyView; return bufferCopyView;
} }

View File

@ -48,8 +48,8 @@ namespace utils {
wgpu::BufferCopyView CreateBufferCopyView(wgpu::Buffer buffer, wgpu::BufferCopyView CreateBufferCopyView(wgpu::Buffer buffer,
uint64_t offset, uint64_t offset,
uint32_t rowPitch, uint32_t bytesPerRow,
uint32_t imageHeight); uint32_t rowsPerImage);
wgpu::TextureCopyView CreateTextureCopyView(wgpu::Texture texture, wgpu::TextureCopyView CreateTextureCopyView(wgpu::Texture texture,
uint32_t level, uint32_t level,
uint32_t slice, uint32_t slice,