[dawn][opengl] Add texture component swizzle feature support

Bug: 414312052
Change-Id: I40bc798ad188eca376fb6e3e8cb4c8e94b23868e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/253156
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Fr <beaufort.francois@gmail.com>
Reviewed-by: Zhaoming Jiang <zhaoming.jiang@microsoft.com>
diff --git a/src/dawn/native/CommandBufferStateTracker.cpp b/src/dawn/native/CommandBufferStateTracker.cpp
index 728c0bd..a17fb58 100644
--- a/src/dawn/native/CommandBufferStateTracker.cpp
+++ b/src/dawn/native/CommandBufferStateTracker.cpp
@@ -287,7 +287,10 @@
            a->GetDimension() == b->GetDimension() && a->GetBaseMipLevel() == b->GetBaseMipLevel() &&
            a->GetLevelCount() == b->GetLevelCount() &&
            a->GetBaseArrayLayer() == b->GetBaseArrayLayer() &&
-           a->GetLayerCount() == b->GetLayerCount();
+           a->GetLayerCount() == b->GetLayerCount() && a->GetSwizzleRed() == b->GetSwizzleRed() &&
+           a->GetSwizzleGreen() == b->GetSwizzleGreen() &&
+           a->GetSwizzleBlue() == b->GetSwizzleBlue() &&
+           a->GetSwizzleAlpha() == b->GetSwizzleAlpha();
 }
 
 using VectorOfTextureViews = absl::InlinedVector<const TextureViewBase*, 8>;
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 3d87d4a..03b29c0 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -57,6 +57,26 @@
 
 namespace {
 
+GLenum ComponentSwizzle(wgpu::ComponentSwizzle swizzle) {
+    switch (swizzle) {
+        case wgpu::ComponentSwizzle::Zero:
+            return GL_ZERO;
+        case wgpu::ComponentSwizzle::One:
+            return GL_ONE;
+        case wgpu::ComponentSwizzle::R:
+            return GL_RED;
+        case wgpu::ComponentSwizzle::G:
+            return GL_GREEN;
+        case wgpu::ComponentSwizzle::B:
+            return GL_BLUE;
+        case wgpu::ComponentSwizzle::A:
+            return GL_ALPHA;
+
+        case wgpu::ComponentSwizzle::Undefined:
+            DAWN_UNREACHABLE();
+    }
+}
+
 GLenum IndexFormatType(wgpu::IndexFormat format) {
     switch (format) {
         case wgpu::IndexFormat::Uint16:
@@ -407,6 +427,20 @@
                         DAWN_GL_TRY(
                             gl, TexParameteri(target, GL_TEXTURE_MAX_LEVEL,
                                               view->GetBaseMipLevel() + view->GetLevelCount() - 1));
+                        if (mPipelineLayout->GetDevice()->HasFeature(
+                                Feature::TextureComponentSwizzle)) {
+                            DAWN_GL_TRY(gl, TexParameteri(target, GL_TEXTURE_SWIZZLE_R,
+                                                          ComponentSwizzle(view->GetSwizzleRed())));
+                            DAWN_GL_TRY(gl,
+                                        TexParameteri(target, GL_TEXTURE_SWIZZLE_G,
+                                                      ComponentSwizzle(view->GetSwizzleGreen())));
+                            DAWN_GL_TRY(gl,
+                                        TexParameteri(target, GL_TEXTURE_SWIZZLE_B,
+                                                      ComponentSwizzle(view->GetSwizzleBlue())));
+                            DAWN_GL_TRY(gl,
+                                        TexParameteri(target, GL_TEXTURE_SWIZZLE_A,
+                                                      ComponentSwizzle(view->GetSwizzleAlpha())));
+                        }
                     }
 
                     // Some texture builtin function data needs emulation to update into the
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 1110457..e3124ad 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -300,6 +300,11 @@
     if (mFunctions.IsGLExtensionSupported("GL_EXT_float_blend")) {
         EnableFeature(Feature::Float32Blendable);
     }
+
+    // TextureComponentSwizzle
+    if (mFunctions.IsAtLeastGLES(3, 0) || mFunctions.IsAtLeastGL(3, 3)) {
+        EnableFeature(Feature::TextureComponentSwizzle);
+    }
 }
 
 namespace {
diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp
index 4c3e99e..7c572a7 100644
--- a/src/dawn/native/opengl/TextureGL.cpp
+++ b/src/dawn/native/opengl/TextureGL.cpp
@@ -125,6 +125,16 @@
         return true;
     }
 
+    // TODO(414312052): Use TextureViewBase::UsesNonDefaultSwizzle() instead of
+    // textureViewDescriptor.
+    if (auto* swizzleDesc = textureViewDescriptor.Get<TextureComponentSwizzleDescriptor>()) {
+        auto swizzle = swizzleDesc->swizzle.WithTrivialFrontendDefaults();
+        if (swizzle.r != wgpu::ComponentSwizzle::R || swizzle.g != wgpu::ComponentSwizzle::G ||
+            swizzle.b != wgpu::ComponentSwizzle::B || swizzle.a != wgpu::ComponentSwizzle::A) {
+            return true;
+        }
+    }
+
     return false;
 }
 
diff --git a/src/dawn/tests/end2end/TextureComponentSwizzleTests.cpp b/src/dawn/tests/end2end/TextureComponentSwizzleTests.cpp
index 3ff2e2f..a38ff8d 100644
--- a/src/dawn/tests/end2end/TextureComponentSwizzleTests.cpp
+++ b/src/dawn/tests/end2end/TextureComponentSwizzleTests.cpp
@@ -46,6 +46,35 @@
     void SetUp() override {
         DawnTest::SetUp();
         DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(wgpu::FeatureName::TextureComponentSwizzle));
+
+        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
+            @group(0) @binding(0) var texture : texture_2d<f32>;
+
+            @vertex fn vs_main(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4f {
+                var pos = array<vec2f, 3>(
+                    vec2f(-1.0, -1.0),
+                    vec2f(-1.0, 3.0),
+                    vec2f(3.0, -1.0)
+                );
+                return vec4f(pos[vertexIndex], 0.0, 1.0);
+            }
+
+            @fragment fn fs_main() -> @location(0) vec4f {
+                // textureLoad samples at an integer coordinate and mip level 0.
+                return textureLoad(texture, vec2i(0, 0), 0);
+            })");
+
+        utils::ComboRenderPipelineDescriptor pipelineDesc;
+        pipelineDesc.vertex.module = module;
+        pipelineDesc.cFragment.module = module;
+        pipeline = device.CreateRenderPipeline(&pipelineDesc);
+
+        wgpu::TextureDescriptor outputTextureDesc = {};
+        outputTextureDesc.usage =
+            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
+        outputTextureDesc.size = {1, 1, 1};
+        outputTextureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
+        outputTexture = device.CreateTexture(&outputTextureDesc);
     }
 
     std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
@@ -89,118 +118,92 @@
         }
     }
 
+    void RunSwizzleTest(TestParams params,
+                        wgpu::Texture inputTexture,
+                        wgpu::ComponentSwizzle swizzleRed,
+                        wgpu::ComponentSwizzle swizzleGreen,
+                        wgpu::ComponentSwizzle swizzleBlue,
+                        wgpu::ComponentSwizzle swizzleAlpha) {
+        wgpu::TexelCopyTextureInfo dest = {.texture = inputTexture};
+        wgpu::TexelCopyBufferLayout dataLayout = {.bytesPerRow = 256, .rowsPerImage = 1};
+        wgpu::Extent3D writeSize = {1, 1, 1};
+        const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(params.format);
+        device.GetQueue().WriteTexture(&dest, params.inputData.data(), bytesPerTexel, &dataLayout,
+                                       &writeSize);
+
+        // Create the TextureView for the input texture with the specified swizzle.
+        wgpu::TextureViewDescriptor viewDesc = {};
+        wgpu::TextureComponentSwizzleDescriptor swizzleDesc = {};
+        swizzleDesc.swizzle.r = swizzleRed;
+        swizzleDesc.swizzle.g = swizzleGreen;
+        swizzleDesc.swizzle.b = swizzleBlue;
+        swizzleDesc.swizzle.a = swizzleAlpha;
+        viewDesc.nextInChain = &swizzleDesc;
+        wgpu::TextureView textureView = inputTexture.CreateView(&viewDesc);
+
+        // Set up bind group using the swizzled texture view.
+        wgpu::BindGroup bindGroup =
+            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, textureView}});
+
+        // Issue render commands.
+        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+        wgpu::RenderPassDescriptor renderPassDesc = {};
+        wgpu::RenderPassColorAttachment colorAttachment = {};
+        colorAttachment.view = outputTexture.CreateView();
+        colorAttachment.loadOp = wgpu::LoadOp::Clear;
+        colorAttachment.storeOp = wgpu::StoreOp::Store;
+        colorAttachment.clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
+        renderPassDesc.colorAttachmentCount = 1;
+        renderPassDesc.colorAttachments = &colorAttachment;
+
+        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc);
+        pass.SetPipeline(pipeline);
+        pass.SetBindGroup(0, bindGroup);
+        pass.Draw(3);
+        pass.End();
+
+        // Submit commands to the queue.
+        wgpu::CommandBuffer commands = encoder.Finish();
+        queue.Submit(1, &commands);
+
+        utils::RGBA8 expectedColor =
+            utils::RGBA8(GetExpectedValue(swizzleRed, params.baseLoadValues),
+                         GetExpectedValue(swizzleGreen, params.baseLoadValues),
+                         GetExpectedValue(swizzleBlue, params.baseLoadValues),
+                         GetExpectedValue(swizzleAlpha, params.baseLoadValues));
+        EXPECT_PIXEL_RGBA8_EQ(expectedColor, outputTexture, 0, 0);
+    }
+
     void RunTest(TestParams params) {
-        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
-            @group(0) @binding(0) var texture : texture_2d<f32>;
-
-            @vertex fn vs_main(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4f {
-                var pos = array<vec2f, 3>(
-                    vec2f(-1.0, -1.0),
-                    vec2f(-1.0, 3.0),
-                    vec2f(3.0, -1.0)
-                );
-                return vec4f(pos[vertexIndex], 0.0, 1.0);
-            }
-
-            @fragment fn fs_main() -> @location(0) vec4f {
-                // textureLoad samples at an integer coordinate and mip level 0.
-                return textureLoad(texture, vec2i(0, 0), 0);
-            })");
-
-        utils::ComboRenderPipelineDescriptor pipelineDesc;
-        pipelineDesc.vertex.module = module;
-        pipelineDesc.cFragment.module = module;
-        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDesc);
-
-        wgpu::TextureDescriptor outputTextureDesc = {};
-        outputTextureDesc.usage =
-            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
-        outputTextureDesc.size = {1, 1, 1};
-        outputTextureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
-        wgpu::Texture outputTexture = device.CreateTexture(&outputTextureDesc);
-
-        auto RunSwizzleTest = [this, params, pipeline, outputTexture](
-                                  wgpu::ComponentSwizzle swizzleRed,
-                                  wgpu::ComponentSwizzle swizzleGreen,
-                                  wgpu::ComponentSwizzle swizzleBlue,
-                                  wgpu::ComponentSwizzle swizzleAlpha) {
-            // Create source texture.
-            wgpu::TextureDescriptor textureDesc = {};
-            textureDesc.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
-            textureDesc.size = {1, 1, 1};
-            textureDesc.format = params.format;
-            wgpu::Texture texture = device.CreateTexture(&textureDesc);
-
-            wgpu::TexelCopyTextureInfo dest = {.texture = texture};
-            wgpu::TexelCopyBufferLayout dataLayout = {.bytesPerRow = 256, .rowsPerImage = 1};
-            wgpu::Extent3D writeSize = {1, 1, 1};
-            const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(params.format);
-            device.GetQueue().WriteTexture(&dest, params.inputData.data(), bytesPerTexel,
-                                           &dataLayout, &writeSize);
-
-            // Create the TextureView for the source texture with the specified swizzle.
-            wgpu::TextureViewDescriptor viewDesc = {};
-            wgpu::TextureComponentSwizzleDescriptor swizzleDesc = {};
-            swizzleDesc.swizzle.r = swizzleRed;
-            swizzleDesc.swizzle.g = swizzleGreen;
-            swizzleDesc.swizzle.b = swizzleBlue;
-            swizzleDesc.swizzle.a = swizzleAlpha;
-            viewDesc.nextInChain = &swizzleDesc;
-            wgpu::TextureView textureView = texture.CreateView(&viewDesc);
-
-            // Set up bind group using the swizzled texture view.
-            wgpu::BindGroup bindGroup =
-                utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, textureView}});
-
-            // Issue render commands.
-            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
-            wgpu::RenderPassDescriptor renderPassDesc = {};
-            wgpu::RenderPassColorAttachment colorAttachment = {};
-            colorAttachment.view = outputTexture.CreateView();
-            colorAttachment.loadOp = wgpu::LoadOp::Clear;
-            colorAttachment.storeOp = wgpu::StoreOp::Store;
-            colorAttachment.clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
-            renderPassDesc.colorAttachmentCount = 1;
-            renderPassDesc.colorAttachments = &colorAttachment;
-
-            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc);
-            pass.SetPipeline(pipeline);
-            pass.SetBindGroup(0, bindGroup);
-            pass.Draw(3);
-            pass.End();
-
-            // Submit commands to the queue.
-            wgpu::CommandBuffer commands = encoder.Finish();
-            queue.Submit(1, &commands);
-
-            utils::RGBA8 expectedColor =
-                utils::RGBA8(GetExpectedValue(swizzleRed, params.baseLoadValues),
-                             GetExpectedValue(swizzleGreen, params.baseLoadValues),
-                             GetExpectedValue(swizzleBlue, params.baseLoadValues),
-                             GetExpectedValue(swizzleAlpha, params.baseLoadValues));
-            EXPECT_PIXEL_RGBA8_EQ(expectedColor, outputTexture, 0, 0);
-        };
+        wgpu::TextureDescriptor textureDesc = {};
+        textureDesc.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
+        textureDesc.size = {1, 1, 1};
+        textureDesc.format = params.format;
+        wgpu::Texture inputTexture = device.CreateTexture(&textureDesc);
 
         for (auto swizzleRed : kComponentSwizzles) {
-            RunSwizzleTest(swizzleRed, wgpu::ComponentSwizzle::G, wgpu::ComponentSwizzle::B,
-                           wgpu::ComponentSwizzle::A);
+            RunSwizzleTest(params, inputTexture, swizzleRed, wgpu::ComponentSwizzle::G,
+                           wgpu::ComponentSwizzle::B, wgpu::ComponentSwizzle::A);
         }
 
         for (auto swizzleGreen : kComponentSwizzles) {
-            RunSwizzleTest(wgpu::ComponentSwizzle::R, swizzleGreen, wgpu::ComponentSwizzle::B,
-                           wgpu::ComponentSwizzle::A);
+            RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R, swizzleGreen,
+                           wgpu::ComponentSwizzle::B, wgpu::ComponentSwizzle::A);
         }
 
         for (auto swizzleBlue : kComponentSwizzles) {
-            RunSwizzleTest(wgpu::ComponentSwizzle::R, wgpu::ComponentSwizzle::G, swizzleBlue,
-                           wgpu::ComponentSwizzle::A);
+            RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R,
+                           wgpu::ComponentSwizzle::G, swizzleBlue, wgpu::ComponentSwizzle::A);
         }
 
         for (auto swizzleAlpha : kComponentSwizzles) {
-            RunSwizzleTest(wgpu::ComponentSwizzle::R, wgpu::ComponentSwizzle::G,
-                           wgpu::ComponentSwizzle::B, swizzleAlpha);
+            RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R,
+                           wgpu::ComponentSwizzle::G, wgpu::ComponentSwizzle::B, swizzleAlpha);
         }
     }
+
+    wgpu::RenderPipeline pipeline;
+    wgpu::Texture outputTexture;
 };
 
 // Test that texture component swizzle works as expected when the 'texture-component-swizzle'
@@ -230,7 +233,35 @@
     RunTest(params);
 }
 
-DAWN_INSTANTIATE_TEST(TextureComponentSwizzleTest, D3D12Backend(), MetalBackend(), VulkanBackend());
+// Test that custom swizzle correctly reorders texture components and that a subsequent use of the
+// default swizzle correctly reverts to the standard component mapping.
+TEST_P(TextureComponentSwizzleTest, UseDefaultSwizzleAfterNonDefaultSwizzle) {
+    TestParams params;
+    params.format = wgpu::TextureFormat::RGBA8Unorm;
+    params.inputData = {255, 128, 64, 0};
+    params.baseLoadValues = {255, 128, 64, 0};
+
+    wgpu::TextureDescriptor textureDesc = {};
+    textureDesc.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
+    textureDesc.size = {1, 1, 1};
+    textureDesc.format = params.format;
+    wgpu::Texture inputTexture = device.CreateTexture(&textureDesc);
+
+    // First, use a non-default swizzle.
+    RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::One, wgpu::ComponentSwizzle::One,
+                   wgpu::ComponentSwizzle::One, wgpu::ComponentSwizzle::One);
+
+    // Then, use a default swizzle.
+    RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R, wgpu::ComponentSwizzle::G,
+                   wgpu::ComponentSwizzle::B, wgpu::ComponentSwizzle::A);
+}
+
+DAWN_INSTANTIATE_TEST(TextureComponentSwizzleTest,
+                      D3D12Backend(),
+                      MetalBackend(),
+                      OpenGLBackend(),
+                      OpenGLESBackend(),
+                      VulkanBackend());
 
 }  // anonymous namespace
 }  // namespace dawn
diff --git a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
index ea74a2a..c163322 100644
--- a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
@@ -2003,6 +2003,86 @@
     TestMaxVertexAttributes(true, true);
 }
 
+enum class SwizzleChannel {
+    Red,
+    Green,
+    Blue,
+    Alpha,
+};
+
+class CompatTextureViewSwizzleValidationTests : public CompatTextureViewValidationTests {
+  protected:
+    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+        std::vector<wgpu::FeatureName> requiredFeatures =
+            CompatTextureViewValidationTests::GetRequiredFeatures();
+        requiredFeatures.push_back(wgpu::FeatureName::TextureComponentSwizzle);
+        return requiredFeatures;
+    }
+
+    void SetSwizzleChannel(wgpu::TextureComponentSwizzle& swizzle,
+                           SwizzleChannel channel,
+                           wgpu::ComponentSwizzle value) {
+        switch (channel) {
+            case SwizzleChannel::Red:
+                swizzle.r = value;
+                break;
+            case SwizzleChannel::Green:
+                swizzle.g = value;
+                break;
+            case SwizzleChannel::Blue:
+                swizzle.b = value;
+                break;
+            case SwizzleChannel::Alpha:
+                swizzle.a = value;
+                break;
+            default:
+                DAWN_UNREACHABLE();
+        }
+    }
+};
+
+// Test we get a validation error if we have 2 different swizzles of a texture
+// in the same bind group. Unless FlexibleTextureViews is enabled.
+TEST_P(CompatTextureViewSwizzleValidationTests,
+       CanNotDrawDifferentSwizzleSameTextureSameBindGroup) {
+    for (auto swizzleChannel : {SwizzleChannel::Red, SwizzleChannel::Green, SwizzleChannel::Blue,
+                                SwizzleChannel::Alpha}) {
+        TestMultipleTextureViewValidationInRenderPass(
+            device, wgpu::TextureFormat::RGBA8Unorm, kRenderTwoTexturesOneBindgroupWGSL,
+            [this, &swizzleChannel](wgpu::Device device, wgpu::Texture texture,
+                                    wgpu::RenderPipeline pipeline,
+                                    std::function<void(wgpu::RenderPassEncoder pass)> drawFn) {
+                wgpu::TextureViewDescriptor viewDesc1;
+                wgpu::TextureComponentSwizzleDescriptor swizzleDesc1 = {};
+                SetSwizzleChannel(swizzleDesc1.swizzle, swizzleChannel,
+                                  wgpu::ComponentSwizzle::Zero);
+                viewDesc1.nextInChain = &swizzleDesc1;
+
+                wgpu::TextureViewDescriptor viewDesc2;
+                wgpu::TextureComponentSwizzleDescriptor swizzleDesc2 = {};
+                SetSwizzleChannel(swizzleDesc2.swizzle, swizzleChannel,
+                                  wgpu::ComponentSwizzle::One);
+                viewDesc2.nextInChain = &swizzleDesc2;
+
+                wgpu::BindGroup bindGroup = utils::MakeBindGroup(
+                    device, pipeline.GetBindGroupLayout(0),
+                    {{0, texture.CreateView(&viewDesc1)}, {1, texture.CreateView(&viewDesc2)}});
+
+                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+
+                utils::BasicRenderPass rp = utils::CreateBasicRenderPass(device, 4, 1);
+                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rp.renderPassInfo);
+                pass.SetPipeline(pipeline);
+                pass.SetBindGroup(0, bindGroup);
+                drawFn(pass);
+                pass.End();
+
+                ASSERT_TEXTURE_VIEW_ERROR_IF_NO_FLEXIBLE_FEATURE(
+                    encoder.Finish(), testing::HasSubstr("different views"));
+            });
+    }
+}
+
 INSTANTIATE_TEST_SUITE_P(,
                          CompatTextureViewValidationTests,
                          ::testing::Values(FlexibleTextureViewsFeature::Disabled,
@@ -2015,6 +2095,12 @@
                                            FlexibleTextureViewsFeature::Enabled),
                          CompatTextureViewValidationTests::PrintToStringParamName);
 
+INSTANTIATE_TEST_SUITE_P(,
+                         CompatTextureViewSwizzleValidationTests,
+                         ::testing::Values(FlexibleTextureViewsFeature::Disabled,
+                                           FlexibleTextureViewsFeature::Enabled),
+                         CompatTextureViewValidationTests::PrintToStringParamName);
+
 class CompatLayoutLimitsTests : public CompatValidationTest {
   protected:
     void GetRequiredLimits(const dawn::utils::ComboLimits& supported,