// Copyright 2017 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <cmath>

#include "tests/DawnTest.h"

#include "common/Assert.h"
#include "common/Constants.h"
#include "utils/DawnHelpers.h"

constexpr static unsigned int kRTSize = 64;

class BlendStateTest : public DawnTest {
    protected:
        void SetUp() override {
            DawnTest::SetUp();

            vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
                #version 450
                void main() {
                    const vec2 pos[3] = vec2[3](vec2(-1.f, -1.f), vec2(3.f, -1.f), vec2(-1.f, 3.f));
                    gl_Position = vec4(pos[gl_VertexIndex], 0.f, 1.f);
                }
            )");

            bindGroupLayout = utils::MakeBindGroupLayout(
                device, {
                            {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer},
                        });

            pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);

            renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
        }

        struct TriangleSpec {
            RGBA8 color;
            std::array<float, 4> blendFactor = {};
        };

        // Set up basePipeline and testPipeline. testPipeline has the given blend state on the first attachment. basePipeline has no blending
        void SetupSingleSourcePipelines(const dawn::BlendState &blendState) {
            dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
                #version 450
                layout(set = 0, binding = 0) uniform myBlock {
                    vec4 color;
                } myUbo;

                layout(location = 0) out vec4 fragColor;

                void main() {
                    fragColor = myUbo.color;
                }
            )");

            basePipeline = device.CreateRenderPipelineBuilder()
                .SetColorAttachmentFormat(0, renderPass.colorFormat)
                .SetLayout(pipelineLayout)
                .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
                .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
                .GetResult();

            testPipeline = device.CreateRenderPipelineBuilder()
                .SetColorAttachmentFormat(0, renderPass.colorFormat)
                .SetLayout(pipelineLayout)
                .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
                .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
                .SetColorAttachmentBlendState(0, blendState)
                .GetResult();
        }

        // Create a bind group to set the colors as a uniform buffer
        template <size_t N>
        dawn::BindGroup MakeBindGroupForColors(std::array<RGBA8, N> colors) {
            std::array<float, 4 * N> data;
            for (unsigned int i = 0; i < N; ++i) {
                data[4 * i + 0] = static_cast<float>(colors[i].r) / 255.f;
                data[4 * i + 1] = static_cast<float>(colors[i].g) / 255.f;
                data[4 * i + 2] = static_cast<float>(colors[i].b) / 255.f;
                data[4 * i + 3] = static_cast<float>(colors[i].a) / 255.f;
            }

            uint32_t bufferSize = static_cast<uint32_t>(4 * N * sizeof(float));

            dawn::Buffer buffer = utils::CreateBufferFromData(device, &data, bufferSize, dawn::BufferUsageBit::Uniform);

            dawn::BufferView view = buffer.CreateBufferViewBuilder()
                .SetExtent(0, bufferSize)
                .GetResult();

            return device.CreateBindGroupBuilder()
                .SetLayout(bindGroupLayout)
                .SetBufferViews(0, 1, &view)
                .GetResult();
        }

        // Test that after drawing a triangle with the base color, and then the given triangle spec, the color is as expected
        void DoSingleSourceTest(RGBA8 base, const TriangleSpec& triangle, const RGBA8& expected) {
            dawn::CommandBuffer commands = device.CreateCommandBufferBuilder()
                .BeginRenderPass(renderPass.renderPassInfo)
                    // First use the base pipeline to draw a triangle with no blending
                    .SetRenderPipeline(basePipeline)
                    .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { base } })))
                    .DrawArrays(3, 1, 0, 0)

                    // Then use the test pipeline to draw the test triangle with blending
                    .SetRenderPipeline(testPipeline)
                    .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { triangle.color } })))
                    .SetBlendColor(triangle.blendFactor[0], triangle.blendFactor[1], triangle.blendFactor[2], triangle.blendFactor[3])
                    .DrawArrays(3, 1, 0, 0)
                .EndRenderPass()
                .GetResult();


            queue.Submit(1, &commands);

            EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2);
        }

        // Given a vector of tests where each element is <testColor, expectedColor>, check that all expectations are true for the given blend operation
        void CheckBlendOperation(RGBA8 base, dawn::BlendOperation operation, std::vector<std::pair<RGBA8, RGBA8>> tests) {
            dawn::BlendState blendState = device.CreateBlendStateBuilder()
                .SetBlendEnabled(true)
                .SetColorBlend(operation, dawn::BlendFactor::One, dawn::BlendFactor::One)
                .SetAlphaBlend(operation, dawn::BlendFactor::One, dawn::BlendFactor::One)
                .GetResult();

            SetupSingleSourcePipelines(blendState);

            for (const auto& test : tests) {
                DoSingleSourceTest(base, { test.first }, test.second);
            }
        }

        // Given a vector of tests where each element is <testSpec, expectedColor>, check that all expectations are true for the given blend factors
        void CheckBlendFactor(RGBA8 base, dawn::BlendFactor colorSrcFactor, dawn::BlendFactor colorDstFactor, dawn::BlendFactor alphaSrcFactor, dawn::BlendFactor alphaDstFactor, std::vector<std::pair<TriangleSpec, RGBA8>> tests) {
            dawn::BlendState blendState = device.CreateBlendStateBuilder()
                .SetBlendEnabled(true)
                .SetColorBlend(dawn::BlendOperation::Add, colorSrcFactor, colorDstFactor)
                .SetAlphaBlend(dawn::BlendOperation::Add, alphaSrcFactor, alphaDstFactor)
                .GetResult();

            SetupSingleSourcePipelines(blendState);

            for (const auto& test : tests) {
                DoSingleSourceTest(base, test.first, test.second);
            }
        }

        void CheckSrcBlendFactor(RGBA8 base, dawn::BlendFactor colorFactor, dawn::BlendFactor alphaFactor, std::vector<std::pair<TriangleSpec, RGBA8>> tests) {
            CheckBlendFactor(base, colorFactor, dawn::BlendFactor::One, alphaFactor, dawn::BlendFactor::One, tests);
        }

        void CheckDstBlendFactor(RGBA8 base, dawn::BlendFactor colorFactor, dawn::BlendFactor alphaFactor, std::vector<std::pair<TriangleSpec, RGBA8>> tests) {
            CheckBlendFactor(base, dawn::BlendFactor::One, colorFactor, dawn::BlendFactor::One, alphaFactor, tests);
        }

        utils::BasicRenderPass renderPass;
        dawn::RenderPipeline basePipeline;
        dawn::RenderPipeline testPipeline;
        dawn::ShaderModule vsModule;
        dawn::BindGroupLayout bindGroupLayout;
        dawn::PipelineLayout pipelineLayout;
};

namespace {
    // Add two colors and clamp
    constexpr RGBA8 operator+(const RGBA8& col1, const RGBA8& col2) {
        int r = static_cast<int>(col1.r) + static_cast<int>(col2.r);
        int g = static_cast<int>(col1.g) + static_cast<int>(col2.g);
        int b = static_cast<int>(col1.b) + static_cast<int>(col2.b);
        int a = static_cast<int>(col1.a) + static_cast<int>(col2.a);
        r = (r > 255 ? 255 : (r < 0 ? 0 : r));
        g = (g > 255 ? 255 : (g < 0 ? 0 : g));
        b = (b > 255 ? 255 : (b < 0 ? 0 : b));
        a = (a > 255 ? 255 : (a < 0 ? 0 : a));

        return RGBA8(static_cast<uint8_t>(r), static_cast<uint8_t>(g), static_cast<uint8_t>(b), static_cast<uint8_t>(a));
    }

    // Subtract two colors and clamp
    constexpr RGBA8 operator-(const RGBA8& col1, const RGBA8& col2) {
        int r = static_cast<int>(col1.r) - static_cast<int>(col2.r);
        int g = static_cast<int>(col1.g) - static_cast<int>(col2.g);
        int b = static_cast<int>(col1.b) - static_cast<int>(col2.b);
        int a = static_cast<int>(col1.a) - static_cast<int>(col2.a);
        r = (r > 255 ? 255 : (r < 0 ? 0 : r));
        g = (g > 255 ? 255 : (g < 0 ? 0 : g));
        b = (b > 255 ? 255 : (b < 0 ? 0 : b));
        a = (a > 255 ? 255 : (a < 0 ? 0 : a));

        return RGBA8(static_cast<uint8_t>(r), static_cast<uint8_t>(g), static_cast<uint8_t>(b), static_cast<uint8_t>(a));
    }

    // Get the component-wise minimum of two colors
    RGBA8 min(const RGBA8& col1, const RGBA8& col2) {
        return RGBA8(
            std::min(col1.r, col2.r),
            std::min(col1.g, col2.g),
            std::min(col1.b, col2.b),
            std::min(col1.a, col2.a)
        );
    }

    // Get the component-wise maximum of two colors
    RGBA8 max(const RGBA8& col1, const RGBA8& col2) {
        return RGBA8(
            std::max(col1.r, col2.r),
            std::max(col1.g, col2.g),
            std::max(col1.b, col2.b),
            std::max(col1.a, col2.a)
        );
    }

    // Blend two RGBA8 color values parameterized by the provided factors in the range [0.f, 1.f]
    RGBA8 mix(const RGBA8& col1, const RGBA8& col2, std::array<float, 4> fac) {
        float r = static_cast<float>(col1.r) * (1.f - fac[0]) + static_cast<float>(col2.r) * fac[0];
        float g = static_cast<float>(col1.g) * (1.f - fac[1]) + static_cast<float>(col2.g) * fac[1];
        float b = static_cast<float>(col1.b) * (1.f - fac[2]) + static_cast<float>(col2.b) * fac[2];
        float a = static_cast<float>(col1.a) * (1.f - fac[3]) + static_cast<float>(col2.a) * fac[3];

        return RGBA8({ static_cast<uint8_t>(std::round(r)), static_cast<uint8_t>(std::round(g)), static_cast<uint8_t>(std::round(b)), static_cast<uint8_t>(std::round(a)) });
    }

    // Blend two RGBA8 color values parameterized by the provided RGBA8 factor
    RGBA8 mix(const RGBA8& col1, const RGBA8& col2, const RGBA8& fac) {
        std::array<float, 4> f = { {
            static_cast<float>(fac.r) / 255.f,
            static_cast<float>(fac.g) / 255.f,
            static_cast<float>(fac.b) / 255.f,
            static_cast<float>(fac.a) / 255.f,
        } };
        return mix(col1, col2, f);
    }

    constexpr std::array<RGBA8, 8> kColors = { {
        // check operations over multiple channels
        RGBA8(64,0,0,0),
        RGBA8(0,64,0,0),
        RGBA8(64,0,32,0),
        RGBA8(0,64,32,0),
        RGBA8(128,0,128,128),
        RGBA8(0,128,128,128),

        // check cases that may cause overflow
        RGBA8(0,0,0,0),
        RGBA8(255,255,255,255),
    } };
}

// Test compilation and usage of the fixture
TEST_P(BlendStateTest, Basic) {
    dawn::BlendState blendState = device.CreateBlendStateBuilder().GetResult();
    SetupSingleSourcePipelines(blendState);

    DoSingleSourceTest(RGBA8(0, 0, 0, 0), { RGBA8(255, 0, 0, 0) }, RGBA8(255, 0, 0, 0));
}

// The following tests check test that the blend operation works
TEST_P(BlendStateTest, BlendOperationAdd) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<RGBA8, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(color, base + color);
    });
    CheckBlendOperation(base, dawn::BlendOperation::Add, tests);
}

TEST_P(BlendStateTest, BlendOperationSubtract) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<RGBA8, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(color, color - base);
    });
    CheckBlendOperation(base, dawn::BlendOperation::Subtract, tests);
}

TEST_P(BlendStateTest, BlendOperationReverseSubtract) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<RGBA8, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(color, base - color);
    });
    CheckBlendOperation(base, dawn::BlendOperation::ReverseSubtract, tests);
}

TEST_P(BlendStateTest, BlendOperationMin) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<RGBA8, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(color, min(base, color));
    });
    CheckBlendOperation(base, dawn::BlendOperation::Min, tests);
}

TEST_P(BlendStateTest, BlendOperationMax) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<RGBA8, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(color, max(base, color));
    });
    CheckBlendOperation(base, dawn::BlendOperation::Max, tests);
}

// The following tests check that the Source blend factor works
TEST_P(BlendStateTest, SrcBlendFactorZero) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(TriangleSpec({ { color } }), base);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::Zero, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorOne) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(TriangleSpec({ { color } }), base + color);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::One, dawn::BlendFactor::One, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorSrcColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = color;
        fac.a = 0;
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::SrcColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorOneMinusSrcColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - color;
        fac.a = 0;
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::OneMinusSrcColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorSrcAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac(color.a, color.a, color.a, color.a);
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::SrcAlpha, dawn::BlendFactor::SrcAlpha, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorOneMinusSrcAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - RGBA8(color.a, color.a, color.a, color.a);
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::OneMinusSrcAlpha, dawn::BlendFactor::OneMinusSrcAlpha, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorDstColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = base;
        fac.a = 0;
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::DstColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorOneMinusDstColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - base;
        fac.a = 0;
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::OneMinusDstColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorDstAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac(base.a, base.a, base.a, base.a);
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::DstAlpha, dawn::BlendFactor::DstAlpha, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorOneMinusDstAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - RGBA8(base.a, base.a, base.a, base.a);
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::OneMinusDstAlpha, dawn::BlendFactor::OneMinusDstAlpha, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorSrcAlphaSaturated) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        uint8_t f = std::min(color.a, static_cast<uint8_t>(255 - base.a));
        RGBA8 fac(f, f, f, 255);
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::SrcAlphaSaturated, dawn::BlendFactor::SrcAlphaSaturated, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorBlendColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        auto triangleSpec = TriangleSpec({ { color }, {{ 0.2f, 0.4f, 0.6f, 0.8f }} });
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, triangleSpec.blendFactor);
        return std::make_pair(triangleSpec, expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::BlendColor, dawn::BlendFactor::BlendColor, tests);
}

TEST_P(BlendStateTest, SrcBlendFactorOneMinusBlendColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        auto triangleSpec = TriangleSpec({ { color }, {{ 0.2f, 0.4f, 0.6f, 0.8f }} });
        std::array<float, 4> f = { { 0.8f, 0.6f, 0.4f, 0.2f } };
        RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, f);
        return std::make_pair(triangleSpec, expected);
    });
    CheckSrcBlendFactor(base, dawn::BlendFactor::OneMinusBlendColor, dawn::BlendFactor::OneMinusBlendColor, tests);
}

// The following tests check that the Destination blend factor works
TEST_P(BlendStateTest, DstBlendFactorZero) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(TriangleSpec({ { color } }), color);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::Zero, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, DstBlendFactorOne) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        return std::make_pair(TriangleSpec({ { color } }), base + color);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::One, dawn::BlendFactor::One, tests);
}

TEST_P(BlendStateTest, DstBlendFactorSrcColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = color;
        fac.a = 0;
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::SrcColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, DstBlendFactorOneMinusSrcColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - color;
        fac.a = 0;
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::OneMinusSrcColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, DstBlendFactorSrcAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac(color.a, color.a, color.a, color.a);
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::SrcAlpha, dawn::BlendFactor::SrcAlpha, tests);
}

TEST_P(BlendStateTest, DstBlendFactorOneMinusSrcAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - RGBA8(color.a, color.a, color.a, color.a);
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::OneMinusSrcAlpha, dawn::BlendFactor::OneMinusSrcAlpha, tests);
}

TEST_P(BlendStateTest, DstBlendFactorDstColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = base;
        fac.a = 0;
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::DstColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, DstBlendFactorOneMinusDstColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - base;
        fac.a = 0;
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::OneMinusDstColor, dawn::BlendFactor::Zero, tests);
}

TEST_P(BlendStateTest, DstBlendFactorDstAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac(base.a, base.a, base.a, base.a);
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::DstAlpha, dawn::BlendFactor::DstAlpha, tests);
}

TEST_P(BlendStateTest, DstBlendFactorOneMinusDstAlpha) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        RGBA8 fac = RGBA8(255, 255, 255, 255) - RGBA8(base.a, base.a, base.a, base.a);
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::OneMinusDstAlpha, dawn::BlendFactor::OneMinusDstAlpha, tests);
}

TEST_P(BlendStateTest, DstBlendFactorSrcAlphaSaturated) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        uint8_t f = std::min(color.a, static_cast<uint8_t>(255 - base.a));
        RGBA8 fac(f, f, f, 255);
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
        return std::make_pair(TriangleSpec({ { color } }), expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::SrcAlphaSaturated, dawn::BlendFactor::SrcAlphaSaturated, tests);
}

TEST_P(BlendStateTest, DstBlendFactorBlendColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        auto triangleSpec = TriangleSpec({ { color }, {{ 0.2f, 0.4f, 0.6f, 0.8f }} });
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, triangleSpec.blendFactor);
        return std::make_pair(triangleSpec, expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::BlendColor, dawn::BlendFactor::BlendColor, tests);
}

TEST_P(BlendStateTest, DstBlendFactorOneMinusBlendColor) {
    RGBA8 base(32, 64, 128, 192);
    std::vector<std::pair<TriangleSpec, RGBA8>> tests;
    std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) {
        auto triangleSpec = TriangleSpec({ { color }, {{ 0.2f, 0.4f, 0.6f, 0.8f }} });
        std::array<float, 4> f = { { 0.8f, 0.6f, 0.4f, 0.2f } };
        RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, f);
        return std::make_pair(triangleSpec, expected);
    });
    CheckDstBlendFactor(base, dawn::BlendFactor::OneMinusBlendColor, dawn::BlendFactor::OneMinusBlendColor, tests);
}

// Check that the color write mask works
TEST_P(BlendStateTest, ColorWriteMask) {
    {
        // Test single channel color write
        dawn::BlendState blendState = device.CreateBlendStateBuilder()
            .SetBlendEnabled(true)
            .SetColorBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetAlphaBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetColorWriteMask(dawn::ColorWriteMask::Red)
            .GetResult();
        SetupSingleSourcePipelines(blendState);

        RGBA8 base(32, 64, 128, 192);
        for (auto& color : kColors) {
            RGBA8 expected = base + RGBA8(color.r, 0, 0, 0);
            DoSingleSourceTest(base, { color }, expected);
        }
    }

    {
        // Test multi channel color write
        dawn::BlendState blendState = device.CreateBlendStateBuilder()
            .SetBlendEnabled(true)
            .SetColorBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetAlphaBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetColorWriteMask(dawn::ColorWriteMask::Green | dawn::ColorWriteMask::Alpha)
            .GetResult();
        SetupSingleSourcePipelines(blendState);

        RGBA8 base(32, 64, 128, 192);
        for (auto& color : kColors) {
            RGBA8 expected = base + RGBA8(0, color.g, 0, color.a);
            DoSingleSourceTest(base, { color }, expected);
        }
    }

    {
        // Test no channel color write
        dawn::BlendState blendState = device.CreateBlendStateBuilder()
            .SetBlendEnabled(true)
            .SetColorBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetAlphaBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetColorWriteMask(dawn::ColorWriteMask::None)
            .GetResult();
        SetupSingleSourcePipelines(blendState);

        RGBA8 base(32, 64, 128, 192);
        for (auto& color : kColors) {
            DoSingleSourceTest(base, { color }, base);
        }
    }
}

// Check that the color write mask works when blending is disabled
TEST_P(BlendStateTest, ColorWriteMaskBlendingDisabled) {
    {
        dawn::BlendState blendState = device.CreateBlendStateBuilder()
            .SetBlendEnabled(false)
            .SetColorWriteMask(dawn::ColorWriteMask::Red)
            .GetResult();
        SetupSingleSourcePipelines(blendState);

        RGBA8 base(32, 64, 128, 192);
        RGBA8 expected(32, 0, 0, 0);
        dawn::CommandBuffer commands = device.CreateCommandBufferBuilder()
            .BeginRenderPass(renderPass.renderPassInfo)
                .SetRenderPipeline(testPipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { base } })))
                .DrawArrays(3, 1, 0, 0)
            .EndRenderPass()
            .GetResult();

        queue.Submit(1, &commands);
        EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2);
    }
}

// Test that independent blend states on render targets works
TEST_P(BlendStateTest, IndependentBlendState) {

    std::array<dawn::Texture, 4> renderTargets;
    std::array<dawn::TextureView, 4> renderTargetViews;

    for (uint32_t i = 0; i < 4; ++i) {
        renderTargets[i] = device.CreateTextureBuilder()
            .SetDimension(dawn::TextureDimension::e2D)
            .SetExtent(kRTSize, kRTSize, 1)
            .SetFormat(dawn::TextureFormat::R8G8B8A8Unorm)
            .SetMipLevels(1)
            .SetAllowedUsage(dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc)
            .GetResult();
        renderTargetViews[i] = renderTargets[i].CreateTextureViewBuilder().GetResult();
    }

    dawn::RenderPassDescriptor renderpass = device.CreateRenderPassDescriptorBuilder()
        .SetColorAttachment(0, renderTargetViews[0], dawn::LoadOp::Clear)
        .SetColorAttachment(1, renderTargetViews[1], dawn::LoadOp::Clear)
        .SetColorAttachment(2, renderTargetViews[2], dawn::LoadOp::Clear)
        .SetColorAttachment(3, renderTargetViews[3], dawn::LoadOp::Clear)
        .GetResult();

    dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
        #version 450
        layout(set = 0, binding = 0) uniform myBlock {
            vec4 color0;
            vec4 color1;
            vec4 color2;
            vec4 color3;
        } myUbo;

        layout(location = 0) out vec4 fragColor0;
        layout(location = 1) out vec4 fragColor1;
        layout(location = 2) out vec4 fragColor2;
        layout(location = 3) out vec4 fragColor3;

        void main() {
            fragColor0 = myUbo.color0;
            fragColor1 = myUbo.color1;
            fragColor2 = myUbo.color2;
            fragColor3 = myUbo.color3;
        }
    )");

    std::array<dawn::BlendState, 3> blendStates = { {
        device.CreateBlendStateBuilder()
            .SetBlendEnabled(true)
            .SetColorBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetAlphaBlend(dawn::BlendOperation::Add, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .GetResult(),
        device.CreateBlendStateBuilder()
            .SetBlendEnabled(true)
            .SetColorBlend(dawn::BlendOperation::Subtract, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetAlphaBlend(dawn::BlendOperation::Subtract, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .GetResult(),
        device.CreateBlendStateBuilder()
            .SetBlendEnabled(true)
            .SetColorBlend(dawn::BlendOperation::Min, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .SetAlphaBlend(dawn::BlendOperation::Min, dawn::BlendFactor::One, dawn::BlendFactor::One)
            .GetResult(),
    } };

    basePipeline = device.CreateRenderPipelineBuilder()
        .SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetColorAttachmentFormat(1, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetColorAttachmentFormat(2, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetColorAttachmentFormat(3, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetLayout(pipelineLayout)
        .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
        .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
        .GetResult();

    testPipeline = device.CreateRenderPipelineBuilder()
        .SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetColorAttachmentFormat(1, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetColorAttachmentFormat(2, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetColorAttachmentFormat(3, dawn::TextureFormat::R8G8B8A8Unorm)
        .SetLayout(pipelineLayout)
        .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
        .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
        .SetColorAttachmentBlendState(0, blendStates[0])
        .SetColorAttachmentBlendState(1, blendStates[1])
        // Blend state not set on third color attachment. It should be default
        .SetColorAttachmentBlendState(3, blendStates[2])
        .GetResult();


    for (unsigned int c = 0; c < kColors.size(); ++c) {
        RGBA8 base = kColors[((c + 31) * 29) % kColors.size()];
        RGBA8 color0 = kColors[((c + 19) * 13) % kColors.size()];
        RGBA8 color1 = kColors[((c + 11) * 43) % kColors.size()];
        RGBA8 color2 = kColors[((c + 7) * 3) % kColors.size()];
        RGBA8 color3 = kColors[((c + 13) * 71) % kColors.size()];

        RGBA8 expected0 = color0 + base;
        RGBA8 expected1 = color1 - base;
        RGBA8 expected2 = color2;
        RGBA8 expected3 = min(color3, base);

        dawn::CommandBuffer commands = device.CreateCommandBufferBuilder()
            .BeginRenderPass(renderpass)
                .SetRenderPipeline(basePipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 4>({ { base, base, base, base } })))
                .DrawArrays(3, 1, 0, 0)

                .SetRenderPipeline(testPipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 4>({ { color0, color1, color2, color3 } })))
                .DrawArrays(3, 1, 0, 0)
            .EndRenderPass()
            .GetResult();

        queue.Submit(1, &commands);

        EXPECT_PIXEL_RGBA8_EQ(expected0, renderTargets[0], kRTSize / 2, kRTSize / 2) << "Attachment slot 0 should have been " << color0 << " + " << base << " = " << expected0;
        EXPECT_PIXEL_RGBA8_EQ(expected1, renderTargets[1], kRTSize / 2, kRTSize / 2) << "Attachment slot 1 should have been " << color1 << " - " << base << " = " << expected1;
        EXPECT_PIXEL_RGBA8_EQ(expected2, renderTargets[2], kRTSize / 2, kRTSize / 2) << "Attachment slot 2 should have been " << color2 << " = " << expected2 << "(no blending)";
        EXPECT_PIXEL_RGBA8_EQ(expected3, renderTargets[3], kRTSize / 2, kRTSize / 2) << "Attachment slot 3 should have been min(" << color3 << ", " << base << ") = " << expected3;
    }
}

// Test that the default blend color is correctly set at the beginning of every subpass
TEST_P(BlendStateTest, DefaultBlendColor) {
    dawn::BlendState blendState = device.CreateBlendStateBuilder()
        .SetBlendEnabled(true)
        .SetColorBlend(dawn::BlendOperation::Add, dawn::BlendFactor::BlendColor, dawn::BlendFactor::One)
        .SetAlphaBlend(dawn::BlendOperation::Add, dawn::BlendFactor::BlendColor, dawn::BlendFactor::One)
        .GetResult();

    dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
        #version 450
        layout(set = 0, binding = 0) uniform myBlock {
            vec4 color;
        } myUbo;

        layout(location = 0) out vec4 fragColor;

        void main() {
            fragColor = myUbo.color;
        }
    )");

    basePipeline = device.CreateRenderPipelineBuilder()
        .SetColorAttachmentFormat(0, renderPass.colorFormat)
        .SetLayout(pipelineLayout)
        .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
        .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
        .GetResult();

    testPipeline = device.CreateRenderPipelineBuilder()
        .SetColorAttachmentFormat(0, renderPass.colorFormat)
        .SetLayout(pipelineLayout)
        .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
        .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
        .SetColorAttachmentBlendState(0, blendState)
        .GetResult();

    // Check that the initial blend color is (0,0,0,0)
    {
        dawn::CommandBuffer commands = device.CreateCommandBufferBuilder()
            .BeginRenderPass(renderPass.renderPassInfo)
                .SetRenderPipeline(basePipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(0, 0, 0, 0) } })))
                .DrawArrays(3, 1, 0, 0)
                .SetRenderPipeline(testPipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(255, 255, 255, 255) } })))
                .DrawArrays(3, 1, 0, 0)
            .EndRenderPass()
            .GetResult();

        queue.Submit(1, &commands);

        EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, kRTSize / 2, kRTSize / 2);
    }

    // Check that setting the blend color works
    {
        dawn::CommandBuffer commands = device.CreateCommandBufferBuilder()
            .BeginRenderPass(renderPass.renderPassInfo)
                .SetRenderPipeline(basePipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(0, 0, 0, 0) } })))
                .DrawArrays(3, 1, 0, 0)
                .SetRenderPipeline(testPipeline)
                .SetBlendColor(1, 1, 1, 1)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(255, 255, 255, 255) } })))
                .DrawArrays(3, 1, 0, 0)
            .EndRenderPass()
            .GetResult();

        queue.Submit(1, &commands);

        EXPECT_PIXEL_RGBA8_EQ(RGBA8(255, 255, 255, 255), renderPass.color, kRTSize / 2, kRTSize / 2);
    }

    // Check that the blend color is not inherited between render passes
    {
        dawn::CommandBuffer commands = device.CreateCommandBufferBuilder()
            .BeginRenderPass(renderPass.renderPassInfo)
                .SetRenderPipeline(basePipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(0, 0, 0, 0) } })))
                .DrawArrays(3, 1, 0, 0)
                .SetRenderPipeline(testPipeline)
                .SetBlendColor(1, 1, 1, 1)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(255, 255, 255, 255) } })))
                .DrawArrays(3, 1, 0, 0)
            .EndRenderPass()
            .BeginRenderPass(renderPass.renderPassInfo)
                .SetRenderPipeline(basePipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(0, 0, 0, 0) } })))
                .DrawArrays(3, 1, 0, 0)
                .SetRenderPipeline(testPipeline)
                .SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 1>({ { RGBA8(255, 255, 255, 255) } })))
                .DrawArrays(3, 1, 0, 0)
            .EndRenderPass()
            .GetResult();

        queue.Submit(1, &commands);

        EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, kRTSize / 2, kRTSize / 2);
    }
}

DAWN_INSTANTIATE_TEST(BlendStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend)
