Format: Move the TexelBlockInfo inside an AspectInfo.

In follow up CLs additional will be added to the AspectInfo, like the
supported component types.

Also simplify the logic for GetTexelInfo since all aspects are the first
aspects, except stencil which is always stencil8.

Bug: dawn:517
Change-Id: Iebbcb8a7f8fa2c4b7b06f65d6e4e8917c0a85366
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/30100
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Corentin Wallez 2020-10-15 09:05:03 +00:00 committed by Commit Bot service account
parent 84b70a6e4d
commit 6298d2b70c
19 changed files with 174 additions and 214 deletions

View File

@ -168,15 +168,15 @@ namespace dawn_native {
const TextureBase* texture = copy->source.texture.Get();
const TexelBlockInfo& blockInfo =
texture->GetFormat().GetTexelBlockInfo(copy->source.aspect);
const uint64_t heightInBlocks = copy->copySize.height / blockInfo.blockHeight;
texture->GetFormat().GetAspectInfo(copy->source.aspect).block;
const uint64_t heightInBlocks = copy->copySize.height / blockInfo.height;
if (copy->destination.rowsPerImage > heightInBlocks) {
return false;
}
const uint64_t copyTextureDataSizePerRow =
copy->copySize.width / blockInfo.blockWidth * blockInfo.blockByteSize;
copy->copySize.width / blockInfo.width * blockInfo.byteSize;
if (copy->destination.bytesPerRow > copyTextureDataSizePerRow) {
return false;
}

View File

@ -650,7 +650,7 @@ namespace dawn_native {
DAWN_TRY(ValidateTextureCopyRange(*destination, *copySize));
}
const TexelBlockInfo& blockInfo =
destination->texture->GetFormat().GetTexelBlockInfo(destination->aspect);
destination->texture->GetFormat().GetAspectInfo(destination->aspect).block;
if (GetDevice()->IsValidationEnabled()) {
DAWN_TRY(ValidateLinearTextureData(source->layout, source->buffer->GetSize(),
blockInfo, *copySize));
@ -662,15 +662,15 @@ namespace dawn_native {
// Compute default value for rowsPerImage
uint32_t defaultedRowsPerImage = source->layout.rowsPerImage;
if (defaultedRowsPerImage == 0) {
ASSERT(copySize->height % blockInfo.blockHeight == 0);
defaultedRowsPerImage = copySize->height / blockInfo.blockHeight;
ASSERT(copySize->height % blockInfo.height == 0);
defaultedRowsPerImage = copySize->height / blockInfo.height;
}
// In the case of one row copy bytesPerRow might not contain enough bytes
uint32_t bytesPerRow = source->layout.bytesPerRow;
if (copySize->height <= 1 && copySize->depth <= 1) {
bytesPerRow =
Align(copySize->width * blockInfo.blockByteSize, kTextureBytesPerRowAlignment);
Align(copySize->width * blockInfo.byteSize, kTextureBytesPerRowAlignment);
}
// Skip noop copies.
@ -714,11 +714,10 @@ namespace dawn_native {
DAWN_TRY(ValidateTextureCopyRange(*source, *copySize));
}
const TexelBlockInfo& blockInfo =
source->texture->GetFormat().GetTexelBlockInfo(source->aspect);
source->texture->GetFormat().GetAspectInfo(source->aspect).block;
if (GetDevice()->IsValidationEnabled()) {
DAWN_TRY(ValidateLinearTextureData(
destination->layout, destination->buffer->GetSize(),
source->texture->GetFormat().GetTexelBlockInfo(source->aspect), *copySize));
destination->layout, destination->buffer->GetSize(), blockInfo, *copySize));
mTopLevelTextures.insert(source->texture);
mTopLevelBuffers.insert(destination->buffer);
@ -727,15 +726,15 @@ namespace dawn_native {
// Compute default value for rowsPerImage
uint32_t defaultedRowsPerImage = destination->layout.rowsPerImage;
if (defaultedRowsPerImage == 0) {
ASSERT(copySize->height % blockInfo.blockHeight == 0);
defaultedRowsPerImage = copySize->height / blockInfo.blockHeight;
ASSERT(copySize->height % blockInfo.height == 0);
defaultedRowsPerImage = copySize->height / blockInfo.height;
}
// In the case of one row copy bytesPerRow might not contain enough bytes
uint32_t bytesPerRow = destination->layout.bytesPerRow;
if (copySize->height <= 1 && copySize->depth <= 1) {
bytesPerRow =
Align(copySize->width * blockInfo.blockByteSize, kTextureBytesPerRowAlignment);
Align(copySize->width * blockInfo.byteSize, kTextureBytesPerRowAlignment);
}
// Skip noop copies.

View File

@ -374,8 +374,8 @@ namespace dawn_native {
const Extent3D& copySize,
uint32_t bytesPerRow,
uint32_t rowsPerImage) {
ASSERT(copySize.height % blockInfo.blockHeight == 0);
uint32_t heightInBlocks = copySize.height / blockInfo.blockHeight;
ASSERT(copySize.height % blockInfo.height == 0);
uint32_t heightInBlocks = copySize.height / blockInfo.height;
// Default value for rowsPerImage
if (rowsPerImage == 0) {
@ -384,7 +384,7 @@ namespace dawn_native {
ASSERT(rowsPerImage >= heightInBlocks);
if (copySize.height > 1 || copySize.depth > 1) {
ASSERT(bytesPerRow >= copySize.width / blockInfo.blockWidth * blockInfo.blockByteSize);
ASSERT(bytesPerRow >= copySize.width / blockInfo.width * blockInfo.byteSize);
}
if (copySize.width == 0 || copySize.height == 0 || copySize.depth == 0) {
@ -400,7 +400,7 @@ namespace dawn_native {
// bytesPerImage. Otherwise the result is a multiplication of two uint32_t numbers.
uint64_t bytesInLastSlice =
uint64_t(bytesPerRow) * (heightInBlocks - 1) +
(uint64_t(copySize.width) / blockInfo.blockWidth * blockInfo.blockByteSize);
(uint64_t(copySize.width) / blockInfo.width * blockInfo.byteSize);
// This error cannot be thrown for copySize.depth = 1.
// For copySize.depth > 1 we know that:
@ -430,14 +430,13 @@ namespace dawn_native {
const TexelBlockInfo& blockInfo,
const Extent3D& copyExtent) {
// Validation for the texel block alignments:
if (layout.offset % blockInfo.blockByteSize != 0) {
if (layout.offset % blockInfo.byteSize != 0) {
return DAWN_VALIDATION_ERROR("Offset must be a multiple of the texel or block size");
}
// Validation for other members in layout:
if ((copyExtent.height > 1 || copyExtent.depth > 1) &&
layout.bytesPerRow <
copyExtent.width / blockInfo.blockWidth * blockInfo.blockByteSize) {
layout.bytesPerRow < copyExtent.width / blockInfo.width * blockInfo.byteSize) {
return DAWN_VALIDATION_ERROR(
"bytesPerRow must not be less than the number of bytes per row");
}
@ -445,8 +444,8 @@ namespace dawn_native {
// TODO(tommek@google.com): to match the spec there should be another condition here
// on rowsPerImage >= copyExtent.height if copyExtent.depth > 1.
ASSERT(copyExtent.height % blockInfo.blockHeight == 0);
uint32_t heightInBlocks = copyExtent.height / blockInfo.blockHeight;
ASSERT(copyExtent.height % blockInfo.height == 0);
uint32_t heightInBlocks = copyExtent.height / blockInfo.height;
// Validation for the copy being in-bounds:
if (layout.rowsPerImage != 0 && layout.rowsPerImage < heightInBlocks) {
@ -551,25 +550,27 @@ namespace dawn_native {
}
// Validation for the texel block alignments:
const TexelBlockInfo& blockInfo =
textureCopy.texture->GetFormat().GetTexelBlockInfo(textureCopy.aspect);
if (textureCopy.origin.x % blockInfo.blockWidth != 0) {
const Format& format = textureCopy.texture->GetFormat();
if (format.isCompressed) {
const TexelBlockInfo& blockInfo = format.GetAspectInfo(textureCopy.aspect).block;
if (textureCopy.origin.x % blockInfo.width != 0) {
return DAWN_VALIDATION_ERROR(
"Offset.x must be a multiple of compressed texture format block width");
}
if (textureCopy.origin.y % blockInfo.blockHeight != 0) {
if (textureCopy.origin.y % blockInfo.height != 0) {
return DAWN_VALIDATION_ERROR(
"Offset.y must be a multiple of compressed texture format block height");
}
if (copySize.width % blockInfo.blockWidth != 0) {
if (copySize.width % blockInfo.width != 0) {
return DAWN_VALIDATION_ERROR(
"copySize.width must be a multiple of compressed texture format block width");
}
if (copySize.height % blockInfo.blockHeight != 0) {
if (copySize.height % blockInfo.height != 0) {
return DAWN_VALIDATION_ERROR(
"copySize.height must be a multiple of compressed texture format block height");
}
}
return {};
}

View File

@ -22,6 +22,12 @@
namespace dawn_native {
namespace {
static const AspectInfo kStencil8AspectInfo = {{1, 1, 1}};
}
// Format
// static
@ -78,62 +84,20 @@ namespace dawn_native {
return componentType == type;
}
TexelBlockInfo Format::GetTexelBlockInfo(wgpu::TextureAspect aspect) const {
switch (aspect) {
case wgpu::TextureAspect::All:
return blockInfo;
case wgpu::TextureAspect::DepthOnly:
ASSERT(HasDepth());
switch (format) {
case wgpu::TextureFormat::Depth32Float:
return blockInfo;
default:
UNREACHABLE();
break;
}
break;
case wgpu::TextureAspect::StencilOnly:
ASSERT(HasStencil());
switch (format) {
case wgpu::TextureFormat::Depth24PlusStencil8:
return {1, 1, 1};
default:
UNREACHABLE();
break;
}
break;
}
const AspectInfo& Format::GetAspectInfo(wgpu::TextureAspect aspect) const {
return GetAspectInfo(ConvertAspect(*this, aspect));
}
TexelBlockInfo Format::GetTexelBlockInfo(Aspect aspect) const {
const AspectInfo& Format::GetAspectInfo(Aspect aspect) const {
ASSERT(HasOneBit(aspect));
ASSERT(aspects & aspect);
switch (aspect) {
case Aspect::Color:
ASSERT(aspects == aspect);
return blockInfo;
case Aspect::Depth:
switch (format) {
case wgpu::TextureFormat::Depth32Float:
return blockInfo;
default:
UNREACHABLE();
break;
}
case Aspect::Stencil:
switch (format) {
case wgpu::TextureFormat::Depth24PlusStencil8:
return {1, 1, 1};
default:
UNREACHABLE();
break;
}
break;
case Aspect::None:
UNREACHABLE();
// The stencil aspect is the only aspect that's not the first aspect. Since it is alwaus the
// same aspect information, special case it to return a constant AspectInfo.
if (aspect == Aspect::Stencil) {
return kStencil8AspectInfo;
} else {
return firstAspect;
}
}
@ -182,9 +146,9 @@ namespace dawn_native {
internalFormat.supportsStorageUsage = supportsStorageUsage;
internalFormat.aspects = Aspect::Color;
internalFormat.type = type;
internalFormat.blockInfo.blockByteSize = byteSize;
internalFormat.blockInfo.blockWidth = 1;
internalFormat.blockInfo.blockHeight = 1;
internalFormat.firstAspect.block.byteSize = byteSize;
internalFormat.firstAspect.block.width = 1;
internalFormat.firstAspect.block.height = 1;
AddFormat(internalFormat);
};
@ -198,9 +162,9 @@ namespace dawn_native {
internalFormat.supportsStorageUsage = false;
internalFormat.aspects = aspects;
internalFormat.type = Type::Other;
internalFormat.blockInfo.blockByteSize = byteSize;
internalFormat.blockInfo.blockWidth = 1;
internalFormat.blockInfo.blockHeight = 1;
internalFormat.firstAspect.block.byteSize = byteSize;
internalFormat.firstAspect.block.width = 1;
internalFormat.firstAspect.block.height = 1;
AddFormat(internalFormat);
};
@ -214,9 +178,9 @@ namespace dawn_native {
internalFormat.supportsStorageUsage = false;
internalFormat.aspects = Aspect::Depth;
internalFormat.type = type;
internalFormat.blockInfo.blockByteSize = byteSize;
internalFormat.blockInfo.blockWidth = 1;
internalFormat.blockInfo.blockHeight = 1;
internalFormat.firstAspect.block.byteSize = byteSize;
internalFormat.firstAspect.block.width = 1;
internalFormat.firstAspect.block.height = 1;
AddFormat(internalFormat);
};
@ -230,9 +194,9 @@ namespace dawn_native {
internalFormat.supportsStorageUsage = false;
internalFormat.aspects = Aspect::Color;
internalFormat.type = Type::Float;
internalFormat.blockInfo.blockByteSize = byteSize;
internalFormat.blockInfo.blockWidth = width;
internalFormat.blockInfo.blockHeight = height;
internalFormat.firstAspect.block.byteSize = byteSize;
internalFormat.firstAspect.block.width = width;
internalFormat.firstAspect.block.height = height;
AddFormat(internalFormat);
};

View File

@ -18,9 +18,8 @@
#include "dawn_native/dawn_platform.h"
#include "common/ityp_bitset.h"
#include "dawn_native/Error.h"
#include "dawn_native/EnumClassBitmasks.h"
#include "dawn_native/Error.h"
#include <array>
@ -30,9 +29,13 @@ namespace dawn_native {
class DeviceBase;
struct TexelBlockInfo {
uint32_t blockByteSize;
uint32_t blockWidth;
uint32_t blockHeight;
uint32_t byteSize;
uint32_t width;
uint32_t height;
};
struct AspectInfo {
TexelBlockInfo block;
};
// The number of formats Dawn knows about. Asserts in BuildFormatTable ensure that this is the
@ -69,15 +72,17 @@ namespace dawn_native {
bool HasDepthOrStencil() const;
bool HasComponentType(Type componentType) const;
TexelBlockInfo GetTexelBlockInfo(wgpu::TextureAspect aspect) const;
TexelBlockInfo GetTexelBlockInfo(Aspect aspect) const;
const AspectInfo& GetAspectInfo(wgpu::TextureAspect aspect) const;
const AspectInfo& GetAspectInfo(Aspect aspect) const;
// The index of the format in the list of all known formats: a unique number for each format
// in [0, kKnownFormatCount)
size_t GetIndex() const;
private:
TexelBlockInfo blockInfo;
// The most common aspect: the color aspect for color texture, the depth aspect for
// depth[-stencil] textures.
AspectInfo firstAspect;
friend FormatTable BuildFormatTable(const DeviceBase* device);
};

View File

@ -88,11 +88,11 @@ namespace dawn_native {
uint64_t optimalOffsetAlignment =
device->GetOptimalBufferToTextureCopyOffsetAlignment();
ASSERT(IsPowerOfTwo(optimalOffsetAlignment));
ASSERT(IsPowerOfTwo(blockInfo.blockByteSize));
ASSERT(IsPowerOfTwo(blockInfo.byteSize));
// We need the offset to be aligned to both optimalOffsetAlignment and blockByteSize,
// since both of them are powers of two, we only need to align to the max value.
uint64_t offsetAlignment =
std::max(optimalOffsetAlignment, uint64_t(blockInfo.blockByteSize));
std::max(optimalOffsetAlignment, uint64_t(blockInfo.byteSize));
UploadHandle uploadHandle;
DAWN_TRY_ASSIGN(uploadHandle, device->GetDynamicUploader()->Allocate(
@ -106,7 +106,7 @@ namespace dawn_native {
uint32_t dataRowsPerImage = dataLayout.rowsPerImage;
if (dataRowsPerImage == 0) {
dataRowsPerImage = writeSizePixel.height / blockInfo.blockHeight;
dataRowsPerImage = writeSizePixel.height / blockInfo.height;
}
ASSERT(dataRowsPerImage >= alignedRowsPerImage);
@ -266,16 +266,15 @@ namespace dawn_native {
const TextureDataLayout& dataLayout,
const Extent3D& writeSizePixel) {
const TexelBlockInfo& blockInfo =
destination.texture->GetFormat().GetTexelBlockInfo(destination.aspect);
destination.texture->GetFormat().GetAspectInfo(destination.aspect).block;
// We are only copying the part of the data that will appear in the texture.
// Note that validating texture copy range ensures that writeSizePixel->width and
// writeSizePixel->height are multiples of blockWidth and blockHeight respectively.
ASSERT(writeSizePixel.width % blockInfo.blockWidth == 0);
ASSERT(writeSizePixel.height % blockInfo.blockHeight == 0);
uint32_t alignedBytesPerRow =
writeSizePixel.width / blockInfo.blockWidth * blockInfo.blockByteSize;
uint32_t alignedRowsPerImage = writeSizePixel.height / blockInfo.blockHeight;
ASSERT(writeSizePixel.width % blockInfo.width == 0);
ASSERT(writeSizePixel.height % blockInfo.height == 0);
uint32_t alignedBytesPerRow = writeSizePixel.width / blockInfo.width * blockInfo.byteSize;
uint32_t alignedRowsPerImage = writeSizePixel.height / blockInfo.height;
uint32_t optimalBytesPerRowAlignment = GetDevice()->GetOptimalBytesPerRowAlignment();
uint32_t optimallyAlignedBytesPerRow =
@ -418,7 +417,8 @@ namespace dawn_native {
DAWN_TRY(ValidateTextureCopyRange(*destination, *writeSize));
DAWN_TRY(ValidateLinearTextureData(
*dataLayout, dataSize,
destination->texture->GetFormat().GetTexelBlockInfo(destination->aspect), *writeSize));
destination->texture->GetFormat().GetAspectInfo(destination->aspect).block,
*writeSize));
DAWN_TRY(destination->texture->ValidateCanUseInSubmitNow());

View File

@ -165,12 +165,15 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("Texture has too many mip levels");
}
const TexelBlockInfo& blockInfo = format->GetTexelBlockInfo(wgpu::TextureAspect::All);
if (format->isCompressed && (descriptor->size.width % blockInfo.blockWidth != 0 ||
descriptor->size.height % blockInfo.blockHeight != 0)) {
if (format->isCompressed) {
const TexelBlockInfo& blockInfo =
format->GetAspectInfo(wgpu::TextureAspect::All).block;
if (descriptor->size.width % blockInfo.width != 0 ||
descriptor->size.height % blockInfo.height != 0) {
return DAWN_VALIDATION_ERROR(
"The size of the texture is incompatible with the texture format");
}
}
if (descriptor->dimension == wgpu::TextureDimension::e2D &&
descriptor->size.depth > kMaxTexture2DArrayLayers) {
@ -558,11 +561,10 @@ namespace dawn_native {
// 4 at non-zero mipmap levels.
if (mFormat.isCompressed) {
// TODO(jiawei.shao@intel.com): check if there are any overflows.
const TexelBlockInfo& blockInfo = mFormat.GetTexelBlockInfo(wgpu::TextureAspect::All);
uint32_t blockWidth = blockInfo.blockWidth;
uint32_t blockHeight = blockInfo.blockHeight;
extent.width = (extent.width + blockWidth - 1) / blockWidth * blockWidth;
extent.height = (extent.height + blockHeight - 1) / blockHeight * blockHeight;
const TexelBlockInfo& blockInfo = mFormat.GetAspectInfo(wgpu::TextureAspect::All).block;
extent.width = (extent.width + blockInfo.width - 1) / blockInfo.width * blockInfo.width;
extent.height =
(extent.height + blockInfo.height - 1) / blockInfo.height * blockInfo.height;
}
return extent;

View File

@ -770,7 +770,7 @@ namespace dawn_native { namespace d3d12 {
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst);
const TexelBlockInfo& blockInfo =
texture->GetFormat().GetTexelBlockInfo(copy->source.aspect);
texture->GetFormat().GetAspectInfo(copy->source.aspect).block;
// See comments around ComputeTextureCopySplits() for more details.
const TextureCopySplits copySplits = ComputeTextureCopySplits(

View File

@ -32,8 +32,8 @@ namespace dawn_native { namespace d3d12 {
uint32_t byteOffsetY = offset % slicePitch;
uint32_t byteOffsetZ = offset - byteOffsetY;
return {byteOffsetX / blockInfo.blockByteSize * blockInfo.blockWidth,
byteOffsetY / bytesPerRow * blockInfo.blockHeight, byteOffsetZ / slicePitch};
return {byteOffsetX / blockInfo.byteSize * blockInfo.width,
byteOffsetY / bytesPerRow * blockInfo.height, byteOffsetZ / slicePitch};
}
} // namespace
@ -45,7 +45,7 @@ namespace dawn_native { namespace d3d12 {
uint32_t rowsPerImage) {
Texture2DCopySplit copy;
ASSERT(bytesPerRow % blockInfo.blockByteSize == 0);
ASSERT(bytesPerRow % blockInfo.byteSize == 0);
uint64_t alignedOffset =
offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1);
@ -75,11 +75,9 @@ namespace dawn_native { namespace d3d12 {
Origin3D texelOffset = ComputeTexelOffsets(
blockInfo, static_cast<uint32_t>(offset - alignedOffset), bytesPerRow, slicePitch);
uint32_t copyBytesPerRowPitch =
copySize.width / blockInfo.blockWidth * blockInfo.blockByteSize;
uint32_t byteOffsetInRowPitch =
texelOffset.x / blockInfo.blockWidth * blockInfo.blockByteSize;
uint32_t rowsPerImageInTexels = rowsPerImage * blockInfo.blockHeight;
uint32_t copyBytesPerRowPitch = copySize.width / blockInfo.width * blockInfo.byteSize;
uint32_t byteOffsetInRowPitch = texelOffset.x / blockInfo.width * blockInfo.byteSize;
uint32_t rowsPerImageInTexels = rowsPerImage * blockInfo.height;
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
@ -157,7 +155,7 @@ namespace dawn_native { namespace d3d12 {
copy.copies[0].textureOffset = origin;
ASSERT(bytesPerRow > byteOffsetInRowPitch);
uint32_t texelsPerRow = bytesPerRow / blockInfo.blockByteSize * blockInfo.blockWidth;
uint32_t texelsPerRow = bytesPerRow / blockInfo.byteSize * blockInfo.width;
copy.copies[0].copySize.width = texelsPerRow - texelOffset.x;
copy.copies[0].copySize.height = copySize.height;
copy.copies[0].copySize.depth = copySize.depth;
@ -177,11 +175,10 @@ namespace dawn_native { namespace d3d12 {
copy.copies[1].copySize.depth = copySize.depth;
copy.copies[1].bufferOffset.x = 0;
copy.copies[1].bufferOffset.y = texelOffset.y + blockInfo.blockHeight;
copy.copies[1].bufferOffset.y = texelOffset.y + blockInfo.height;
copy.copies[1].bufferOffset.z = texelOffset.z;
copy.copies[1].bufferSize.width = copy.copies[1].copySize.width;
copy.copies[1].bufferSize.height =
rowsPerImageInTexels + texelOffset.y + blockInfo.blockHeight;
copy.copies[1].bufferSize.height = rowsPerImageInTexels + texelOffset.y + blockInfo.height;
copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z;
return copy;

View File

@ -947,12 +947,11 @@ namespace dawn_native { namespace d3d12 {
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, range);
for (Aspect aspect : IterateEnumMask(range.aspects)) {
const TexelBlockInfo& blockInfo = GetFormat().GetTexelBlockInfo(aspect);
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(aspect).block;
uint32_t bytesPerRow =
Align((GetWidth() / blockInfo.blockWidth) * blockInfo.blockByteSize,
uint32_t bytesPerRow = Align((GetWidth() / blockInfo.width) * blockInfo.byteSize,
kTextureBytesPerRowAlignment);
uint64_t bufferSize64 = bytesPerRow * (GetHeight() / blockInfo.blockHeight);
uint64_t bufferSize64 = bytesPerRow * (GetHeight() / blockInfo.height);
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
}
@ -962,7 +961,7 @@ namespace dawn_native { namespace d3d12 {
UploadHandle uploadHandle;
DAWN_TRY_ASSIGN(uploadHandle,
uploader->Allocate(bufferSize, device->GetPendingCommandSerial(),
blockInfo.blockByteSize));
blockInfo.byteSize));
memset(uploadHandle.mappedBuffer, clearColor, bufferSize);
for (uint32_t level = range.baseMipLevel;
@ -970,7 +969,7 @@ namespace dawn_native { namespace d3d12 {
// compute d3d12 texture copy locations for texture and buffer
Extent3D copySize = GetMipLevelVirtualSize(level);
uint32_t rowsPerImage = GetHeight() / blockInfo.blockHeight;
uint32_t rowsPerImage = GetHeight() / blockInfo.height;
Texture2DCopySplit copySplit = ComputeTextureCopySplit(
{0, 0, 0}, copySize, blockInfo, uploadHandle.startOffset, bytesPerRow,
rowsPerImage);

View File

@ -185,7 +185,7 @@ namespace dawn_native { namespace d3d12 {
Aspect aspect) {
ASSERT(HasOneBit(aspect));
// See comments in ComputeTextureCopySplits() for more details.
const TexelBlockInfo& blockInfo = texture->GetFormat().GetTexelBlockInfo(aspect);
const TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(aspect).block;
const TextureCopySplits copySplits = ComputeTextureCopySplits(
textureCopy.origin, copySize, blockInfo, offsetBytes, bytesPerRow, rowsPerImage);

View File

@ -297,12 +297,10 @@ namespace dawn_native { namespace metal {
// This function assumes data is perfectly aligned. Otherwise, it might be necessary
// to split copying to several stages: see ComputeTextureBufferCopySplit.
const TexelBlockInfo& blockInfo = texture->GetFormat().GetTexelBlockInfo(dst->aspect);
uint32_t blockSize = blockInfo.blockByteSize;
uint32_t blockWidth = blockInfo.blockWidth;
uint32_t blockHeight = blockInfo.blockHeight;
ASSERT(dataLayout.rowsPerImage == copySizePixels.height / blockHeight);
ASSERT(dataLayout.bytesPerRow == copySizePixels.width / blockWidth * blockSize);
const TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(dst->aspect).block;
ASSERT(dataLayout.rowsPerImage == copySizePixels.height / blockInfo.height);
ASSERT(dataLayout.bytesPerRow ==
copySizePixels.width / blockInfo.width * blockInfo.byteSize);
EnsureDestinationTextureInitialized(texture, *dst, copySizePixels);

View File

@ -491,16 +491,16 @@ namespace dawn_native { namespace metal {
// Compute the buffer size big enough to fill the largest mip.
Extent3D largestMipSize = GetMipLevelVirtualSize(range.baseMipLevel);
const TexelBlockInfo& blockInfo =
GetFormat().GetTexelBlockInfo(wgpu::TextureAspect::All);
GetFormat().GetAspectInfo(wgpu::TextureAspect::All).block;
// Metal validation layers: sourceBytesPerRow must be at least 64.
uint32_t largestMipBytesPerRow = std::max(
(largestMipSize.width / blockInfo.blockWidth) * blockInfo.blockByteSize, 64u);
uint32_t largestMipBytesPerRow =
std::max((largestMipSize.width / blockInfo.width) * blockInfo.byteSize, 64u);
// Metal validation layers: sourceBytesPerImage must be at least 512.
uint64_t largestMipBytesPerImage =
std::max(static_cast<uint64_t>(largestMipBytesPerRow) *
(largestMipSize.height / blockInfo.blockHeight),
(largestMipSize.height / blockInfo.height),
512llu);
// TODO(enga): Multiply by largestMipSize.depth and do a larger 3D copy to clear a whole
@ -515,7 +515,7 @@ namespace dawn_native { namespace metal {
UploadHandle uploadHandle;
DAWN_TRY_ASSIGN(uploadHandle,
uploader->Allocate(bufferSize, device->GetPendingCommandSerial(),
blockInfo.blockByteSize));
blockInfo.byteSize));
memset(uploadHandle.mappedBuffer, clearColor, bufferSize);
id<MTLBlitCommandEncoder> encoder = commandContext->EnsureBlit();

View File

@ -54,7 +54,7 @@ namespace dawn_native { namespace metal {
Aspect aspect) {
TextureBufferCopySplit copy;
const Format textureFormat = texture->GetFormat();
const TexelBlockInfo& blockInfo = textureFormat.GetTexelBlockInfo(aspect);
const TexelBlockInfo& blockInfo = textureFormat.GetAspectInfo(aspect).block;
// 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
@ -115,7 +115,7 @@ namespace dawn_native { namespace metal {
}
// Doing all the copy in last image except the last row.
uint32_t copyBlockRowCount = copyExtent.height / blockInfo.blockHeight;
uint32_t copyBlockRowCount = copyExtent.height / blockInfo.height;
if (copyBlockRowCount > 1) {
copy.copies[copy.count].bufferOffset = currentOffset;
copy.copies[copy.count].bytesPerRow = bytesPerRow;
@ -123,10 +123,10 @@ namespace dawn_native { namespace metal {
copy.copies[copy.count].textureOrigin = {origin.x, origin.y,
origin.z + copyExtent.depth - 1};
ASSERT(copyExtent.height - blockInfo.blockHeight <
ASSERT(copyExtent.height - blockInfo.height <
texture->GetMipLevelVirtualSize(mipLevel).height);
copy.copies[copy.count].copyExtent = {clampedCopyExtent.width,
copyExtent.height - blockInfo.blockHeight, 1};
copyExtent.height - blockInfo.height, 1};
++copy.count;
@ -136,17 +136,16 @@ namespace dawn_native { namespace metal {
// Doing the last row copy with the exact number of bytes in last row.
// Workaround this issue in a way just like the copy to a 1D texture.
uint32_t lastRowDataSize =
(copyExtent.width / blockInfo.blockWidth) * blockInfo.blockByteSize;
uint32_t lastRowDataSize = (copyExtent.width / blockInfo.width) * blockInfo.byteSize;
uint32_t lastRowCopyExtentHeight =
blockInfo.blockHeight + clampedCopyExtent.height - copyExtent.height;
ASSERT(lastRowCopyExtentHeight <= blockInfo.blockHeight);
blockInfo.height + clampedCopyExtent.height - copyExtent.height;
ASSERT(lastRowCopyExtentHeight <= blockInfo.height);
copy.copies[copy.count].bufferOffset = currentOffset;
copy.copies[copy.count].bytesPerRow = lastRowDataSize;
copy.copies[copy.count].bytesPerImage = lastRowDataSize;
copy.copies[copy.count].textureOrigin = {
origin.x, origin.y + copyExtent.height - blockInfo.blockHeight,
copy.copies[copy.count].textureOrigin = {origin.x,
origin.y + copyExtent.height - blockInfo.height,
origin.z + copyExtent.depth - 1};
copy.copies[copy.count].copyExtent = {clampedCopyExtent.width, lastRowCopyExtentHeight, 1};
++copy.count;

View File

@ -531,22 +531,21 @@ namespace dawn_native { namespace opengl {
gl.BindTexture(target, texture->GetHandle());
const Format& formatInfo = texture->GetFormat();
const TexelBlockInfo& blockInfo = formatInfo.GetTexelBlockInfo(dst.aspect);
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, src.bytesPerRow / blockInfo.blockByteSize *
blockInfo.blockWidth);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
src.rowsPerImage * blockInfo.blockHeight);
const TexelBlockInfo& blockInfo = formatInfo.GetAspectInfo(dst.aspect).block;
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
src.bytesPerRow / blockInfo.byteSize * blockInfo.width);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage * blockInfo.height);
if (formatInfo.isCompressed) {
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.blockByteSize);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.blockWidth);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.blockHeight);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
uint64_t copyDataSize = (copySize.width / blockInfo.blockWidth) *
(copySize.height / blockInfo.blockHeight) *
blockInfo.blockByteSize * copySize.depth;
uint64_t copyDataSize = (copySize.width / blockInfo.width) *
(copySize.height / blockInfo.height) *
blockInfo.byteSize * copySize.depth;
Extent3D copyExtent = ComputeTextureCopyExtent(dst, copySize);
if (texture->GetArrayLayers() > 1) {
@ -624,11 +623,11 @@ namespace dawn_native { namespace opengl {
gl.GenFramebuffers(1, &readFBO);
gl.BindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
const TexelBlockInfo& blockInfo = formatInfo.GetTexelBlockInfo(src.aspect);
const TexelBlockInfo& blockInfo = formatInfo.GetAspectInfo(src.aspect).block;
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage * blockInfo.blockHeight);
gl.PixelStorei(GL_PACK_ROW_LENGTH, dst.bytesPerRow / blockInfo.blockByteSize);
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage * blockInfo.height);
gl.PixelStorei(GL_PACK_ROW_LENGTH, dst.bytesPerRow / blockInfo.byteSize);
GLenum glAttachment;
GLenum glFormat;

View File

@ -294,8 +294,8 @@ namespace dawn_native { namespace opengl {
ASSERT(range.aspects == Aspect::Color);
static constexpr uint32_t MAX_TEXEL_SIZE = 16;
const TexelBlockInfo& blockInfo = GetFormat().GetTexelBlockInfo(Aspect::Color);
ASSERT(blockInfo.blockByteSize <= MAX_TEXEL_SIZE);
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(Aspect::Color).block;
ASSERT(blockInfo.byteSize <= MAX_TEXEL_SIZE);
std::array<GLbyte, MAX_TEXEL_SIZE> clearColorData;
clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 255;
@ -324,20 +324,19 @@ namespace dawn_native { namespace opengl {
ASSERT(range.aspects == Aspect::Color);
// create temp buffer with clear color to copy to the texture image
const TexelBlockInfo& blockInfo = GetFormat().GetTexelBlockInfo(Aspect::Color);
ASSERT(kTextureBytesPerRowAlignment % blockInfo.blockByteSize == 0);
uint32_t bytesPerRow =
Align((GetWidth() / blockInfo.blockWidth) * blockInfo.blockByteSize,
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(Aspect::Color).block;
ASSERT(kTextureBytesPerRowAlignment % blockInfo.byteSize == 0);
uint32_t bytesPerRow = Align((GetWidth() / blockInfo.width) * blockInfo.byteSize,
kTextureBytesPerRowAlignment);
// Make sure that we are not rounding
ASSERT(bytesPerRow % blockInfo.blockByteSize == 0);
ASSERT(GetHeight() % blockInfo.blockHeight == 0);
ASSERT(bytesPerRow % blockInfo.byteSize == 0);
ASSERT(GetHeight() % blockInfo.height == 0);
dawn_native::BufferDescriptor descriptor = {};
descriptor.mappedAtCreation = true;
descriptor.usage = wgpu::BufferUsage::CopySrc;
descriptor.size = bytesPerRow * (GetHeight() / blockInfo.blockHeight);
descriptor.size = bytesPerRow * (GetHeight() / blockInfo.height);
if (descriptor.size > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
}
@ -353,7 +352,7 @@ namespace dawn_native { namespace opengl {
// Bind buffer and texture, and make the buffer to texture copy
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
(bytesPerRow / blockInfo.blockByteSize) * blockInfo.blockWidth);
(bytesPerRow / blockInfo.byteSize) * blockInfo.width);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {

View File

@ -436,15 +436,15 @@ namespace dawn_native { namespace vulkan {
ASSERT(srcCopy.texture->GetFormat().format == dstCopy.texture->GetFormat().format);
ASSERT(srcCopy.aspect == dstCopy.aspect);
dawn_native::Format format = srcCopy.texture->GetFormat();
const TexelBlockInfo& blockInfo = format.GetTexelBlockInfo(srcCopy.aspect);
ASSERT(copySize.width % blockInfo.blockWidth == 0);
uint32_t widthInBlocks = copySize.width / blockInfo.blockWidth;
ASSERT(copySize.height % blockInfo.blockHeight == 0);
uint32_t heightInBlocks = copySize.height / blockInfo.blockHeight;
const TexelBlockInfo& blockInfo = format.GetAspectInfo(srcCopy.aspect).block;
ASSERT(copySize.width % blockInfo.width == 0);
uint32_t widthInBlocks = copySize.width / blockInfo.width;
ASSERT(copySize.height % blockInfo.height == 0);
uint32_t heightInBlocks = copySize.height / blockInfo.height;
// Create the temporary buffer. Note that We don't need to respect WebGPU's 256 alignment
// because it isn't a hard constraint in Vulkan.
uint64_t tempBufferSize = widthInBlocks * heightInBlocks * blockInfo.blockByteSize;
uint64_t tempBufferSize = widthInBlocks * heightInBlocks * blockInfo.byteSize;
BufferDescriptor tempBufferDescriptor;
tempBufferDescriptor.size = tempBufferSize;
tempBufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
@ -456,8 +456,7 @@ namespace dawn_native { namespace vulkan {
tempBufferCopy.buffer = tempBuffer.Get();
tempBufferCopy.rowsPerImage = heightInBlocks;
tempBufferCopy.offset = 0;
tempBufferCopy.bytesPerRow =
copySize.width / blockInfo.blockWidth * blockInfo.blockByteSize;
tempBufferCopy.bytesPerRow = copySize.width / blockInfo.width * blockInfo.byteSize;
VkCommandBuffer commands = recordingContext->commandBuffer;
VkImage srcImage = ToBackend(srcCopy.texture)->GetHandle();

View File

@ -108,11 +108,10 @@ namespace dawn_native { namespace vulkan {
region.bufferOffset = dataLayout.offset;
// In Vulkan the row length is in texels while it is in bytes for Dawn
const TexelBlockInfo& blockInfo =
texture->GetFormat().GetTexelBlockInfo(textureCopy.aspect);
ASSERT(dataLayout.bytesPerRow % blockInfo.blockByteSize == 0);
region.bufferRowLength =
dataLayout.bytesPerRow / blockInfo.blockByteSize * blockInfo.blockWidth;
region.bufferImageHeight = dataLayout.rowsPerImage * blockInfo.blockHeight;
texture->GetFormat().GetAspectInfo(textureCopy.aspect).block;
ASSERT(dataLayout.bytesPerRow % blockInfo.byteSize == 0);
region.bufferRowLength = dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width;
region.bufferImageHeight = dataLayout.rowsPerImage * blockInfo.height;
region.imageSubresource.aspectMask = VulkanAspectMask(textureCopy.aspect);
region.imageSubresource.mipLevel = textureCopy.mipLevel;

View File

@ -291,9 +291,9 @@ class CopySplitTest : public testing::Test {
ASSERT(textureSpec.width % textureSpec.blockWidth == 0 &&
textureSpec.height % textureSpec.blockHeight == 0);
dawn_native::TexelBlockInfo blockInfo = {};
blockInfo.blockWidth = textureSpec.blockWidth;
blockInfo.blockHeight = textureSpec.blockHeight;
blockInfo.blockByteSize = textureSpec.texelBlockSizeInBytes;
blockInfo.width = textureSpec.blockWidth;
blockInfo.height = textureSpec.blockHeight;
blockInfo.byteSize = textureSpec.texelBlockSizeInBytes;
Texture2DCopySplit copySplit = ComputeTextureCopySplit(
{textureSpec.x, textureSpec.y, textureSpec.z},
{textureSpec.width, textureSpec.height, textureSpec.depth}, blockInfo,