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:
parent
c244f53921
commit
cdf2d8de77
|
@ -215,8 +215,10 @@
|
|||
"members": [
|
||||
{"name": "buffer", "type": "buffer"},
|
||||
{"name": "offset", "type": "uint64_t", "default": 0},
|
||||
{"name": "row pitch", "type": "uint32_t"},
|
||||
{"name": "image height", "type": "uint32_t"}
|
||||
{"name": "row pitch", "type": "uint32_t", "default": 0},
|
||||
{"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": {
|
||||
|
|
|
@ -32,7 +32,7 @@ static constexpr uint32_t kMaxVertexBuffers = 16u;
|
|||
static constexpr uint32_t kMaxVertexBufferStride = 2048u;
|
||||
static constexpr uint32_t kNumStages = 3;
|
||||
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
|
||||
static constexpr uint64_t kMinDynamicBufferOffsetAlignment = 256u;
|
||||
// Max numbers of dynamic uniform buffers
|
||||
|
|
|
@ -110,16 +110,16 @@ namespace dawn_native {
|
|||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateImageHeight(const Format& format,
|
||||
uint32_t imageHeight,
|
||||
uint32_t copyHeight) {
|
||||
if (imageHeight < copyHeight) {
|
||||
return DAWN_VALIDATION_ERROR("Image height must not be less than the copy height.");
|
||||
MaybeError ValidateRowsPerImage(const Format& format,
|
||||
uint32_t rowsPerImage,
|
||||
uint32_t copyHeight) {
|
||||
if (rowsPerImage < copyHeight) {
|
||||
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(
|
||||
"Image height must be a multiple of compressed texture format block width");
|
||||
"rowsPerImage must be a multiple of compressed texture format block width");
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -180,37 +180,37 @@ namespace dawn_native {
|
|||
|
||||
MaybeError ComputeTextureCopyBufferSize(const Format& textureFormat,
|
||||
const Extent3D& copySize,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight,
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t rowsPerImage,
|
||||
uint32_t* bufferSize) {
|
||||
ASSERT(imageHeight >= copySize.height);
|
||||
ASSERT(rowsPerImage >= copySize.height);
|
||||
uint32_t blockByteSize = textureFormat.blockByteSize;
|
||||
uint32_t blockWidth = textureFormat.blockWidth;
|
||||
uint32_t blockHeight = textureFormat.blockHeight;
|
||||
|
||||
// TODO(cwallez@chromium.org): check for overflows
|
||||
uint32_t slicePitch = rowPitch * imageHeight / blockWidth;
|
||||
uint32_t sliceSize = rowPitch * (copySize.height / blockHeight - 1) +
|
||||
uint32_t slicePitch = bytesPerRow * rowsPerImage / blockWidth;
|
||||
uint32_t sliceSize = bytesPerRow * (copySize.height / blockHeight - 1) +
|
||||
(copySize.width / blockWidth) * blockByteSize;
|
||||
*bufferSize = (slicePitch * (copySize.depth - 1)) + sliceSize;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
MaybeError ValidateRowPitch(const Format& format,
|
||||
const Extent3D& copySize,
|
||||
uint32_t rowPitch) {
|
||||
if (rowPitch % kTextureRowPitchAlignment != 0) {
|
||||
return DAWN_VALIDATION_ERROR("Row pitch must be a multiple of 256");
|
||||
MaybeError ValidateBytesPerRow(const Format& format,
|
||||
const Extent3D& copySize,
|
||||
uint32_t bytesPerRow) {
|
||||
if (bytesPerRow % kTextureBytesPerRowAlignment != 0) {
|
||||
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(
|
||||
"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 {};
|
||||
|
@ -483,6 +483,40 @@ namespace dawn_native {
|
|||
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
|
||||
|
||||
CommandEncoder::CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor*)
|
||||
|
@ -629,32 +663,36 @@ namespace dawn_native {
|
|||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
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));
|
||||
|
||||
CopyBufferToTextureCmd* copy =
|
||||
allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
|
||||
copy->source.buffer = source->buffer;
|
||||
copy->source.offset = source->offset;
|
||||
copy->source.buffer = fixedSource.buffer;
|
||||
copy->source.offset = fixedSource.offset;
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.origin = destination->origin;
|
||||
copy->copySize = *copySize;
|
||||
copy->destination.mipLevel = destination->mipLevel;
|
||||
copy->destination.arrayLayer = destination->arrayLayer;
|
||||
if (source->rowPitch == 0) {
|
||||
copy->source.rowPitch =
|
||||
ComputeDefaultRowPitch(destination->texture->GetFormat(), copySize->width);
|
||||
if (fixedSource.bytesPerRow == 0) {
|
||||
copy->source.bytesPerRow =
|
||||
ComputeDefaultBytesPerRow(destination->texture->GetFormat(), copySize->width);
|
||||
} else {
|
||||
copy->source.rowPitch = source->rowPitch;
|
||||
copy->source.bytesPerRow = fixedSource.bytesPerRow;
|
||||
}
|
||||
if (source->imageHeight == 0) {
|
||||
copy->source.imageHeight = copySize->height;
|
||||
if (fixedSource.rowsPerImage == 0) {
|
||||
copy->source.rowsPerImage = copySize->height;
|
||||
} else {
|
||||
copy->source.imageHeight = source->imageHeight;
|
||||
copy->source.rowsPerImage = fixedSource.rowsPerImage;
|
||||
}
|
||||
|
||||
if (GetDevice()->IsValidationEnabled()) {
|
||||
mTopLevelBuffers.insert(source->buffer);
|
||||
mTopLevelBuffers.insert(fixedSource.buffer);
|
||||
mTopLevelTextures.insert(destination->texture);
|
||||
}
|
||||
return {};
|
||||
|
@ -665,8 +703,12 @@ namespace dawn_native {
|
|||
const BufferCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
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(destination->buffer));
|
||||
DAWN_TRY(GetDevice()->ValidateObject(fixedDestination.buffer));
|
||||
|
||||
CopyTextureToBufferCmd* copy =
|
||||
allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
|
||||
|
@ -675,23 +717,23 @@ namespace dawn_native {
|
|||
copy->copySize = *copySize;
|
||||
copy->source.mipLevel = source->mipLevel;
|
||||
copy->source.arrayLayer = source->arrayLayer;
|
||||
copy->destination.buffer = destination->buffer;
|
||||
copy->destination.offset = destination->offset;
|
||||
if (destination->rowPitch == 0) {
|
||||
copy->destination.rowPitch =
|
||||
ComputeDefaultRowPitch(source->texture->GetFormat(), copySize->width);
|
||||
copy->destination.buffer = fixedDestination.buffer;
|
||||
copy->destination.offset = fixedDestination.offset;
|
||||
if (fixedDestination.bytesPerRow == 0) {
|
||||
copy->destination.bytesPerRow =
|
||||
ComputeDefaultBytesPerRow(source->texture->GetFormat(), copySize->width);
|
||||
} else {
|
||||
copy->destination.rowPitch = destination->rowPitch;
|
||||
copy->destination.bytesPerRow = fixedDestination.bytesPerRow;
|
||||
}
|
||||
if (destination->imageHeight == 0) {
|
||||
copy->destination.imageHeight = copySize->height;
|
||||
if (fixedDestination.rowsPerImage == 0) {
|
||||
copy->destination.rowsPerImage = copySize->height;
|
||||
} else {
|
||||
copy->destination.imageHeight = destination->imageHeight;
|
||||
copy->destination.rowsPerImage = fixedDestination.rowsPerImage;
|
||||
}
|
||||
|
||||
if (GetDevice()->IsValidationEnabled()) {
|
||||
mTopLevelTextures.insert(source->texture);
|
||||
mTopLevelBuffers.insert(destination->buffer);
|
||||
mTopLevelBuffers.insert(fixedDestination.buffer);
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
@ -825,20 +867,21 @@ namespace dawn_native {
|
|||
DAWN_TRY(
|
||||
ValidateTextureSampleCountInCopyCommands(copy->destination.texture.Get()));
|
||||
|
||||
DAWN_TRY(ValidateImageHeight(copy->destination.texture->GetFormat(),
|
||||
copy->source.imageHeight, copy->copySize.height));
|
||||
DAWN_TRY(ValidateRowsPerImage(copy->destination.texture->GetFormat(),
|
||||
copy->source.rowsPerImage,
|
||||
copy->copySize.height));
|
||||
DAWN_TRY(ValidateImageOrigin(copy->destination.texture->GetFormat(),
|
||||
copy->destination.origin));
|
||||
DAWN_TRY(ValidateImageCopySize(copy->destination.texture->GetFormat(),
|
||||
copy->copySize));
|
||||
|
||||
uint32_t bufferCopySize = 0;
|
||||
DAWN_TRY(ValidateRowPitch(copy->destination.texture->GetFormat(),
|
||||
copy->copySize, copy->source.rowPitch));
|
||||
DAWN_TRY(ValidateBytesPerRow(copy->destination.texture->GetFormat(),
|
||||
copy->copySize, copy->source.bytesPerRow));
|
||||
|
||||
DAWN_TRY(ComputeTextureCopyBufferSize(
|
||||
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(ValidateCopySizeFitsInBuffer(copy->source, bufferCopySize));
|
||||
|
@ -858,20 +901,20 @@ namespace dawn_native {
|
|||
|
||||
DAWN_TRY(ValidateTextureSampleCountInCopyCommands(copy->source.texture.Get()));
|
||||
|
||||
DAWN_TRY(ValidateImageHeight(copy->source.texture->GetFormat(),
|
||||
copy->destination.imageHeight,
|
||||
copy->copySize.height));
|
||||
DAWN_TRY(ValidateRowsPerImage(copy->source.texture->GetFormat(),
|
||||
copy->destination.rowsPerImage,
|
||||
copy->copySize.height));
|
||||
DAWN_TRY(ValidateImageOrigin(copy->source.texture->GetFormat(),
|
||||
copy->source.origin));
|
||||
DAWN_TRY(
|
||||
ValidateImageCopySize(copy->source.texture->GetFormat(), copy->copySize));
|
||||
|
||||
uint32_t bufferCopySize = 0;
|
||||
DAWN_TRY(ValidateRowPitch(copy->source.texture->GetFormat(), copy->copySize,
|
||||
copy->destination.rowPitch));
|
||||
DAWN_TRY(ValidateBytesPerRow(copy->source.texture->GetFormat(), copy->copySize,
|
||||
copy->destination.bytesPerRow));
|
||||
DAWN_TRY(ComputeTextureCopyBufferSize(
|
||||
copy->source.texture->GetFormat(), copy->copySize,
|
||||
copy->destination.rowPitch, copy->destination.imageHeight,
|
||||
copy->destination.bytesPerRow, copy->destination.rowsPerImage,
|
||||
&bufferCopySize));
|
||||
|
||||
DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize));
|
||||
|
|
|
@ -93,9 +93,9 @@ namespace dawn_native {
|
|||
|
||||
struct BufferCopy {
|
||||
Ref<BufferBase> buffer;
|
||||
uint64_t offset; // Bytes
|
||||
uint32_t rowPitch; // Bytes
|
||||
uint32_t imageHeight; // Texels
|
||||
uint64_t offset;
|
||||
uint32_t bytesPerRow;
|
||||
uint32_t rowsPerImage;
|
||||
};
|
||||
|
||||
struct TextureCopy {
|
||||
|
|
|
@ -564,7 +564,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
auto copySplit = ComputeTextureCopySplit(
|
||||
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 =
|
||||
ComputeTextureCopyLocationForTexture(texture, copy->destination.mipLevel,
|
||||
|
@ -576,7 +576,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
||||
ComputeBufferLocationForCopyTextureRegion(
|
||||
texture, buffer->GetD3D12Resource().Get(), info.bufferSize,
|
||||
copySplit.offset, copy->source.rowPitch);
|
||||
copySplit.offset, copy->source.bytesPerRow);
|
||||
D3D12_BOX sourceRegion =
|
||||
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
|
||||
|
||||
|
@ -601,8 +601,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
TextureCopySplit copySplit = ComputeTextureCopySplit(
|
||||
copy->source.origin, copy->copySize, texture->GetFormat(),
|
||||
copy->destination.offset, copy->destination.rowPitch,
|
||||
copy->destination.imageHeight);
|
||||
copy->destination.offset, copy->destination.bytesPerRow,
|
||||
copy->destination.rowsPerImage);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION textureLocation =
|
||||
ComputeTextureCopyLocationForTexture(texture, copy->source.mipLevel,
|
||||
|
@ -614,7 +614,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
||||
ComputeBufferLocationForCopyTextureRegion(
|
||||
texture, buffer->GetD3D12Resource().Get(), info.bufferSize,
|
||||
copySplit.offset, copy->destination.rowPitch);
|
||||
copySplit.offset, copy->destination.bytesPerRow);
|
||||
|
||||
D3D12_BOX sourceRegion =
|
||||
ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize);
|
||||
|
|
|
@ -23,15 +23,15 @@ namespace dawn_native { namespace d3d12 {
|
|||
namespace {
|
||||
Origin3D ComputeTexelOffsets(const Format& format,
|
||||
uint32_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t slicePitch) {
|
||||
uint32_t byteOffsetX = offset % rowPitch;
|
||||
uint32_t byteOffsetX = offset % bytesPerRow;
|
||||
offset -= byteOffsetX;
|
||||
uint32_t byteOffsetY = offset % slicePitch;
|
||||
uint32_t byteOffsetZ = offset - byteOffsetY;
|
||||
|
||||
return {byteOffsetX / format.blockByteSize * format.blockWidth,
|
||||
byteOffsetY / rowPitch * format.blockHeight, byteOffsetZ / slicePitch};
|
||||
byteOffsetY / bytesPerRow * format.blockHeight, byteOffsetZ / slicePitch};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -39,11 +39,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
Extent3D copySize,
|
||||
const Format& format,
|
||||
uint64_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight) {
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t rowsPerImage) {
|
||||
TextureCopySplit copy;
|
||||
|
||||
ASSERT(rowPitch % format.blockByteSize == 0);
|
||||
ASSERT(bytesPerRow % format.blockByteSize == 0);
|
||||
|
||||
uint64_t alignedOffset =
|
||||
offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1);
|
||||
|
@ -69,16 +69,16 @@ namespace dawn_native { namespace d3d12 {
|
|||
ASSERT(alignedOffset < offset);
|
||||
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(
|
||||
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 byteOffsetInRowPitch = texelOffset.x / format.blockWidth * format.blockByteSize;
|
||||
if (copyBytesPerRowPitch + byteOffsetInRowPitch <= rowPitch) {
|
||||
// The region's rows fit inside the row pitch. In this case, extend the width of the
|
||||
if (copyBytesPerRowPitch + byteOffsetInRowPitch <= bytesPerRow) {
|
||||
// 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
|
||||
// |<--------------- row pitch --------------->|
|
||||
// |<------------- bytes per row ------------->|
|
||||
//
|
||||
// |-------------------------------------------|
|
||||
// | |
|
||||
|
@ -107,14 +107,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
copy.copies[0].bufferOffset = texelOffset;
|
||||
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;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
// The region's rows straddle the row pitch. Split the copy into two copies
|
||||
// |<--------------- row pitch --------------->|
|
||||
// The region's rows straddle the bytes per row. Split the copy into two copies
|
||||
// |<------------- bytes per row ------------->|
|
||||
//
|
||||
// |-------------------------------------------|
|
||||
// | |
|
||||
|
@ -151,15 +151,15 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
copy.copies[0].textureOffset = origin;
|
||||
|
||||
ASSERT(rowPitch > byteOffsetInRowPitch);
|
||||
uint32_t texelsPerRow = rowPitch / format.blockByteSize * format.blockWidth;
|
||||
ASSERT(bytesPerRow > byteOffsetInRowPitch);
|
||||
uint32_t texelsPerRow = bytesPerRow / format.blockByteSize * format.blockWidth;
|
||||
copy.copies[0].copySize.width = texelsPerRow - texelOffset.x;
|
||||
copy.copies[0].copySize.height = copySize.height;
|
||||
copy.copies[0].copySize.depth = copySize.depth;
|
||||
|
||||
copy.copies[0].bufferOffset = texelOffset;
|
||||
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[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.z = texelOffset.z;
|
||||
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;
|
||||
|
||||
return copy;
|
||||
|
|
|
@ -47,8 +47,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
Extent3D copySize,
|
||||
const Format& format,
|
||||
uint64_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight);
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t rowsPerImage);
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
#endif // DAWNNATIVE_D3D12_TEXTURECOPYSPLITTER_H_
|
||||
|
|
|
@ -691,10 +691,10 @@ namespace dawn_native { namespace d3d12 {
|
|||
} else {
|
||||
// TODO(natlee@microsoft.com): test compressed textures are cleared
|
||||
// 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,
|
||||
kTextureRowPitchAlignment);
|
||||
uint64_t bufferSize64 = rowPitch * (GetSize().height / GetFormat().blockHeight);
|
||||
kTextureBytesPerRowAlignment);
|
||||
uint64_t bufferSize64 = bytesPerRow * (GetSize().height / GetFormat().blockHeight);
|
||||
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
|
||||
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
|
||||
Extent3D copySize = GetMipLevelVirtualSize(level);
|
||||
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;
|
||||
++layer) {
|
||||
|
@ -729,7 +729,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
D3D12_TEXTURE_COPY_LOCATION bufferLocation =
|
||||
ComputeBufferLocationForCopyTextureRegion(
|
||||
this, ToBackend(uploadHandle.stagingBuffer)->GetResource(),
|
||||
info.bufferSize, copySplit.offset, rowPitch);
|
||||
info.bufferSize, copySplit.offset, bytesPerRow);
|
||||
D3D12_BOX sourceRegion =
|
||||
ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);
|
||||
|
||||
|
|
|
@ -335,14 +335,14 @@ namespace dawn_native { namespace metal {
|
|||
Extent3D virtualSizeAtLevel,
|
||||
uint64_t bufferSize,
|
||||
uint64_t bufferOffset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight) {
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t rowsPerImage) {
|
||||
TextureBufferCopySplit copy;
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// where in memory, each row data (D) of the texture is followed by some padding data
|
||||
// (P):
|
||||
|
@ -356,8 +356,8 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
// We work around this limitation by detecting when Metal would complain and copy the
|
||||
// last image and row separately using tight sourceBytesPerRow or sourceBytesPerImage.
|
||||
uint32_t rowPitchCountPerImage = imageHeight / textureFormat.blockHeight;
|
||||
uint32_t bytesPerImage = rowPitch * rowPitchCountPerImage;
|
||||
uint32_t dataRowsPerImage = rowsPerImage / textureFormat.blockHeight;
|
||||
uint32_t bytesPerImage = bytesPerRow * dataRowsPerImage;
|
||||
|
||||
// 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
|
||||
|
@ -377,7 +377,7 @@ namespace dawn_native { namespace metal {
|
|||
if (!needWorkaround) {
|
||||
copy.count = 1;
|
||||
copy.copies[0].bufferOffset = bufferOffset;
|
||||
copy.copies[0].bytesPerRow = rowPitch;
|
||||
copy.copies[0].bytesPerRow = bytesPerRow;
|
||||
copy.copies[0].bytesPerImage = bytesPerImage;
|
||||
copy.copies[0].textureOrigin = MakeMTLOrigin(origin);
|
||||
copy.copies[0].copyExtent =
|
||||
|
@ -390,7 +390,7 @@ namespace dawn_native { namespace metal {
|
|||
// Doing all the copy except the last image.
|
||||
if (copyExtent.depth > 1) {
|
||||
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].textureOrigin = MakeMTLOrigin(origin);
|
||||
copy.copies[copy.count].copyExtent = MTLSizeMake(
|
||||
|
@ -406,8 +406,8 @@ namespace dawn_native { namespace metal {
|
|||
uint32_t copyBlockRowCount = copyExtent.height / textureFormat.blockHeight;
|
||||
if (copyBlockRowCount > 1) {
|
||||
copy.copies[copy.count].bufferOffset = currentOffset;
|
||||
copy.copies[copy.count].bytesPerRow = rowPitch;
|
||||
copy.copies[copy.count].bytesPerImage = rowPitch * (copyBlockRowCount - 1);
|
||||
copy.copies[copy.count].bytesPerRow = bytesPerRow;
|
||||
copy.copies[copy.count].bytesPerImage = bytesPerRow * (copyBlockRowCount - 1);
|
||||
copy.copies[copy.count].textureOrigin =
|
||||
MTLOriginMake(origin.x, origin.y, origin.z + copyExtent.depth - 1);
|
||||
|
||||
|
@ -418,7 +418,7 @@ namespace dawn_native { namespace metal {
|
|||
++copy.count;
|
||||
|
||||
// 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.
|
||||
|
@ -752,7 +752,7 @@ namespace dawn_native { namespace metal {
|
|||
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(dst.mipLevel);
|
||||
TextureBufferCopySplit splittedCopies = ComputeTextureBufferCopySplit(
|
||||
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) {
|
||||
const TextureBufferCopySplit::CopyInfo& copyInfo = splittedCopies.copies[i];
|
||||
|
@ -782,7 +782,7 @@ namespace dawn_native { namespace metal {
|
|||
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(src.mipLevel);
|
||||
TextureBufferCopySplit splittedCopies = ComputeTextureBufferCopySplit(
|
||||
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) {
|
||||
const TextureBufferCopySplit::CopyInfo& copyInfo = splittedCopies.copies[i];
|
||||
|
|
|
@ -490,9 +490,10 @@ namespace dawn_native { namespace opengl {
|
|||
gl.BindTexture(target, texture->GetHandle());
|
||||
|
||||
const Format& formatInfo = texture->GetFormat();
|
||||
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||
src.rowPitch / formatInfo.blockByteSize * formatInfo.blockWidth);
|
||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.imageHeight);
|
||||
gl.PixelStorei(
|
||||
GL_UNPACK_ROW_LENGTH,
|
||||
src.bytesPerRow / formatInfo.blockByteSize * formatInfo.blockWidth);
|
||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage);
|
||||
|
||||
if (formatInfo.isCompressed) {
|
||||
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.PixelStorei(GL_PACK_ROW_LENGTH,
|
||||
dst.rowPitch / texture->GetFormat().blockByteSize);
|
||||
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.imageHeight);
|
||||
dst.bytesPerRow / texture->GetFormat().blockByteSize);
|
||||
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage);
|
||||
ASSERT(copySize.depth == 1 && src.origin.z == 0);
|
||||
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
|
||||
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, copySize.height,
|
||||
|
|
|
@ -286,17 +286,17 @@ namespace dawn_native { namespace opengl {
|
|||
} else {
|
||||
// TODO(natlee@microsoft.com): test compressed textures are cleared
|
||||
// create temp buffer with clear color to copy to the texture image
|
||||
ASSERT(kTextureRowPitchAlignment % GetFormat().blockByteSize == 0);
|
||||
uint32_t rowPitch =
|
||||
ASSERT(kTextureBytesPerRowAlignment % GetFormat().blockByteSize == 0);
|
||||
uint32_t bytesPerRow =
|
||||
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize,
|
||||
kTextureRowPitchAlignment);
|
||||
kTextureBytesPerRowAlignment);
|
||||
|
||||
// Make sure that we are not rounding
|
||||
ASSERT(rowPitch % GetFormat().blockByteSize == 0);
|
||||
ASSERT(bytesPerRow % GetFormat().blockByteSize == 0);
|
||||
ASSERT(GetSize().height % GetFormat().blockHeight == 0);
|
||||
|
||||
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()) {
|
||||
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
|
||||
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||
(rowPitch / GetFormat().blockByteSize) * GetFormat().blockWidth);
|
||||
(bytesPerRow / GetFormat().blockByteSize) * GetFormat().blockWidth);
|
||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
||||
for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
|
||||
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, srcBuffer->GetHandle());
|
||||
|
|
|
@ -329,9 +329,9 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
BufferCopy tempBufferCopy;
|
||||
tempBufferCopy.buffer = tempBuffer.Get();
|
||||
tempBufferCopy.imageHeight = copySize.height;
|
||||
tempBufferCopy.rowsPerImage = copySize.height;
|
||||
tempBufferCopy.offset = 0;
|
||||
tempBufferCopy.rowPitch = copySize.width / format.blockWidth * format.blockByteSize;
|
||||
tempBufferCopy.bytesPerRow = copySize.width / format.blockWidth * format.blockByteSize;
|
||||
|
||||
VkCommandBuffer commands = recordingContext->commandBuffer;
|
||||
VkImage srcImage = ToBackend(srcCopy.texture)->GetHandle();
|
||||
|
|
|
@ -721,10 +721,10 @@ namespace dawn_native { namespace vulkan {
|
|||
} else {
|
||||
// TODO(natlee@microsoft.com): test compressed textures are cleared
|
||||
// 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,
|
||||
kTextureRowPitchAlignment);
|
||||
uint64_t bufferSize64 = rowPitch * (GetSize().height / GetFormat().blockHeight);
|
||||
kTextureBytesPerRowAlignment);
|
||||
uint64_t bufferSize64 = bytesPerRow * (GetSize().height / GetFormat().blockHeight);
|
||||
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
|
||||
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
|
||||
dawn_native::BufferCopy bufferCopy;
|
||||
bufferCopy.imageHeight = 0;
|
||||
bufferCopy.rowsPerImage = 0;
|
||||
bufferCopy.offset = uploadHandle.startOffset;
|
||||
bufferCopy.rowPitch = rowPitch;
|
||||
bufferCopy.bytesPerRow = bytesPerRow;
|
||||
|
||||
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
|
||||
Extent3D copySize = GetMipLevelVirtualSize(level);
|
||||
|
|
|
@ -75,9 +75,9 @@ namespace dawn_native { namespace vulkan {
|
|||
region.bufferOffset = bufferCopy.offset;
|
||||
// In Vulkan the row length is in texels while it is in bytes for Dawn
|
||||
const Format& format = texture->GetFormat();
|
||||
ASSERT(bufferCopy.rowPitch % format.blockByteSize == 0);
|
||||
region.bufferRowLength = bufferCopy.rowPitch / format.blockByteSize * format.blockWidth;
|
||||
region.bufferImageHeight = bufferCopy.imageHeight;
|
||||
ASSERT(bufferCopy.bytesPerRow % format.blockByteSize == 0);
|
||||
region.bufferRowLength = bufferCopy.bytesPerRow / format.blockByteSize * format.blockWidth;
|
||||
region.bufferImageHeight = bufferCopy.rowsPerImage;
|
||||
|
||||
region.imageSubresource.aspectMask = texture->GetVkAspectMask();
|
||||
region.imageSubresource.mipLevel = textureCopy.mipLevel;
|
||||
|
|
|
@ -796,7 +796,7 @@ std::ostringstream& DawnTestBase::AddBufferExpectation(const char* file,
|
|||
deferred.readbackOffset = readback.offset;
|
||||
deferred.size = size;
|
||||
deferred.rowBytes = size;
|
||||
deferred.rowPitch = size;
|
||||
deferred.bytesPerRow = size;
|
||||
deferred.expectation.reset(expectation);
|
||||
|
||||
mDeferredExpectations.push_back(std::move(deferred));
|
||||
|
@ -815,8 +815,8 @@ std::ostringstream& DawnTestBase::AddTextureExpectation(const char* file,
|
|||
uint32_t slice,
|
||||
uint32_t pixelSize,
|
||||
detail::Expectation* expectation) {
|
||||
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment);
|
||||
uint32_t size = rowPitch * (height - 1) + width * pixelSize;
|
||||
uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
|
||||
uint32_t size = bytesPerRow * (height - 1) + width * pixelSize;
|
||||
|
||||
auto readback = ReserveReadback(size);
|
||||
|
||||
|
@ -825,7 +825,7 @@ std::ostringstream& DawnTestBase::AddTextureExpectation(const char* file,
|
|||
wgpu::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, level, slice, {x, y, 0});
|
||||
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::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
@ -841,7 +841,7 @@ std::ostringstream& DawnTestBase::AddTextureExpectation(const char* file,
|
|||
deferred.readbackOffset = readback.offset;
|
||||
deferred.size = size;
|
||||
deferred.rowBytes = width * pixelSize;
|
||||
deferred.rowPitch = rowPitch;
|
||||
deferred.bytesPerRow = bytesPerRow;
|
||||
deferred.expectation.reset(expectation);
|
||||
|
||||
mDeferredExpectations.push_back(std::move(deferred));
|
||||
|
@ -929,15 +929,16 @@ void DawnTestBase::ResolveExpectations() {
|
|||
|
||||
uint32_t size;
|
||||
std::vector<char> packedData;
|
||||
if (expectation.rowBytes != expectation.rowPitch) {
|
||||
DAWN_ASSERT(expectation.rowPitch > expectation.rowBytes);
|
||||
if (expectation.rowBytes != expectation.bytesPerRow) {
|
||||
DAWN_ASSERT(expectation.bytesPerRow > expectation.rowBytes);
|
||||
uint32_t rowCount =
|
||||
(expectation.size + expectation.rowPitch - 1) / expectation.rowPitch;
|
||||
(expectation.size + expectation.bytesPerRow - 1) / expectation.bytesPerRow;
|
||||
uint32_t packedSize = rowCount * expectation.rowBytes;
|
||||
packedData.resize(packedSize);
|
||||
for (uint32_t r = 0; r < rowCount; ++r) {
|
||||
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();
|
||||
|
|
|
@ -302,7 +302,7 @@ class DawnTestBase {
|
|||
uint64_t readbackOffset;
|
||||
uint64_t size;
|
||||
uint32_t rowBytes;
|
||||
uint32_t rowPitch;
|
||||
uint32_t bytesPerRow;
|
||||
std::unique_ptr<detail::Expectation> expectation;
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316
|
||||
// Use unique_ptr because of missing move/copy constructors on std::basic_ostringstream
|
||||
|
|
|
@ -158,7 +158,7 @@ class ComparisonSamplerTest : public DawnTest {
|
|||
wgpu::BufferCopyView bufferCopyView = {
|
||||
.buffer = mTextureUploadBuffer,
|
||||
.offset = 0,
|
||||
.rowPitch = kTextureRowPitchAlignment,
|
||||
.rowPitch = kTextureBytesPerRowAlignment,
|
||||
.imageHeight = 1,
|
||||
};
|
||||
wgpu::TextureCopyView textureCopyView = {
|
||||
|
|
|
@ -28,8 +28,8 @@ struct CopyConfig {
|
|||
uint32_t viewMipmapLevel = 0;
|
||||
uint32_t viewArrayLayer = 0;
|
||||
uint32_t bufferOffset = 0;
|
||||
uint32_t rowPitchAlignment = kTextureRowPitchAlignment;
|
||||
uint32_t imageHeight = 0;
|
||||
uint32_t bytesPerRowAlignment = kTextureBytesPerRowAlignment;
|
||||
uint32_t rowsPerImage = 0;
|
||||
};
|
||||
|
||||
class CompressedTextureBCFormatTest : public DawnTest {
|
||||
|
@ -52,7 +52,7 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
const CopyConfig& copyConfig) {
|
||||
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;
|
||||
uint32_t actualWidthAtLevel = textureSize.width >> copyConfig.viewMipmapLevel;
|
||||
uint32_t actualHeightAtLevel = textureSize.height >> copyConfig.viewMipmapLevel;
|
||||
|
@ -61,8 +61,8 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
uint32_t copyHeightInBlockAtLevel =
|
||||
(actualHeightAtLevel + kBCBlockHeightInTexels - 1) / kBCBlockHeightInTexels;
|
||||
uint32_t bufferRowPitchInBytes = 0;
|
||||
if (copyConfig.rowPitchAlignment != 0) {
|
||||
bufferRowPitchInBytes = copyConfig.rowPitchAlignment;
|
||||
if (copyConfig.bytesPerRowAlignment != 0) {
|
||||
bufferRowPitchInBytes = copyConfig.bytesPerRowAlignment;
|
||||
} else {
|
||||
bufferRowPitchInBytes =
|
||||
copyWidthInBlockAtLevel *
|
||||
|
@ -89,7 +89,7 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
device, uploadData.data(), uploadBufferSize, wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(stagingBuffer, copyConfig.bufferOffset,
|
||||
copyConfig.rowPitchAlignment, copyConfig.imageHeight);
|
||||
copyConfig.bytesPerRowAlignment, copyConfig.rowsPerImage);
|
||||
wgpu::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(bcCompressedTexture, copyConfig.viewMipmapLevel,
|
||||
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) {
|
||||
// TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan
|
||||
// bots.
|
||||
|
@ -504,11 +504,11 @@ TEST_P(CompressedTextureBCFormatTest, CopyWithZeroRowPitch) {
|
|||
config.textureDescriptor.size.height = 8;
|
||||
config.textureDescriptor.size.depth = 1;
|
||||
|
||||
config.rowPitchAlignment = 0;
|
||||
config.bytesPerRowAlignment = 0;
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = format;
|
||||
config.textureDescriptor.size.width = kTextureRowPitchAlignment /
|
||||
config.textureDescriptor.size.width = kTextureBytesPerRowAlignment /
|
||||
CompressedFormatBlockSizeInBytes(format) *
|
||||
kBCBlockWidthInTexels;
|
||||
config.copyExtent3D = config.textureDescriptor.size;
|
||||
|
@ -870,7 +870,7 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetAndExtentFitRowPitch) {
|
|||
config.textureDescriptor.format = 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;
|
||||
|
||||
|
@ -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
|
||||
// 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
|
||||
// ComputeTexelOffsets().
|
||||
TEST_P(CompressedTextureBCFormatTest, BufferOffsetExceedsSlicePitch) {
|
||||
|
@ -900,16 +900,16 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetExceedsSlicePitch) {
|
|||
const wgpu::Extent3D textureSizeLevel0 = config.textureDescriptor.size;
|
||||
const uint32_t blockCountPerRow = textureSizeLevel0.width / kBCBlockWidthInTexels;
|
||||
const uint32_t slicePitchInBytes =
|
||||
config.rowPitchAlignment * (textureSizeLevel0.height / kBCBlockHeightInTexels);
|
||||
config.bytesPerRowAlignment * (textureSizeLevel0.height / kBCBlockHeightInTexels);
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = 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.rowPitchAlignment + slicePitchInBytes;
|
||||
config.bytesPerRowAlignment + slicePitchInBytes;
|
||||
|
||||
TestCopyRegionIntoBCFormatTextures(config);
|
||||
}
|
||||
|
@ -940,7 +940,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWithBufferOffsetAndExtentExceedRowPitc
|
|||
config.textureDescriptor.format = 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 + 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
|
||||
// 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().
|
||||
TEST_P(CompressedTextureBCFormatTest, RowPitchEqualToSlicePitch) {
|
||||
// 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;
|
||||
|
||||
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) {
|
||||
config.textureDescriptor.format = 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 + slicePitchInBytes;
|
||||
|
@ -997,7 +997,7 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeight) {
|
|||
config.textureDescriptor.size = {8, 8, 1};
|
||||
config.copyExtent3D = config.textureDescriptor.size;
|
||||
|
||||
config.imageHeight = config.textureDescriptor.size.height * 2;
|
||||
config.rowsPerImage = config.textureDescriptor.size.height * 2;
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = format;
|
||||
|
@ -1040,7 +1040,7 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeightAndClampedCopyExtent) {
|
|||
|
||||
config.copyExtent3D = {kCopyWidthAtLevel, kCopyHeightAtLevel, 1};
|
||||
|
||||
config.imageHeight = kCopyHeightAtLevel * 2;
|
||||
config.rowsPerImage = kCopyHeightAtLevel * 2;
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = format;
|
||||
|
|
|
@ -37,7 +37,7 @@ class CopyTests : public DawnTest {
|
|||
struct BufferSpec {
|
||||
uint64_t size;
|
||||
uint64_t offset;
|
||||
uint32_t rowPitch;
|
||||
uint32_t bytesPerRow;
|
||||
};
|
||||
|
||||
static void FillTextureData(uint32_t width,
|
||||
|
@ -56,8 +56,8 @@ class CopyTests : public DawnTest {
|
|||
}
|
||||
|
||||
BufferSpec MinimumBufferSpec(uint32_t width, uint32_t height) {
|
||||
uint32_t rowPitch = Align(width * kBytesPerTexel, kTextureRowPitchAlignment);
|
||||
return { rowPitch * (height - 1) + width * kBytesPerTexel, 0, rowPitch };
|
||||
uint32_t bytesPerRow = Align(width * kBytesPerTexel, kTextureBytesPerRowAlignment);
|
||||
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) {
|
||||
|
@ -90,8 +90,8 @@ class CopyTests_T2B : public CopyTests {
|
|||
|
||||
uint32_t width = textureSpec.width >> textureSpec.level;
|
||||
uint32_t height = textureSpec.height >> textureSpec.level;
|
||||
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment);
|
||||
uint32_t texelsPerRow = rowPitch / kBytesPerTexel;
|
||||
uint32_t bytesPerRow = Align(kBytesPerTexel * width, kTextureBytesPerRowAlignment);
|
||||
uint32_t texelsPerRow = bytesPerRow / kBytesPerTexel;
|
||||
uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width;
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
@ -99,7 +99,7 @@ class CopyTests_T2B : public CopyTests {
|
|||
std::vector<std::vector<RGBA8>> textureArrayData(textureSpec.arraySize);
|
||||
for (uint32_t slice = 0; slice < textureSpec.arraySize; ++slice) {
|
||||
textureArrayData[slice].resize(texelCountPerLayer);
|
||||
FillTextureData(width, height, rowPitch / kBytesPerTexel, slice,
|
||||
FillTextureData(width, height, bytesPerRow / kBytesPerTexel, slice,
|
||||
textureArrayData[slice].data());
|
||||
|
||||
// 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()),
|
||||
wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, bytesPerRow, 0);
|
||||
wgpu::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, textureSpec.level, slice, {0, 0, 0});
|
||||
wgpu::Extent3D copySize = {width, height, 1};
|
||||
encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
}
|
||||
|
||||
// Create a buffer of size `size * textureSpec.arrayLayer` and populate it with empty data (0,0,0,0)
|
||||
// Note: Prepopulating the buffer 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 not modified by the copy
|
||||
// Create a buffer of size `size * textureSpec.arrayLayer` and populate it with empty
|
||||
// data (0,0,0,0) Note: Prepopulating the buffer with empty data ensures that there is
|
||||
// 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;
|
||||
bufDescriptor.size = bufferSpec.size * textureSpec.arraySize;
|
||||
bufDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
|
||||
|
@ -128,11 +129,12 @@ class CopyTests_T2B : public CopyTests {
|
|||
|
||||
uint64_t bufferOffset = bufferSpec.offset;
|
||||
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(
|
||||
texture, textureSpec.level, slice, {textureSpec.x, textureSpec.y, 0});
|
||||
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};
|
||||
encoder.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, ©Size);
|
||||
bufferOffset += bufferSpec.size;
|
||||
|
@ -142,22 +144,28 @@ class CopyTests_T2B : public CopyTests {
|
|||
queue.Submit(1, &commands);
|
||||
|
||||
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) {
|
||||
// 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());
|
||||
PackTextureData(
|
||||
&textureArrayData[slice][textureSpec.x + textureSpec.y * (rowPitch / kBytesPerTexel)],
|
||||
textureSpec.copyWidth,
|
||||
textureSpec.copyHeight,
|
||||
rowPitch / kBytesPerTexel,
|
||||
expected.data(),
|
||||
bufferSpec.rowPitch / kBytesPerTexel);
|
||||
&textureArrayData[slice][textureSpec.x +
|
||||
textureSpec.y * (bytesPerRow / kBytesPerTexel)],
|
||||
textureSpec.copyWidth, textureSpec.copyHeight, bytesPerRow / kBytesPerTexel,
|
||||
expected.data(), bufferSpec.bytesPerRow / kBytesPerTexel);
|
||||
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer, bufferOffset, static_cast<uint32_t>(expected.size())) <<
|
||||
"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 row pitch " << bufferSpec.rowPitch << std::endl;
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()),
|
||||
buffer, bufferOffset,
|
||||
static_cast<uint32_t>(expected.size()))
|
||||
<< "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;
|
||||
}
|
||||
|
@ -205,14 +213,15 @@ protected:
|
|||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
||||
// 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 random data in the expectation
|
||||
// and helps ensure that the padding due to the row pitch is not modified by the copy
|
||||
// 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
|
||||
// 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 height = textureSpec.height >> textureSpec.level;
|
||||
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment);
|
||||
uint32_t texelsPerRow = rowPitch / kBytesPerTexel;
|
||||
uint32_t bytesPerRow = Align(kBytesPerTexel * width, kTextureBytesPerRowAlignment);
|
||||
uint32_t texelsPerRow = bytesPerRow / kBytesPerTexel;
|
||||
uint32_t texelCount = texelsPerRow * (height - 1) + width;
|
||||
|
||||
std::vector<RGBA8> emptyData(texelCount);
|
||||
|
@ -220,17 +229,18 @@ protected:
|
|||
device, emptyData.data(), static_cast<uint32_t>(sizeof(RGBA8) * emptyData.size()),
|
||||
wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, bytesPerRow, 0);
|
||||
wgpu::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, textureSpec.level, 0, {0, 0, 0});
|
||||
wgpu::Extent3D copySize = {width, height, 1};
|
||||
encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
}
|
||||
|
||||
// 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 =
|
||||
utils::CreateBufferCopyView(buffer, bufferSpec.offset, bufferSpec.rowPitch, 0);
|
||||
utils::CreateBufferCopyView(buffer, bufferSpec.offset, bufferSpec.bytesPerRow, 0);
|
||||
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
texture, textureSpec.level, 0, {textureSpec.x, textureSpec.y, 0});
|
||||
wgpu::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1};
|
||||
|
@ -241,15 +251,23 @@ protected:
|
|||
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.
|
||||
uint32_t rowPitch = Align(kBytesPerTexel * textureSpec.copyWidth, kTextureRowPitchAlignment);
|
||||
std::vector<RGBA8> expected(rowPitch / kBytesPerTexel * (textureSpec.copyHeight - 1) + textureSpec.copyWidth);
|
||||
PackTextureData(&bufferData[bufferSpec.offset / kBytesPerTexel], textureSpec.copyWidth, textureSpec.copyHeight, bufferSpec.rowPitch / kBytesPerTexel, expected.data(), textureSpec.copyWidth);
|
||||
uint32_t bytesPerRow =
|
||||
Align(kBytesPerTexel * textureSpec.copyWidth, kTextureBytesPerRowAlignment);
|
||||
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) <<
|
||||
"Buffer to Texture copy failed copying "
|
||||
<< bufferSpec.size << "-byte buffer with offset " << bufferSpec.offset << " and row pitch " << bufferSpec.rowPitch << " 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;
|
||||
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, textureSpec.x, textureSpec.y,
|
||||
textureSpec.copyWidth, textureSpec.copyHeight, textureSpec.level, 0)
|
||||
<< "Buffer to Texture copy failed copying " << bufferSpec.size
|
||||
<< "-byte buffer with offset " << bufferSpec.offset << " and bytes per row "
|
||||
<< 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
|
||||
uint32_t width = srcSpec.width >> srcSpec.level;
|
||||
uint32_t height = srcSpec.height >> srcSpec.level;
|
||||
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment);
|
||||
uint32_t texelsPerRow = rowPitch / kBytesPerTexel;
|
||||
uint32_t bytesPerRow = Align(kBytesPerTexel * width, kTextureBytesPerRowAlignment);
|
||||
uint32_t texelsPerRow = bytesPerRow / kBytesPerTexel;
|
||||
uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width;
|
||||
|
||||
std::vector<std::vector<RGBA8>> textureArrayData(srcSpec.arraySize);
|
||||
for (uint32_t slice = 0; slice < srcSpec.arraySize; ++slice) {
|
||||
textureArrayData[slice].resize(texelCountPerLayer);
|
||||
FillTextureData(width, height, rowPitch / kBytesPerTexel, slice,
|
||||
FillTextureData(width, height, bytesPerRow / kBytesPerTexel, slice,
|
||||
textureArrayData[slice].data());
|
||||
|
||||
wgpu::Buffer uploadBuffer = utils::CreateBufferFromData(
|
||||
|
@ -317,7 +335,7 @@ class CopyTests_T2T : public CopyTests {
|
|||
static_cast<uint32_t>(sizeof(RGBA8) * textureArrayData[slice].size()),
|
||||
wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, bytesPerRow, 0);
|
||||
wgpu::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(srcTexture, srcSpec.level, slice, {0, 0, 0});
|
||||
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
|
||||
// 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
|
||||
// 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 dstWidth = dstSpec.width >> 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 dstTexelCount = dstTexelsPerRow * (dstHeight - 1) + dstWidth;
|
||||
|
||||
|
@ -361,11 +379,11 @@ class CopyTests_T2T : public CopyTests {
|
|||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
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) {
|
||||
std::fill(expected.begin(), expected.end(), RGBA8());
|
||||
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);
|
||||
|
||||
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) {
|
||||
constexpr uint32_t kWidth = 32;
|
||||
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) {
|
||||
constexpr uint32_t kWidth = 256;
|
||||
constexpr uint32_t kHeight = 128;
|
||||
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
|
||||
for (unsigned int i = 1; i < 4; ++i) {
|
||||
bufferSpec.rowPitch += 256;
|
||||
bufferSpec.bytesPerRow += 256;
|
||||
bufferSpec.size += 256 * kHeight;
|
||||
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) {
|
||||
constexpr uint32_t kWidth = 259;
|
||||
constexpr uint32_t kHeight = 127;
|
||||
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
|
||||
for (unsigned int i = 1; i < 4; ++i) {
|
||||
bufferSpec.rowPitch += 256;
|
||||
bufferSpec.bytesPerRow += 256;
|
||||
bufferSpec.size += 256 * kHeight;
|
||||
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) {
|
||||
constexpr uint32_t kWidth = 32;
|
||||
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) {
|
||||
constexpr uint32_t kWidth = 256;
|
||||
constexpr uint32_t kHeight = 128;
|
||||
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
|
||||
for (unsigned int i = 1; i < 4; ++i) {
|
||||
bufferSpec.rowPitch += 256;
|
||||
bufferSpec.bytesPerRow += 256;
|
||||
bufferSpec.size += 256 * kHeight;
|
||||
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) {
|
||||
constexpr uint32_t kWidth = 259;
|
||||
constexpr uint32_t kHeight = 127;
|
||||
BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
|
||||
for (unsigned int i = 1; i < 4; ++i) {
|
||||
bufferSpec.rowPitch += 256;
|
||||
bufferSpec.bytesPerRow += 256;
|
||||
bufferSpec.size += 256 * kHeight;
|
||||
DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0 }, bufferSpec);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Constants.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
|
@ -364,6 +365,136 @@ TEST_P(DeprecationTests, ShaderModuleInlinedCodeStateTracking) {
|
|||
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, ©Size);
|
||||
break;
|
||||
case T2B:
|
||||
encoder.CopyTextureToBuffer(&textureCopyView, &bufferView, ©Size);
|
||||
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,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
|
|
|
@ -98,7 +98,7 @@ protected:
|
|||
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
||||
|
||||
// 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];
|
||||
data[0] = data[rowPixels + 1] = RGBA8::kBlack;
|
||||
data[1] = data[rowPixels] = RGBA8::kWhite;
|
||||
|
|
|
@ -117,9 +117,9 @@ protected:
|
|||
|
||||
// Create a texture with pixel = (0, 0, 0, level * 10 + layer + 1) at level `level` and
|
||||
// layer `layer`.
|
||||
static_assert((kTextureRowPitchAlignment % sizeof(RGBA8)) == 0,
|
||||
"Texture row pitch alignment must be a multiple of sizeof(RGBA8).");
|
||||
constexpr uint32_t kPixelsPerRowPitch = kTextureRowPitchAlignment / sizeof(RGBA8);
|
||||
static_assert((kTextureBytesPerRowAlignment % sizeof(RGBA8)) == 0,
|
||||
"Texture bytes per row alignment must be a multiple of sizeof(RGBA8).");
|
||||
constexpr uint32_t kPixelsPerRowPitch = kTextureBytesPerRowAlignment / sizeof(RGBA8);
|
||||
ASSERT_LE(textureWidthLevel0, kPixelsPerRowPitch);
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
@ -135,7 +135,7 @@ protected:
|
|||
wgpu::Buffer stagingBuffer = utils::CreateBufferFromData(
|
||||
device, data.data(), data.size() * sizeof(RGBA8), wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(stagingBuffer, 0, kTextureRowPitchAlignment, 0);
|
||||
utils::CreateBufferCopyView(stagingBuffer, 0, kTextureBytesPerRowAlignment, 0);
|
||||
wgpu::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(mTexture, level, layer, {0, 0, 0});
|
||||
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.
|
||||
uint32_t textureViewWidth = textureWidthLevel0 >> textureViewBaseLevel;
|
||||
uint32_t textureViewHeight = textureHeightLevel0 >> textureViewBaseLevel;
|
||||
uint32_t rowPitch = Align(kBytesPerTexel * textureWidthLevel0, kTextureRowPitchAlignment);
|
||||
uint32_t bytesPerRow =
|
||||
Align(kBytesPerTexel * textureWidthLevel0, kTextureBytesPerRowAlignment);
|
||||
uint32_t expectedDataSize =
|
||||
rowPitch / kBytesPerTexel * (textureWidthLevel0 - 1) + textureHeightLevel0;
|
||||
bytesPerRow / kBytesPerTexel * (textureWidthLevel0 - 1) + textureHeightLevel0;
|
||||
constexpr RGBA8 kExpectedPixel(0, 255, 0, 255);
|
||||
std::vector<RGBA8> expected(expectedDataSize, kExpectedPixel);
|
||||
EXPECT_TEXTURE_RGBA8_EQ(
|
||||
|
|
|
@ -638,13 +638,13 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClear) {
|
|||
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
||||
|
||||
// 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 bufferSize = rowPitch * kSize;
|
||||
uint32_t bytesPerRow = Align(kSize * kFormatBlockByteSize, kTextureBytesPerRowAlignment);
|
||||
uint32_t bufferSize = bytesPerRow * kSize;
|
||||
std::vector<uint8_t> data(bufferSize, 100);
|
||||
wgpu::Buffer bufferDst = utils::CreateBufferFromData(
|
||||
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::Extent3D copySize = {kSize, kSize, 1};
|
||||
|
||||
|
@ -669,12 +669,13 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClearUnalignedSize) {
|
|||
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
||||
|
||||
// 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 bufferSize = rowPitch * kUnalignedSize;
|
||||
uint32_t bytesPerRow =
|
||||
Align(kUnalignedSize * kFormatBlockByteSize, kTextureBytesPerRowAlignment);
|
||||
uint32_t bufferSize = bytesPerRow * kUnalignedSize;
|
||||
std::vector<uint8_t> data(bufferSize, 100);
|
||||
wgpu::Buffer bufferDst = utils::CreateBufferFromData(
|
||||
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::Extent3D copySize = {kUnalignedSize, kUnalignedSize, 1};
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ namespace {
|
|||
|
||||
struct BufferSpec {
|
||||
uint64_t offset;
|
||||
uint32_t rowPitch;
|
||||
uint32_t imageHeight;
|
||||
uint32_t bytesPerRow;
|
||||
uint32_t rowsPerImage;
|
||||
};
|
||||
|
||||
// Check that each copy region fits inside the buffer footprint
|
||||
|
@ -123,14 +123,14 @@ namespace {
|
|||
for (uint32_t i = 0; i < copySplit.count; ++i) {
|
||||
const auto& copy = copySplit.copies[i];
|
||||
|
||||
uint32_t rowPitchInTexels =
|
||||
bufferSpec.rowPitch / textureSpec.texelBlockSizeInBytes * texelsPerBlock;
|
||||
uint32_t bytesPerRowInTexels =
|
||||
bufferSpec.bytesPerRow / textureSpec.texelBlockSizeInBytes * texelsPerBlock;
|
||||
uint32_t slicePitchInTexels =
|
||||
rowPitchInTexels * (bufferSpec.imageHeight / textureSpec.blockHeight);
|
||||
bytesPerRowInTexels * (bufferSpec.rowsPerImage / textureSpec.blockHeight);
|
||||
uint32_t absoluteTexelOffset =
|
||||
copySplit.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock +
|
||||
copy.bufferOffset.x / textureSpec.blockWidth * texelsPerBlock +
|
||||
copy.bufferOffset.y / textureSpec.blockHeight * rowPitchInTexels +
|
||||
copy.bufferOffset.y / textureSpec.blockHeight * bytesPerRowInTexels +
|
||||
copy.bufferOffset.z * slicePitchInTexels;
|
||||
|
||||
ASSERT(absoluteTexelOffset >=
|
||||
|
@ -140,8 +140,8 @@ namespace {
|
|||
bufferSpec.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock;
|
||||
|
||||
uint32_t z = relativeTexelOffset / slicePitchInTexels;
|
||||
uint32_t y = (relativeTexelOffset % slicePitchInTexels) / rowPitchInTexels;
|
||||
uint32_t x = relativeTexelOffset % rowPitchInTexels;
|
||||
uint32_t y = (relativeTexelOffset % slicePitchInTexels) / bytesPerRowInTexels;
|
||||
uint32_t x = relativeTexelOffset % bytesPerRowInTexels;
|
||||
|
||||
ASSERT_EQ(copy.textureOffset.x - textureSpec.x, x);
|
||||
ASSERT_EQ(copy.textureOffset.y - textureSpec.y, y);
|
||||
|
@ -167,8 +167,8 @@ namespace {
|
|||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BufferSpec& bufferSpec) {
|
||||
os << "BufferSpec(" << bufferSpec.offset << ", " << bufferSpec.rowPitch << ", "
|
||||
<< bufferSpec.imageHeight << ")";
|
||||
os << "BufferSpec(" << bufferSpec.offset << ", " << bufferSpec.bytesPerRow << ", "
|
||||
<< bufferSpec.rowsPerImage << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
@ -217,43 +217,44 @@ namespace {
|
|||
{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) {
|
||||
uint32_t rowPitch =
|
||||
Align(textureSpec.texelBlockSizeInBytes * textureSpec.width, kTextureRowPitchAlignment);
|
||||
uint32_t bytesPerRow = Align(textureSpec.texelBlockSizeInBytes * textureSpec.width,
|
||||
kTextureBytesPerRowAlignment);
|
||||
|
||||
auto alignNonPow2 = [](uint32_t value, uint32_t size) -> uint32_t {
|
||||
return value == 0 ? 0 : ((value - 1) / size + 1) * size;
|
||||
};
|
||||
|
||||
return {
|
||||
BufferSpec{alignNonPow2(0, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(0, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(512, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(512, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height * 2},
|
||||
|
||||
BufferSpec{alignNonPow2(32, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(32, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height * 2},
|
||||
|
||||
BufferSpec{alignNonPow2(31, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(31, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(257, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(257, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(511, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(511, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(513, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(513, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height},
|
||||
BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), rowPitch,
|
||||
BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), bytesPerRow,
|
||||
textureSpec.height * 2},
|
||||
};
|
||||
}
|
||||
|
@ -280,7 +281,7 @@ class CopySplitTest : public testing::Test {
|
|||
TextureCopySplit copySplit = ComputeTextureCopySplit(
|
||||
{textureSpec.x, textureSpec.y, textureSpec.z},
|
||||
{textureSpec.width, textureSpec.height, textureSpec.depth}, fakeFormat,
|
||||
bufferSpec.offset, bufferSpec.rowPitch, bufferSpec.imageHeight);
|
||||
bufferSpec.offset, bufferSpec.bytesPerRow, bufferSpec.rowsPerImage);
|
||||
ValidateCopySplit(textureSpec, bufferSpec, copySplit);
|
||||
return copySplit;
|
||||
}
|
||||
|
@ -418,9 +419,9 @@ TEST_F(CopySplitTest, BufferOffset) {
|
|||
TEST_F(CopySplitTest, RowPitch) {
|
||||
for (TextureSpec textureSpec : kBaseTextureSpecs) {
|
||||
for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
|
||||
uint32_t baseRowPitch = bufferSpec.rowPitch;
|
||||
uint32_t baseRowPitch = bufferSpec.bytesPerRow;
|
||||
for (uint32_t i = 0; i < 5; ++i) {
|
||||
bufferSpec.rowPitch = baseRowPitch + i * 256;
|
||||
bufferSpec.bytesPerRow = baseRowPitch + i * 256;
|
||||
|
||||
TextureCopySplit copySplit = DoTest(textureSpec, bufferSpec);
|
||||
if (HasFatalFailure()) {
|
||||
|
@ -437,9 +438,9 @@ TEST_F(CopySplitTest, RowPitch) {
|
|||
TEST_F(CopySplitTest, ImageHeight) {
|
||||
for (TextureSpec textureSpec : kBaseTextureSpecs) {
|
||||
for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
|
||||
uint32_t baseImageHeight = bufferSpec.imageHeight;
|
||||
uint32_t baseImageHeight = bufferSpec.rowsPerImage;
|
||||
for (uint32_t i = 0; i < 5; ++i) {
|
||||
bufferSpec.imageHeight = baseImageHeight + i * 256;
|
||||
bufferSpec.rowsPerImage = baseImageHeight + i * 256;
|
||||
|
||||
TextureCopySplit copySplit = DoTest(textureSpec, bufferSpec);
|
||||
if (HasFatalFailure()) {
|
||||
|
|
|
@ -68,8 +68,8 @@ class CopyCommandTest : public ValidationTest {
|
|||
uint32_t depth,
|
||||
wgpu::TextureFormat format = wgpu::TextureFormat::RGBA8Unorm) {
|
||||
uint32_t bytesPerPixel = TextureFormatPixelSize(format);
|
||||
uint32_t rowPitch = Align(width * bytesPerPixel, kTextureRowPitchAlignment);
|
||||
return (rowPitch * (height - 1) + width * bytesPerPixel) * depth;
|
||||
uint32_t bytesPerRow = Align(width * bytesPerPixel, kTextureBytesPerRowAlignment);
|
||||
return (bytesPerRow * (height - 1) + width * bytesPerPixel) * depth;
|
||||
}
|
||||
|
||||
void ValidateExpectation(wgpu::CommandEncoder encoder, utils::Expectation expectation) {
|
||||
|
@ -291,7 +291,7 @@ TEST_F(CopyCommandTest_B2T, Success) {
|
|||
{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
|
||||
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},
|
||||
{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
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 512, 0, destination, 0, 0, {0, 0, 0},
|
||||
{4, 3, 1});
|
||||
|
||||
// Not OOB on the buffer although row pitch * height overflows
|
||||
// but (row pitch * (height - 1) + width * bytesPerPixel) * depth does not overflow
|
||||
// Not OOB on the buffer although bytes per row * height overflows
|
||||
// but (bytes per row * (height - 1) + width * bytesPerPixel) * depth does not overflow
|
||||
{
|
||||
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);
|
||||
|
||||
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::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},
|
||||
{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},
|
||||
{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},
|
||||
{65, 1, 1});
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ TEST_F(CopyCommandTest_T2B, Success) {
|
|||
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
|
||||
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,
|
||||
{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
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, destination, 0, 512, 0,
|
||||
{4, 3, 1});
|
||||
|
||||
// Not OOB on the buffer although row pitch * height overflows
|
||||
// but (row pitch * (height - 1) + width * bytesPerPixel) * depth does not overflow
|
||||
// Not OOB on the buffer although bytes per row * height overflows
|
||||
// but (bytes per row * (height - 1) + width * bytesPerPixel) * depth does not overflow
|
||||
{
|
||||
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 =
|
||||
CreateBuffer(destinationBufferSize, wgpu::BufferUsage::CopyDst);
|
||||
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::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,
|
||||
{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,
|
||||
{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,
|
||||
{65, 1, 1});
|
||||
}
|
||||
|
@ -1198,16 +1199,16 @@ class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest {
|
|||
wgpu::Buffer buffer,
|
||||
uint64_t bufferOffset,
|
||||
uint32_t bufferRowPitch,
|
||||
uint32_t imageHeight,
|
||||
uint32_t rowsPerImage,
|
||||
wgpu::Texture texture,
|
||||
uint32_t level,
|
||||
uint32_t arraySlice,
|
||||
wgpu::Origin3D origin,
|
||||
wgpu::Extent3D extent3D) {
|
||||
TestB2TCopy(expectation, buffer, bufferOffset, bufferRowPitch, imageHeight, texture, level,
|
||||
TestB2TCopy(expectation, buffer, bufferOffset, bufferRowPitch, rowsPerImage, texture, level,
|
||||
arraySlice, origin, extent3D);
|
||||
TestT2BCopy(expectation, texture, level, arraySlice, origin, buffer, bufferOffset,
|
||||
bufferRowPitch, imageHeight, extent3D);
|
||||
bufferRowPitch, rowsPerImage, extent3D);
|
||||
}
|
||||
|
||||
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.
|
||||
TEST_F(CopyCommandTest_CompressedTextureFormats, ImageHeight) {
|
||||
wgpu::Buffer buffer =
|
||||
|
@ -1345,14 +1346,14 @@ TEST_F(CopyCommandTest_CompressedTextureFormats, ImageHeight) {
|
|||
for (wgpu::TextureFormat bcFormat : kBCFormats) {
|
||||
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;
|
||||
TestBothTBCopies(utils::Expectation::Success, buffer, 0, 256, kValidImageHeight,
|
||||
texture, 0, 0, {0, 0, 0}, {4, 4, 1});
|
||||
}
|
||||
|
||||
// Failures on invalid imageHeight.
|
||||
// Failures on invalid rowsPerImage.
|
||||
{
|
||||
constexpr uint32_t kInvalidImageHeight = 3;
|
||||
TestBothTBCopies(utils::Expectation::Failure, buffer, 0, 256, kInvalidImageHeight,
|
||||
|
|
|
@ -536,8 +536,8 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::BufferCopyView copyDst;
|
||||
copyDst.buffer = copyDstBuffer;
|
||||
copyDst.offset = 0;
|
||||
copyDst.rowPitch = 256;
|
||||
copyDst.imageHeight = 0;
|
||||
copyDst.bytesPerRow = 256;
|
||||
copyDst.rowsPerImage = 0;
|
||||
|
||||
wgpu::Extent3D copySize = {1, 1, 1};
|
||||
|
||||
|
@ -588,8 +588,8 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::BufferCopyView copySrc;
|
||||
copySrc.buffer = copySrcBuffer;
|
||||
copySrc.offset = 0;
|
||||
copySrc.rowPitch = 256;
|
||||
copySrc.imageHeight = 0;
|
||||
copySrc.bytesPerRow = 256;
|
||||
copySrc.rowsPerImage = 0;
|
||||
|
||||
wgpu::TextureCopyView copyDst;
|
||||
copyDst.texture = secondDeviceWrappedTexture;
|
||||
|
@ -787,8 +787,8 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
// Draw a non-trivial picture
|
||||
uint32_t width = 640, height = 480, pixelSize = 4;
|
||||
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment);
|
||||
uint32_t size = rowPitch * (height - 1) + width * pixelSize;
|
||||
uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
|
||||
uint32_t size = bytesPerRow * (height - 1) + width * pixelSize;
|
||||
unsigned char data[size];
|
||||
for (uint32_t row = 0; row < height; row++) {
|
||||
for (uint32_t col = 0; col < width; col++) {
|
||||
|
@ -808,7 +808,7 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::Buffer copySrcBuffer =
|
||||
utils::CreateBufferFromData(secondDevice, data, size, wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView copySrc =
|
||||
utils::CreateBufferCopyView(copySrcBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(copySrcBuffer, 0, bytesPerRow, 0);
|
||||
wgpu::TextureCopyView copyDst =
|
||||
utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0});
|
||||
wgpu::Extent3D copySize = {width, height, 1};
|
||||
|
@ -836,7 +836,7 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::TextureCopyView copySrc =
|
||||
utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0});
|
||||
wgpu::BufferCopyView copyDst =
|
||||
utils::CreateBufferCopyView(copyDstBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(copyDstBuffer, 0, bytesPerRow, 0);
|
||||
|
||||
wgpu::Extent3D copySize = {width, height, 1};
|
||||
|
||||
|
|
|
@ -676,8 +676,8 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::BufferCopyView copyDst;
|
||||
copyDst.buffer = copyDstBuffer;
|
||||
copyDst.offset = 0;
|
||||
copyDst.rowPitch = 256;
|
||||
copyDst.imageHeight = 0;
|
||||
copyDst.bytesPerRow = 256;
|
||||
copyDst.rowsPerImage = 0;
|
||||
|
||||
wgpu::Extent3D copySize = {1, 1, 1};
|
||||
|
||||
|
@ -732,8 +732,8 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::BufferCopyView copySrc;
|
||||
copySrc.buffer = copySrcBuffer;
|
||||
copySrc.offset = 0;
|
||||
copySrc.rowPitch = 256;
|
||||
copySrc.imageHeight = 0;
|
||||
copySrc.bytesPerRow = 256;
|
||||
copySrc.rowsPerImage = 0;
|
||||
|
||||
wgpu::TextureCopyView copyDst;
|
||||
copyDst.texture = secondDeviceWrappedTexture;
|
||||
|
@ -961,8 +961,8 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
// Draw a non-trivial picture
|
||||
uint32_t width = 640, height = 480, pixelSize = 4;
|
||||
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment);
|
||||
uint32_t size = rowPitch * (height - 1) + width * pixelSize;
|
||||
uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
|
||||
uint32_t size = bytesPerRow * (height - 1) + width * pixelSize;
|
||||
unsigned char data[size];
|
||||
for (uint32_t row = 0; row < height; row++) {
|
||||
for (uint32_t col = 0; col < width; col++) {
|
||||
|
@ -982,7 +982,7 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::Buffer copySrcBuffer =
|
||||
utils::CreateBufferFromData(secondDevice, data, size, wgpu::BufferUsage::CopySrc);
|
||||
wgpu::BufferCopyView copySrc =
|
||||
utils::CreateBufferCopyView(copySrcBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(copySrcBuffer, 0, bytesPerRow, 0);
|
||||
wgpu::TextureCopyView copyDst =
|
||||
utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0});
|
||||
wgpu::Extent3D copySize = {width, height, 1};
|
||||
|
@ -1010,7 +1010,7 @@ namespace dawn_native { namespace vulkan {
|
|||
wgpu::TextureCopyView copySrc =
|
||||
utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0});
|
||||
wgpu::BufferCopyView copyDst =
|
||||
utils::CreateBufferCopyView(copyDstBuffer, 0, rowPitch, 0);
|
||||
utils::CreateBufferCopyView(copyDstBuffer, 0, bytesPerRow, 0);
|
||||
|
||||
wgpu::Extent3D copySize = {width, height, 1};
|
||||
|
||||
|
|
|
@ -235,13 +235,13 @@ namespace utils {
|
|||
|
||||
wgpu::BufferCopyView CreateBufferCopyView(wgpu::Buffer buffer,
|
||||
uint64_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight) {
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t rowsPerImage) {
|
||||
wgpu::BufferCopyView bufferCopyView;
|
||||
bufferCopyView.buffer = buffer;
|
||||
bufferCopyView.offset = offset;
|
||||
bufferCopyView.rowPitch = rowPitch;
|
||||
bufferCopyView.imageHeight = imageHeight;
|
||||
bufferCopyView.bytesPerRow = bytesPerRow;
|
||||
bufferCopyView.rowsPerImage = rowsPerImage;
|
||||
|
||||
return bufferCopyView;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ namespace utils {
|
|||
|
||||
wgpu::BufferCopyView CreateBufferCopyView(wgpu::Buffer buffer,
|
||||
uint64_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight);
|
||||
uint32_t bytesPerRow,
|
||||
uint32_t rowsPerImage);
|
||||
wgpu::TextureCopyView CreateTextureCopyView(wgpu::Texture texture,
|
||||
uint32_t level,
|
||||
uint32_t slice,
|
||||
|
|
Loading…
Reference in New Issue