Texture: Change to mArrayLayerCount to mSize.depth

This makes the tracking in TextureBase match the shape of
wgpu::TextureDescriptor.

GetSize() becomes a bit more surprising because the depth can sometimes
be the array size, so new getters GetWidth(), GetHeight() and GetDepth()
are added.

Some simplifications to the backend texture creation code are included
that will make it less error prone to add support for 1D / 3D textures.

Bug: dawn:22

Change-Id: I33b6ca99af9d58fc88f5f626cfd5e2e62a8b45cb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23103
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2020-06-15 09:57:51 +00:00 committed by Commit Bot service account
parent 4234d78201
commit 8a5325ca9a
8 changed files with 100 additions and 102 deletions

View File

@ -372,17 +372,10 @@ namespace dawn_native {
mDimension(descriptor->dimension), mDimension(descriptor->dimension),
mFormat(device->GetValidInternalFormat(descriptor->format)), mFormat(device->GetValidInternalFormat(descriptor->format)),
mSize(descriptor->size), mSize(descriptor->size),
mArrayLayerCount(descriptor->size.depth),
mMipLevelCount(descriptor->mipLevelCount), mMipLevelCount(descriptor->mipLevelCount),
mSampleCount(descriptor->sampleCount), mSampleCount(descriptor->sampleCount),
mUsage(descriptor->usage), mUsage(descriptor->usage),
mState(state) { mState(state) {
// TODO(cwallez@chromium.org): Store the array layers in size.depth instead if extracting it
// in mArrayLayerCount.
ASSERT(mDimension == wgpu::TextureDimension::e2D);
mArrayLayerCount = mSize.depth;
mSize.depth = 1;
uint32_t subresourceCount = GetSubresourceCount(); uint32_t subresourceCount = GetSubresourceCount();
mIsSubresourceContentInitializedAtIndex = std::vector<bool>(subresourceCount, false); mIsSubresourceContentInitializedAtIndex = std::vector<bool>(subresourceCount, false);
@ -418,9 +411,26 @@ namespace dawn_native {
ASSERT(!IsError()); ASSERT(!IsError());
return mSize; return mSize;
} }
uint32_t TextureBase::GetWidth() const {
ASSERT(!IsError());
return mSize.width;
}
uint32_t TextureBase::GetHeight() const {
ASSERT(!IsError());
ASSERT(mDimension == wgpu::TextureDimension::e2D ||
mDimension == wgpu::TextureDimension::e3D);
return mSize.height;
}
uint32_t TextureBase::GetDepth() const {
ASSERT(!IsError());
ASSERT(mDimension == wgpu::TextureDimension::e3D);
return mSize.depth;
}
uint32_t TextureBase::GetArrayLayers() const { uint32_t TextureBase::GetArrayLayers() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mArrayLayerCount; // TODO(cwallez@chromium.org): Update for 1D / 3D textures when they are supported.
ASSERT(mDimension == wgpu::TextureDimension::e2D);
return mSize.depth;
} }
uint32_t TextureBase::GetNumMipLevels() const { uint32_t TextureBase::GetNumMipLevels() const {
ASSERT(!IsError()); ASSERT(!IsError());
@ -428,7 +438,7 @@ namespace dawn_native {
} }
SubresourceRange TextureBase::GetAllSubresources() const { SubresourceRange TextureBase::GetAllSubresources() const {
ASSERT(!IsError()); ASSERT(!IsError());
return {0, mMipLevelCount, 0, mArrayLayerCount}; return {0, mMipLevelCount, 0, GetArrayLayers()};
} }
uint32_t TextureBase::GetSampleCount() const { uint32_t TextureBase::GetSampleCount() const {
ASSERT(!IsError()); ASSERT(!IsError());
@ -436,7 +446,7 @@ namespace dawn_native {
} }
uint32_t TextureBase::GetSubresourceCount() const { uint32_t TextureBase::GetSubresourceCount() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mMipLevelCount * mArrayLayerCount; return mMipLevelCount * mSize.depth;
} }
wgpu::TextureUsage TextureBase::GetUsage() const { wgpu::TextureUsage TextureBase::GetUsage() const {
ASSERT(!IsError()); ASSERT(!IsError());
@ -501,9 +511,16 @@ namespace dawn_native {
} }
Extent3D TextureBase::GetMipLevelVirtualSize(uint32_t level) const { Extent3D TextureBase::GetMipLevelVirtualSize(uint32_t level) const {
Extent3D extent; Extent3D extent = {std::max(mSize.width >> level, 1u), 1u, 1u};
extent.width = std::max(mSize.width >> level, 1u); if (mDimension == wgpu::TextureDimension::e1D) {
return extent;
}
extent.height = std::max(mSize.height >> level, 1u); extent.height = std::max(mSize.height >> level, 1u);
if (mDimension == wgpu::TextureDimension::e2D) {
return extent;
}
extent.depth = std::max(mSize.depth >> level, 1u); extent.depth = std::max(mSize.depth >> level, 1u);
return extent; return extent;
} }

View File

@ -66,6 +66,9 @@ namespace dawn_native {
wgpu::TextureDimension GetDimension() const; wgpu::TextureDimension GetDimension() const;
const Format& GetFormat() const; const Format& GetFormat() const;
const Extent3D& GetSize() const; const Extent3D& GetSize() const;
uint32_t GetWidth() const;
uint32_t GetHeight() const;
uint32_t GetDepth() const;
uint32_t GetArrayLayers() const; uint32_t GetArrayLayers() const;
uint32_t GetNumMipLevels() const; uint32_t GetNumMipLevels() const;
SubresourceRange GetAllSubresources() const; SubresourceRange GetAllSubresources() const;
@ -105,7 +108,6 @@ namespace dawn_native {
// TODO(cwallez@chromium.org): This should be deduplicated in the Device // TODO(cwallez@chromium.org): This should be deduplicated in the Device
const Format& mFormat; const Format& mFormat;
Extent3D mSize; Extent3D mSize;
uint32_t mArrayLayerCount;
uint32_t mMipLevelCount; uint32_t mMipLevelCount;
uint32_t mSampleCount; uint32_t mSampleCount;
wgpu::TextureUsage mUsage = wgpu::TextureUsage::None; wgpu::TextureUsage mUsage = wgpu::TextureUsage::None;

View File

@ -63,17 +63,6 @@ namespace dawn_native { namespace d3d12 {
const Extent3D& srcSize = src->GetSize(); const Extent3D& srcSize = src->GetSize();
const Extent3D& dstSize = dst->GetSize(); const Extent3D& dstSize = dst->GetSize();
auto GetCopyDepth = [](const Texture* texture) {
switch (texture->GetDimension()) {
case wgpu::TextureDimension::e1D:
return 1u;
case wgpu::TextureDimension::e2D:
return texture->GetArrayLayers();
case wgpu::TextureDimension::e3D:
return texture->GetSize().depth;
}
};
// https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-copyresource // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-copyresource
// In order to use D3D12's copy resource, the textures must be the same dimensions, and // In order to use D3D12's copy resource, the textures must be the same dimensions, and
// the copy must be of the entire resource. // the copy must be of the entire resource.
@ -87,8 +76,8 @@ namespace dawn_native { namespace d3d12 {
copySize.width == srcSize.width && // copySize.width == srcSize.width && //
copySize.height == dstSize.height && // copySize.height == dstSize.height && //
copySize.height == srcSize.height && // copySize.height == srcSize.height && //
copySize.depth == GetCopyDepth(src) && // copySize.depth == dstSize.depth && //
copySize.depth == GetCopyDepth(dst); copySize.depth == srcSize.depth;
} }
} // anonymous namespace } // anonymous namespace

View File

@ -452,6 +452,7 @@ namespace dawn_native { namespace d3d12 {
const Extent3D& size = GetSize(); const Extent3D& size = GetSize();
resourceDescriptor.Width = size.width; resourceDescriptor.Width = size.width;
resourceDescriptor.Height = size.height; resourceDescriptor.Height = size.height;
resourceDescriptor.DepthOrArraySize = size.depth;
// This will need to be much more nuanced when WebGPU has // This will need to be much more nuanced when WebGPU has
// texture view compatibility rules. // texture view compatibility rules.
@ -462,7 +463,6 @@ namespace dawn_native { namespace d3d12 {
? D3D12TypelessTextureFormat(GetFormat().format) ? D3D12TypelessTextureFormat(GetFormat().format)
: D3D12TextureFormat(GetFormat().format); : D3D12TextureFormat(GetFormat().format);
resourceDescriptor.DepthOrArraySize = GetDepthOrArraySize();
resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels()); resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
resourceDescriptor.Format = dxgiFormat; resourceDescriptor.Format = dxgiFormat;
resourceDescriptor.SampleDesc.Count = GetSampleCount(); resourceDescriptor.SampleDesc.Count = GetSampleCount();
@ -547,15 +547,6 @@ namespace dawn_native { namespace d3d12 {
return mResourceAllocation.GetD3D12Resource().Get(); return mResourceAllocation.GetD3D12Resource().Get();
} }
UINT16 Texture::GetDepthOrArraySize() {
switch (GetDimension()) {
case wgpu::TextureDimension::e2D:
return static_cast<UINT16>(GetArrayLayers());
default:
UNREACHABLE();
}
}
void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext, void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
wgpu::TextureUsage usage, wgpu::TextureUsage usage,
uint32_t mipLevel, uint32_t mipLevel,
@ -878,9 +869,9 @@ namespace dawn_native { namespace d3d12 {
// TODO(natlee@microsoft.com): test compressed textures are cleared // TODO(natlee@microsoft.com): test compressed textures are cleared
// create temp buffer with clear color to copy to the texture image // create temp buffer with clear color to copy to the texture image
uint32_t bytesPerRow = uint32_t bytesPerRow =
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize, Align((GetWidth() / GetFormat().blockWidth) * GetFormat().blockByteSize,
kTextureBytesPerRowAlignment); kTextureBytesPerRowAlignment);
uint64_t bufferSize64 = bytesPerRow * (GetSize().height / GetFormat().blockHeight); uint64_t bufferSize64 = bytesPerRow * (GetHeight() / GetFormat().blockHeight);
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) { if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
} }
@ -900,7 +891,7 @@ namespace dawn_native { namespace d3d12 {
// compute d3d12 texture copy locations for texture and buffer // compute d3d12 texture copy locations for texture and buffer
Extent3D copySize = GetMipLevelVirtualSize(level); Extent3D copySize = GetMipLevelVirtualSize(level);
uint32_t rowsPerImage = GetSize().height; uint32_t rowsPerImage = GetHeight();
TextureCopySplit copySplit = TextureCopySplit copySplit =
ComputeTextureCopySplit({0, 0, 0}, copySize, GetFormat(), ComputeTextureCopySplit({0, 0, 0}, copySize, GetFormat(),
uploadHandle.startOffset, bytesPerRow, rowsPerImage); uploadHandle.startOffset, bytesPerRow, rowsPerImage);

View File

@ -95,8 +95,6 @@ namespace dawn_native { namespace d3d12 {
const SubresourceRange& range, const SubresourceRange& range,
TextureBase::ClearValue clearValue); TextureBase::ClearValue clearValue);
UINT16 GetDepthOrArraySize();
void TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext, void TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
std::vector<D3D12_RESOURCE_BARRIER>* barrier, std::vector<D3D12_RESOURCE_BARRIER>* barrier,
D3D12_RESOURCE_STATES newState, D3D12_RESOURCE_STATES newState,

View File

@ -54,22 +54,6 @@ namespace dawn_native { namespace metal {
return result; return result;
} }
MTLTextureType MetalTextureType(wgpu::TextureDimension dimension,
unsigned int arrayLayers,
unsigned int sampleCount) {
switch (dimension) {
case wgpu::TextureDimension::e2D:
if (sampleCount > 1) {
ASSERT(arrayLayers == 1);
return MTLTextureType2DMultisample;
} else {
return (arrayLayers > 1) ? MTLTextureType2DArray : MTLTextureType2D;
}
default:
UNREACHABLE();
}
}
MTLTextureType MetalTextureViewType(wgpu::TextureViewDimension dimension, MTLTextureType MetalTextureViewType(wgpu::TextureViewDimension dimension,
unsigned int sampleCount) { unsigned int sampleCount) {
switch (dimension) { switch (dimension) {
@ -301,21 +285,38 @@ namespace dawn_native { namespace metal {
MTLTextureDescriptor* CreateMetalTextureDescriptor(const TextureDescriptor* descriptor) { MTLTextureDescriptor* CreateMetalTextureDescriptor(const TextureDescriptor* descriptor) {
MTLTextureDescriptor* mtlDesc = [MTLTextureDescriptor new]; MTLTextureDescriptor* mtlDesc = [MTLTextureDescriptor new];
mtlDesc.textureType = MetalTextureType(descriptor->dimension, descriptor->size.depth,
descriptor->sampleCount);
mtlDesc.usage = MetalTextureUsage(descriptor->usage);
mtlDesc.pixelFormat = MetalPixelFormat(descriptor->format);
mtlDesc.width = descriptor->size.width; mtlDesc.width = descriptor->size.width;
mtlDesc.height = descriptor->size.height; mtlDesc.height = descriptor->size.height;
ASSERT(descriptor->dimension == wgpu::TextureDimension::e2D); mtlDesc.sampleCount = descriptor->sampleCount;
mtlDesc.depth = 1; mtlDesc.usage = MetalTextureUsage(descriptor->usage);
mtlDesc.pixelFormat = MetalPixelFormat(descriptor->format);
mtlDesc.mipmapLevelCount = descriptor->mipLevelCount; mtlDesc.mipmapLevelCount = descriptor->mipLevelCount;
mtlDesc.arrayLength = descriptor->size.depth;
mtlDesc.storageMode = MTLStorageModePrivate; mtlDesc.storageMode = MTLStorageModePrivate;
mtlDesc.sampleCount = descriptor->sampleCount; // Choose the correct MTLTextureType and paper over differences in how the array layer count
// is specified.
mtlDesc.depth = descriptor->size.depth;
mtlDesc.arrayLength = 1;
switch (descriptor->dimension) {
case wgpu::TextureDimension::e2D:
if (mtlDesc.depth > 1) {
ASSERT(mtlDesc.sampleCount == 1);
mtlDesc.textureType = MTLTextureType2DArray;
mtlDesc.arrayLength = mtlDesc.depth;
mtlDesc.depth = 1;
} else {
if (mtlDesc.sampleCount > 1) {
mtlDesc.textureType = MTLTextureType2DMultisample;
} else {
mtlDesc.textureType = MTLTextureType2D;
}
}
break;
default:
UNREACHABLE();
}
return mtlDesc; return mtlDesc;
} }

View File

@ -108,8 +108,8 @@ namespace dawn_native { namespace opengl {
: Texture(device, descriptor, GenTexture(device->gl), TextureState::OwnedInternal) { : Texture(device, descriptor, GenTexture(device->gl), TextureState::OwnedInternal) {
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
uint32_t width = GetSize().width; uint32_t width = GetWidth();
uint32_t height = GetSize().height; uint32_t height = GetHeight();
uint32_t levels = GetNumMipLevels(); uint32_t levels = GetNumMipLevels();
uint32_t arrayLayers = GetArrayLayers(); uint32_t arrayLayers = GetArrayLayers();
uint32_t sampleCount = GetSampleCount(); uint32_t sampleCount = GetSampleCount();
@ -292,15 +292,15 @@ namespace dawn_native { namespace opengl {
// create temp buffer with clear color to copy to the texture image // create temp buffer with clear color to copy to the texture image
ASSERT(kTextureBytesPerRowAlignment % GetFormat().blockByteSize == 0); ASSERT(kTextureBytesPerRowAlignment % GetFormat().blockByteSize == 0);
uint32_t bytesPerRow = uint32_t bytesPerRow =
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize, Align((GetWidth() / GetFormat().blockWidth) * GetFormat().blockByteSize,
kTextureBytesPerRowAlignment); kTextureBytesPerRowAlignment);
// Make sure that we are not rounding // Make sure that we are not rounding
ASSERT(bytesPerRow % GetFormat().blockByteSize == 0); ASSERT(bytesPerRow % GetFormat().blockByteSize == 0);
ASSERT(GetSize().height % GetFormat().blockHeight == 0); ASSERT(GetHeight() % GetFormat().blockHeight == 0);
dawn_native::BufferDescriptor descriptor; dawn_native::BufferDescriptor descriptor;
descriptor.size = bytesPerRow * (GetSize().height / GetFormat().blockHeight); descriptor.size = bytesPerRow * (GetHeight() / GetFormat().blockHeight);
if (descriptor.size > std::numeric_limits<uint32_t>::max()) { if (descriptor.size > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
} }

View File

@ -32,18 +32,6 @@
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {
namespace { namespace {
// Converts an Dawn texture dimension to a Vulkan image type.
// Note that in Vulkan dimensionality is only 1D, 2D, 3D. Arrays and cube maps are expressed
// via the array size and a "cubemap compatible" flag.
VkImageType VulkanImageType(wgpu::TextureDimension dimension) {
switch (dimension) {
case wgpu::TextureDimension::e2D:
return VK_IMAGE_TYPE_2D;
default:
UNREACHABLE();
}
}
// Converts an Dawn texture dimension to a Vulkan image view type. // Converts an Dawn texture dimension to a Vulkan image view type.
// Contrary to image types, image view types include arrayness and cubemapness // Contrary to image types, image view types include arrayness and cubemapness
VkImageViewType VulkanImageViewType(wgpu::TextureViewDimension dimension) { VkImageViewType VulkanImageViewType(wgpu::TextureViewDimension dimension) {
@ -221,10 +209,6 @@ namespace dawn_native { namespace vulkan {
} }
} }
VkExtent3D VulkanExtent3D(const Extent3D& extent) {
return {extent.width, extent.height, extent.depth};
}
VkImageMemoryBarrier BuildMemoryBarrier(const Format& format, VkImageMemoryBarrier BuildMemoryBarrier(const Format& format,
const VkImage& image, const VkImage& image,
wgpu::TextureUsage lastUsage, wgpu::TextureUsage lastUsage,
@ -252,6 +236,27 @@ namespace dawn_native { namespace vulkan {
return barrier; return barrier;
} }
void FillVulkanCreateInfoSizesAndType(const Texture& texture, VkImageCreateInfo* info) {
const Extent3D& size = texture.GetSize();
info->mipLevels = texture.GetNumMipLevels();
info->samples = VulkanSampleCount(texture.GetSampleCount());
// Fill in the image type, and paper over differences in how the array layer count is
// specified between WebGPU and Vulkan.
switch (texture.GetDimension()) {
case wgpu::TextureDimension::e2D:
info->imageType = VK_IMAGE_TYPE_2D;
info->extent = {size.width, size.height, 1};
info->arrayLayers = size.depth;
break;
default:
UNREACHABLE();
break;
}
}
} // namespace } // namespace
// Converts Dawn texture format to Vulkan formats. // Converts Dawn texture format to Vulkan formats.
@ -495,15 +500,12 @@ namespace dawn_native { namespace vulkan {
// combination of sample, usage etc. because validation should have been done in the Dawn // combination of sample, usage etc. because validation should have been done in the Dawn
// frontend already based on the minimum supported formats in the Vulkan spec // frontend already based on the minimum supported formats in the Vulkan spec
VkImageCreateInfo createInfo = {}; VkImageCreateInfo createInfo = {};
FillVulkanCreateInfoSizesAndType(*this, &createInfo);
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.imageType = VulkanImageType(GetDimension());
createInfo.format = VulkanImageFormat(device, GetFormat().format); createInfo.format = VulkanImageFormat(device, GetFormat().format);
createInfo.extent = VulkanExtent3D(GetSize());
createInfo.mipLevels = GetNumMipLevels();
createInfo.arrayLayers = GetArrayLayers();
createInfo.samples = VulkanSampleCount(GetSampleCount());
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL; createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat()); createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat());
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
@ -513,7 +515,7 @@ namespace dawn_native { namespace vulkan {
ASSERT(IsSampleCountSupported(device, createInfo)); ASSERT(IsSampleCountSupported(device, createInfo));
if (GetArrayLayers() >= 6 && GetSize().width == GetSize().height) { if (GetArrayLayers() >= 6 && GetWidth() == GetHeight()) {
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
} }
@ -556,15 +558,13 @@ namespace dawn_native { namespace vulkan {
} }
mExternalState = ExternalState::PendingAcquire; mExternalState = ExternalState::PendingAcquire;
VkImageCreateInfo baseCreateInfo = {}; VkImageCreateInfo baseCreateInfo = {};
FillVulkanCreateInfoSizesAndType(*this, &baseCreateInfo);
baseCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; baseCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
baseCreateInfo.pNext = nullptr; baseCreateInfo.pNext = nullptr;
baseCreateInfo.imageType = VulkanImageType(GetDimension());
baseCreateInfo.format = format; baseCreateInfo.format = format;
baseCreateInfo.extent = VulkanExtent3D(GetSize());
baseCreateInfo.mipLevels = GetNumMipLevels();
baseCreateInfo.arrayLayers = GetArrayLayers();
baseCreateInfo.samples = VulkanSampleCount(GetSampleCount());
baseCreateInfo.usage = usage; baseCreateInfo.usage = usage;
baseCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; baseCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
baseCreateInfo.queueFamilyIndexCount = 0; baseCreateInfo.queueFamilyIndexCount = 0;
@ -909,9 +909,9 @@ namespace dawn_native { namespace vulkan {
// TODO(natlee@microsoft.com): test compressed textures are cleared // TODO(natlee@microsoft.com): test compressed textures are cleared
// create temp buffer with clear color to copy to the texture image // create temp buffer with clear color to copy to the texture image
uint32_t bytesPerRow = uint32_t bytesPerRow =
Align((GetSize().width / GetFormat().blockWidth) * GetFormat().blockByteSize, Align((GetWidth() / GetFormat().blockWidth) * GetFormat().blockByteSize,
kTextureBytesPerRowAlignment); kTextureBytesPerRowAlignment);
uint64_t bufferSize64 = bytesPerRow * (GetSize().height / GetFormat().blockHeight); uint64_t bufferSize64 = bytesPerRow * (GetHeight() / GetFormat().blockHeight);
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) { if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
} }