// 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 size_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
