Pass Aspect to TextureBase::GetSize for multiplanar sizes.
Bug: dawn:2099
Change-Id: Ie25ee6686f0ccfcfd33116c1d6316d671c91a36c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/154760
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Austin Eng <enga@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Quyen Le <lehoangquyen@chromium.org>
diff --git a/src/dawn/native/CommandBuffer.cpp b/src/dawn/native/CommandBuffer.cpp
index 06a12f6..9bfc06d 100644
--- a/src/dawn/native/CommandBuffer.cpp
+++ b/src/dawn/native/CommandBuffer.cpp
@@ -91,9 +91,12 @@
}
bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
- const Extent3D copySize,
- const uint32_t mipLevel) {
- Extent3D extent = texture->GetMipLevelSingleSubresourcePhysicalSize(mipLevel);
+ const Extent3D& copySize,
+ const uint32_t mipLevel,
+ Aspect aspect) {
+ DAWN_ASSERT(HasOneBit(aspect) || aspect == (Aspect::Depth | Aspect::Stencil));
+
+ Extent3D extent = texture->GetMipLevelSingleSubresourcePhysicalSize(mipLevel, aspect);
switch (texture->GetDimension()) {
case wgpu::TextureDimension::e1D:
@@ -108,6 +111,14 @@
DAWN_UNREACHABLE();
}
+bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
+ const Extent3D& copySize,
+ const uint32_t mipLevel,
+ wgpu::TextureAspect textureAspect) {
+ auto aspect = SelectFormatAspects(texture->GetFormat(), textureAspect);
+ return IsCompleteSubresourceCopiedTo(texture, copySize, mipLevel, aspect);
+}
+
SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy, const Extent3D& copySize) {
switch (copy.texture->GetDimension()) {
case wgpu::TextureDimension::e1D:
diff --git a/src/dawn/native/CommandBuffer.h b/src/dawn/native/CommandBuffer.h
index 12a81b3..a64c6da 100644
--- a/src/dawn/native/CommandBuffer.h
+++ b/src/dawn/native/CommandBuffer.h
@@ -64,8 +64,13 @@
};
bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
- const Extent3D copySize,
- const uint32_t mipLevel);
+ const Extent3D& copySize,
+ const uint32_t mipLevel,
+ Aspect aspect);
+bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
+ const Extent3D& copySize,
+ const uint32_t mipLevel,
+ wgpu::TextureAspect textureAspect);
SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy, const Extent3D& copySize);
void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass);
diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp
index 7ce6935..ee88515 100644
--- a/src/dawn/native/CommandEncoder.cpp
+++ b/src/dawn/native/CommandEncoder.cpp
@@ -144,14 +144,7 @@
MaybeError ValidateOrSetAttachmentSize(const TextureViewBase* attachment,
uint32_t* width,
uint32_t* height) {
- Extent3D attachmentSize = attachment->GetTexture()->GetMipLevelSingleSubresourceVirtualSize(
- attachment->GetBaseMipLevel());
- // TODO(dawn:2099): TextureBase::GetWidth/Height should take an Aspect parameter and perform the
- // necessary computation instead.
- if (attachment->GetTexture()->GetFormat().IsMultiPlanar()) {
- attachmentSize = attachment->GetTexture()->GetFormat().GetAspectSize(
- attachment->GetAspects(), attachmentSize);
- }
+ Extent3D attachmentSize = attachment->GetSingleSubresourceVirtualSize();
if (*width == 0) {
DAWN_ASSERT(*height == 0);
@@ -230,12 +223,8 @@
"The resolve target %s mip level count (%u) is not 1.", resolveTarget,
resolveTarget->GetLevelCount());
- const Extent3D& colorTextureSize =
- attachment->GetTexture()->GetMipLevelSingleSubresourceVirtualSize(
- attachment->GetBaseMipLevel());
- const Extent3D& resolveTextureSize =
- resolveTarget->GetTexture()->GetMipLevelSingleSubresourceVirtualSize(
- resolveTarget->GetBaseMipLevel());
+ const Extent3D& colorTextureSize = attachment->GetSingleSubresourceVirtualSize();
+ const Extent3D& resolveTextureSize = resolveTarget->GetSingleSubresourceVirtualSize();
DAWN_INVALID_IF(colorTextureSize.width != resolveTextureSize.width ||
colorTextureSize.height != resolveTextureSize.height,
"The Resolve target %s size (width: %u, height: %u) does not match the color "
@@ -260,9 +249,7 @@
MaybeError ValidateColorAttachmentDepthSlice(const TextureViewBase* attachment,
uint32_t depthSlice) {
if (attachment->GetDimension() == wgpu::TextureViewDimension::e3D) {
- const Extent3D& attachmentSize =
- attachment->GetTexture()->GetMipLevelSingleSubresourceVirtualSize(
- attachment->GetBaseMipLevel());
+ const Extent3D& attachmentSize = attachment->GetSingleSubresourceVirtualSize();
DAWN_INVALID_IF(depthSlice >= attachmentSize.depthOrArrayLayers,
"The depth slice index (%u) of 3D %s used as attachment is >= the "
@@ -1047,7 +1034,7 @@
Ref<TextureViewBase> implicitMSAATargetRef;
DAWN_TRY_ASSIGN(implicitMSAATargetRef,
device->CreateImplicitMSAARenderTextureViewFor(
- resolveTarget->GetTexture(), implicitSampleCount));
+ resolveTarget, implicitSampleCount));
colorTarget = implicitMSAATargetRef.Get();
cmd->colorAttachments[index].view = std::move(implicitMSAATargetRef);
@@ -1314,9 +1301,7 @@
descriptor.usage =
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
descriptor.format = resolveTarget->GetFormat().format;
- descriptor.size =
- resolveTarget->GetTexture()->GetMipLevelSingleSubresourceVirtualSize(
- resolveTarget->GetBaseMipLevel());
+ descriptor.size = resolveTarget->GetSingleSubresourceVirtualSize();
descriptor.dimension = wgpu::TextureDimension::e2D;
descriptor.mipLevelCount = 1;
@@ -1372,7 +1357,7 @@
dstImageCopyTexture.origin = {0, 0,
copyTarget.copyDst->GetBaseArrayLayer()};
- Extent3D extent3D = copyTarget.copySrc->GetTexture()->GetSize();
+ Extent3D extent3D = copyTarget.copySrc->GetSingleSubresourceVirtualSize();
auto internalUsageScope = MakeInternalUsageScope();
this->APICopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture,
@@ -1677,6 +1662,10 @@
DAWN_TRY(GetDevice()->ValidateObject(source->texture));
DAWN_TRY(GetDevice()->ValidateObject(destination->texture));
+ DAWN_INVALID_IF(source->texture->GetFormat().IsMultiPlanar() ||
+ destination->texture->GetFormat().IsMultiPlanar(),
+ "Copying between a multiplanar texture and another texture is "
+ "currently not allowed.");
DAWN_TRY_CONTEXT(ValidateImageCopyTexture(GetDevice(), *source, *copySize),
"validating source %s.", source->texture);
DAWN_TRY_CONTEXT(ValidateImageCopyTexture(GetDevice(), *destination, *copySize),
diff --git a/src/dawn/native/CommandValidation.cpp b/src/dawn/native/CommandValidation.cpp
index 609d3c8..d3a92ce 100644
--- a/src/dawn/native/CommandValidation.cpp
+++ b/src/dawn/native/CommandValidation.cpp
@@ -337,13 +337,15 @@
textureCopy.mipLevel, texture->GetNumMipLevels(), texture);
DAWN_TRY(ValidateTextureAspect(textureCopy.aspect));
- DAWN_INVALID_IF(SelectFormatAspects(texture->GetFormat(), textureCopy.aspect) == Aspect::None,
+
+ const auto aspect = SelectFormatAspects(texture->GetFormat(), textureCopy.aspect);
+ DAWN_INVALID_IF(aspect == Aspect::None,
"%s format (%s) does not have the selected aspect (%s).", texture,
texture->GetFormat().format, textureCopy.aspect);
if (texture->GetSampleCount() > 1 || texture->GetFormat().HasDepthOrStencil()) {
Extent3D subresourceSize =
- texture->GetMipLevelSingleSubresourcePhysicalSize(textureCopy.mipLevel);
+ texture->GetMipLevelSingleSubresourcePhysicalSize(textureCopy.mipLevel, aspect);
DAWN_ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
DAWN_INVALID_IF(
textureCopy.origin.x != 0 || textureCopy.origin.y != 0 ||
@@ -363,9 +365,14 @@
const ImageCopyTexture& textureCopy,
const Extent3D& copySize) {
const TextureBase* texture = textureCopy.texture;
+ const Format& format = textureCopy.texture->GetFormat();
+ const Aspect aspect = ConvertAspect(format, textureCopy.aspect);
+
+ DAWN_ASSERT(!format.IsMultiPlanar() || HasOneBit(aspect));
// Validation for the copy being in-bounds:
- Extent3D mipSize = texture->GetMipLevelSingleSubresourcePhysicalSize(textureCopy.mipLevel);
+ Extent3D mipSize =
+ texture->GetMipLevelSingleSubresourcePhysicalSize(textureCopy.mipLevel, aspect);
// For 1D/2D textures, include the array layer as depth so it can be checked with other
// dimensions.
if (texture->GetDimension() != wgpu::TextureDimension::e3D) {
@@ -386,7 +393,6 @@
&textureCopy.origin, ©Size, texture, textureCopy.mipLevel, &mipSize);
// Validation for the texel block alignments:
- const Format& format = textureCopy.texture->GetFormat();
if (format.isCompressed) {
const TexelBlockInfo& blockInfo = format.GetAspectInfo(textureCopy.aspect).block;
DAWN_INVALID_IF(
diff --git a/src/dawn/native/CopyTextureForBrowserHelper.cpp b/src/dawn/native/CopyTextureForBrowserHelper.cpp
index 0ebd828..3c46ff7 100644
--- a/src/dawn/native/CopyTextureForBrowserHelper.cpp
+++ b/src/dawn/native/CopyTextureForBrowserHelper.cpp
@@ -747,7 +747,7 @@
const CopyTextureForBrowserOptions* options) {
TextureInfo info;
info.origin = source->origin;
- info.size = source->texture->GetSize();
+ info.size = source->texture->GetSize(source->aspect);
Ref<TextureViewBase> srcTextureView = nullptr;
TextureViewDescriptor srcTextureViewDesc = {};
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 7a9bd34c..83cbd18 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -884,14 +884,15 @@
}
ResultOrError<Ref<TextureViewBase>> DeviceBase::CreateImplicitMSAARenderTextureViewFor(
- const TextureBase* singleSampledTexture,
+ const TextureViewBase* singleSampledTextureView,
uint32_t sampleCount) {
DAWN_ASSERT(IsLockedByCurrentThreadIfNeeded());
TextureDescriptor desc = {};
desc.dimension = wgpu::TextureDimension::e2D;
- desc.format = singleSampledTexture->GetFormat().format;
- desc.size = {singleSampledTexture->GetWidth(), singleSampledTexture->GetHeight(), 1};
+ desc.format = singleSampledTextureView->GetFormat().format;
+ desc.size = {singleSampledTextureView->GetSingleSubresourceVirtualSize().width,
+ singleSampledTextureView->GetSingleSubresourceVirtualSize().height, 1};
desc.sampleCount = sampleCount;
desc.usage = wgpu::TextureUsage::RenderAttachment;
if (HasFeature(Feature::TransientAttachments)) {
diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h
index a8ea07f..1a4c9dc 100644
--- a/src/dawn/native/Device.h
+++ b/src/dawn/native/Device.h
@@ -200,7 +200,7 @@
PipelineLayoutBase* GetEmptyPipelineLayout();
ResultOrError<Ref<TextureViewBase>> CreateImplicitMSAARenderTextureViewFor(
- const TextureBase* singleSampledTexture,
+ const TextureViewBase* singleSampledTexture,
uint32_t sampleCount);
ResultOrError<Ref<TextureViewBase>> GetOrCreatePlaceholderTextureViewForExternalTexture();
diff --git a/src/dawn/native/ExternalTexture.cpp b/src/dawn/native/ExternalTexture.cpp
index be0c85a..1f64fdf 100644
--- a/src/dawn/native/ExternalTexture.cpp
+++ b/src/dawn/native/ExternalTexture.cpp
@@ -101,7 +101,7 @@
DAWN_INVALID_IF(descriptor->visibleSize.width == 0 || descriptor->visibleSize.height == 0,
"VisibleSize %s have 0 on width or height.", &descriptor->visibleSize);
- const Extent3D textureSize = descriptor->plane0->GetTexture()->GetSize();
+ const Extent3D textureSize = descriptor->plane0->GetSingleSubresourceVirtualSize();
DAWN_INVALID_IF(descriptor->visibleSize.width > textureSize.width ||
descriptor->visibleSize.height > textureSize.height,
"VisibleSize %s is exceed the texture size, defined by Plane0 size (%u, %u).",
@@ -289,8 +289,8 @@
// Calculate scale factors and offsets from the specified visibleSize.
DAWN_ASSERT(descriptor->visibleSize.width > 0);
DAWN_ASSERT(descriptor->visibleSize.height > 0);
- uint32_t frameWidth = descriptor->plane0->GetTexture()->GetWidth();
- uint32_t frameHeight = descriptor->plane0->GetTexture()->GetHeight();
+ uint32_t frameWidth = descriptor->plane0->GetSingleSubresourceVirtualSize().width;
+ uint32_t frameHeight = descriptor->plane0->GetSingleSubresourceVirtualSize().height;
float xScale =
static_cast<float>(descriptor->visibleSize.width) / static_cast<float>(frameWidth);
float yScale =
diff --git a/src/dawn/native/Format.cpp b/src/dawn/native/Format.cpp
index 87d081a..715be6f 100644
--- a/src/dawn/native/Format.cpp
+++ b/src/dawn/native/Format.cpp
@@ -140,41 +140,6 @@
return aspectInfo[aspectIndex];
}
-Extent3D Format::GetAspectSize(Aspect aspect, const Extent3D& textureSize) const {
- switch (aspect) {
- case Aspect::Color:
- case Aspect::Depth:
- case Aspect::Stencil:
- case Aspect::CombinedDepthStencil:
- return textureSize;
- case Aspect::Plane0:
- DAWN_ASSERT(IsMultiPlanar());
- return textureSize;
- case Aspect::Plane1: {
- DAWN_ASSERT(IsMultiPlanar());
- auto planeSize = textureSize;
- switch (format) {
- case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
- case wgpu::TextureFormat::R10X6BG10X6Biplanar420Unorm:
- if (planeSize.width > 1) {
- planeSize.width >>= 1;
- }
- if (planeSize.height > 1) {
- planeSize.height >>= 1;
- }
- break;
- default:
- DAWN_UNREACHABLE();
- }
- return planeSize;
- }
- case Aspect::None:
- break;
- }
-
- DAWN_UNREACHABLE();
-}
-
FormatIndex Format::GetIndex() const {
return ComputeFormatIndex(format);
}
diff --git a/src/dawn/native/Format.h b/src/dawn/native/Format.h
index 1137ff4..8a84465 100644
--- a/src/dawn/native/Format.h
+++ b/src/dawn/native/Format.h
@@ -154,9 +154,6 @@
// Currently means they differ only in sRGB-ness.
bool ViewCompatibleWith(const Format& otherFormat) const;
- // Returns the aspect's size given the texture's size.
- Extent3D GetAspectSize(Aspect aspect, const Extent3D& textureSize) const;
-
private:
// Used to store the aspectInfo for one or more planes. For single plane "color" formats,
// only the first aspect info or aspectInfo[0] is valid. For depth-stencil, the first aspect
diff --git a/src/dawn/native/SwapChain.cpp b/src/dawn/native/SwapChain.cpp
index 9ef69f5..469b616 100644
--- a/src/dawn/native/SwapChain.cpp
+++ b/src/dawn/native/SwapChain.cpp
@@ -200,8 +200,8 @@
DAWN_ASSERT(mCurrentTexture->GetFormat().format == mFormat);
DAWN_ASSERT(IsSubset(mUsage, mCurrentTexture->GetUsage()));
DAWN_ASSERT(mCurrentTexture->GetDimension() == wgpu::TextureDimension::e2D);
- DAWN_ASSERT(mCurrentTexture->GetWidth() == mWidth);
- DAWN_ASSERT(mCurrentTexture->GetHeight() == mHeight);
+ DAWN_ASSERT(mCurrentTexture->GetWidth(Aspect::Color) == mWidth);
+ DAWN_ASSERT(mCurrentTexture->GetHeight(Aspect::Color) == mHeight);
DAWN_ASSERT(mCurrentTexture->GetNumMipLevels() == 1);
DAWN_ASSERT(mCurrentTexture->GetArrayLayers() == 1);
diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp
index 02bbaba..7ec38f4 100644
--- a/src/dawn/native/Texture.cpp
+++ b/src/dawn/native/Texture.cpp
@@ -210,11 +210,12 @@
case wgpu::TextureViewDimension::Cube:
case wgpu::TextureViewDimension::CubeArray:
DAWN_INVALID_IF(
- texture->GetSize().width != texture->GetSize().height,
+ texture->GetSize(descriptor->aspect).width !=
+ texture->GetSize(descriptor->aspect).height,
"A %s texture view is not compatible with %s because the texture's width "
"(%u) and height (%u) are not equal.",
- descriptor->dimension, texture, texture->GetSize().width,
- texture->GetSize().height);
+ descriptor->dimension, texture, texture->GetSize(descriptor->aspect).width,
+ texture->GetSize(descriptor->aspect).height);
DAWN_INVALID_IF(descriptor->dimension == wgpu::TextureViewDimension::CubeArray &&
device->IsCompatibilityMode(),
"A %s texture view for %s is not supported in compatibility mode",
@@ -516,7 +517,8 @@
const Format* viewFormat;
DAWN_TRY_ASSIGN(viewFormat, device->GetInternalFormat(descriptor->format));
- DAWN_INVALID_IF(SelectFormatAspects(format, descriptor->aspect) == Aspect::None,
+ const auto aspect = SelectFormatAspects(format, descriptor->aspect);
+ DAWN_INVALID_IF(aspect == Aspect::None,
"Texture format (%s) does not have the texture view's selected aspect (%s).",
format.format, descriptor->aspect);
@@ -638,7 +640,7 @@
: ApiObjectBase(device, descriptor->label),
mDimension(descriptor->dimension),
mFormat(device->GetValidInternalFormat(descriptor->format)),
- mSize(descriptor->size),
+ mBaseSize(descriptor->size),
mMipLevelCount(descriptor->mipLevelCount),
mSampleCount(descriptor->sampleCount),
mUsage(descriptor->usage),
@@ -699,7 +701,7 @@
: ApiObjectBase(device, tag, descriptor->label),
mDimension(descriptor->dimension),
mFormat(kUnusedFormat),
- mSize(descriptor->size),
+ mBaseSize(descriptor->size),
mMipLevelCount(descriptor->mipLevelCount),
mSampleCount(descriptor->sampleCount),
mUsage(descriptor->usage),
@@ -734,29 +736,74 @@
DAWN_ASSERT(!IsError());
return mViewFormats;
}
-const Extent3D& TextureBase::GetSize() const {
+
+const Extent3D& TextureBase::GetBaseSize() const {
DAWN_ASSERT(!IsError());
- return mSize;
+ return mBaseSize;
}
-uint32_t TextureBase::GetWidth() const {
+
+Extent3D TextureBase::GetSize(Aspect aspect) const {
DAWN_ASSERT(!IsError());
- return mSize.width;
+ switch (aspect) {
+ case Aspect::Color:
+ case Aspect::Depth:
+ case Aspect::Stencil:
+ case Aspect::CombinedDepthStencil:
+ return mBaseSize;
+ case Aspect::Plane0:
+ DAWN_ASSERT(GetFormat().IsMultiPlanar());
+ return mBaseSize;
+ case Aspect::Plane1: {
+ DAWN_ASSERT(GetFormat().IsMultiPlanar());
+ auto planeSize = mBaseSize;
+ switch (GetFormat().format) {
+ case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
+ case wgpu::TextureFormat::R10X6BG10X6Biplanar420Unorm:
+ if (planeSize.width > 1) {
+ planeSize.width >>= 1;
+ }
+ if (planeSize.height > 1) {
+ planeSize.height >>= 1;
+ }
+ break;
+ default:
+ DAWN_UNREACHABLE();
+ }
+ return planeSize;
+ }
+ case Aspect::None:
+ break;
+ }
+
+ if (aspect == (Aspect::Depth | Aspect::Stencil)) {
+ return mBaseSize;
+ }
+
+ DAWN_UNREACHABLE();
}
-uint32_t TextureBase::GetHeight() const {
+Extent3D TextureBase::GetSize(wgpu::TextureAspect textureAspect) const {
+ const auto aspect = SelectFormatAspects(GetFormat(), textureAspect);
+ return GetSize(aspect);
+}
+uint32_t TextureBase::GetWidth(Aspect aspect) const {
DAWN_ASSERT(!IsError());
- return mSize.height;
+ return GetSize(aspect).width;
}
-uint32_t TextureBase::GetDepth() const {
+uint32_t TextureBase::GetHeight(Aspect aspect) const {
+ DAWN_ASSERT(!IsError());
+ return GetSize(aspect).height;
+}
+uint32_t TextureBase::GetDepth(Aspect aspect) const {
DAWN_ASSERT(!IsError());
DAWN_ASSERT(mDimension == wgpu::TextureDimension::e3D);
- return mSize.depthOrArrayLayers;
+ return GetSize(aspect).depthOrArrayLayers;
}
uint32_t TextureBase::GetArrayLayers() const {
DAWN_ASSERT(!IsError());
if (mDimension == wgpu::TextureDimension::e3D) {
return 1;
}
- return mSize.depthOrArrayLayers;
+ return mBaseSize.depthOrArrayLayers;
}
uint32_t TextureBase::GetNumMipLevels() const {
DAWN_ASSERT(!IsError());
@@ -866,8 +913,10 @@
return mSampleCount > 1;
}
-bool TextureBase::CoverFullSubresource(uint32_t mipLevel, const Extent3D& size) const {
- Extent3D levelSize = GetMipLevelSingleSubresourcePhysicalSize(mipLevel);
+bool TextureBase::CoversFullSubresource(uint32_t mipLevel,
+ Aspect aspect,
+ const Extent3D& size) const {
+ Extent3D levelSize = GetMipLevelSingleSubresourcePhysicalSize(mipLevel, aspect);
switch (GetDimension()) {
case wgpu::TextureDimension::e1D:
return size.width == levelSize.width;
@@ -879,23 +928,25 @@
DAWN_UNREACHABLE();
}
-Extent3D TextureBase::GetMipLevelSingleSubresourceVirtualSize(uint32_t level) const {
- Extent3D extent = {std::max(mSize.width >> level, 1u), 1u, 1u};
+Extent3D TextureBase::GetMipLevelSingleSubresourceVirtualSize(uint32_t level, Aspect aspect) const {
+ Extent3D aspectSize = GetSize(aspect);
+ Extent3D extent = {std::max(aspectSize.width >> level, 1u), 1u, 1u};
if (mDimension == wgpu::TextureDimension::e1D) {
return extent;
}
- extent.height = std::max(mSize.height >> level, 1u);
+ extent.height = std::max(aspectSize.height >> level, 1u);
if (mDimension == wgpu::TextureDimension::e2D) {
return extent;
}
- extent.depthOrArrayLayers = std::max(mSize.depthOrArrayLayers >> level, 1u);
+ extent.depthOrArrayLayers = std::max(aspectSize.depthOrArrayLayers >> level, 1u);
return extent;
}
-Extent3D TextureBase::GetMipLevelSingleSubresourcePhysicalSize(uint32_t level) const {
- Extent3D extent = GetMipLevelSingleSubresourceVirtualSize(level);
+Extent3D TextureBase::GetMipLevelSingleSubresourcePhysicalSize(uint32_t level,
+ Aspect aspect) const {
+ Extent3D extent = GetMipLevelSingleSubresourceVirtualSize(level, aspect);
// Compressed Textures will have paddings if their width or height is not a multiple of
// 4 at non-zero mipmap levels.
@@ -913,9 +964,10 @@
}
Extent3D TextureBase::ClampToMipLevelVirtualSize(uint32_t level,
+ Aspect aspect,
const Origin3D& origin,
const Extent3D& extent) const {
- const Extent3D virtualSizeAtLevel = GetMipLevelSingleSubresourceVirtualSize(level);
+ const Extent3D virtualSizeAtLevel = GetMipLevelSingleSubresourceVirtualSize(level, aspect);
DAWN_ASSERT(origin.x <= virtualSizeAtLevel.width);
DAWN_ASSERT(origin.y <= virtualSizeAtLevel.height);
uint32_t clampedCopyExtentWidth = (extent.width > virtualSizeAtLevel.width - origin.x)
@@ -927,10 +979,10 @@
return {clampedCopyExtentWidth, clampedCopyExtentHeight, extent.depthOrArrayLayers};
}
-Extent3D TextureBase::GetMipLevelSubresourceVirtualSize(uint32_t level) const {
- Extent3D extent = GetMipLevelSingleSubresourceVirtualSize(level);
+Extent3D TextureBase::GetMipLevelSubresourceVirtualSize(uint32_t level, Aspect aspect) const {
+ Extent3D extent = GetMipLevelSingleSubresourceVirtualSize(level, aspect);
if (mDimension == wgpu::TextureDimension::e2D) {
- extent.depthOrArrayLayers = mSize.depthOrArrayLayers;
+ extent.depthOrArrayLayers = mBaseSize.depthOrArrayLayers;
}
return extent;
}
@@ -968,14 +1020,14 @@
}
uint32_t TextureBase::APIGetWidth() const {
- return mSize.width;
+ return mBaseSize.width;
}
uint32_t TextureBase::APIGetHeight() const {
- return mSize.height;
+ return mBaseSize.height;
}
uint32_t TextureBase::APIGetDepthOrArrayLayers() const {
- return mSize.depthOrArrayLayers;
+ return mBaseSize.depthOrArrayLayers;
}
uint32_t TextureBase::APIGetMipLevelCount() const {
@@ -1095,6 +1147,11 @@
return mRange;
}
+Extent3D TextureViewBase::GetSingleSubresourceVirtualSize() const {
+ DAWN_ASSERT(!IsError());
+ return GetTexture()->GetMipLevelSingleSubresourceVirtualSize(GetBaseMipLevel(), GetAspects());
+}
+
ApiObjectList* TextureViewBase::GetObjectTrackingList() {
DAWN_ASSERT(!IsError());
return mTexture->GetViewTrackingList();
diff --git a/src/dawn/native/Texture.h b/src/dawn/native/Texture.h
index 505895c..bc030bd 100644
--- a/src/dawn/native/Texture.h
+++ b/src/dawn/native/Texture.h
@@ -70,10 +70,15 @@
wgpu::TextureDimension GetDimension() const;
const Format& GetFormat() const;
const FormatSet& GetViewFormats() const;
- const Extent3D& GetSize() const;
- uint32_t GetWidth() const;
- uint32_t GetHeight() const;
- uint32_t GetDepth() const;
+
+ // For multiplanar textures, base size is the size of plane 0. For other types of textures,
+ // base size is the original size passed via TextureDescriptor.
+ const Extent3D& GetBaseSize() const;
+ Extent3D GetSize(Aspect aspect) const;
+ Extent3D GetSize(wgpu::TextureAspect aspect) const;
+ uint32_t GetWidth(Aspect aspect) const;
+ uint32_t GetHeight(Aspect aspect) const;
+ uint32_t GetDepth(Aspect aspect) const;
uint32_t GetArrayLayers() const;
uint32_t GetNumMipLevels() const;
SubresourceRange GetAllSubresources() const;
@@ -97,21 +102,22 @@
bool IsMultisampledTexture() const;
// Returns true if the size covers the whole subresource.
- bool CoverFullSubresource(uint32_t mipLevel, const Extent3D& size) const;
+ bool CoversFullSubresource(uint32_t mipLevel, Aspect aspect, const Extent3D& size) const;
// For a texture with non-block-compressed texture format, its physical size is always equal
// to its virtual size. For a texture with block compressed texture format, the physical
// size is the one with paddings if necessary, which is always a multiple of the block size
// and used in texture copying. The virtual size is the one without paddings, which is not
// required to be a multiple of the block size and used in texture sampling.
- Extent3D GetMipLevelSingleSubresourcePhysicalSize(uint32_t level) const;
- Extent3D GetMipLevelSingleSubresourceVirtualSize(uint32_t level) const;
+ Extent3D GetMipLevelSingleSubresourcePhysicalSize(uint32_t level, Aspect aspect) const;
+ Extent3D GetMipLevelSingleSubresourceVirtualSize(uint32_t level, Aspect aspect) const;
Extent3D ClampToMipLevelVirtualSize(uint32_t level,
+ Aspect aspect,
const Origin3D& origin,
const Extent3D& extent) const;
// For 2d-array textures, this keeps the array layers in contrast to
// GetMipLevelSingleSubresourceVirtualSize.
- Extent3D GetMipLevelSubresourceVirtualSize(uint32_t level) const;
+ Extent3D GetMipLevelSubresourceVirtualSize(uint32_t level, Aspect aspect) const;
ResultOrError<Ref<TextureViewBase>> CreateView(
const TextureViewDescriptor* descriptor = nullptr);
@@ -158,7 +164,7 @@
wgpu::TextureDimension mDimension;
const Format& mFormat;
FormatSet mViewFormats;
- Extent3D mSize;
+ Extent3D mBaseSize;
uint32_t mMipLevelCount;
uint32_t mSampleCount;
wgpu::TextureUsage mUsage = wgpu::TextureUsage::None;
@@ -196,6 +202,9 @@
uint32_t GetLayerCount() const;
const SubresourceRange& GetSubresourceRange() const;
+ // Returns the size of the texture's subresource at this view's base mip level and aspect.
+ Extent3D GetSingleSubresourceVirtualSize() const;
+
protected:
void DestroyImpl() override;
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index b0c5032..b56b0f4 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -241,12 +241,12 @@
T desc;
if constexpr (std::is_same<T, D3D11_TEXTURE1D_DESC>::value) {
- desc.Width = GetSize().width;
+ desc.Width = GetBaseSize().width;
desc.ArraySize = GetArrayLayers();
desc.MiscFlags = 0;
} else if constexpr (std::is_same<T, D3D11_TEXTURE2D_DESC>::value) {
- desc.Width = GetSize().width;
- desc.Height = GetSize().height;
+ desc.Width = GetBaseSize().width;
+ desc.Height = GetBaseSize().height;
desc.ArraySize = GetArrayLayers();
desc.SampleDesc.Count = GetSampleCount();
desc.SampleDesc.Quality = 0;
@@ -256,9 +256,9 @@
desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
}
} else if constexpr (std::is_same<T, D3D11_TEXTURE3D_DESC>::value) {
- desc.Width = GetSize().width;
- desc.Height = GetSize().height;
- desc.Depth = GetSize().depthOrArrayLayers;
+ desc.Width = GetBaseSize().width;
+ desc.Height = GetBaseSize().height;
+ desc.Depth = GetBaseSize().depthOrArrayLayers;
desc.MiscFlags = 0;
}
@@ -537,35 +537,37 @@
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
// TODO(dawn:1705): Use interim texture clear-and-copy as compressed textures do to
// avoid CPU-to-GPU write.
- Extent3D writeSize = GetMipLevelSubresourceVirtualSize(range.baseMipLevel);
- uint32_t bytesPerRow = blockInfo.byteSize * writeSize.width;
+ for (Aspect aspect : IterateEnumMask(range.aspects)) {
+ Extent3D writeSize = GetMipLevelSubresourceVirtualSize(range.baseMipLevel, aspect);
+ uint32_t bytesPerRow = blockInfo.byteSize * writeSize.width;
- uint32_t rowsPerImage = writeSize.height;
- uint64_t byteLength;
- DAWN_TRY_ASSIGN(byteLength,
- ComputeRequiredBytesInCopy(blockInfo, writeSize, bytesPerRow, rowsPerImage));
+ uint32_t rowsPerImage = writeSize.height;
+ uint64_t byteLength;
+ DAWN_TRY_ASSIGN(byteLength, ComputeRequiredBytesInCopy(blockInfo, writeSize, bytesPerRow,
+ rowsPerImage));
- std::vector<uint8_t> clearData(byteLength, clearValue == ClearValue::Zero ? 0 : 1);
- SubresourceRange writeRange = range;
- writeRange.layerCount = 1;
- writeRange.levelCount = 1;
- for (uint32_t layer = range.baseArrayLayer; layer < range.baseArrayLayer + range.layerCount;
- ++layer) {
- for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
- ++level) {
- if (clearValue == TextureBase::ClearValue::Zero &&
- IsSubresourceContentInitialized(
- SubresourceRange::SingleMipAndLayer(level, layer, range.aspects))) {
- // Skip lazy clears if already initialized.
- continue;
+ std::vector<uint8_t> clearData(byteLength, clearValue == ClearValue::Zero ? 0 : 1);
+ SubresourceRange writeRange = range;
+ writeRange.layerCount = 1;
+ writeRange.levelCount = 1;
+ for (uint32_t layer = range.baseArrayLayer; layer < range.baseArrayLayer + range.layerCount;
+ ++layer) {
+ for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
+ ++level) {
+ if (clearValue == TextureBase::ClearValue::Zero &&
+ IsSubresourceContentInitialized(
+ SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
+ // Skip lazy clears if already initialized.
+ continue;
+ }
+ writeRange.baseArrayLayer = layer;
+ writeRange.baseMipLevel = level;
+ writeSize = GetMipLevelSubresourceVirtualSize(level, aspect);
+ bytesPerRow = blockInfo.byteSize * writeSize.width;
+ rowsPerImage = writeSize.height;
+ DAWN_TRY(WriteInternal(commandContext, writeRange, {0, 0, 0}, writeSize,
+ clearData.data(), bytesPerRow, rowsPerImage));
}
- writeRange.baseArrayLayer = layer;
- writeRange.baseMipLevel = level;
- writeSize = GetMipLevelSubresourceVirtualSize(level);
- bytesPerRow = blockInfo.byteSize * writeSize.width;
- rowsPerImage = writeSize.height;
- DAWN_TRY(WriteInternal(commandContext, writeRange, {0, 0, 0}, writeSize,
- clearData.data(), bytesPerRow, rowsPerImage));
}
}
@@ -575,13 +577,14 @@
MaybeError Texture::ClearCompressed(CommandRecordingContext* commandContext,
const SubresourceRange& range,
TextureBase::ClearValue clearValue) {
+ DAWN_ASSERT(range.aspects == Aspect::Color);
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
// Create an interim texture of renderable format for reinterpretation conversion.
TextureDescriptor desc = {};
desc.label = "CopyUncompressedTextureToCompressedTexureInterim";
desc.dimension = GetDimension();
DAWN_ASSERT(desc.dimension == wgpu::TextureDimension::e2D);
- desc.size = {GetSize().width, GetSize().height, 1};
+ desc.size = {GetWidth(Aspect::Color), GetHeight(Aspect::Color), 1};
desc.format = UncompressedTextureFormat(GetFormat().format);
desc.mipLevelCount = 1;
desc.sampleCount = 1;
@@ -631,7 +634,7 @@
continue;
}
uint32_t dstSubresource = GetSubresourceIndex(level, layer, D3D11Aspect(range.aspects));
- auto physicalSize = GetMipLevelSingleSubresourcePhysicalSize(level);
+ auto physicalSize = GetMipLevelSingleSubresourcePhysicalSize(level, Aspect::Color);
// The documentation says D3D11_BOX's coordinates should be in texels for
// textures. However the validation layer seemingly assumes them to be in
// blocks. Otherwise it would complain like this:
@@ -680,7 +683,8 @@
const uint8_t* data,
uint32_t bytesPerRow,
uint32_t rowsPerImage) {
- if (IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel,
+ subresources.aspects)) {
SetIsSubresourceContentInitialized(true, subresources);
} else {
// Dawn validation should have ensured that full subresources write for depth/stencil
@@ -760,7 +764,8 @@
DAWN_TRY_ASSIGN(stagingTexture, CreateInternal(ToBackend(GetDevice()), &desc, Kind::Staging));
// Depth-stencil subresources can only be written to completely and not partially.
- DAWN_ASSERT(IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel));
+ DAWN_ASSERT(
+ IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel, subresources.aspects));
SubresourceRange otherRange = subresources;
Aspect otherAspects = GetFormat().aspects & ~subresources.aspects;
@@ -993,7 +998,8 @@
->EnsureSubresourceContentInitialized(commandContext, srcSubresources));
SubresourceRange dstSubresources = GetSubresourcesAffectedByCopy(dst, copy->copySize);
- if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel,
+ dst.aspect)) {
dst.texture->SetIsSubresourceContentInitialized(true, dstSubresources);
} else {
// Partial update subresource of a depth/stencil texture is not allowed.
@@ -1035,8 +1041,9 @@
DAWN_UNREACHABLE();
}
- bool isWholeSubresource = src.texture->CoverFullSubresource(src.mipLevel, copy->copySize) &&
- dst.texture->CoverFullSubresource(dst.mipLevel, copy->copySize);
+ bool isWholeSubresource =
+ src.texture->CoversFullSubresource(src.mipLevel, src.aspect, copy->copySize) &&
+ dst.texture->CoversFullSubresource(dst.mipLevel, dst.aspect, copy->copySize);
// Partial update subresource of a depth/stencil texture is not allowed.
DAWN_ASSERT(isWholeSubresource || !src.texture->GetFormat().HasDepthOrStencil());
@@ -1072,7 +1079,7 @@
TextureDescriptor desc = {};
desc.label = "InterimStencilTexture";
desc.dimension = GetDimension();
- desc.size = GetSize();
+ desc.size = GetSize(Aspect::Stencil);
desc.format = wgpu::TextureFormat::R8Uint;
desc.mipLevelCount = GetNumMipLevels();
desc.sampleCount = GetSampleCount();
@@ -1086,7 +1093,7 @@
// TODO(dawn:1705): Improve to only sync as few as possible.
const auto range = view->GetSubresourceRange();
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
- Extent3D size = GetMipLevelSubresourceVirtualSize(range.baseMipLevel);
+ Extent3D size = GetMipLevelSubresourceVirtualSize(range.baseMipLevel, range.aspects);
uint32_t bytesPerRow = blockInfo.byteSize * size.width;
uint32_t rowsPerImage = size.height;
uint64_t byteLength;
@@ -1098,7 +1105,7 @@
++layer) {
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
- size = GetMipLevelSubresourceVirtualSize(level);
+ size = GetMipLevelSubresourceVirtualSize(level, range.aspects);
bytesPerRow = blockInfo.byteSize * size.width;
rowsPerImage = size.height;
auto singleRange = SubresourceRange::MakeSingle(range.aspects, layer, level);
@@ -1339,7 +1346,8 @@
case wgpu::TextureViewDimension::e3D:
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
uavDesc.Texture3D.FirstWSlice = 0;
- uavDesc.Texture3D.WSize = std::max(1u, GetTexture()->GetDepth() >> GetBaseMipLevel());
+ uavDesc.Texture3D.WSize =
+ std::max(1u, GetSingleSubresourceVirtualSize().depthOrArrayLayers);
uavDesc.Texture3D.MipSlice = GetBaseMipLevel();
break;
// Cube and Cubemap can't be used as storage texture. So there is no need to create UAV
diff --git a/src/dawn/native/d3d12/CommandBufferD3D12.cpp b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
index 4c2eb2e..b4c49af 100644
--- a/src/dawn/native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
@@ -69,8 +69,8 @@
DAWN_ASSERT(src.texture->GetFormat().CopyCompatibleWith(dst.texture->GetFormat()));
DAWN_ASSERT(src.aspect == dst.aspect);
- const Extent3D& srcSize = src.texture->GetSize();
- const Extent3D& dstSize = dst.texture->GetSize();
+ const Extent3D& srcSize = src.texture->GetSize(src.aspect);
+ const Extent3D& dstSize = dst.texture->GetSize(dst.aspect);
// 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
@@ -839,7 +839,8 @@
GetSubresourcesAffectedByCopy(copy->destination, copy->copySize);
if (IsCompleteSubresourceCopiedTo(texture, copy->copySize,
- copy->destination.mipLevel)) {
+ copy->destination.mipLevel,
+ copy->destination.aspect)) {
texture->SetIsSubresourceContentInitialized(true, subresources);
} else {
DAWN_TRY(
@@ -913,7 +914,8 @@
DAWN_TRY(source->EnsureSubresourceContentInitialized(commandContext, srcRange));
if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
- copy->destination.mipLevel)) {
+ copy->destination.mipLevel,
+ copy->destination.aspect)) {
destination->SetIsSubresourceContentInitialized(true, dstRange);
} else {
DAWN_TRY(
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index a460199..af836c4 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -550,7 +550,7 @@
SubresourceRange range = GetSubresourcesAffectedByCopy(dst, copySizePixels);
- if (IsCompleteSubresourceCopiedTo(texture, copySizePixels, dst.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(texture, copySizePixels, dst.mipLevel, dst.aspect)) {
texture->SetIsSubresourceContentInitialized(true, range);
} else {
DAWN_TRY(texture->EnsureSubresourceContentInitialized(commandContext, range));
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index 5c19073..9ce8b1f 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -246,7 +246,7 @@
resourceDescriptor.Dimension = D3D12TextureDimension(GetDimension());
resourceDescriptor.Alignment = 0;
- const Extent3D& size = GetSize();
+ const Extent3D& size = GetBaseSize();
resourceDescriptor.Width = size.width;
resourceDescriptor.Height = size.height;
resourceDescriptor.DepthOrArraySize = size.depthOrArrayLayers;
@@ -812,7 +812,7 @@
uint32_t sliceCount = 1;
if (GetDimension() == wgpu::TextureDimension::e3D) {
baseSlice = 0;
- sliceCount = std::max(GetDepth() >> level, 1u);
+ sliceCount = std::max(GetDepth(Aspect::Color) >> level, 1u);
}
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
GetRTVDescriptor(GetFormat(), level, baseSlice, sliceCount);
@@ -830,7 +830,8 @@
for (Aspect aspect : IterateEnumMask(range.aspects)) {
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(aspect).block;
- Extent3D largestMipSize = GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel);
+ Extent3D largestMipSize =
+ GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel, aspect);
uint32_t bytesPerRow =
Align((largestMipSize.width / blockInfo.width) * blockInfo.byteSize,
@@ -847,7 +848,7 @@
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
// compute d3d12 texture copy locations for texture and buffer
- Extent3D copySize = GetMipLevelSingleSubresourcePhysicalSize(level);
+ Extent3D copySize = GetMipLevelSingleSubresourcePhysicalSize(level, aspect);
for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
@@ -1116,7 +1117,8 @@
case wgpu::TextureViewDimension::e3D:
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
uavDesc.Texture3D.FirstWSlice = 0;
- uavDesc.Texture3D.WSize = std::max(1u, GetTexture()->GetDepth() >> GetBaseMipLevel());
+ uavDesc.Texture3D.WSize =
+ std::max(1u, GetSingleSubresourceVirtualSize().depthOrArrayLayers);
uavDesc.Texture3D.MipSlice = GetBaseMipLevel();
break;
// Cube and Cubemap can't be used as storage texture. So there is no need to create UAV
diff --git a/src/dawn/native/metal/TextureMTL.mm b/src/dawn/native/metal/TextureMTL.mm
index 9180ad8..18be29e 100644
--- a/src/dawn/native/metal/TextureMTL.mm
+++ b/src/dawn/native/metal/TextureMTL.mm
@@ -679,7 +679,8 @@
NSRef<MTLTextureDescriptor> mtlDescRef = AcquireNSRef([MTLTextureDescriptor new]);
MTLTextureDescriptor* mtlDesc = mtlDescRef.Get();
- mtlDesc.width = GetWidth();
+ DAWN_ASSERT(!GetFormat().IsMultiPlanar());
+ mtlDesc.width = GetBaseSize().width;
mtlDesc.sampleCount = GetSampleCount();
// Metal only allows format reinterpretation to happen on swizzle pattern or conversion
// between linear space and sRGB. For example, creating bgra8Unorm texture view on
@@ -715,7 +716,7 @@
break;
case wgpu::TextureDimension::e2D:
- mtlDesc.height = GetHeight();
+ mtlDesc.height = GetBaseSize().height;
mtlDesc.arrayLength = GetArrayLayers();
mtlDesc.depth = 1;
if (mtlDesc.arrayLength > 1) {
@@ -728,8 +729,8 @@
}
break;
case wgpu::TextureDimension::e3D:
- mtlDesc.height = GetHeight();
- mtlDesc.depth = GetDepth();
+ mtlDesc.height = GetBaseSize().height;
+ mtlDesc.depth = GetBaseSize().depthOrArrayLayers;
mtlDesc.arrayLength = 1;
DAWN_ASSERT(mtlDesc.sampleCount == 1);
mtlDesc.textureType = MTLTextureType3D;
@@ -993,9 +994,9 @@
}
}
- DAWN_TRY(
- EncodeEmptyMetalRenderPass(device, commandContext, descriptor,
- GetMipLevelSingleSubresourceVirtualSize(level)));
+ DAWN_TRY(EncodeEmptyMetalRenderPass(
+ device, commandContext, descriptor,
+ GetMipLevelSingleSubresourceVirtualSize(level, range.aspects)));
}
}
} else {
@@ -1008,7 +1009,8 @@
NSRef<MTLRenderPassDescriptor> descriptor;
uint32_t attachment = 0;
- uint32_t depth = GetMipLevelSingleSubresourceVirtualSize(level).depthOrArrayLayers;
+ uint32_t depth = GetMipLevelSingleSubresourceVirtualSize(level, Aspect::Color)
+ .depthOrArrayLayers;
for (uint32_t arrayLayer = range.baseArrayLayer;
arrayLayer < range.baseArrayLayer + range.layerCount; arrayLayer++) {
@@ -1042,16 +1044,16 @@
attachment = 0;
DAWN_TRY(EncodeEmptyMetalRenderPass(
device, commandContext, descriptor.Get(),
- GetMipLevelSingleSubresourceVirtualSize(level)));
+ GetMipLevelSingleSubresourceVirtualSize(level, Aspect::Color)));
descriptor = nullptr;
}
}
}
if (descriptor != nullptr) {
- DAWN_TRY(
- EncodeEmptyMetalRenderPass(device, commandContext, descriptor.Get(),
- GetMipLevelSingleSubresourceVirtualSize(level)));
+ DAWN_TRY(EncodeEmptyMetalRenderPass(
+ device, commandContext, descriptor.Get(),
+ GetMipLevelSingleSubresourceVirtualSize(level, Aspect::Color)));
}
}
}
@@ -1065,7 +1067,8 @@
// Computations for the bytes per row / image height are done using the physical size
// so that enough data is reserved for compressed textures.
- Extent3D largestMipSize = GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel);
+ Extent3D largestMipSize =
+ GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel, aspect);
uint32_t largestMipBytesPerRow =
(largestMipSize.width / blockInfo.width) * blockInfo.byteSize;
uint64_t largestMipBytesPerImage = static_cast<uint64_t>(largestMipBytesPerRow) *
@@ -1087,7 +1090,7 @@
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
- Extent3D virtualSize = GetMipLevelSingleSubresourceVirtualSize(level);
+ Extent3D virtualSize = GetMipLevelSingleSubresourceVirtualSize(level, aspect);
for (uint32_t arrayLayer = range.baseArrayLayer;
arrayLayer < range.baseArrayLayer + range.layerCount; ++arrayLayer) {
diff --git a/src/dawn/native/metal/UtilsMetal.mm b/src/dawn/native/metal/UtilsMetal.mm
index 4ec1fa2..b63475c 100644
--- a/src/dawn/native/metal/UtilsMetal.mm
+++ b/src/dawn/native/metal/UtilsMetal.mm
@@ -262,7 +262,7 @@
// clamped to the edge of the texture if the block extends outside the bounds of a
// texture.
const Extent3D clampedCopyExtent =
- texture->ClampToMipLevelVirtualSize(mipLevel, origin, copyExtent);
+ texture->ClampToMipLevelVirtualSize(mipLevel, aspect, origin, copyExtent);
// Note: all current GPUs have a 3D texture size limit of 2048 and otherwise 16348
// for non-3D textures except for Apple2 GPUs (iPhone6) which has a non-3D texture
@@ -329,7 +329,7 @@
uint32_t copyBlockRowCount = copyExtent.height / blockInfo.height;
if (copyBlockRowCount > 1) {
DAWN_ASSERT(copyExtent.height - blockInfo.height <
- texture->GetMipLevelSingleSubresourceVirtualSize(mipLevel).height);
+ texture->GetMipLevelSingleSubresourceVirtualSize(mipLevel, aspect).height);
const uint32_t localBytesPerImage = 0; // workaround case 3
copy.push_back(TextureBufferCopySplit::CopyInfo(
currentOffset, bytesPerRow, localBytesPerImage,
@@ -363,7 +363,7 @@
const Extent3D& size) {
DAWN_ASSERT(texture == dst.texture.Get());
SubresourceRange range = GetSubresourcesAffectedByCopy(dst, size);
- if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), size, dst.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), size, dst.mipLevel, dst.aspect)) {
texture->SetIsSubresourceContentInitialized(true, range);
} else {
DAWN_TRY(texture->EnsureSubresourceContentInitialized(commandContext, range));
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index e7bfb43..d410bcd 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -513,7 +513,7 @@
Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel =
- texture->GetMipLevelSingleSubresourceVirtualSize(textureCopy.mipLevel);
+ texture->GetMipLevelSingleSubresourceVirtualSize(textureCopy.mipLevel, textureCopy.aspect);
DAWN_ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
DAWN_ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
@@ -628,8 +628,8 @@
buffer->EnsureDataInitialized();
SubresourceRange range = GetSubresourcesAffectedByCopy(dst, copy->copySize);
- if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize,
- dst.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel,
+ dst.aspect)) {
dst.texture->SetIsSubresourceContentInitialized(true, range);
} else {
DAWN_TRY(ToBackend(dst.texture)->EnsureSubresourceContentInitialized(range));
@@ -776,7 +776,7 @@
SubresourceRange dstRange = GetSubresourcesAffectedByCopy(dst, copy->copySize);
DAWN_TRY(srcTexture->EnsureSubresourceContentInitialized(srcRange));
- if (IsCompleteSubresourceCopiedTo(dstTexture, copySize, dst.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(dstTexture, copySize, dst.mipLevel, dst.aspect)) {
dstTexture->SetIsSubresourceContentInitialized(true, dstRange);
} else {
DAWN_TRY(dstTexture->EnsureSubresourceContentInitialized(dstRange));
@@ -1342,7 +1342,8 @@
uint32_t z = destination.origin.z;
if (texture->GetFormat().isCompressed) {
size_t rowSize = copySize.width / blockInfo.width * blockInfo.byteSize;
- Extent3D virtSize = texture->GetMipLevelSingleSubresourceVirtualSize(destination.mipLevel);
+ Extent3D virtSize = texture->GetMipLevelSingleSubresourceVirtualSize(destination.mipLevel,
+ destination.aspect);
uint32_t width = std::min(copySize.width, virtSize.width - x);
// In GLES glPixelStorei() doesn't affect CompressedTexSubImage*D() and
diff --git a/src/dawn/native/opengl/QueueGL.cpp b/src/dawn/native/opengl/QueueGL.cpp
index 3b0f79b..706e17e 100644
--- a/src/dawn/native/opengl/QueueGL.cpp
+++ b/src/dawn/native/opengl/QueueGL.cpp
@@ -63,7 +63,8 @@
textureCopy.aspect = SelectFormatAspects(destination.texture->GetFormat(), destination.aspect);
SubresourceRange range = GetSubresourcesAffectedByCopy(textureCopy, writeSizePixel);
- if (IsCompleteSubresourceCopiedTo(destination.texture, writeSizePixel, destination.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(destination.texture, writeSizePixel, destination.mipLevel,
+ destination.aspect)) {
destination.texture->SetIsSubresourceContentInitialized(true, range);
} else {
DAWN_TRY(ToBackend(destination.texture)->EnsureSubresourceContentInitialized(range));
diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp
index 99ac041..b9cbca6 100644
--- a/src/dawn/native/opengl/TextureGL.cpp
+++ b/src/dawn/native/opengl/TextureGL.cpp
@@ -193,7 +193,7 @@
gl.BindTexture(mTarget, mHandle);
- AllocateTexture(gl, mTarget, GetSampleCount(), levels, glFormat.internalFormat, GetSize());
+ AllocateTexture(gl, mTarget, GetSampleCount(), levels, glFormat.internalFormat, GetBaseSize());
// The texture is not complete if it uses mipmapping and not all levels up to
// MAX_LEVEL have been defined.
@@ -375,7 +375,7 @@
const GLFormat& glFormat = GetGLFormat();
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
- Extent3D mipSize = GetMipLevelSingleSubresourcePhysicalSize(level);
+ Extent3D mipSize = GetMipLevelSingleSubresourcePhysicalSize(level, Aspect::Color);
for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero &&
@@ -441,8 +441,9 @@
DoClear();
break;
case wgpu::TextureDimension::e3D:
- uint32_t depth = GetMipLevelSingleSubresourceVirtualSize(level)
- .depthOrArrayLayers;
+ uint32_t depth =
+ GetMipLevelSingleSubresourceVirtualSize(level, Aspect::Color)
+ .depthOrArrayLayers;
for (GLint z = 0; z < static_cast<GLint>(depth); ++z) {
gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachment,
GetHandle(), level, z);
@@ -471,7 +472,8 @@
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(Aspect::Color).block;
DAWN_ASSERT(kTextureBytesPerRowAlignment % blockInfo.byteSize == 0);
- Extent3D largestMipSize = GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel);
+ Extent3D largestMipSize =
+ GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel, Aspect::Color);
uint32_t bytesPerRow =
Align((largestMipSize.width / blockInfo.width) * blockInfo.byteSize, 4);
@@ -515,7 +517,7 @@
dataLayout.bytesPerRow = bytesPerRow;
dataLayout.rowsPerImage = largestMipSize.height;
- Extent3D mipSize = GetMipLevelSingleSubresourcePhysicalSize(level);
+ Extent3D mipSize = GetMipLevelSingleSubresourcePhysicalSize(level, Aspect::Color);
for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
@@ -647,8 +649,8 @@
uint32_t srcLevel = GetBaseMipLevel();
uint32_t numLevels = GetLevelCount();
- uint32_t width = texture->GetWidth() >> srcLevel;
- uint32_t height = texture->GetHeight() >> srcLevel;
+ uint32_t width = GetSingleSubresourceVirtualSize().width;
+ uint32_t height = GetSingleSubresourceVirtualSize().height;
Extent3D size{width, height, GetLayerCount()};
if (mHandle == 0) {
diff --git a/src/dawn/native/vulkan/CommandBufferVk.cpp b/src/dawn/native/vulkan/CommandBufferVk.cpp
index 78d3dd8..2faf05e 100644
--- a/src/dawn/native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn/native/vulkan/CommandBufferVk.cpp
@@ -579,7 +579,7 @@
GetSubresourcesAffectedByCopy(copy->destination, copy->copySize);
if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize,
- subresource.mipLevel)) {
+ subresource.mipLevel, dst.aspect)) {
// Since texture has been overwritten, it has been "initialized"
dst.texture->SetIsSubresourceContentInitialized(true, range);
} else {
@@ -647,8 +647,8 @@
DAWN_TRY(ToBackend(src.texture)
->EnsureSubresourceContentInitialized(recordingContext, srcRange));
- if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize,
- dst.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel,
+ dst.aspect)) {
// Since destination texture has been overwritten, it has been "initialized"
dst.texture->SetIsSubresourceContentInitialized(true, dstRange);
} else {
diff --git a/src/dawn/native/vulkan/DeviceVk.cpp b/src/dawn/native/vulkan/DeviceVk.cpp
index 63ac944..455add0 100644
--- a/src/dawn/native/vulkan/DeviceVk.cpp
+++ b/src/dawn/native/vulkan/DeviceVk.cpp
@@ -801,7 +801,8 @@
SubresourceRange range = GetSubresourcesAffectedByCopy(dst, copySizePixels);
- if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copySizePixels, subresource.mipLevel)) {
+ if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copySizePixels, subresource.mipLevel,
+ dst.aspect)) {
// Since texture has been overwritten, it has been "initialized"
dst.texture->SetIsSubresourceContentInitialized(true, range);
} else {
diff --git a/src/dawn/native/vulkan/SwapChainVk.cpp b/src/dawn/native/vulkan/SwapChainVk.cpp
index 0fe1bd2..d7ca5c0 100644
--- a/src/dawn/native/vulkan/SwapChainVk.cpp
+++ b/src/dawn/native/vulkan/SwapChainVk.cpp
@@ -551,13 +551,13 @@
region.srcSubresource.baseArrayLayer = 0;
region.srcSubresource.layerCount = 1;
region.srcOffsets[0] = {0, 0, 0};
- region.srcOffsets[1] = {static_cast<int32_t>(mBlitTexture->GetWidth()),
- static_cast<int32_t>(mBlitTexture->GetHeight()), 1};
+ region.srcOffsets[1] = {static_cast<int32_t>(mBlitTexture->GetWidth(Aspect::Color)),
+ static_cast<int32_t>(mBlitTexture->GetHeight(Aspect::Color)), 1};
region.dstSubresource = region.srcSubresource;
region.dstOffsets[0] = {0, 0, 0};
- region.dstOffsets[1] = {static_cast<int32_t>(mTexture->GetWidth()),
- static_cast<int32_t>(mTexture->GetHeight()), 1};
+ region.dstOffsets[1] = {static_cast<int32_t>(mTexture->GetWidth(Aspect::Color)),
+ static_cast<int32_t>(mTexture->GetHeight(Aspect::Color)), 1};
device->fn.CmdBlitImage(recordingContext->commandBuffer, mBlitTexture->GetHandle(),
mBlitTexture->GetCurrentLayoutForSwapChain(), mTexture->GetHandle(),
diff --git a/src/dawn/native/vulkan/TextureVk.cpp b/src/dawn/native/vulkan/TextureVk.cpp
index ac52da5..d71df30 100644
--- a/src/dawn/native/vulkan/TextureVk.cpp
+++ b/src/dawn/native/vulkan/TextureVk.cpp
@@ -190,7 +190,7 @@
}
void FillVulkanCreateInfoSizesAndType(const Texture& texture, VkImageCreateInfo* info) {
- const Extent3D& size = texture.GetSize();
+ const Extent3D& size = texture.GetBaseSize();
info->mipLevels = texture.GetNumMipLevels();
info->samples = VulkanSampleCount(texture.GetSampleCount());
@@ -746,7 +746,7 @@
DAWN_ASSERT(IsSampleCountSupported(device, createInfo));
- if (GetArrayLayers() >= 6 && GetWidth() == GetHeight()) {
+ if (GetArrayLayers() >= 6 && GetBaseSize().width == GetBaseSize().height) {
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
}
@@ -794,7 +794,7 @@
format == wgpu::TextureFormat::RGBA32Float;
textureIsBuggy &= GetNumMipLevels() > 1;
textureIsBuggy &= GetDimension() == wgpu::TextureDimension::e2D;
- textureIsBuggy &= IsPowerOfTwo(GetWidth()) && IsPowerOfTwo(GetHeight());
+ textureIsBuggy &= IsPowerOfTwo(GetBaseSize().width) && IsPowerOfTwo(GetBaseSize().height);
if (textureIsBuggy) {
DAWN_TRY(ClearTexture(ToBackend(GetDevice())->GetPendingRecordingContext(),
GetAllSubresources(), TextureBase::ClearValue::Zero));
@@ -1290,8 +1290,8 @@
range.aspects == Aspect::Plane1);
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
- Extent3D largestMipSize = GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel);
- largestMipSize = GetFormat().GetAspectSize(range.aspects, largestMipSize);
+ Extent3D largestMipSize =
+ GetMipLevelSingleSubresourcePhysicalSize(range.baseMipLevel, range.aspects);
uint32_t bytesPerRow = Align((largestMipSize.width / blockInfo.width) * blockInfo.byteSize,
device->GetOptimalBytesPerRowAlignment());
@@ -1307,8 +1307,7 @@
std::vector<VkBufferImageCopy> regions;
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
- Extent3D copySize = GetMipLevelSingleSubresourcePhysicalSize(level);
- copySize = GetFormat().GetAspectSize(range.aspects, copySize);
+ Extent3D copySize = GetMipLevelSingleSubresourcePhysicalSize(level, range.aspects);
imageRange.baseMipLevel = level;
for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
diff --git a/src/dawn/native/vulkan/UtilsVulkan.cpp b/src/dawn/native/vulkan/UtilsVulkan.cpp
index 7080e11..0d651ef 100644
--- a/src/dawn/native/vulkan/UtilsVulkan.cpp
+++ b/src/dawn/native/vulkan/UtilsVulkan.cpp
@@ -115,7 +115,7 @@
Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel =
- texture->GetMipLevelSingleSubresourceVirtualSize(textureCopy.mipLevel);
+ texture->GetMipLevelSingleSubresourceVirtualSize(textureCopy.mipLevel, textureCopy.aspect);
DAWN_ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
DAWN_ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
diff --git a/src/dawn/tests/end2end/VideoViewsTests.cpp b/src/dawn/tests/end2end/VideoViewsTests.cpp
index 77c36e5..161214f 100644
--- a/src/dawn/tests/end2end/VideoViewsTests.cpp
+++ b/src/dawn/tests/end2end/VideoViewsTests.cpp
@@ -773,13 +773,13 @@
wgpu::Texture srcTexture = platformTexture->wgpuTexture;
wgpu::BufferDescriptor bufferDescriptor;
- bufferDescriptor.size = 1;
+ bufferDescriptor.size = 256;
bufferDescriptor.usage = wgpu::BufferUsage::CopyDst;
wgpu::Buffer dstBuffer = device.CreateBuffer(&bufferDescriptor);
wgpu::ImageCopyTexture copySrc = utils::CreateImageCopyTexture(srcTexture, 0, {0, 0, 0});
- wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(dstBuffer, 0, 4);
+ wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(dstBuffer, 0, 256);
wgpu::Extent3D copySize = {1, 1, 1};
@@ -799,14 +799,14 @@
wgpu::Texture srcTexture = platformTexture->wgpuTexture;
wgpu::BufferDescriptor bufferDescriptor;
- bufferDescriptor.size = 1;
+ bufferDescriptor.size = 256;
bufferDescriptor.usage = wgpu::BufferUsage::CopyDst;
wgpu::Buffer dstBuffer = device.CreateBuffer(&bufferDescriptor);
wgpu::ImageCopyTexture copySrc =
utils::CreateImageCopyTexture(srcTexture, 0, {0, 0, 0}, wgpu::TextureAspect::Plane0Only);
- wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(dstBuffer, 0, 4);
+ wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(dstBuffer, 0, 256);
wgpu::Extent3D copySize = {1, 1, 1};
@@ -1433,6 +1433,62 @@
}
}
+// Test copying from a multi-planar format to a buffer fails if texture aspect is not single plane.
+TEST_P(VideoViewsExtendedUsagesTests, T2BCopyAllAspectsFails) {
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
+
+ auto srcTexture =
+ CreateMultiPlanarTexture(wgpu::TextureFormat::R8BG8Biplanar420Unorm,
+ wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc,
+ /*isCheckerboard*/ false,
+ /*initialized*/ true);
+
+ wgpu::BufferDescriptor bufferDescriptor;
+ bufferDescriptor.size = 256;
+ bufferDescriptor.usage = wgpu::BufferUsage::CopyDst;
+ wgpu::Buffer dstBuffer = device.CreateBuffer(&bufferDescriptor);
+
+ wgpu::ImageCopyTexture copySrc =
+ utils::CreateImageCopyTexture(srcTexture, 0, {0, 0, 0}, wgpu::TextureAspect::All);
+
+ wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(dstBuffer, 0, 256);
+
+ wgpu::Extent3D copySize = {1, 1, 1};
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ encoder.CopyTextureToBuffer(©Src, ©Dst, ©Size);
+ ASSERT_DEVICE_ERROR_MSG(encoder.Finish(), testing::HasSubstr("More than a single aspect"));
+}
+
+// Test copying from one multi-planar formatted texture into another fails even if
+// MultiPlanarFormatExtendedUsages is enabled.
+TEST_P(VideoViewsExtendedUsagesTests, T2TCopyPlaneAspectFails) {
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
+
+ auto srcTexture =
+ CreateMultiPlanarTexture(wgpu::TextureFormat::R8BG8Biplanar420Unorm,
+ wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc,
+ /*isCheckerboard*/ false,
+ /*initialized*/ true);
+ auto dstTexture =
+ CreateMultiPlanarTexture(wgpu::TextureFormat::R8BG8Biplanar420Unorm,
+ wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst,
+ /*isCheckerboard*/ false,
+ /*initialized*/ true);
+
+ wgpu::ImageCopyTexture copySrc =
+ utils::CreateImageCopyTexture(srcTexture, 0, {0, 0, 0}, wgpu::TextureAspect::Plane0Only);
+
+ wgpu::ImageCopyTexture copyDst =
+ utils::CreateImageCopyTexture(dstTexture, 0, {0, 0, 0}, wgpu::TextureAspect::Plane0Only);
+
+ wgpu::Extent3D copySize = {1, 1, 1};
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ encoder.CopyTextureToTexture(©Src, ©Dst, ©Size);
+ ASSERT_DEVICE_ERROR_MSG(encoder.Finish(), testing::HasSubstr("not allowed"));
+}
+
DAWN_INSTANTIATE_TEST_B(VideoViewsTests,
VideoViewsTestBackend::Backends(),
VideoViewsTestBackend::Formats());