Improve validation errors for CreateExternalTexture
Also adds a label to ExternalTextureDescriptor to match the pattern of
all other descriptors.
Also adds missing validation that the planes must not be multisampled
(with a test) and fixes the validation unittests to not leak state from
one test to another (so they test exactly what they need to).
Bug: dawn:563
Change-Id: I88a4d7a859e67e5af85efd5ba16572c9014df6ad
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65562
Reviewed-by: Brandon Jones <bajones@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/dawn.json b/dawn.json
index 1e92c03..3d2c0f7 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1154,6 +1154,7 @@
"extensible": "in",
"tags": ["dawn"],
"members": [
+ {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
{"name": "plane 0", "type": "texture view"},
{"name": "format", "type": "texture format"}
]
diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp
index 30883f3..7077d6a 100644
--- a/src/dawn_native/Device.cpp
+++ b/src/dawn_native/Device.cpp
@@ -1287,7 +1287,8 @@
ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTexture(
const ExternalTextureDescriptor* descriptor) {
if (IsValidationEnabled()) {
- DAWN_TRY(ValidateExternalTextureDescriptor(this, descriptor));
+ DAWN_TRY_CONTEXT(ValidateExternalTextureDescriptor(this, descriptor), "validating %s",
+ descriptor);
}
return ExternalTextureBase::Create(this, descriptor);
diff --git a/src/dawn_native/ExternalTexture.cpp b/src/dawn_native/ExternalTexture.cpp
index d70b9b7..148e24d 100644
--- a/src/dawn_native/ExternalTexture.cpp
+++ b/src/dawn_native/ExternalTexture.cpp
@@ -30,23 +30,22 @@
"at least one of the passed texture views.");
}
- if ((textureView->GetTexture()->GetUsage() & wgpu::TextureUsage::TextureBinding) !=
- wgpu::TextureUsage::TextureBinding) {
- return DAWN_VALIDATION_ERROR(
- "The external texture descriptor specifies a texture that was not created with "
- "TextureUsage::TextureBinding.");
- }
+ DAWN_INVALID_IF(
+ (textureView->GetTexture()->GetUsage() & wgpu::TextureUsage::TextureBinding) == 0,
+ "The external texture plane (%s) usage (%s) doesn't include the required usage (%s)",
+ textureView, textureView->GetTexture()->GetUsage(), wgpu::TextureUsage::TextureBinding);
- if (textureView->GetDimension() != wgpu::TextureViewDimension::e2D) {
- return DAWN_VALIDATION_ERROR(
- "The external texture descriptor contains a texture view with a non-2D dimension.");
- }
+ DAWN_INVALID_IF(textureView->GetDimension() != wgpu::TextureViewDimension::e2D,
+ "The external texture plane (%s) dimension (%s) is not 2D.", textureView,
+ textureView->GetDimension());
- if (textureView->GetLevelCount() > 1) {
- return DAWN_VALIDATION_ERROR(
- "The external texture descriptor contains a texture view with a level count "
- "greater than 1.");
- }
+ DAWN_INVALID_IF(textureView->GetLevelCount() > 1,
+ "The external texture plane (%s) mip level count (%u) is not 1.",
+ textureView, textureView->GetLevelCount());
+
+ DAWN_INVALID_IF(textureView->GetTexture()->GetSampleCount() != 1,
+ "The external texture plane (%s) sample count (%u) is not one.",
+ textureView, textureView->GetTexture()->GetSampleCount());
return {};
}
@@ -66,11 +65,14 @@
case wgpu::TextureFormat::RGBA8Unorm:
case wgpu::TextureFormat::BGRA8Unorm:
case wgpu::TextureFormat::RGBA16Float:
- DAWN_TRY(ValidateExternalTexturePlane(descriptor->plane0, descriptor->format));
+ DAWN_TRY_CONTEXT(
+ ValidateExternalTexturePlane(descriptor->plane0, descriptor->format),
+ "validating plane0 against the external texture format (%s)",
+ descriptor->format);
break;
default:
- return DAWN_VALIDATION_ERROR(
- "The external texture descriptor specifies an unsupported format.");
+ return DAWN_FORMAT_VALIDATION_ERROR(
+ "Format (%s) is not a supported external texture format.", descriptor->format);
}
return {};
@@ -102,9 +104,8 @@
MaybeError ExternalTextureBase::ValidateCanUseInSubmitNow() const {
ASSERT(!IsError());
- if (mState == ExternalTextureState::Destroyed) {
- return DAWN_VALIDATION_ERROR("Destroyed external texture used in a submit");
- }
+ DAWN_INVALID_IF(mState == ExternalTextureState::Destroyed,
+ "Destroyed external texture %s is used in a submit.", this);
return {};
}
diff --git a/src/tests/unittests/validation/ExternalTextureTests.cpp b/src/tests/unittests/validation/ExternalTextureTests.cpp
index c484d5c..8e22c8f 100644
--- a/src/tests/unittests/validation/ExternalTextureTests.cpp
+++ b/src/tests/unittests/validation/ExternalTextureTests.cpp
@@ -54,37 +54,49 @@
};
TEST_F(ExternalTextureTest, CreateExternalTextureValidation) {
- wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
- wgpu::ExternalTextureDescriptor externalDesc;
- externalDesc.format = kDefaultTextureFormat;
-
// Creating an external texture from a 2D, single-subresource texture should succeed.
{
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
externalDesc.plane0 = texture.CreateView();
device.CreateExternalTexture(&externalDesc);
}
// Creating an external texture with a mismatched texture view format should fail.
{
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
textureDescriptor.format = wgpu::TextureFormat::RGBA8Uint;
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
externalDesc.plane0 = texture.CreateView();
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
// Creating an external texture from a non-2D texture should fail.
{
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
textureDescriptor.dimension = wgpu::TextureDimension::e3D;
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
externalDesc.plane0 = internalTexture.CreateView();
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
// Creating an external texture from a texture with mip count > 1 should fail.
{
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
textureDescriptor.mipLevelCount = 2;
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
externalDesc.plane0 = internalTexture.CreateView();
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
@@ -92,25 +104,45 @@
// Creating an external texture from a texture without TextureUsage::TextureBinding should
// fail.
{
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
textureDescriptor.mipLevelCount = 2;
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
externalDesc.plane0 = internalTexture.CreateView();
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
// Creating an external texture with an unsupported format should fail.
{
- constexpr wgpu::TextureFormat kUnsupportedFormat = wgpu::TextureFormat::R8Uint;
- textureDescriptor.format = kUnsupportedFormat;
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
+ textureDescriptor.format = wgpu::TextureFormat::R8Uint;
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
externalDesc.plane0 = internalTexture.CreateView();
- externalDesc.format = kUnsupportedFormat;
+ externalDesc.format = textureDescriptor.format;
+ ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
+ }
+
+ // Creating an external texture with an multisampled texture should fail.
+ {
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
+ textureDescriptor.sampleCount = 4;
+ wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
+
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
+ externalDesc.plane0 = internalTexture.CreateView();
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
// Creating an external texture with an error texture view should fail.
{
+ wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
+
wgpu::TextureViewDescriptor errorViewDescriptor;
errorViewDescriptor.format = kDefaultTextureFormat;
errorViewDescriptor.dimension = wgpu::TextureViewDimension::e2D;
@@ -119,6 +151,8 @@
ASSERT_DEVICE_ERROR(wgpu::TextureView errorTextureView =
internalTexture.CreateView(&errorViewDescriptor));
+ wgpu::ExternalTextureDescriptor externalDesc;
+ externalDesc.format = kDefaultTextureFormat;
externalDesc.plane0 = errorTextureView;
externalDesc.format = kDefaultTextureFormat;
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
@@ -321,4 +355,4 @@
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
}
}
-} // namespace
\ No newline at end of file
+} // namespace