// Copyright 2023 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 <algorithm>
#include <array>
#include <string>
#include <vector>

#include "dawn/common/Assert.h"
#include "dawn/common/Constants.h"
#include "dawn/common/Math.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

constexpr wgpu::TextureFormat kDefaultFormat = wgpu::TextureFormat::RGBA8Unorm;

class TextureShaderBuiltinTests : public DawnTest {
  protected:
    wgpu::Texture Create2DTexture(const char* label,
                                  uint32_t width,
                                  uint32_t height,
                                  uint32_t arrayLayerCount,
                                  uint32_t mipLevelCount,
                                  uint32_t sampleCount,
                                  wgpu::TextureUsage usage,
                                  wgpu::TextureViewDimension textureBindingViewDimension) {
        wgpu::TextureDescriptor descriptor;
        descriptor.label = label;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = width;
        descriptor.size.height = height;
        descriptor.size.depthOrArrayLayers = arrayLayerCount;
        descriptor.sampleCount = sampleCount;
        descriptor.format = kDefaultFormat;
        descriptor.mipLevelCount = mipLevelCount;
        descriptor.usage = usage;

        // Only set the textureBindingViewDimension in compat mode. It's not needed
        // nor used in non-compat.
        wgpu::TextureBindingViewDimension textureBindingViewDimensionDesc;
        if (IsCompatibilityMode()) {
            textureBindingViewDimensionDesc.textureBindingViewDimension =
                textureBindingViewDimension;
            descriptor.nextInChain = &textureBindingViewDimensionDesc;
        }

        return device.CreateTexture(&descriptor);
    }

    wgpu::Texture CreateTexture(const char* label,
                                uint32_t arrayLayerCount,
                                uint32_t mipLevelCount,
                                uint32_t sampleCount,
                                wgpu::TextureViewDimension textureBindingViewDimension) {
        DAWN_ASSERT(arrayLayerCount > 0 && mipLevelCount > 0);
        DAWN_ASSERT(sampleCount == 1 || sampleCount == 4);

        const uint32_t textureWidthLevel0 = 1 << mipLevelCount;
        const uint32_t textureHeightLevel0 = 1 << mipLevelCount;
        constexpr wgpu::TextureUsage kUsage = wgpu::TextureUsage::CopyDst |
                                              wgpu::TextureUsage::TextureBinding |
                                              wgpu::TextureUsage::RenderAttachment;
        return Create2DTexture(label, textureWidthLevel0, textureHeightLevel0, arrayLayerCount,
                               mipLevelCount, sampleCount, kUsage, textureBindingViewDimension);
    }

    wgpu::Texture CreateTexture(const char* label,
                                uint32_t arrayLayerCount,
                                uint32_t mipLevelCount,
                                uint32_t sampleCount) {
        return CreateTexture(label, arrayLayerCount, mipLevelCount, sampleCount,
                             arrayLayerCount == 1 ? wgpu::TextureViewDimension::e2D
                                                  : wgpu::TextureViewDimension::e2DArray);
    }

    wgpu::TextureView CreateTextureView(const wgpu::Texture& tex,
                                        const char* label,
                                        wgpu::TextureViewDimension dimension,
                                        uint32_t baseMipLevel = 0,
                                        uint32_t mipLevelCount = wgpu::kMipLevelCountUndefined) {
        wgpu::TextureViewDescriptor descriptor;
        descriptor.label = label;
        descriptor.dimension = dimension;
        // textureNumLevels return texture view levels
        descriptor.baseMipLevel = baseMipLevel;
        descriptor.mipLevelCount = mipLevelCount;
        return tex.CreateView(&descriptor);
    }
};

// Note: the following tests for various texture method behavior is mainly
// targeted at OpenGL/OpenGLES backend without native GLSL support for these builtins.
// These tests should be trivial for otherbackend, and thus can be used as control case.

// Test calling textureNumLevels & textureNumSamples & textureDimensions in one shader.
// Note: textureDimensions implicitly calls textureNumLevels after tint shader transform to clamp
// mip levels.
TEST_P(TextureShaderBuiltinTests, Basic) {
    constexpr uint32_t kLayers = 3;
    constexpr uint32_t kMipLevels = 2;
    wgpu::Texture tex1 = CreateTexture("tex1", kLayers, kMipLevels, 1);
    wgpu::TextureView texView1 =
        CreateTextureView(tex1, "texView1", wgpu::TextureViewDimension::e2DArray);

    constexpr uint32_t kSampleCount = 4;
    wgpu::Texture tex2 = CreateTexture("tex2", 1, 1, kSampleCount);
    wgpu::TextureView texView2 = tex2.CreateView();

    constexpr uint32_t kMipLevelsView = 1;
    wgpu::Texture tex3 =
        CreateTexture("tex3", kLayers, kMipLevels, 1, wgpu::TextureViewDimension::e2DArray);
    wgpu::TextureView texView3 =
        CreateTextureView(tex3, "texView3",
                          IsCompatibilityMode() ? wgpu::TextureViewDimension::e2DArray
                                                : wgpu::TextureViewDimension::e2D,
                          1, kMipLevelsView);

    const uint32_t textureWidthLevel0 = 1 << kMipLevels;
    const uint32_t textureWidthLevel1 = textureWidthLevel0 >> 1;
    const uint32_t expected[] = {kLayers,        kMipLevels,         kSampleCount,
                                 kMipLevelsView, textureWidthLevel0, textureWidthLevel1};

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    const char* tex3Type = IsCompatibilityMode() ? "texture_2d_array<f32>" : "texture_2d<f32>";

    std::ostringstream shaderSource;
    // clang-format off
    shaderSource << R"(
    @group(0) @binding(0) var<storage, read_write> dstBuf : array<u32>;
    @group(0) @binding(1) var tex1 : texture_2d_array<f32>;
    // Use sparse binding to test impact of binding remapping
    @group(0) @binding(4) var tex2 : texture_multisampled_2d<f32>;
    @group(1) @binding(3) var tex3 : )" << tex3Type << R"(;

    @compute @workgroup_size(1, 1, 1) fn main() {
        dstBuf[0] = textureNumLayers(tex1); // control case
        dstBuf[1] = textureNumLevels(tex1);
        dstBuf[2] = textureNumSamples(tex2);
        dstBuf[3] = textureNumLevels(tex3);
        dstBuf[4] = textureDimensions(tex1, 0).x;
        dstBuf[5] = textureDimensions(tex1, 1).x;
        }
        )";
    // clang-format on

    wgpu::ComputePipelineDescriptor pipelineDescriptor;
    pipelineDescriptor.compute.module = utils::CreateShaderModule(device, shaderSource.str());
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDescriptor);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer},
                                                      {1, texView1},
                                                      {4, texView2},
                                                  }));
        pass.SetBindGroup(1, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(1),
                                                  {
                                                      {3, texView3},
                                                  }));
        pass.DispatchWorkgroups(1);
        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, 0, sizeof(expected) / sizeof(uint32_t));
}

// Testing that baseMipLevel is handled correctly.
TEST_P(TextureShaderBuiltinTests, BaseMipLevelTextureView) {
    constexpr uint32_t kLayers = 1;
    constexpr uint32_t kMipLevels = 3;
    wgpu::Texture tex =
        CreateTexture("tex", kLayers, kMipLevels, 1, wgpu::TextureViewDimension::e2D);

    constexpr uint32_t kBaseMipLevel = 1;
    constexpr uint32_t kViewMipLevelCount = 2;
    DAWN_ASSERT(kBaseMipLevel + kViewMipLevelCount <= kMipLevels);
    wgpu::TextureView texView = CreateTextureView(tex, "texView", wgpu::TextureViewDimension::e2D,
                                                  kBaseMipLevel, kViewMipLevelCount);

    const uint32_t textureWidthLevel0 = 1 << kMipLevels;
    const uint32_t textureWidthLevel1 = textureWidthLevel0 >> 1;
    const uint32_t textureWidthLevel2 = textureWidthLevel1 >> 1;
    const uint32_t expected[] = {
        textureWidthLevel1,
        textureWidthLevel1,
        textureWidthLevel2,
    };

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    std::ostringstream shaderSource;
    // clang-format off
    shaderSource << R"(
    @group(0) @binding(0) var<storage, read_write> dstBuf : array<u32>;
    @group(0) @binding(1) var tex : texture_2d<f32>;

    @compute @workgroup_size(1, 1, 1) fn main() {
        dstBuf[0] = textureDimensions(tex).x;
        dstBuf[1] = textureDimensions(tex, 0).x;
        dstBuf[2] = textureDimensions(tex, 1).x;
    }
    )";
    // clang-format on

    wgpu::ComputePipelineDescriptor pipelineDescriptor;
    pipelineDescriptor.compute.module = utils::CreateShaderModule(device, shaderSource.str());
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDescriptor);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer},
                                                      {1, texView},
                                                  }));
        pass.DispatchWorkgroups(1);
        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, 0, sizeof(expected) / sizeof(uint32_t));
}

// Testing that baseMipLevel is handled correctly for texture_cube.
TEST_P(TextureShaderBuiltinTests, BaseMipLevelTextureViewCube) {
    constexpr uint32_t kCubeLayers = 6;
    constexpr uint32_t kMipLevels = 3;
    wgpu::Texture texCube =
        CreateTexture("texCube", kCubeLayers, kMipLevels, 1, wgpu::TextureViewDimension::Cube);

    constexpr uint32_t kBaseMipLevel = 1;
    constexpr uint32_t kViewMipLevelCount = 2;
    DAWN_ASSERT(kBaseMipLevel + kViewMipLevelCount <= kMipLevels);
    wgpu::TextureView texViewCube =
        CreateTextureView(texCube, "texViewCube", wgpu::TextureViewDimension::Cube, kBaseMipLevel,
                          kViewMipLevelCount);

    const uint32_t textureWidthLevel0 = 1 << kMipLevels;
    const uint32_t textureWidthLevel1 = textureWidthLevel0 >> 1;
    const uint32_t textureWidthLevel2 = textureWidthLevel1 >> 1;
    const uint32_t expected[] = {textureWidthLevel1, textureWidthLevel1, textureWidthLevel2,
                                 kViewMipLevelCount};

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    std::ostringstream shaderSource;
    // clang-format off
    shaderSource << R"(
    @group(0) @binding(0) var<storage, read_write> dstBuf : array<u32>;
    @group(0) @binding(1) var tex_cube : texture_cube<f32>;

    @compute @workgroup_size(1, 1, 1) fn main() {
        dstBuf[0] = textureDimensions(tex_cube).x;
        dstBuf[1] = textureDimensions(tex_cube, 0).x;
        dstBuf[2] = textureDimensions(tex_cube, 1).x;
        dstBuf[3] = textureNumLevels(tex_cube);
    }
    )";
    // clang-format on

    wgpu::ComputePipelineDescriptor pipelineDescriptor;
    pipelineDescriptor.compute.module = utils::CreateShaderModule(device, shaderSource.str());
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDescriptor);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer},
                                                      {1, texViewCube},
                                                  }));
        pass.DispatchWorkgroups(1);
        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, 0, sizeof(expected) / sizeof(uint32_t));
}

// Test calling textureNumLevels & textureNumSamples inside function and taking a function param as
// the argument.
TEST_P(TextureShaderBuiltinTests, BuiltinCallInFunction) {
    constexpr uint32_t kLayers = 3;
    constexpr uint32_t kMipLevels1 = 2;
    wgpu::Texture tex1 = CreateTexture("tex1", kLayers, kMipLevels1, 1);
    wgpu::TextureView texView1 =
        CreateTextureView(tex1, "texView1", wgpu::TextureViewDimension::e2DArray);
    constexpr uint32_t kMipLevels2 = 5;
    wgpu::Texture tex2 =
        CreateTexture("tex2", 1, kMipLevels2, 1, wgpu::TextureViewDimension::e2DArray);
    wgpu::TextureView texView2 =
        CreateTextureView(tex2, "texView2", wgpu::TextureViewDimension::e2DArray);

    const uint32_t expected[] = {
        kLayers, kMipLevels1, kMipLevels1, kMipLevels2, kMipLevels1 + 100u,
    };

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    wgpu::ComputePipelineDescriptor pipelineDescriptor;
    pipelineDescriptor.compute.module = utils::CreateShaderModule(device, R"(
@group(0) @binding(0) var<storage, read_write> dstBuf : array<u32>;
@group(0) @binding(1) var tex1 : texture_2d_array<f32>;
@group(0) @binding(2) var tex2 : texture_2d_array<f32>;

fn f(tex: texture_2d_array<f32>) -> u32 {
    return textureNumLevels(tex);
}

fn f_nested(tex: texture_2d_array<f32>, d: u32) -> u32 {
    return f(tex) + d;
}

@compute @workgroup_size(1, 1, 1) fn main() {
    dstBuf[0] = textureNumLayers(tex1); // control case
    dstBuf[1] = textureNumLevels(tex1);
    dstBuf[2] = f(tex1);
    dstBuf[3] = f(tex2);
    dstBuf[4] = f_nested(tex1, 100u);
}
    )");
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDescriptor);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer},
                                                      {1, texView1},
                                                      {2, texView2},
                                                  }));
        pass.DispatchWorkgroups(1);
        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, 0, sizeof(expected) / sizeof(uint32_t));
}

// Test the internal uniform buffer data is properly updated between dispatches
// When the same pipeline is set only once.
TEST_P(TextureShaderBuiltinTests, OnePipelineMultipleDispatches) {
    const char* shader = R"(
@group(0) @binding(0) var<storage, read_write> dstBuf : array<u32>;
@group(0) @binding(1) var tex1 : texture_2d_array<f32>;
// Use sparse binding to test impact of binding remapping
@group(0) @binding(4) var tex2 : texture_multisampled_2d<f32>;
@group(1) @binding(3) var tex3 : texture_2d_array<f32>;

@compute @workgroup_size(1, 1, 1) fn main() {
    dstBuf[0] = textureNumLayers(tex1); // control case
    dstBuf[1] = textureNumLevels(tex1);
    dstBuf[2] = textureNumSamples(tex2);
    dstBuf[3] = textureNumLevels(tex3);
}
    )";

    constexpr uint32_t kLayers_1 = 3;
    constexpr uint32_t kMipLevels_1 = 2;
    wgpu::Texture tex1_1 = CreateTexture("tex1_1", kLayers_1, kMipLevels_1, 1);
    wgpu::TextureView texView1_1 =
        CreateTextureView(tex1_1, "texView1_1", wgpu::TextureViewDimension::e2DArray);
    constexpr uint32_t kLayers_2 = 5;
    constexpr uint32_t kMipLevels_2 = 4;
    wgpu::Texture tex1_2 = CreateTexture("tex1_2", kLayers_2, kMipLevels_2, 1);
    wgpu::TextureView texView1_2 =
        CreateTextureView(tex1_2, "texView1_2", wgpu::TextureViewDimension::e2DArray);

    constexpr uint32_t kSampleCount_1 = 4;
    wgpu::Texture tex2_1 = CreateTexture("tex2_1", 1, 1, kSampleCount_1);
    wgpu::TextureView texView2_1 = tex2_1.CreateView();
    constexpr uint32_t kSampleCount_2 = 4;
    wgpu::Texture tex2_2 = CreateTexture("tex2_2", 1, 1, kSampleCount_2);
    wgpu::TextureView texView2_2 = tex2_2.CreateView();

    constexpr uint32_t kMipLevelsView_1 = 1;
    wgpu::Texture tex3_1 = CreateTexture("tex3_1", kLayers_1, kMipLevels_1, 1);
    wgpu::TextureView texView3_1 = CreateTextureView(
        tex3_1, "texView3_1", wgpu::TextureViewDimension::e2DArray, 0, kMipLevelsView_1);
    constexpr uint32_t kMipLevelsView_2 = 2;
    wgpu::Texture tex3_2 = CreateTexture("tex3_2", kLayers_2, kMipLevels_2, 1);
    wgpu::TextureView texView3_2 = CreateTextureView(
        tex3_2, "texView3_2", wgpu::TextureViewDimension::e2DArray, 0, kMipLevelsView_2);

    constexpr uint32_t expected_1[] = {
        // Output from first dispatch
        kLayers_1,
        kMipLevels_1,
        kSampleCount_1,
        kMipLevelsView_1,
    };
    constexpr uint32_t expected_2[] = {
        // Output from second dispatch with different bind group
        kLayers_2,
        kMipLevels_2,
        kSampleCount_2,
        kMipLevelsView_2,
    };
    constexpr uint32_t expected_3[] = {
        // Output from third dispatch with bind group partially reset
        kLayers_1,
        kMipLevels_1,
        kSampleCount_1,
        kMipLevelsView_2,
    };
    DAWN_ASSERT(sizeof(expected_1) == sizeof(expected_2));
    DAWN_ASSERT(sizeof(expected_1) == sizeof(expected_3));

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected_1);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer_1 = device.CreateBuffer(&bufferDesc);
    wgpu::Buffer buffer_2 = device.CreateBuffer(&bufferDesc);
    wgpu::Buffer buffer_3 = device.CreateBuffer(&bufferDesc);

    wgpu::ComputePipeline pipeline;
    {
        wgpu::ComputePipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.compute.module = utils::CreateShaderModule(device, shader);
        pipeline = device.CreateComputePipeline(&pipelineDescriptor);
    }

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);

        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer_1},
                                                      {1, texView1_1},
                                                      {4, texView2_1},
                                                  }));
        pass.SetBindGroup(1, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(1),
                                                  {
                                                      {3, texView3_1},
                                                  }));
        pass.DispatchWorkgroups(1);

        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer_2},
                                                      {1, texView1_2},
                                                      {4, texView2_2},
                                                  }));
        pass.SetBindGroup(1, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(1),
                                                  {
                                                      {3, texView3_2},
                                                  }));
        pass.DispatchWorkgroups(1);

        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer_3},
                                                      {1, texView1_1},
                                                      {4, texView2_1},
                                                  }));
        // Note: bind group 1 is not set
        pass.DispatchWorkgroups(1);

        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected_1, buffer_1, 0, sizeof(expected_1) / sizeof(uint32_t));
    EXPECT_BUFFER_U32_RANGE_EQ(expected_2, buffer_2, 0, sizeof(expected_2) / sizeof(uint32_t));
    EXPECT_BUFFER_U32_RANGE_EQ(expected_3, buffer_3, 0, sizeof(expected_3) / sizeof(uint32_t));
}

// Test textureNumLevels & textureNumSamples results correctness used in multiple pipelines sharing
// same shader module.
TEST_P(TextureShaderBuiltinTests, OneShaderModuleMultipleEntryPoints) {
    std::ostringstream shaderSource;

    const char* tex3Type = IsCompatibilityMode() ? "texture_2d_array<f32>" : "texture_2d<f32>";
    // clang-format off
    shaderSource << R"(
@group(0) @binding(0) var<storage, read_write> dstBuf : array<u32>;
@group(0) @binding(1) var tex1 : texture_2d_array<f32>;
// Use sparse binding to test impact of binding remapping
@group(0) @binding(4) var tex2 : texture_multisampled_2d<f32>;
@group(1) @binding(3) var tex3 : )" << tex3Type << R"(;

@compute @workgroup_size(1, 1, 1) fn main1() {
    dstBuf[0] = textureNumLayers(tex1); // control case
    dstBuf[1] = textureNumLevels(tex1);
    dstBuf[2] = textureNumSamples(tex2);
    dstBuf[3] = textureNumLevels(tex3);
}

@compute @workgroup_size(1, 1, 1) fn main2() {
    dstBuf[0] = textureNumLayers(tex1); // control case
    dstBuf[1] = textureNumLevels(tex1);
    dstBuf[2] = textureNumSamples(tex2);
    // _ = textureNumLevels(tex3);
    dstBuf[3] = 99;
}
    )";
    // clang-format on

    constexpr uint32_t kLayers_1 = 3;
    constexpr uint32_t kMipLevels_1 = 2;
    wgpu::Texture tex1_1 = CreateTexture("tex1_1", kLayers_1, kMipLevels_1, 1);
    wgpu::TextureView texView1_1 =
        CreateTextureView(tex1_1, "tex1_1", wgpu::TextureViewDimension::e2DArray);
    constexpr uint32_t kLayers_2 = 5;
    constexpr uint32_t kMipLevels_2 = 4;
    wgpu::Texture tex1_2 = CreateTexture("tex1_2", kLayers_2, kMipLevels_2, 1);
    wgpu::TextureView texView1_2 =
        CreateTextureView(tex1_2, "tex1_2", wgpu::TextureViewDimension::e2DArray);

    constexpr uint32_t kSampleCount_1 = 4;
    wgpu::Texture tex2_1 = CreateTexture("tex2_1", 1, 1, kSampleCount_1);
    wgpu::TextureView texView2_1 = tex2_1.CreateView();
    // constexpr uint32_t kSampleCount_2 = 1;
    constexpr uint32_t kSampleCount_2 = 4;
    wgpu::Texture tex2_2 = CreateTexture("tex2_2", 1, 1, kSampleCount_2);
    wgpu::TextureView texView2_2 = tex2_2.CreateView();

    constexpr uint32_t kMipLevelsView_1 = 1;
    wgpu::Texture tex3_1 =
        CreateTexture("tex3_1", kLayers_1, kMipLevels_1, 1, wgpu::TextureViewDimension::e2DArray);
    wgpu::TextureView texView3_1 =
        CreateTextureView(tex3_1, "tex3_1",
                          IsCompatibilityMode() ? wgpu::TextureViewDimension::e2DArray
                                                : wgpu::TextureViewDimension::e2D,
                          0, kMipLevelsView_1);
    constexpr uint32_t kMipLevelsView_2 = 1;
    wgpu::Texture tex3_2 =
        CreateTexture("tex3_2", kLayers_2, kMipLevels_2, 1, wgpu::TextureViewDimension::e2DArray);
    wgpu::TextureView texView3_2 =
        CreateTextureView(tex3_2, "tex3_2",
                          IsCompatibilityMode() ? wgpu::TextureViewDimension::e2DArray
                                                : wgpu::TextureViewDimension::e2D,
                          0, kMipLevelsView_2);

    constexpr uint32_t expected_1[] = {
        // Output from first dispatch
        kLayers_1,
        kMipLevels_1,
        kSampleCount_1,
        kMipLevelsView_1,
    };
    constexpr uint32_t expected_2[] = {
        // Output from second dispatch with different bind group
        kLayers_2,
        kMipLevels_2,
        kSampleCount_2,
        99,
    };
    DAWN_ASSERT(sizeof(expected_1) == sizeof(expected_2));

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected_1);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer_1 = device.CreateBuffer(&bufferDesc);
    wgpu::Buffer buffer_2 = device.CreateBuffer(&bufferDesc);

    wgpu::ShaderModule module = utils::CreateShaderModule(device, shaderSource.str());
    wgpu::ComputePipeline pipeline_1;
    {
        wgpu::ComputePipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.compute.module = module;
        pipelineDescriptor.compute.entryPoint = "main1";
        pipeline_1 = device.CreateComputePipeline(&pipelineDescriptor);
    }
    wgpu::ComputePipeline pipeline_2;
    {
        wgpu::ComputePipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.compute.module = module;
        pipelineDescriptor.compute.entryPoint = "main2";
        pipeline_2 = device.CreateComputePipeline(&pipelineDescriptor);
    }

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();

        pass.SetPipeline(pipeline_1);
        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline_1.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer_1},
                                                      {1, texView1_1},
                                                      {4, texView2_1},
                                                  }));
        pass.SetBindGroup(1, utils::MakeBindGroup(device, pipeline_1.GetBindGroupLayout(1),
                                                  {
                                                      {3, texView3_1},
                                                  }));
        pass.DispatchWorkgroups(1);

        pass.SetPipeline(pipeline_2);
        pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline_2.GetBindGroupLayout(0),
                                                  {
                                                      {0, buffer_2},
                                                      {1, texView1_2},
                                                      {4, texView2_2},
                                                  }));
        pass.DispatchWorkgroups(1);

        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected_1, buffer_1, 0, sizeof(expected_1) / sizeof(uint32_t));
    EXPECT_BUFFER_U32_RANGE_EQ(expected_2, buffer_2, 0, sizeof(expected_2) / sizeof(uint32_t));
}

// Test when the pipeline changed but the bind group is unchanged, the texture builtins uniforms are
// updated correctly.
TEST_P(TextureShaderBuiltinTests, MultiplePipelinesOneBindGroup) {
    const char* shader_1 = R"(
@group(1) @binding(0) var<storage, read_write> dstBuf : array<u32>;
// Use sparse binding to test impact of binding remapping
@group(0) @binding(1) var tex1 : texture_2d<f32>;
@group(0) @binding(4) var tex2 : texture_2d<f32>;

@compute @workgroup_size(1, 1, 1) fn main() {
    dstBuf[0] = textureNumLevels(tex1);
}
    )";

    const char* shader_2 = R"(
@group(1) @binding(0) var<storage, read_write> dstBuf : array<u32>;
// Use sparse binding to test impact of binding remapping
@group(0) @binding(1) var tex1 : texture_2d<f32>;
@group(0) @binding(4) var tex2 : texture_2d<f32>;

@compute @workgroup_size(1, 1, 1) fn main() {
    dstBuf[0] = textureNumLevels(tex2);
}
    )";

    // Explicitly create bind group layout, shared by 2 different pipelines.
    wgpu::BindGroupLayout bindGroupLayoutShared = utils::MakeBindGroupLayout(
        device, {
                    {1, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e2D},
                    {4, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e2D},
                });

    wgpu::BindGroupLayout bindGroupLayoutBuffer = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage},
                });

    constexpr uint32_t kMipLevels_1 = 2;
    constexpr uint32_t kMipLevels_2 = 3;

    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size.width = 4;
    textureDesc.size.height = 4;
    textureDesc.format = kDefaultFormat;
    textureDesc.mipLevelCount = kMipLevels_1;
    textureDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::TextureView texView_1 = device.CreateTexture(&textureDesc).CreateView();

    textureDesc.mipLevelCount = kMipLevels_2;
    wgpu::TextureView texView_2 = device.CreateTexture(&textureDesc).CreateView();

    constexpr uint32_t expected_1[] = {
        // Output from first dispatch
        kMipLevels_1,
    };
    constexpr uint32_t expected_2[] = {
        // Output from second dispatch with different pipeline
        kMipLevels_2,
    };
    DAWN_ASSERT(sizeof(expected_1) == sizeof(expected_2));

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected_1);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer_1 = device.CreateBuffer(&bufferDesc);
    wgpu::Buffer buffer_2 = device.CreateBuffer(&bufferDesc);

    wgpu::PipelineLayout pipelineLayout =
        utils::MakePipelineLayout(device, {bindGroupLayoutShared, bindGroupLayoutBuffer});

    wgpu::ComputePipelineDescriptor pipelineDesc;
    pipelineDesc.layout = pipelineLayout;
    pipelineDesc.compute.module = utils::CreateShaderModule(device, shader_1);
    wgpu::ComputePipeline pipeline_1 = device.CreateComputePipeline(&pipelineDesc);

    pipelineDesc.compute.module = utils::CreateShaderModule(device, shader_2);
    wgpu::ComputePipeline pipeline_2 = device.CreateComputePipeline(&pipelineDesc);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline_1);

        pass.SetBindGroup(0, utils::MakeBindGroup(device, bindGroupLayoutShared,
                                                  {
                                                      {1, texView_1},
                                                      {4, texView_2},
                                                  }));
        pass.SetBindGroup(1, utils::MakeBindGroup(device, bindGroupLayoutBuffer,
                                                  {
                                                      {0, buffer_1},
                                                  }));
        pass.DispatchWorkgroups(1);

        // Note: Change the pipeline, but don't change the shared bind group
        pass.SetPipeline(pipeline_2);
        pass.SetBindGroup(1, utils::MakeBindGroup(device, bindGroupLayoutBuffer,
                                                  {
                                                      {0, buffer_2},
                                                  }));
        pass.DispatchWorkgroups(1);

        pass.End();
    }

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected_1, buffer_1, 0, sizeof(expected_1) / sizeof(uint32_t));
    EXPECT_BUFFER_U32_RANGE_EQ(expected_2, buffer_2, 0, sizeof(expected_2) / sizeof(uint32_t));
}

// Regression Test for crbug.com/427409135, Test builtins are handled correctly for render pipeline,
// when multiple entries in the same bind group from the vertex and fragment stage is not pushing to
// the same offset in the uniform.
TEST_P(TextureShaderBuiltinTests, RenderPipelineAvoidSameOffset) {
    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);

    // One texture builtin in the vertex shader
    const char* vertexShader = R"(
// Use sparse binding to test impact of binding remapping
@group(0) @binding(1) var tex1 : texture_2d<f32>;

struct VertexOutput {
    @builtin(position) position: vec4<f32>,
    @location(0) @interpolate(flat, either) value: u32,
};

@vertex fn main() -> VertexOutput {
    var out : VertexOutput;
    out.value = textureNumLevels(tex1);
    // Make sure this position is not culled.
    out.position = vec4f(0.5, 0.5, 0.5, 1.0);
    return out;
}
    )";

    // One texture builtin in the fragment shader, in the same bind group
    const char* fragmentShader = R"(
@group(1) @binding(0) var<storage, read_write> dstBuf : array<u32>;
// Use sparse binding to test impact of binding remapping
@group(0) @binding(3) var tex2 : texture_2d<f32>;

struct VertexOutput {
    @builtin(position) position: vec4<f32>,
    @location(0) @interpolate(flat, either) value: u32,
};

@fragment fn main(in: VertexOutput) -> @location(0) vec4f{
    dstBuf[0] = in.value;
    dstBuf[1] = textureNumLevels(tex2);
    return vec4f(1.0, 1.0, 1.0, 1.0);
}
    )";

    constexpr uint32_t kMipLevels_1 = 2;
    constexpr uint32_t kMipLevels_2 = 3;

    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.size.width = 4;
    textureDesc.size.height = 4;
    textureDesc.format = kDefaultFormat;
    textureDesc.mipLevelCount = kMipLevels_1;
    textureDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::TextureView texView_1 = device.CreateTexture(&textureDesc).CreateView();

    textureDesc.mipLevelCount = kMipLevels_2;
    wgpu::TextureView texView_2 = device.CreateTexture(&textureDesc).CreateView();

    constexpr uint32_t expected[] = {
        kMipLevels_1,
        kMipLevels_2,
    };

    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = sizeof(expected);
    bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
        device, {
                    {1, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
                     wgpu::TextureSampleType::Float, wgpu::TextureViewDimension::e2D},
                    {3, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
                     wgpu::TextureSampleType::Float, wgpu::TextureViewDimension::e2D},
                });
    wgpu::BindGroupLayout bglBuffer = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage},
                });

    wgpu::PipelineLayout pipelineLayout = utils::MakePipelineLayout(device, {bgl, bglBuffer});

    utils::ComboRenderPipelineDescriptor pipelineDesc;
    pipelineDesc.layout = pipelineLayout;
    pipelineDesc.vertex.module = utils::CreateShaderModule(device, vertexShader);
    pipelineDesc.cFragment.module = utils::CreateShaderModule(device, fragmentShader);
    pipelineDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pipelineDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline renderPipeline = device.CreateRenderPipeline(&pipelineDesc);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
    wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);

    pass.SetPipeline(renderPipeline);
    pass.SetBindGroup(0, utils::MakeBindGroup(device, bgl,
                                              {
                                                  {1, texView_1},
                                                  {3, texView_2},
                                              }));
    pass.SetBindGroup(1, utils::MakeBindGroup(device, bglBuffer,
                                              {
                                                  {0, buffer},
                                              }));
    pass.Draw(1);
    pass.End();

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

    EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, 0, sizeof(expected) / sizeof(uint32_t));
}

DAWN_INSTANTIATE_TEST(TextureShaderBuiltinTests,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

}  // anonymous namespace
}  // namespace dawn
