Allow creating texture views from destroyed textures
Bug: dawn:1031
Change-Id: I3af52d5c53c4ccf2c30a4eccb9c50dfe2e822f25
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/60221
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp
index a5e91d2..2c43bc1 100644
--- a/src/dawn_native/Texture.cpp
+++ b/src/dawn_native/Texture.cpp
@@ -323,9 +323,6 @@
// Parent texture should have been already validated.
ASSERT(texture);
ASSERT(!texture->IsError());
- if (texture->GetTextureState() == TextureBase::TextureState::Destroyed) {
- return DAWN_VALIDATION_ERROR("Destroyed texture used to create texture view");
- }
DAWN_TRY(ValidateTextureViewDimension(descriptor->dimension));
if (descriptor->dimension == wgpu::TextureViewDimension::e1D) {
diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm
index fbce964..bcc1652 100644
--- a/src/dawn_native/metal/TextureMTL.mm
+++ b/src/dawn_native/metal/TextureMTL.mm
@@ -660,6 +660,12 @@
MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) {
Texture* texture = ToBackend(GetTexture());
+
+ // Texture could be destroyed by the time we make a view.
+ if (GetTexture()->GetTextureState() == Texture::TextureState::Destroyed) {
+ return {};
+ }
+
id<MTLTexture> mtlTexture = texture->GetMTLTexture();
if (!UsageNeedsTextureView(texture->GetInternalUsage())) {
diff --git a/src/dawn_native/opengl/TextureGL.cpp b/src/dawn_native/opengl/TextureGL.cpp
index dc4cddf..f58030e 100644
--- a/src/dawn_native/opengl/TextureGL.cpp
+++ b/src/dawn_native/opengl/TextureGL.cpp
@@ -533,6 +533,11 @@
mTarget = TargetForTextureViewDimension(descriptor->dimension, descriptor->arrayLayerCount,
texture->GetSampleCount());
+ // Texture could be destroyed by the time we make a view.
+ if (GetTexture()->GetTextureState() == Texture::TextureState::Destroyed) {
+ return;
+ }
+
if (!UsageNeedsTextureView(texture->GetUsage())) {
mHandle = 0;
} else if (!RequiresCreatingNewTextureView(texture, descriptor)) {
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp
index 348861a..36c296e 100644
--- a/src/dawn_native/vulkan/TextureVk.cpp
+++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -1180,6 +1180,11 @@
return {};
}
+ // Texture could be destroyed by the time we make a view.
+ if (GetTexture()->GetTextureState() == Texture::TextureState::Destroyed) {
+ return {};
+ }
+
Device* device = ToBackend(GetTexture()->GetDevice());
VkImageViewCreateInfo createInfo;
diff --git a/src/tests/end2end/TextureViewTests.cpp b/src/tests/end2end/TextureViewTests.cpp
index afacd94..f38a4d9 100644
--- a/src/tests/end2end/TextureViewTests.cpp
+++ b/src/tests/end2end/TextureViewTests.cpp
@@ -679,6 +679,23 @@
wgpu::TextureView view = texture.CreateView();
}
+// Test that a texture view can be created from a destroyed texture without
+// backend errors.
+TEST_P(TextureViewTest, DestroyedTexture) {
+ wgpu::TextureDescriptor descriptor;
+ descriptor.size = {4, 4, 2};
+ descriptor.usage = wgpu::TextureUsage::Sampled | wgpu::TextureUsage::CopyDst;
+ descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
+
+ wgpu::Texture texture = device.CreateTexture(&descriptor);
+ texture.Destroy();
+
+ wgpu::TextureViewDescriptor viewDesc = {};
+ viewDesc.baseArrayLayer = 1;
+ viewDesc.arrayLayerCount = 1;
+ wgpu::TextureView view = texture.CreateView(&viewDesc);
+}
+
DAWN_INSTANTIATE_TEST(TextureViewTest,
D3D12Backend(),
MetalBackend(),
diff --git a/src/tests/unittests/validation/TextureViewValidationTests.cpp b/src/tests/unittests/validation/TextureViewValidationTests.cpp
index e60ba91..7f633bf 100644
--- a/src/tests/unittests/validation/TextureViewValidationTests.cpp
+++ b/src/tests/unittests/validation/TextureViewValidationTests.cpp
@@ -510,13 +510,13 @@
}
}
- // Test that it's invalid to create a texture view from a destroyed texture
+ // Test that it's valid to create a texture view from a destroyed texture
TEST_F(TextureViewValidationTest, DestroyCreateTextureView) {
wgpu::Texture texture = Create2DArrayTexture(device, 1);
wgpu::TextureViewDescriptor descriptor =
CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
texture.Destroy();
- ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
+ texture.CreateView(&descriptor);
}
// Test that the selected TextureAspects must exist in the texture format