From 10ec4ee7efb3c0fd10bdb7191da77cdd6d063ea9 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Thu, 31 Mar 2022 01:26:49 +0000 Subject: [PATCH] Disallow creating a 2D-array view on a multisampled texture Spec issue: https://github.com/gpuweb/gpuweb/issues/2715 Spec PR: https://github.com/gpuweb/gpuweb/pull/2716 This is invalid in the Metal API because MTLTextureType2DArray is imcompatible with MTLTextureType2DMultisample, even if the layer count is 1. MTLTextureType2DMultisampleArray is not supported until macOS 10.14 and iOS 14.0. Further, the view type must match between the API and the shader. a 2D view array requires texture2d_array in MSL. It would be inconsistent to allow 1-layer 2D arrays which internally get translated as (non-array) MTLTextureType2DMultisample. You would expect to need to use texture2d_ms_array in the shader. Change-Id: Ib9268c1276d3d31e90d6c61118e27fa2afd0617d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/85200 Reviewed-by: Loko Kung Commit-Queue: Austin Eng --- src/dawn/native/Texture.cpp | 5 +++ .../end2end/MultisampledRenderingTests.cpp | 27 -------------- .../validation/TextureViewValidationTests.cpp | 35 +++++++++++++++++++ 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp index c7664363d8..0e64f62486 100644 --- a/src/dawn/native/Texture.cpp +++ b/src/dawn/native/Texture.cpp @@ -144,6 +144,11 @@ namespace dawn::native { "of %s.", descriptor->dimension, texture->GetDimension(), texture); + DAWN_INVALID_IF(texture->GetSampleCount() > 1 && + descriptor->dimension != wgpu::TextureViewDimension::e2D, + "The dimension (%s) of the multisampled texture view is not %s.", + descriptor->dimension, wgpu::TextureViewDimension::e2D); + switch (descriptor->dimension) { case wgpu::TextureViewDimension::Cube: case wgpu::TextureViewDimension::CubeArray: diff --git a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp index 0ad7f62dc3..5c00237be1 100644 --- a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp +++ b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp @@ -313,33 +313,6 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) { } } -// Test that a single-layer multisampled texture view can be created and resolved from. -TEST_P(MultisampledRenderingTest, ResolveFromSingleLayerArrayInto2DTexture) { - constexpr bool kTestDepth = false; - wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); - wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth); - - constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f}; - - // Draw a green triangle. - { - wgpu::TextureViewDescriptor desc = {}; - desc.dimension = wgpu::TextureViewDimension::e2DArray; - desc.arrayLayerCount = 1; - - utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest( - {mMultisampledColorTexture.CreateView(&desc)}, {mResolveView}, wgpu::LoadOp::Clear, - wgpu::LoadOp::Clear, kTestDepth); - - EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen); - } - - wgpu::CommandBuffer commandBuffer = commandEncoder.Finish(); - queue.Submit(1, &commandBuffer); - - VerifyResolveTarget(kGreen, mResolveTexture); -} - // Test multisampled rendering with depth test works correctly. TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTest) { constexpr bool kTestDepth = true; diff --git a/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp b/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp index f56243ddc3..b10973038c 100644 --- a/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp @@ -405,6 +405,41 @@ namespace { // a single mip and layer. } + // Test creating texture view on a multisampled 2D texture + TEST_F(TextureViewValidationTest, CreateTextureViewOnMultisampledTexture2D) { + wgpu::Texture texture = + Create2DArrayTexture(device, /* arrayLayerCount */ 1, kWidth, kHeight, + /* mipLevelCount */ 1, /* sampleCount */ 4); + + // It is OK to create a 2D texture view on a multisampled 2D texture. + { + wgpu::TextureViewDescriptor descriptor = {}; + texture.CreateView(&descriptor); + } + + // It is an error to create a 1-layer 2D array texture view on a multisampled 2D texture. + { + wgpu::TextureViewDescriptor descriptor = {}; + descriptor.dimension = wgpu::TextureViewDimension::e2DArray; + descriptor.arrayLayerCount = 1; + ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor)); + } + + // It is an error to create a 1D texture view on a multisampled 2D texture. + { + wgpu::TextureViewDescriptor descriptor = {}; + descriptor.dimension = wgpu::TextureViewDimension::e1D; + ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor)); + } + + // It is an error to create a 3D texture view on a multisampled 2D texture. + { + wgpu::TextureViewDescriptor descriptor = {}; + descriptor.dimension = wgpu::TextureViewDimension::e3D; + ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor)); + } + } + // Using the "none" ("default") values validates the same as explicitly // specifying the values they're supposed to default to. // Variant for a 2D texture with more than 1 array layer.