From 44771b3567de6fec18712ea107f748ce41d6804d Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Wed, 7 Apr 2021 17:00:42 +0000 Subject: [PATCH] Fix a bug for multisample texture validation If a texture format supports multisample, it should be renderable. This change adds this validation rule to fix a bug. It also adds a validation test in dawn_unittests. BUG: dawn:731 Change-Id: I33a06cb16367e4e379b29b223ef6b69128baf30f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/46840 Reviewed-by: Corentin Wallez Reviewed-by: Austin Eng Commit-Queue: Yunchao He --- src/dawn_native/Texture.cpp | 10 +++++-- .../validation/TextureValidationTests.cpp | 28 +++++++++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp index f03c202eb5..55eb68fb1f 100644 --- a/src/dawn_native/Texture.cpp +++ b/src/dawn_native/Texture.cpp @@ -122,10 +122,14 @@ namespace dawn_native { return DAWN_VALIDATION_ERROR("Multisampled texture must be 2D with depth=1"); } - if (format->isCompressed) { - return DAWN_VALIDATION_ERROR( - "The sample counts of the textures in BC formats must be 1."); + // If a format can support multisample, it must be renderable. Because Vulkan + // requires that if the format is not color-renderable or depth/stencil renderable, + // sampleCount must be 1. + if (!format->isRenderable) { + return DAWN_VALIDATION_ERROR("This format cannot support multisample."); } + // Compressed formats are not renderable. They cannot support multisample. + ASSERT(!format->isCompressed); if (descriptor->usage & wgpu::TextureUsage::Storage) { return DAWN_VALIDATION_ERROR( diff --git a/src/tests/unittests/validation/TextureValidationTests.cpp b/src/tests/unittests/validation/TextureValidationTests.cpp index 48da264dde..6c90b09f24 100644 --- a/src/tests/unittests/validation/TextureValidationTests.cpp +++ b/src/tests/unittests/validation/TextureValidationTests.cpp @@ -21,6 +21,12 @@ namespace { + constexpr wgpu::TextureFormat kNonRenderableColorFormats[] = { + wgpu::TextureFormat::RG11B10Ufloat, wgpu::TextureFormat::RGB9E5Ufloat, + wgpu::TextureFormat::R8Snorm, wgpu::TextureFormat::RG8Snorm, + wgpu::TextureFormat::RGBA8Snorm, + }; + class TextureValidationTest : public ValidationTest { protected: void SetUp() override { @@ -105,6 +111,19 @@ namespace { ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor)); } + // It is an error to create a multisample texture when the format cannot support + // multisample. + { + wgpu::TextureDescriptor descriptor = defaultDescriptor; + descriptor.sampleCount = 4; + + for (wgpu::TextureFormat format : kNonRenderableColorFormats) { + // If a format can support multisample, it must be renderable. + descriptor.format = format; + ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor)); + } + } + // Currently we do not support multisampled 2D textures with depth>1. { wgpu::TextureDescriptor descriptor = defaultDescriptor; @@ -453,14 +472,7 @@ namespace { descriptor.format = wgpu::TextureFormat::RGBA8Unorm; device.CreateTexture(&descriptor); - wgpu::TextureFormat nonRenderableFormats[] = { - wgpu::TextureFormat::RG11B10Ufloat, - wgpu::TextureFormat::R8Snorm, - wgpu::TextureFormat::RG8Snorm, - wgpu::TextureFormat::RGBA8Snorm, - }; - - for (wgpu::TextureFormat format : nonRenderableFormats) { + for (wgpu::TextureFormat format : kNonRenderableColorFormats) { // Fails because `format` is non-renderable descriptor.format = format; ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));