// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <optional>
#include <vector>

#include "src/dawn/tests/DawnTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/TextureUtils.h"
#include "src/dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

constexpr static uint32_t kSize = 4;

using TextureFormat = wgpu::TextureFormat;
DAWN_TEST_PARAM_STRUCT(ReadOnlyDepthStencilAttachmentTestsParams, TextureFormat);

class ReadOnlyDepthStencilAttachmentTests
    : public DawnTestWithParams<ReadOnlyDepthStencilAttachmentTestsParams> {
  protected:
    void SetUp() override {
        DawnTestWithParams<ReadOnlyDepthStencilAttachmentTestsParams>::SetUp();
        DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        switch (GetParam().mTextureFormat) {
            case wgpu::TextureFormat::Depth32FloatStencil8:
                if (SupportsFeatures({wgpu::FeatureName::Depth32FloatStencil8})) {
                    mIsFormatSupported = true;
                    return {wgpu::FeatureName::Depth32FloatStencil8};
                }

                return {};
            default:
                mIsFormatSupported = true;
                return {};
        }
    }

    struct TestSpec {
        wgpu::TextureAspect readonlyAspects;
        std::optional<wgpu::TextureAspect> sampledAspect = std::nullopt;

        wgpu::CompareFunction depthCompare = wgpu::CompareFunction::Always;
        wgpu::CompareFunction stencilCompare = wgpu::CompareFunction::Always;
        wgpu::OptionalBool depthWriteEnabled = wgpu::OptionalBool::False;
        bool stencilWriteEnabled = false;

        float depthClearValue = 0.0;
        uint32_t stencilClearValue = 0;
        uint32_t stencilRef = 0;

        wgpu::Texture depthStencilTexture;
    };

    wgpu::RenderPipeline CreateRenderPipeline(wgpu::TextureFormat format,
                                              const TestSpec& spec) const {
        utils::ComboRenderPipelineDescriptor pipelineDescriptor;

        // Draw a rectangle via two triangles. The depth value of the top of the rectangle is 0.4.
        // The depth value of the bottom is 0.0. The depth value gradually change from 0.4 to 0.0
        // from the top to the bottom. The top part will compare with the depth values and fail to
        // pass the depth test. The bottom part will compare with the depth values in depth buffer
        // and pass the depth test, and sample from the depth buffer in fragment shader in the same
        // pipeline.
        pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
            @vertex
            fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array(
                    vec3f(-1.0,  1.0, 0.4),
                    vec3f(-1.0, -1.0, 0.0),
                    vec3f( 1.0,  1.0, 0.4),
                    vec3f( 1.0,  1.0, 0.4),
                    vec3f(-1.0, -1.0, 0.0),
                    vec3f( 1.0, -1.0, 0.0));
                return vec4f(pos[VertexIndex], 1.0);
            })");

        wgpu::BindGroupLayout bgl;
        if (!spec.sampledAspect.has_value()) {
            // Draw a solid blue into color buffer if not sample from depth/stencil attachment.
            pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
                @fragment fn main() -> @location(0) vec4f {
                    return vec4f(0.0, 0.0, 1.0, 0.0);
                })");
            bgl = utils::MakeBindGroupLayout(device, {});
        } else if (spec.sampledAspect == wgpu::TextureAspect::DepthOnly) {
            // Sample from depth attachment and draw that sampled texel into color buffer.
            if (IsCompatibilityMode()) {
                // Can not use texture_depth_xx with non-comparison sampler in compat mode.
                pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
                        @group(0) @binding(0) var samp : sampler;
                        @group(0) @binding(1) var tex : texture_2d<f32>;

                        @fragment
                        fn main(@builtin(position) FragCoord : vec4f) -> @location(0) vec4f {
                            return vec4f(textureSample(tex, samp, FragCoord.xy).r, 0.0, 0.0, 0.0);
                        })");
                bgl = utils::MakeBindGroupLayout(
                    device,
                    {
                        {0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                        {1, wgpu::ShaderStage::Fragment,
                         wgpu::TextureSampleType::UnfilterableFloat},
                    });
            } else {
                pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
                        @group(0) @binding(0) var samp : sampler;
                        @group(0) @binding(1) var tex : texture_depth_2d;

                        @fragment
                        fn main(@builtin(position) FragCoord : vec4f) -> @location(0) vec4f {
                            return vec4f(textureSample(tex, samp, FragCoord.xy), 0.0, 0.0, 0.0);
                        })");
                bgl = utils::MakeBindGroupLayout(
                    device,
                    {
                        {0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                        {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth},
                    });
            }
        } else {
            DAWN_ASSERT(spec.sampledAspect == wgpu::TextureAspect::StencilOnly);
            // Sample from stencil attachment and draw that sampled texel into color buffer.
            pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
                    @group(0) @binding(0) var samp : sampler;
                    @group(0) @binding(1) var tex : texture_2d<u32>;

                    @fragment
                    fn main(@builtin(position) FragCoord : vec4f) -> @location(0) vec4f {
                        _ = samp;
                        var texel = textureLoad(tex, vec2i(FragCoord.xy), 0);
                        return vec4f(f32(texel[0]) / 255.0, 0.0, 0.0, 0.0);
                    })");
            bgl = utils::MakeBindGroupLayout(
                device,
                {
                    {0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                    {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Uint},
                });
        }

        wgpu::DepthStencilState* depthStencil = pipelineDescriptor.EnableDepthStencil(format);
        depthStencil->depthCompare = spec.depthCompare;
        depthStencil->depthWriteEnabled = spec.depthWriteEnabled;
        depthStencil->stencilFront.compare = spec.stencilCompare;
        if (spec.stencilWriteEnabled) {
            depthStencil->stencilFront.passOp = wgpu::StencilOperation::Replace;
        }

        wgpu::PipelineLayoutDescriptor plDescriptor;
        plDescriptor.bindGroupLayoutCount = 1;
        plDescriptor.bindGroupLayouts = &bgl;
        pipelineDescriptor.layout = device.CreatePipelineLayout(&plDescriptor);

        return device.CreateRenderPipeline(&pipelineDescriptor);
    }

    struct RenderResult {
        wgpu::Texture color;
        wgpu::Texture depthStencil;
    };
    RenderResult DoRender(const TestSpec& spec) const {
        wgpu::TextureFormat testFormat = GetParam().mTextureFormat;

        // Create or reuse the test textures.
        wgpu::Texture depthStencilTexture = spec.depthStencilTexture;
        if (!depthStencilTexture) {
            wgpu::TextureDescriptor dsTextureDesc = {};
            dsTextureDesc.size = {kSize, kSize, 1};
            dsTextureDesc.format = testFormat;
            dsTextureDesc.usage =
                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
            depthStencilTexture = device.CreateTexture(&dsTextureDesc);
        }

        wgpu::TextureDescriptor colorTextureDesc = {};
        colorTextureDesc.size = {kSize, kSize, 1};
        colorTextureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
        colorTextureDesc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        wgpu::Texture colorTexture = device.CreateTexture(&colorTextureDesc);

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

        // Do a first render pass that writes the initial values to the aspects that will be
        // readonly.
        if (!spec.depthStencilTexture) {
            utils::ComboRenderPassDescriptor passDescriptorInit({},
                                                                depthStencilTexture.CreateView());
            passDescriptorInit.UnsetDepthStencilLoadStoreOpsForFormat(testFormat);
            passDescriptorInit.cDepthStencilAttachmentInfo.depthClearValue = spec.depthClearValue;
            passDescriptorInit.cDepthStencilAttachmentInfo.stencilClearValue =
                spec.stencilClearValue;

            wgpu::RenderPassEncoder passInit = commandEncoder.BeginRenderPass(&passDescriptorInit);
            passInit.End();
        }

        // Do the render pass with the readonly attachment, that will potentially use the pipeline
        // to read and/or write attachments.
        utils::ComboRenderPassDescriptor passDescriptor({colorTexture.CreateView()},
                                                        depthStencilTexture.CreateView());
        passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
        passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
        passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(testFormat);

        if (spec.readonlyAspects != wgpu::TextureAspect::StencilOnly) {
            passDescriptor.cDepthStencilAttachmentInfo.depthReadOnly = true;
            passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
            passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;
        }
        if (spec.readonlyAspects != wgpu::TextureAspect::DepthOnly) {
            passDescriptor.cDepthStencilAttachmentInfo.stencilReadOnly = true;
            passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
            passDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
        }

        // Create a render pass with readonly depth/stencil attachment. The attachment has already
        // been initialized. The pipeline in this render pass will sample from the attachment. TODO
        // The pipeline will read from the attachment to do depth/stencil test too.
        wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
        wgpu::RenderPipeline pipeline = CreateRenderPipeline(testFormat, spec);
        pass.SetPipeline(pipeline);
        pass.SetStencilReference(spec.stencilRef);

        // Bind the bindgroup is needed.
        if (spec.sampledAspect.has_value()) {
            wgpu::TextureViewDescriptor viewDesc = {};
            viewDesc.aspect = spec.sampledAspect.value();
            wgpu::TextureView view = depthStencilTexture.CreateView(&viewDesc);

            wgpu::BindGroup bindGroup = utils::MakeBindGroup(
                device, pipeline.GetBindGroupLayout(0), {{0, device.CreateSampler()}, {1, view}});
            pass.SetBindGroup(0, bindGroup);
        } else {
            wgpu::BindGroup bindGroup =
                utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {});
            pass.SetBindGroup(0, bindGroup);
        }

        pass.Draw(6);
        pass.End();

        wgpu::CommandBuffer commands = commandEncoder.Finish();
        queue.Submit(1, &commands);

        return {colorTexture, depthStencilTexture};
    }

    void CheckFullColor(wgpu::Texture color, utils::RGBA8 fullColor) {
        std::vector<utils::RGBA8> expected(kSize * kSize, fullColor);
        EXPECT_TEXTURE_EQ(expected.data(), color, {0, 0}, {kSize, kSize});
    }

    void CheckTopBottomColor(wgpu::Texture color, utils::RGBA8 topColor, utils::RGBA8 bottomColor) {
        std::vector<utils::RGBA8> expectedTop(kSize * kSize / 2, topColor);
        EXPECT_TEXTURE_EQ(expectedTop.data(), color, {0, 0}, {kSize, kSize / 2});
        std::vector<utils::RGBA8> expectedBottom(kSize * kSize / 2, bottomColor);
        EXPECT_TEXTURE_EQ(expectedBottom.data(), color, {0, kSize / 2}, {kSize, kSize / 2});
    }

  private:
    bool mIsFormatSupported = false;
};

class ReadOnlyDepthAttachmentTests : public ReadOnlyDepthStencilAttachmentTests {};

TEST_P(ReadOnlyDepthAttachmentTests, SampleFromAttachment) {
    // TODO(crbug.com/523272948): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    TestSpec spec;
    spec.readonlyAspects = wgpu::TextureAspect::DepthOnly;
    spec.sampledAspect = wgpu::TextureAspect::DepthOnly;
    spec.depthCompare = wgpu::CompareFunction::LessEqual;
    spec.depthClearValue = 0.2;
    auto render = DoRender(spec);

    // The top part is not rendered by the pipeline. Its color is the default clear color for
    // color attachment.
    // The bottom part is rendered, whose red channel is sampled from depth attachment, which
    // is initialized into 0.2.
    CheckTopBottomColor(render.color, {0, 0, 0, 0}, {static_cast<uint8_t>(0.2 * 255), 0, 0, 0});
}

TEST_P(ReadOnlyDepthAttachmentTests, NotSampleFromAttachment) {
    // TODO(crbug.com/523272948): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    TestSpec spec;
    spec.readonlyAspects = wgpu::TextureAspect::DepthOnly;
    spec.depthCompare = wgpu::CompareFunction::LessEqual;
    spec.depthClearValue = 0.2;
    auto render = DoRender(spec);

    // The top part is not rendered by the pipeline. Its color is the default clear color for
    // color attachment.
    // The bottom part is rendered. Its color is set to blue.
    CheckTopBottomColor(render.color, {0, 0, 0, 0}, {0, 0, 255, 0});
}

// Regression test for crbug.com/dawn/1512 where having aspectReadOnly for an unused aspect of a
// depth-stencil texture would cause the attachment to be considered read-only, causing layout
// mismatch issues.
TEST_P(ReadOnlyDepthAttachmentTests, UnusedAspectWithReadOnly) {
    wgpu::TextureFormat format = GetParam().mTextureFormat;
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = format;
    tDesc.usage = wgpu::TextureUsage::RenderAttachment;
    wgpu::Texture depthStencilTexture = device.CreateTexture(&tDesc);

    utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
    if (utils::IsStencilOnlyFormat(format)) {
        passDescriptor.cDepthStencilAttachmentInfo.depthReadOnly = true;
        passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
        passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;
    } else {
        passDescriptor.cDepthStencilAttachmentInfo.depthReadOnly = false;
    }
    if (utils::IsDepthOnlyFormat(format)) {
        passDescriptor.cDepthStencilAttachmentInfo.stencilReadOnly = true;
        passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
        passDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
    } else {
        passDescriptor.cDepthStencilAttachmentInfo.stencilReadOnly = false;
    }

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&passDescriptor);
    pass.End();
    wgpu::CommandBuffer commands = encoder.Finish();

    queue.Submit(1, &commands);
}

class ReadOnlyStencilAttachmentTests : public ReadOnlyDepthStencilAttachmentTests {};

TEST_P(ReadOnlyStencilAttachmentTests, SampleFromAttachment) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // stencilRefValue < stencilValue (stencilInitValue), so stencil test passes. The pipeline
    // samples from stencil buffer and writes into color buffer.
    {
        TestSpec spec;
        spec.readonlyAspects = wgpu::TextureAspect::StencilOnly;
        spec.sampledAspect = wgpu::TextureAspect::StencilOnly;
        spec.stencilCompare = wgpu::CompareFunction::LessEqual;
        spec.stencilClearValue = 3;
        spec.stencilRef = 2;
        auto render = DoRender(spec);
        CheckFullColor(render.color, {3, 0, 0, 0});
    }

    // stencilRefValue > stencilValue (stencilInitValue), so stencil test fails. The pipeline
    // doesn't change color buffer. Sampled data from stencil buffer is discarded.
    {
        TestSpec spec;
        spec.readonlyAspects = wgpu::TextureAspect::StencilOnly;
        spec.sampledAspect = wgpu::TextureAspect::StencilOnly;
        spec.stencilCompare = wgpu::CompareFunction::LessEqual;
        spec.stencilClearValue = 1;
        spec.stencilRef = 2;
        auto render = DoRender(spec);
        CheckFullColor(render.color, {0, 0, 0, 0});
    }
}

TEST_P(ReadOnlyStencilAttachmentTests, NotSampleFromAttachment) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // stencilRefValue < stencilValue (stencilInitValue), so stencil test passes. The pipeline
    // draw solid blue into color buffer.
    {
        TestSpec spec;
        spec.readonlyAspects = wgpu::TextureAspect::StencilOnly;
        spec.stencilCompare = wgpu::CompareFunction::LessEqual;
        spec.stencilClearValue = 3;
        spec.stencilRef = 2;
        auto render = DoRender(spec);
        CheckFullColor(render.color, {0, 0, 255, 0});
    }

    // stencilRefValue > stencilValue (stencilInitValue), so stencil test fails. The pipeline
    // doesn't change color buffer. drawing data is discarded.
    {
        TestSpec spec;
        spec.readonlyAspects = wgpu::TextureAspect::StencilOnly;
        spec.stencilCompare = wgpu::CompareFunction::LessEqual;
        spec.stencilClearValue = 1;
        spec.stencilRef = 2;
        auto render = DoRender(spec);
        CheckFullColor(render.color, {0, 0, 0, 0});
    }
}

class ReadOnlyDepthAndStencilAttachmentTests : public ReadOnlyDepthStencilAttachmentTests {
  protected:
    void SetUp() override {
        ReadOnlyDepthStencilAttachmentTests::SetUp();

        // TODO(crbug.com/473870505): [Capture] support depth/stencil and multi-planar textures.
        DAWN_SUPPRESS_TEST_IF(IsCaptureReplayCheckingEnabled());
    }
};

// Test that using stencilReadOnly while modifying the depth aspect works.
TEST_P(ReadOnlyDepthAndStencilAttachmentTests, ModifyDepthSampleStencil) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // Stencil test is always true but the depth test passes only for the
    TestSpec spec1;
    spec1.readonlyAspects = wgpu::TextureAspect::StencilOnly;
    spec1.sampledAspect = wgpu::TextureAspect::StencilOnly;
    spec1.stencilClearValue = 42;
    spec1.depthClearValue = 0.2;
    spec1.depthCompare = wgpu::CompareFunction::LessEqual;
    spec1.depthWriteEnabled = wgpu::OptionalBool::True;
    auto render1 = DoRender(spec1);

    // Stencil was read successfully, but only in the bottom part.
    CheckTopBottomColor(render1.color, {0, 0, 0, 0}, {42, 0, 0, 0});

    // Check that the depth was written by setting depthCompare equal, and rendering a solid
    // blue color. The depth was only written on the bottom half due to the depth test in the
    // first render.
    TestSpec spec2;
    spec2.readonlyAspects = wgpu::TextureAspect::StencilOnly;
    spec2.depthStencilTexture = render1.depthStencil;
    spec2.depthCompare = wgpu::CompareFunction::Equal;
    auto render2 = DoRender(spec2);
    CheckTopBottomColor(render2.color, {0, 0, 0, 0}, {0, 0, 255, 0});
}

// Test that using depthReadOnly while modifying the stencil aspect works.
TEST_P(ReadOnlyDepthAndStencilAttachmentTests, SampleDepthModifyStencil) {
    // TODO(crbug.com/523272947): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    // Depth/stencil tests are true, the depth is correctly sampled from the depthClearValue.
    // The stencil is written to the value of the stencil ref.
    TestSpec spec1;
    spec1.readonlyAspects = wgpu::TextureAspect::DepthOnly;
    spec1.sampledAspect = wgpu::TextureAspect::DepthOnly;
    spec1.depthClearValue = 0.2;
    spec1.stencilWriteEnabled = true;
    spec1.stencilRef = 42;
    spec1.stencilClearValue = 0;
    auto render1 = DoRender(spec1);
    CheckFullColor(render1.color, {static_cast<uint8_t>(0.2 * 255), 0, 0, 0});

    // The stencil test checks that the stencil ref matches what's in the stencil buffer
    // so that we know it was correctly written. The whole quad should be drawn.
    TestSpec spec2;
    spec2.readonlyAspects = wgpu::TextureAspect::DepthOnly;
    spec2.depthStencilTexture = render1.depthStencil;
    spec2.stencilCompare = wgpu::CompareFunction::Equal;
    spec2.stencilRef = 42;
    auto render2 = DoRender(spec2);
    CheckFullColor(render2.color, {0, 0, 255, 0});
}

// Test sampling depth with both the depth and stencil readonly.
TEST_P(ReadOnlyDepthAndStencilAttachmentTests, BothReadOnlySampleDepth) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // Sample the depth while using both depth an stencil testing.

    // First render: depth test passes only for the bottom half, stencil passes.
    TestSpec spec;
    spec.readonlyAspects = wgpu::TextureAspect::All;
    spec.sampledAspect = wgpu::TextureAspect::DepthOnly;
    spec.depthCompare = wgpu::CompareFunction::LessEqual;
    spec.depthClearValue = 0.2;
    spec.stencilRef = 42;
    spec.stencilClearValue = 43;
    spec.stencilCompare = wgpu::CompareFunction::LessEqual;
    auto render1 = DoRender(spec);
    CheckTopBottomColor(render1.color, {0, 0, 0, 0}, {static_cast<uint8_t>(0.2 * 255), 0, 0, 0});

    // Second render: stencil test fails.
    spec.stencilClearValue = 41;
    auto render2 = DoRender(spec);
    CheckFullColor(render2.color, {0, 0, 0, 0});
}

// Test sampling stencil with both the depth and stencil readonly.
TEST_P(ReadOnlyDepthAndStencilAttachmentTests, BothReadOnlySampleStencil) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // Sample the stencil while using both depth an stencil testing.

    // First render: depth test passes only for the bottom half, stencil passes.
    TestSpec spec;
    spec.readonlyAspects = wgpu::TextureAspect::All;
    spec.sampledAspect = wgpu::TextureAspect::StencilOnly;
    spec.depthCompare = wgpu::CompareFunction::LessEqual;
    spec.depthClearValue = 0.2;
    spec.stencilRef = 42;
    spec.stencilClearValue = 43;
    spec.stencilCompare = wgpu::CompareFunction::LessEqual;
    auto render1 = DoRender(spec);
    CheckTopBottomColor(render1.color, {0, 0, 0, 0}, {43, 0, 0, 0});

    // Second render: stencil test fails.
    spec.stencilClearValue = 41;
    auto render2 = DoRender(spec);
    CheckFullColor(render2.color, {0, 0, 0, 0});
}

DAWN_INSTANTIATE_TEST_P(
    ReadOnlyDepthAttachmentTests,
    {D3D11Backend(), D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
     OpenGLBackend(), OpenGLESBackend(), VulkanBackend({"vulkan_use_dynamic_rendering"}, {}),
     VulkanBackend({"vulkan_use_create_render_pass_2"}, {"vulkan_use_dynamic_rendering"}),
     VulkanBackend({}, {"vulkan_use_create_render_pass_2", "vulkan_use_dynamic_rendering"}),
     WebGPUBackend()},
    std::vector<wgpu::TextureFormat>(utils::kDepthFormats.begin(), utils::kDepthFormats.end()));
DAWN_INSTANTIATE_TEST_P(
    ReadOnlyStencilAttachmentTests,
    {D3D11Backend(), D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
     OpenGLBackend(), OpenGLESBackend(), VulkanBackend({"vulkan_use_dynamic_rendering"}, {}),
     VulkanBackend({"vulkan_use_create_render_pass_2"}, {"vulkan_use_dynamic_rendering"}),
     VulkanBackend({}, {"vulkan_use_create_render_pass_2", "vulkan_use_dynamic_rendering"}),
     WebGPUBackend()},
    std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(), utils::kStencilFormats.end()));
DAWN_INSTANTIATE_TEST_P(
    ReadOnlyDepthAndStencilAttachmentTests,
    {D3D11Backend(), D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
     OpenGLBackend(), OpenGLESBackend(), VulkanBackend({"vulkan_use_dynamic_rendering"}, {}),
     VulkanBackend({"vulkan_use_create_render_pass_2"}, {"vulkan_use_dynamic_rendering"}),
     VulkanBackend({}, {"vulkan_use_create_render_pass_2", "vulkan_use_dynamic_rendering"}),
     WebGPUBackend()},
    std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
                                     utils::kDepthAndStencilFormats.end()));

}  // anonymous namespace
}  // namespace dawn
