diff --git a/dawn.json b/dawn.json index 095bcfc699..9c3f328265 100644 --- a/dawn.json +++ b/dawn.json @@ -1022,6 +1022,11 @@ {"name": "external texture descriptor", "type": "external texture descriptor", "annotation": "const*"} ] }, + { + "name": "create error external texture", + "returns": "external texture", + "tags": ["dawn"] + }, { "name": "create pipeline layout", "returns": "pipeline layout", diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index ab133bd7bc..f0a216d043 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp @@ -1222,6 +1222,10 @@ BufferBase* DeviceBase::APICreateErrorBuffer() { return BufferBase::MakeError(this, &desc); } +ExternalTextureBase* DeviceBase::APICreateErrorExternalTexture() { + return ExternalTextureBase::MakeError(this); +} + // Other Device API methods // Returns true if future ticking is needed. diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h index dc14e15257..e9fab16507 100644 --- a/src/dawn/native/Device.h +++ b/src/dawn/native/Device.h @@ -264,6 +264,8 @@ class DeviceBase : public RefCountedWithExternalCount { // For Dawn Wire BufferBase* APICreateErrorBuffer(); + ExternalTextureBase* APICreateErrorExternalTexture(); + QueueBase* APIGetQueue(); bool APIGetLimits(SupportedLimits* limits) const; diff --git a/src/dawn/native/ExternalTexture.cpp b/src/dawn/native/ExternalTexture.cpp index 978fb9eab9..a23faa7bdc 100644 --- a/src/dawn/native/ExternalTexture.cpp +++ b/src/dawn/native/ExternalTexture.cpp @@ -123,8 +123,9 @@ ExternalTextureBase::ExternalTextureBase(DeviceBase* device) TrackInDevice(); } +// Error external texture cannot be used in bind group. ExternalTextureBase::ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag) - : ApiObjectBase(device, tag) {} + : ApiObjectBase(device, tag), mState(ExternalTextureState::Destroyed) {} ExternalTextureBase::~ExternalTextureBase() = default; diff --git a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp index 5f70dd7138..246ce5b625 100644 --- a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp +++ b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp @@ -541,4 +541,28 @@ TEST_F(ExternalTextureTest, BindGroupDoesNotMatchLayout) { } } +// Ensure that bind group validation catches error external textures. +TEST_F(ExternalTextureTest, UseErrorExternalTextureInBindGroup) { + // Control case should succeed. + { + wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor(); + wgpu::Texture texture = device.CreateTexture(&textureDescriptor); + + wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor(); + externalDesc.plane0 = texture.CreateView(); + wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc); + wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout( + device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}}); + utils::MakeBindGroup(device, bgl, {{0, externalTexture}}); + } + + // Bind group creation should fail when an error external texture is present. + { + wgpu::ExternalTexture errorExternalTexture = device.CreateErrorExternalTexture(); + wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout( + device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}}); + ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl, {{0, errorExternalTexture}})); + } +} + } // namespace