Implement new formula for requiredBytesInCopy

Changed upstream in:
- https://github.com/gpuweb/gpuweb/pull/1014
- https://github.com/gpuweb/gpuweb/pull/1130

Note that in some of the cases where width==0 || height==0 || depth==0,
this increases the number of linear data bytes required for a copy.
Since this is a corner case, no deprecation logic is added.

Removes a duplicated copy of this logic in TestUtils.cpp.

Bug: dawn:520
Change-Id: I3b3d079c6ef316df7d95ba5c349bf8de4646fa4d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/30741
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Kai Ninomiya
2020-10-23 21:21:33 +00:00
committed by Commit Bot service account
parent ca5aa235da
commit c9d0b492d5
10 changed files with 157 additions and 87 deletions

View File

@@ -25,27 +25,18 @@
namespace utils {
uint32_t GetMinimumBytesPerRow(wgpu::TextureFormat format, uint32_t width) {
const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);
return Align(bytesPerTexel * width, kTextureBytesPerRowAlignment);
const uint32_t bytesPerBlock = utils::GetTexelBlockSizeInBytes(format);
return Align(bytesPerBlock * width, kTextureBytesPerRowAlignment);
}
uint32_t GetBytesInBufferTextureCopy(wgpu::TextureFormat format,
uint32_t width,
uint32_t bytesPerRow,
uint32_t rowsPerImage,
uint32_t copyArrayLayerCount) {
ASSERT(rowsPerImage > 0);
const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);
const uint32_t bytesAtLastImage = bytesPerRow * (rowsPerImage - 1) + bytesPerTexel * width;
return bytesPerRow * rowsPerImage * (copyArrayLayerCount - 1) + bytesAtLastImage;
}
// TODO(jiawei.shao@intel.com): support compressed texture formats
TextureDataCopyLayout GetTextureDataCopyLayoutForTexture2DAtLevel(
wgpu::TextureFormat format,
wgpu::Extent3D textureSizeAtLevel0,
uint32_t mipmapLevel,
uint32_t rowsPerImage) {
// TODO(jiawei.shao@intel.com): support compressed texture formats
ASSERT(utils::GetTextureFormatBlockWidth(format) == 1);
TextureDataCopyLayout layout;
layout.mipSize = {textureSizeAtLevel0.width >> mipmapLevel,
@@ -56,9 +47,17 @@ namespace utils {
uint32_t appliedRowsPerImage = rowsPerImage > 0 ? rowsPerImage : layout.mipSize.height;
layout.bytesPerImage = layout.bytesPerRow * appliedRowsPerImage;
layout.byteLength =
GetBytesInBufferTextureCopy(format, layout.mipSize.width, layout.bytesPerRow,
appliedRowsPerImage, textureSizeAtLevel0.depth);
// TODO(kainino@chromium.org): Remove this intermediate variable.
// It is currently needed because of an issue in the D3D12 copy splitter
// (or maybe in D3D12 itself?) which requires there to be enough room in the
// buffer for the last image to have a height of `rowsPerImage` instead of
// the actual height.
wgpu::Extent3D mipSizeWithHeightWorkaround = layout.mipSize;
mipSizeWithHeightWorkaround.height =
appliedRowsPerImage * utils::GetTextureFormatBlockHeight(format);
layout.byteLength = RequiredBytesInCopy(layout.bytesPerRow, appliedRowsPerImage,
mipSizeWithHeightWorkaround, format);
const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);
layout.texelBlocksPerRow = layout.bytesPerRow / bytesPerTexel;
@@ -72,18 +71,35 @@ namespace utils {
uint64_t rowsPerImage,
wgpu::Extent3D copyExtent,
wgpu::TextureFormat textureFormat) {
if (copyExtent.width == 0 || copyExtent.height == 0 || copyExtent.depth == 0) {
return 0;
} else {
uint32_t blockSize = utils::GetTexelBlockSizeInBytes(textureFormat);
uint32_t blockWidth = utils::GetTextureFormatBlockWidth(textureFormat);
uint32_t blockHeight = utils::GetTextureFormatBlockHeight(textureFormat);
uint32_t blockSize = utils::GetTexelBlockSizeInBytes(textureFormat);
uint32_t blockWidth = utils::GetTextureFormatBlockWidth(textureFormat);
uint32_t blockHeight = utils::GetTextureFormatBlockHeight(textureFormat);
ASSERT(copyExtent.width % blockWidth == 0);
uint32_t widthInBlocks = copyExtent.width / blockWidth;
ASSERT(copyExtent.height % blockHeight == 0);
uint32_t heightInBlocks = copyExtent.height / blockHeight;
return RequiredBytesInCopy(bytesPerRow, rowsPerImage, widthInBlocks, heightInBlocks,
copyExtent.depth, blockSize);
}
uint64_t bytesPerImage = bytesPerRow * rowsPerImage;
uint64_t bytesInLastSlice = bytesPerRow * (copyExtent.height / blockHeight - 1) +
(copyExtent.width / blockWidth * blockSize);
return bytesPerImage * (copyExtent.depth - 1) + bytesInLastSlice;
uint64_t RequiredBytesInCopy(uint64_t bytesPerRow,
uint64_t rowsPerImage,
uint64_t widthInBlocks,
uint64_t heightInBlocks,
uint64_t depth,
uint64_t bytesPerBlock) {
if (depth == 0) {
return 0;
}
uint64_t bytesPerImage = bytesPerRow * rowsPerImage;
uint64_t requiredBytesInCopy = bytesPerImage * (depth - 1);
if (heightInBlocks != 0) {
uint64_t lastRowBytes = widthInBlocks * bytesPerBlock;
uint64_t lastImageBytes = bytesPerRow * (heightInBlocks - 1) + lastRowBytes;
requiredBytesInCopy += lastImageBytes;
}
return requiredBytesInCopy;
}
uint64_t GetTexelCountInCopyRegion(uint64_t bytesPerRow,

View File

@@ -30,11 +30,6 @@ namespace utils {
};
uint32_t GetMinimumBytesPerRow(wgpu::TextureFormat format, uint32_t width);
uint32_t GetBytesInBufferTextureCopy(wgpu::TextureFormat format,
uint32_t width,
uint32_t bytesPerRow,
uint32_t rowsPerImage,
uint32_t copyArrayLayerCount);
TextureDataCopyLayout GetTextureDataCopyLayoutForTexture2DAtLevel(
wgpu::TextureFormat format,
wgpu::Extent3D textureSizeAtLevel0,
@@ -45,6 +40,12 @@ namespace utils {
uint64_t rowsPerImage,
wgpu::Extent3D copyExtent,
wgpu::TextureFormat textureFormat);
uint64_t RequiredBytesInCopy(uint64_t bytesPerRow,
uint64_t rowsPerImage,
uint64_t widthInBlocks,
uint64_t heightInBlocks,
uint64_t depth,
uint64_t bytesPerBlock);
uint64_t GetTexelCountInCopyRegion(uint64_t bytesPerRow,
uint64_t rowsPerImage,