From 7775258f98ce12cd7376f60d52c09e1f46c3ee00 Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Sat, 16 Feb 2019 02:27:30 +0000 Subject: [PATCH] Rename BlendState to ColorState, in order to match web idl BUG=dawn:106 Change-Id: Id2cb1788becfacd09bd7f420d6525d22f96d1fe2 Reviewed-on: https://dawn-review.googlesource.com/c/4781 Commit-Queue: Yunchao He Reviewed-by: Corentin Wallez --- BUILD.gn | 2 +- src/dawn_native/RenderPipeline.cpp | 14 +- src/dawn_native/RenderPipeline.h | 2 +- src/dawn_native/d3d12/RenderPipelineD3D12.cpp | 4 +- src/dawn_native/opengl/RenderPipelineGL.cpp | 4 +- src/dawn_native/vulkan/RenderPipelineVk.cpp | 10 +- ...lendStateTests.cpp => ColorStateTests.cpp} | 785 ++++++++++-------- .../RenderPipelineValidationTests.cpp | 4 +- 8 files changed, 440 insertions(+), 385 deletions(-) rename src/tests/end2end/{BlendStateTests.cpp => ColorStateTests.cpp} (50%) diff --git a/BUILD.gn b/BUILD.gn index 9ccee8885a..ded947497c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -998,8 +998,8 @@ test("dawn_end2end_tests") { "src/tests/DawnTest.h", "src/tests/end2end/BasicTests.cpp", "src/tests/end2end/BindGroupTests.cpp", - "src/tests/end2end/BlendStateTests.cpp", "src/tests/end2end/BufferTests.cpp", + "src/tests/end2end/ColorStateTests.cpp", "src/tests/end2end/ComputeCopyStorageBufferTests.cpp", "src/tests/end2end/CopyTests.cpp", "src/tests/end2end/DepthStencilStateTests.cpp", diff --git a/src/dawn_native/RenderPipeline.cpp b/src/dawn_native/RenderPipeline.cpp index d738852314..2b840425db 100644 --- a/src/dawn_native/RenderPipeline.cpp +++ b/src/dawn_native/RenderPipeline.cpp @@ -151,13 +151,13 @@ namespace dawn_native { mDepthStencilState->stencilFront.passOp != dawn::StencilOperation::Keep; } - bool BlendEnabled(const ColorStateDescriptor* mBlendState) { - return mBlendState->alphaBlend.operation != dawn::BlendOperation::Add || - mBlendState->alphaBlend.srcFactor != dawn::BlendFactor::One || - mBlendState->alphaBlend.dstFactor != dawn::BlendFactor::Zero || - mBlendState->colorBlend.operation != dawn::BlendOperation::Add || - mBlendState->colorBlend.srcFactor != dawn::BlendFactor::One || - mBlendState->colorBlend.dstFactor != dawn::BlendFactor::Zero; + bool BlendEnabled(const ColorStateDescriptor* mColorState) { + return mColorState->alphaBlend.operation != dawn::BlendOperation::Add || + mColorState->alphaBlend.srcFactor != dawn::BlendFactor::One || + mColorState->alphaBlend.dstFactor != dawn::BlendFactor::Zero || + mColorState->colorBlend.operation != dawn::BlendOperation::Add || + mColorState->colorBlend.srcFactor != dawn::BlendFactor::One || + mColorState->colorBlend.dstFactor != dawn::BlendFactor::Zero; } // RenderPipelineBase diff --git a/src/dawn_native/RenderPipeline.h b/src/dawn_native/RenderPipeline.h index 27064c00fa..0e95cedb08 100644 --- a/src/dawn_native/RenderPipeline.h +++ b/src/dawn_native/RenderPipeline.h @@ -30,7 +30,7 @@ namespace dawn_native { MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device, const RenderPipelineDescriptor* descriptor); bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState); - bool BlendEnabled(const ColorStateDescriptor* mBlendState); + bool BlendEnabled(const ColorStateDescriptor* mColorState); class RenderPipelineBase : public PipelineBase { public: diff --git a/src/dawn_native/d3d12/RenderPipelineD3D12.cpp b/src/dawn_native/d3d12/RenderPipelineD3D12.cpp index 83babded64..4e4127d318 100644 --- a/src/dawn_native/d3d12/RenderPipelineD3D12.cpp +++ b/src/dawn_native/d3d12/RenderPipelineD3D12.cpp @@ -127,7 +127,7 @@ namespace dawn_native { namespace d3d12 { return static_cast(colorWriteMask); } - D3D12_RENDER_TARGET_BLEND_DESC ComputeBlendDesc(const ColorStateDescriptor* descriptor) { + D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const ColorStateDescriptor* descriptor) { D3D12_RENDER_TARGET_BLEND_DESC blendDesc; blendDesc.BlendEnable = BlendEnabled(descriptor); blendDesc.SrcBlend = D3D12Blend(descriptor->colorBlend.srcFactor); @@ -287,7 +287,7 @@ namespace dawn_native { namespace d3d12 { for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { descriptorD3D12.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i)); descriptorD3D12.BlendState.RenderTarget[i] = - ComputeBlendDesc(GetColorStateDescriptor(i)); + ComputeColorDesc(GetColorStateDescriptor(i)); } descriptorD3D12.NumRenderTargets = static_cast(GetColorAttachmentsMask().count()); diff --git a/src/dawn_native/opengl/RenderPipelineGL.cpp b/src/dawn_native/opengl/RenderPipelineGL.cpp index 665f039441..830fa407c0 100644 --- a/src/dawn_native/opengl/RenderPipelineGL.cpp +++ b/src/dawn_native/opengl/RenderPipelineGL.cpp @@ -90,7 +90,7 @@ namespace dawn_native { namespace opengl { } } - void ApplyBlendState(uint32_t attachment, const ColorStateDescriptor* descriptor) { + void ApplyColorState(uint32_t attachment, const ColorStateDescriptor* descriptor) { if (BlendEnabled(descriptor)) { glEnablei(GL_BLEND, attachment); glBlendEquationSeparatei(attachment, GLBlendMode(descriptor->colorBlend.operation), @@ -196,7 +196,7 @@ namespace dawn_native { namespace opengl { ApplyDepthStencilState(GetDepthStencilStateDescriptor(), &persistentPipelineState); for (uint32_t attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) { - ApplyBlendState(attachmentSlot, GetColorStateDescriptor(attachmentSlot)); + ApplyColorState(attachmentSlot, GetColorStateDescriptor(attachmentSlot)); } } diff --git a/src/dawn_native/vulkan/RenderPipelineVk.cpp b/src/dawn_native/vulkan/RenderPipelineVk.cpp index 411765dd84..81b73b5bc5 100644 --- a/src/dawn_native/vulkan/RenderPipelineVk.cpp +++ b/src/dawn_native/vulkan/RenderPipelineVk.cpp @@ -111,7 +111,7 @@ namespace dawn_native { namespace vulkan { return static_cast(mask); } - VkPipelineColorBlendAttachmentState ComputeBlendDesc( + VkPipelineColorBlendAttachmentState ComputeColorDesc( const ColorStateDescriptor* descriptor) { VkPipelineColorBlendAttachmentState attachment; attachment.blendEnable = BlendEnabled(descriptor) ? VK_TRUE : VK_FALSE; @@ -199,10 +199,6 @@ namespace dawn_native { namespace vulkan { RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor) : RenderPipelineBase(device, descriptor) { - // Eventually a bunch of the structures that need to be chained in the create info will be - // held by objects such as the BlendState. They aren't implemented yet so we initialize - // everything here. - VkPipelineShaderStageCreateInfo shaderStages[2]; { shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -283,11 +279,11 @@ namespace dawn_native { namespace vulkan { ComputeDepthStencilDesc(GetDepthStencilStateDescriptor()); // Initialize the "blend state info" that will be chained in the "create info" from the data - // pre-computed in the BlendState + // pre-computed in the ColorState std::array colorBlendAttachments; for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { const ColorStateDescriptor* descriptor = GetColorStateDescriptor(i); - colorBlendAttachments[i] = ComputeBlendDesc(descriptor); + colorBlendAttachments[i] = ComputeColorDesc(descriptor); } VkPipelineColorBlendStateCreateInfo colorBlend; colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; diff --git a/src/tests/end2end/BlendStateTests.cpp b/src/tests/end2end/ColorStateTests.cpp similarity index 50% rename from src/tests/end2end/BlendStateTests.cpp rename to src/tests/end2end/ColorStateTests.cpp index 6b9ddd88ba..ea099f4c61 100644 --- a/src/tests/end2end/BlendStateTests.cpp +++ b/src/tests/end2end/ColorStateTests.cpp @@ -24,12 +24,12 @@ constexpr static unsigned int kRTSize = 64; -class BlendStateTest : public DawnTest { - protected: - void SetUp() override { - DawnTest::SetUp(); +class ColorStateTest : public DawnTest { + protected: + void SetUp() override { + DawnTest::SetUp(); - vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( + 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)); @@ -37,24 +37,26 @@ class BlendStateTest : public DawnTest { } )"); - bindGroupLayout = utils::MakeBindGroupLayout( - device, { - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - }); + bindGroupLayout = utils::MakeBindGroupLayout( + device, { + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + }); - pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout); + pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout); - renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - } + renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); + } - struct TriangleSpec { - RGBA8 color; - std::array blendFactor = {}; - }; + struct TriangleSpec { + RGBA8 color; + std::array blendFactor = {}; + }; - // Set up basePipeline and testPipeline. testPipeline has the given blend state on the first attachment. basePipeline has no blending - void SetupSingleSourcePipelines(const dawn::ColorStateDescriptor& colorStateDescriptor) { - dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( + // Set up basePipeline and testPipeline. testPipeline has the given blend state on the first + // attachment. basePipeline has no blending + void SetupSingleSourcePipelines(const dawn::ColorStateDescriptor& colorStateDescriptor) { + dawn::ShaderModule fsModule = + utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( #version 450 layout(set = 0, binding = 0) uniform myBlock { vec4 color; @@ -67,124 +69,144 @@ class BlendStateTest : public DawnTest { } )"); - utils::ComboRenderPipelineDescriptor baseDescriptor(device); - baseDescriptor.layout = pipelineLayout; - baseDescriptor.cVertexStage.module = vsModule; - baseDescriptor.cFragmentStage.module = fsModule; - baseDescriptor.cColorStates[0].format = renderPass.colorFormat; + utils::ComboRenderPipelineDescriptor baseDescriptor(device); + baseDescriptor.layout = pipelineLayout; + baseDescriptor.cVertexStage.module = vsModule; + baseDescriptor.cFragmentStage.module = fsModule; + baseDescriptor.cColorStates[0].format = renderPass.colorFormat; - basePipeline = device.CreateRenderPipeline(&baseDescriptor); + basePipeline = device.CreateRenderPipeline(&baseDescriptor); - utils::ComboRenderPipelineDescriptor testDescriptor(device); - testDescriptor.layout = pipelineLayout; - testDescriptor.cVertexStage.module = vsModule; - testDescriptor.cFragmentStage.module = fsModule; - testDescriptor.cColorStates[0] = colorStateDescriptor; - testDescriptor.cColorStates[0].format = renderPass.colorFormat; + utils::ComboRenderPipelineDescriptor testDescriptor(device); + testDescriptor.layout = pipelineLayout; + testDescriptor.cVertexStage.module = vsModule; + testDescriptor.cFragmentStage.module = fsModule; + testDescriptor.cColorStates[0] = colorStateDescriptor; + testDescriptor.cColorStates[0].format = renderPass.colorFormat; - testPipeline = device.CreateRenderPipeline(&testDescriptor); + testPipeline = device.CreateRenderPipeline(&testDescriptor); + } + + // Create a bind group to set the colors as a uniform buffer + template + dawn::BindGroup MakeBindGroupForColors(std::array colors) { + std::array data; + for (unsigned int i = 0; i < N; ++i) { + data[4 * i + 0] = static_cast(colors[i].r) / 255.f; + data[4 * i + 1] = static_cast(colors[i].g) / 255.f; + data[4 * i + 2] = static_cast(colors[i].b) / 255.f; + data[4 * i + 3] = static_cast(colors[i].a) / 255.f; } - // Create a bind group to set the colors as a uniform buffer - template - dawn::BindGroup MakeBindGroupForColors(std::array colors) { - std::array data; - for (unsigned int i = 0; i < N; ++i) { - data[4 * i + 0] = static_cast(colors[i].r) / 255.f; - data[4 * i + 1] = static_cast(colors[i].g) / 255.f; - data[4 * i + 2] = static_cast(colors[i].b) / 255.f; - data[4 * i + 3] = static_cast(colors[i].a) / 255.f; - } + uint32_t bufferSize = static_cast(4 * N * sizeof(float)); - uint32_t bufferSize = static_cast(4 * N * sizeof(float)); + dawn::Buffer buffer = + utils::CreateBufferFromData(device, &data, bufferSize, dawn::BufferUsageBit::Uniform); + return utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer, 0, bufferSize}}); + } - dawn::Buffer buffer = utils::CreateBufferFromData(device, &data, bufferSize, dawn::BufferUsageBit::Uniform); - return utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer, 0, bufferSize}}); + // 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::Color blendColor{triangle.blendFactor[0], triangle.blendFactor[1], + triangle.blendFactor[2], triangle.blendFactor[3]}; + + dawn::CommandEncoder encoder = device.CreateCommandEncoder(); + { + dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); + // First use the base pipeline to draw a triangle with no blending + pass.SetPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({{base}}))); + pass.Draw(3, 1, 0, 0); + + // Then use the test pipeline to draw the test triangle with blending + pass.SetPipeline(testPipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({{triangle.color}}))); + pass.SetBlendColor(&blendColor); + pass.Draw(3, 1, 0, 0); + pass.EndPass(); } - // 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::Color blendColor{triangle.blendFactor[0], triangle.blendFactor[1], triangle.blendFactor[2], triangle.blendFactor[3]}; + dawn::CommandBuffer commands = encoder.Finish(); + queue.Submit(1, &commands); - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - { - dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); - // First use the base pipeline to draw a triangle with no blending - pass.SetPipeline(basePipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { base } }))); - pass.Draw(3, 1, 0, 0); + EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2); + } - // Then use the test pipeline to draw the test triangle with blending - pass.SetPipeline(testPipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { triangle.color } }))); - pass.SetBlendColor(&blendColor); - pass.Draw(3, 1, 0, 0); - pass.EndPass(); - } + // Given a vector of tests where each element is , check that all + // expectations are true for the given blend operation + void CheckBlendOperation(RGBA8 base, + dawn::BlendOperation operation, + std::vector> tests) { + dawn::BlendDescriptor blend; + blend.operation = operation; + blend.srcFactor = dawn::BlendFactor::One; + blend.dstFactor = dawn::BlendFactor::One; - dawn::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); + dawn::ColorStateDescriptor descriptor; + descriptor.alphaBlend = blend; + descriptor.colorBlend = blend; + descriptor.colorWriteMask = dawn::ColorWriteMask::All; - EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2); + SetupSingleSourcePipelines(descriptor); + + for (const auto& test : tests) { + DoSingleSourceTest(base, {test.first}, test.second); } + } - // Given a vector of tests where each element is , check that all expectations are true for the given blend operation - void CheckBlendOperation(RGBA8 base, dawn::BlendOperation operation, std::vector> tests) { - dawn::BlendDescriptor blend; - blend.operation = operation; - blend.srcFactor = dawn::BlendFactor::One; - blend.dstFactor = dawn::BlendFactor::One; + // Given a vector of tests where each element is , 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> tests) { + dawn::BlendDescriptor colorBlend; + colorBlend.operation = dawn::BlendOperation::Add; + colorBlend.srcFactor = colorSrcFactor; + colorBlend.dstFactor = colorDstFactor; - dawn::ColorStateDescriptor descriptor; - descriptor.alphaBlend = blend; - descriptor.colorBlend = blend; - descriptor.colorWriteMask = dawn::ColorWriteMask::All; + dawn::BlendDescriptor alphaBlend; + alphaBlend.operation = dawn::BlendOperation::Add; + alphaBlend.srcFactor = alphaSrcFactor; + alphaBlend.dstFactor = alphaDstFactor; - SetupSingleSourcePipelines(descriptor); + dawn::ColorStateDescriptor descriptor; + descriptor.colorBlend = colorBlend; + descriptor.alphaBlend = alphaBlend; + descriptor.colorWriteMask = dawn::ColorWriteMask::All; - for (const auto& test : tests) { - DoSingleSourceTest(base, { test.first }, test.second); - } + SetupSingleSourcePipelines(descriptor); + + for (const auto& test : tests) { + DoSingleSourceTest(base, test.first, test.second); } + } - // Given a vector of tests where each element is , 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> tests) { - dawn::BlendDescriptor colorBlend; - colorBlend.operation = dawn::BlendOperation::Add; - colorBlend.srcFactor = colorSrcFactor; - colorBlend.dstFactor = colorDstFactor; + void CheckSrcBlendFactor(RGBA8 base, + dawn::BlendFactor colorFactor, + dawn::BlendFactor alphaFactor, + std::vector> tests) { + CheckBlendFactor(base, colorFactor, dawn::BlendFactor::One, alphaFactor, + dawn::BlendFactor::One, tests); + } - dawn::BlendDescriptor alphaBlend; - alphaBlend.operation = dawn::BlendOperation::Add; - alphaBlend.srcFactor = alphaSrcFactor; - alphaBlend.dstFactor = alphaDstFactor; + void CheckDstBlendFactor(RGBA8 base, + dawn::BlendFactor colorFactor, + dawn::BlendFactor alphaFactor, + std::vector> tests) { + CheckBlendFactor(base, dawn::BlendFactor::One, colorFactor, dawn::BlendFactor::One, + alphaFactor, tests); + } - dawn::ColorStateDescriptor descriptor; - descriptor.colorBlend = colorBlend; - descriptor.alphaBlend = alphaBlend; - descriptor.colorWriteMask = dawn::ColorWriteMask::All; - - SetupSingleSourcePipelines(descriptor); - - for (const auto& test : tests) { - DoSingleSourceTest(base, test.first, test.second); - } - } - - void CheckSrcBlendFactor(RGBA8 base, dawn::BlendFactor colorFactor, dawn::BlendFactor alphaFactor, std::vector> tests) { - CheckBlendFactor(base, colorFactor, dawn::BlendFactor::One, alphaFactor, dawn::BlendFactor::One, tests); - } - - void CheckDstBlendFactor(RGBA8 base, dawn::BlendFactor colorFactor, dawn::BlendFactor alphaFactor, std::vector> 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; + utils::BasicRenderPass renderPass; + dawn::RenderPipeline basePipeline; + dawn::RenderPipeline testPipeline; + dawn::ShaderModule vsModule; + dawn::BindGroupLayout bindGroupLayout; + dawn::PipelineLayout pipelineLayout; }; namespace { @@ -199,7 +221,8 @@ namespace { b = (b > 255 ? 255 : (b < 0 ? 0 : b)); a = (a > 255 ? 255 : (a < 0 ? 0 : a)); - return RGBA8(static_cast(r), static_cast(g), static_cast(b), static_cast(a)); + return RGBA8(static_cast(r), static_cast(g), static_cast(b), + static_cast(a)); } // Subtract two colors and clamp @@ -213,27 +236,20 @@ namespace { b = (b > 255 ? 255 : (b < 0 ? 0 : b)); a = (a > 255 ? 255 : (a < 0 ? 0 : a)); - return RGBA8(static_cast(r), static_cast(g), static_cast(b), static_cast(a)); + return RGBA8(static_cast(r), static_cast(g), static_cast(b), + static_cast(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) - ); + 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) - ); + 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] @@ -243,37 +259,38 @@ namespace { float b = static_cast(col1.b) * (1.f - fac[2]) + static_cast(col2.b) * fac[2]; float a = static_cast(col1.a) * (1.f - fac[3]) + static_cast(col2.a) * fac[3]; - return RGBA8({ static_cast(std::round(r)), static_cast(std::round(g)), static_cast(std::round(b)), static_cast(std::round(a)) }); + return RGBA8({static_cast(std::round(r)), static_cast(std::round(g)), + static_cast(std::round(b)), static_cast(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 f = { { + std::array f = {{ static_cast(fac.r) / 255.f, static_cast(fac.g) / 255.f, static_cast(fac.b) / 255.f, static_cast(fac.a) / 255.f, - } }; + }}; return mix(col1, col2, f); } - constexpr std::array kColors = { { + constexpr std::array 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), + 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), - } }; -} + RGBA8(0, 0, 0, 0), + RGBA8(255, 255, 255, 255), + }}; +} // namespace // Test compilation and usage of the fixture -TEST_P(BlendStateTest, Basic) { +TEST_P(ColorStateTest, Basic) { dawn::BlendDescriptor blend; blend.operation = dawn::BlendOperation::Add; blend.srcFactor = dawn::BlendFactor::One; @@ -285,349 +302,374 @@ TEST_P(BlendStateTest, Basic) { SetupSingleSourcePipelines(descriptor); - DoSingleSourceTest(RGBA8(0, 0, 0, 0), { RGBA8(255, 0, 0, 0) }, RGBA8(255, 0, 0, 0)); + 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) { +TEST_P(ColorStateTest, BlendOperationAdd) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(color, base + color); - }); + 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) { +TEST_P(ColorStateTest, BlendOperationSubtract) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(color, color - base); - }); + 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) { +TEST_P(ColorStateTest, BlendOperationReverseSubtract) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(color, base - color); - }); + 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) { +TEST_P(ColorStateTest, BlendOperationMin) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(color, min(base, color)); - }); + 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) { +TEST_P(ColorStateTest, BlendOperationMax) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(color, max(base, color)); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorZero) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(TriangleSpec({ { color } }), base); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorOne) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(TriangleSpec({ { color } }), base + color); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorSrcColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorOneMinusSrcColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorSrcAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorOneMinusSrcAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorDstColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorOneMinusDstColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorDstAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorOneMinusDstAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorSrcAlphaSaturated) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - uint8_t f = std::min(color.a, static_cast(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); + std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), + [&](const RGBA8& color) { + uint8_t f = std::min(color.a, static_cast(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) { +TEST_P(ColorStateTest, SrcBlendFactorBlendColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, SrcBlendFactorOneMinusBlendColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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 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); + 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 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) { +TEST_P(ColorStateTest, DstBlendFactorZero) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(TriangleSpec({ { color } }), color); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorOne) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - return std::make_pair(TriangleSpec({ { color } }), base + color); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorSrcColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorOneMinusSrcColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorSrcAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorOneMinusSrcAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); + 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) { +TEST_P(ColorStateTest, DstBlendFactorDstColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorOneMinusDstColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorDstAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorOneMinusDstAlpha) { RGBA8 base(32, 64, 128, 192); std::vector> 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); + 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) { +TEST_P(ColorStateTest, DstBlendFactorSrcAlphaSaturated) { RGBA8 base(32, 64, 128, 192); std::vector> tests; - std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), [&](const RGBA8& color) { - uint8_t f = std::min(color.a, static_cast(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); + std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests), + [&](const RGBA8& color) { + uint8_t f = std::min(color.a, static_cast(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) { +TEST_P(ColorStateTest, DstBlendFactorBlendColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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); - }); + 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) { +TEST_P(ColorStateTest, DstBlendFactorOneMinusBlendColor) { RGBA8 base(32, 64, 128, 192); std::vector> 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 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); + 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 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_P(ColorStateTest, ColorWriteMask) { dawn::BlendDescriptor blend; blend.operation = dawn::BlendOperation::Add; blend.srcFactor = dawn::BlendFactor::One; @@ -644,7 +686,7 @@ TEST_P(BlendStateTest, ColorWriteMask) { RGBA8 base(32, 64, 128, 192); for (auto& color : kColors) { RGBA8 expected = base + RGBA8(color.r, 0, 0, 0); - DoSingleSourceTest(base, { color }, expected); + DoSingleSourceTest(base, {color}, expected); } } @@ -656,7 +698,7 @@ TEST_P(BlendStateTest, ColorWriteMask) { RGBA8 base(32, 64, 128, 192); for (auto& color : kColors) { RGBA8 expected = base + RGBA8(0, color.g, 0, color.a); - DoSingleSourceTest(base, { color }, expected); + DoSingleSourceTest(base, {color}, expected); } } @@ -667,13 +709,13 @@ TEST_P(BlendStateTest, ColorWriteMask) { RGBA8 base(32, 64, 128, 192); for (auto& color : kColors) { - DoSingleSourceTest(base, { color }, base); + DoSingleSourceTest(base, {color}, base); } } } // Check that the color write mask works when blending is disabled -TEST_P(BlendStateTest, ColorWriteMaskBlendingDisabled) { +TEST_P(ColorStateTest, ColorWriteMaskBlendingDisabled) { { dawn::BlendDescriptor blend; blend.operation = dawn::BlendOperation::Add; @@ -693,7 +735,7 @@ TEST_P(BlendStateTest, ColorWriteMaskBlendingDisabled) { { dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); pass.SetPipeline(testPipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { base } }))); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({{base}}))); pass.Draw(3, 1, 0, 0); pass.EndPass(); } @@ -704,8 +746,8 @@ TEST_P(BlendStateTest, ColorWriteMaskBlendingDisabled) { } } -// Test that independent blend states on render targets works -TEST_P(BlendStateTest, IndependentBlendState) { +// Test that independent color states on render targets works +TEST_P(ColorStateTest, IndependentColorState) { DAWN_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsIntel()); std::array renderTargets; @@ -731,14 +773,14 @@ TEST_P(BlendStateTest, IndependentBlendState) { for (uint32_t i = 0; i < 4; ++i) { colorAttachments[i].attachment = renderTargetViews[i]; colorAttachments[i].resolveTarget = nullptr; - colorAttachments[i].clearColor = { 0.0f, 0.0f, 0.0f, 0.0f }; + colorAttachments[i].clearColor = {0.0f, 0.0f, 0.0f, 0.0f}; colorAttachments[i].loadOp = dawn::LoadOp::Clear; colorAttachments[i].storeOp = dawn::StoreOp::Store; } dawn::RenderPassDescriptor renderpass = device.CreateRenderPassDescriptorBuilder() - .SetColorAttachments(4, colorAttachments) - .GetResult(); + .SetColorAttachments(4, colorAttachments) + .GetResult(); dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( #version 450 @@ -776,7 +818,7 @@ TEST_P(BlendStateTest, IndependentBlendState) { testDescriptor.cFragmentStage.module = fsModule; testDescriptor.numColorStates = 4; - // set blend states + // set color states dawn::BlendDescriptor blend1; blend1.operation = dawn::BlendOperation::Add; blend1.srcFactor = dawn::BlendFactor::One; @@ -819,11 +861,13 @@ TEST_P(BlendStateTest, IndependentBlendState) { { dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderpass); pass.SetPipeline(basePipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { base, base, base, base } }))); + pass.SetBindGroup( + 0, MakeBindGroupForColors(std::array({{base, base, base, base}}))); pass.Draw(3, 1, 0, 0); pass.SetPipeline(testPipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { color0, color1, color2, color3 } }))); + pass.SetBindGroup(0, MakeBindGroupForColors( + std::array({{color0, color1, color2, color3}}))); pass.Draw(3, 1, 0, 0); pass.EndPass(); } @@ -831,15 +875,23 @@ TEST_P(BlendStateTest, IndependentBlendState) { dawn::CommandBuffer commands = encoder.Finish(); 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; + 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) { +TEST_P(ColorStateTest, DefaultBlendColor) { dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( #version 450 layout(set = 0, binding = 0) uniform myBlock { @@ -883,10 +935,12 @@ TEST_P(BlendStateTest, DefaultBlendColor) { { dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); pass.SetPipeline(basePipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.SetBindGroup(0, + MakeBindGroupForColors(std::array({{RGBA8(0, 0, 0, 0)}}))); pass.Draw(3, 1, 0, 0); pass.SetPipeline(testPipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.SetBindGroup( + 0, MakeBindGroupForColors(std::array({{RGBA8(255, 255, 255, 255)}}))); pass.Draw(3, 1, 0, 0); pass.EndPass(); } @@ -903,11 +957,13 @@ TEST_P(BlendStateTest, DefaultBlendColor) { { dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); pass.SetPipeline(basePipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.SetBindGroup(0, + MakeBindGroupForColors(std::array({{RGBA8(0, 0, 0, 0)}}))); pass.Draw(3, 1, 0, 0); pass.SetPipeline(testPipeline); pass.SetBlendColor(&kWhite); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.SetBindGroup( + 0, MakeBindGroupForColors(std::array({{RGBA8(255, 255, 255, 255)}}))); pass.Draw(3, 1, 0, 0); pass.EndPass(); } @@ -915,7 +971,8 @@ TEST_P(BlendStateTest, DefaultBlendColor) { dawn::CommandBuffer commands = encoder.Finish(); queue.Submit(1, &commands); - EXPECT_PIXEL_RGBA8_EQ(RGBA8(255, 255, 255, 255), renderPass.color, kRTSize / 2, kRTSize / 2); + 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 @@ -924,21 +981,25 @@ TEST_P(BlendStateTest, DefaultBlendColor) { { dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); pass.SetPipeline(basePipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.SetBindGroup(0, + MakeBindGroupForColors(std::array({{RGBA8(0, 0, 0, 0)}}))); pass.Draw(3, 1, 0, 0); pass.SetPipeline(testPipeline); pass.SetBlendColor(&kWhite); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.SetBindGroup( + 0, MakeBindGroupForColors(std::array({{RGBA8(255, 255, 255, 255)}}))); pass.Draw(3, 1, 0, 0); pass.EndPass(); } { dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo); pass.SetPipeline(basePipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.SetBindGroup(0, + MakeBindGroupForColors(std::array({{RGBA8(0, 0, 0, 0)}}))); pass.Draw(3, 1, 0, 0); pass.SetPipeline(testPipeline); - pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.SetBindGroup( + 0, MakeBindGroupForColors(std::array({{RGBA8(255, 255, 255, 255)}}))); pass.Draw(3, 1, 0, 0); pass.EndPass(); } @@ -950,4 +1011,4 @@ TEST_P(BlendStateTest, DefaultBlendColor) { } } -DAWN_INSTANTIATE_TEST(BlendStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend) +DAWN_INSTANTIATE_TEST(ColorStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend) diff --git a/src/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/tests/unittests/validation/RenderPipelineValidationTests.cpp index 550b014026..da666983c6 100644 --- a/src/tests/unittests/validation/RenderPipelineValidationTests.cpp +++ b/src/tests/unittests/validation/RenderPipelineValidationTests.cpp @@ -51,8 +51,7 @@ TEST_F(RenderPipelineValidationTest, CreationSuccess) { device.CreateRenderPipeline(&descriptor); } -TEST_F(RenderPipelineValidationTest, BlendState) { - +TEST_F(RenderPipelineValidationTest, ColorState) { { // This one succeeds because attachment 0 is the color attachment utils::ComboRenderPipelineDescriptor descriptor(device); @@ -72,4 +71,3 @@ TEST_F(RenderPipelineValidationTest, BlendState) { ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor)); } } -