Remove dual source blending

It is not supported on many mobile GPUS on Vulkan
http://vulkan.gpuinfo.org/listreports.php?feature=dualSrcBlend&option=not
and is optional on Metal
This commit is contained in:
Austin Eng 2017-08-03 16:24:49 -04:00 committed by Austin Eng
parent 6366a019db
commit cce6b01b6d
5 changed files with 1 additions and 218 deletions

View File

@ -120,11 +120,7 @@
{"value": 9, "name": "one minus dst alpha"}, {"value": 9, "name": "one minus dst alpha"},
{"value": 10, "name": "src alpha saturated"}, {"value": 10, "name": "src alpha saturated"},
{"value": 11, "name": "blend color"}, {"value": 11, "name": "blend color"},
{"value": 12, "name": "one minus blend color"}, {"value": 12, "name": "one minus blend color"}
{"value": 13, "name": "src1 color"},
{"value": 14, "name": "one minus src1 color"},
{"value": 15, "name": "src1 alpha"},
{"value": 16, "name": "one minus src1 alpha"}
] ]
}, },
"blend operation": { "blend operation": {

View File

@ -49,14 +49,6 @@ namespace d3d12 {
return D3D12_BLEND_BLEND_FACTOR; return D3D12_BLEND_BLEND_FACTOR;
case nxt::BlendFactor::OneMinusBlendColor: case nxt::BlendFactor::OneMinusBlendColor:
return D3D12_BLEND_INV_BLEND_FACTOR; return D3D12_BLEND_INV_BLEND_FACTOR;
case nxt::BlendFactor::Src1Color:
return D3D12_BLEND_SRC1_COLOR;
case nxt::BlendFactor::OneMinusSrc1Color:
return D3D12_BLEND_INV_SRC1_COLOR;
case nxt::BlendFactor::Src1Alpha:
return D3D12_BLEND_SRC1_ALPHA;
case nxt::BlendFactor::OneMinusSrc1Alpha:
return D3D12_BLEND_INV_SRC1_ALPHA;
default: default:
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -49,14 +49,6 @@ namespace metal {
return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor; return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor;
case nxt::BlendFactor::OneMinusBlendColor: case nxt::BlendFactor::OneMinusBlendColor:
return alpha ? MTLBlendFactorOneMinusBlendAlpha : MTLBlendFactorOneMinusBlendColor; return alpha ? MTLBlendFactorOneMinusBlendAlpha : MTLBlendFactorOneMinusBlendColor;
case nxt::BlendFactor::Src1Color:
return MTLBlendFactorSource1Color;
case nxt::BlendFactor::OneMinusSrc1Color:
return MTLBlendFactorOneMinusSource1Color;
case nxt::BlendFactor::Src1Alpha:
return MTLBlendFactorSource1Alpha;
case nxt::BlendFactor::OneMinusSrc1Alpha:
return MTLBlendFactorOneMinusSource1Alpha;
} }
} }

View File

@ -49,14 +49,6 @@ namespace opengl {
return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR; return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR;
case nxt::BlendFactor::OneMinusBlendColor: case nxt::BlendFactor::OneMinusBlendColor:
return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR; return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR;
case nxt::BlendFactor::Src1Color:
return GL_SRC1_COLOR;
case nxt::BlendFactor::OneMinusSrc1Color:
return GL_ONE_MINUS_SRC1_COLOR;
case nxt::BlendFactor::Src1Alpha:
return GL_SRC1_ALPHA;
case nxt::BlendFactor::OneMinusSrc1Alpha:
return GL_ONE_MINUS_SRC1_ALPHA;
default: default:
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -108,39 +108,6 @@ class BlendStateTest : public NXTTest {
.GetResult(); .GetResult();
} }
void SetupDualSourcePipelines(const nxt::BlendState &blendState) {
nxt::ShaderModule fsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
#version 450
layout(set = 0, binding = 0) uniform myBlock {
vec4 color0;
vec4 color1;
} myUbo;
layout(location = 0) out vec4 fragColor0;
layout(location = 1) out vec4 fragColor1;
void main() {
fragColor0 = myUbo.color0;
fragColor1 = myUbo.color1;
}
)");
basePipeline = device.CreateRenderPipelineBuilder()
.SetSubpass(renderpass, 0)
.SetLayout(pipelineLayout)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.GetResult();
testPipeline = device.CreateRenderPipelineBuilder()
.SetSubpass(renderpass, 0)
.SetLayout(pipelineLayout)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.SetColorAttachmentBlendState(0, blendState)
.GetResult();
}
// Create a bind group to set the colors as a uniform buffer // Create a bind group to set the colors as a uniform buffer
template <size_t N> template <size_t N>
nxt::BindGroup MakeBindGroupForColors(std::array<RGBA8, N> colors) { nxt::BindGroup MakeBindGroupForColors(std::array<RGBA8, N> colors) {
@ -194,30 +161,6 @@ class BlendStateTest : public NXTTest {
EXPECT_PIXEL_RGBA8_EQ(expected, renderTarget, kRTSize / 2, kRTSize / 2); EXPECT_PIXEL_RGBA8_EQ(expected, renderTarget, kRTSize / 2, kRTSize / 2);
} }
void DoDualSourceTest(RGBA8 base, const TriangleSpec& triangle, const RGBA8& color1, const RGBA8& expected) {
renderTarget.TransitionUsage(nxt::TextureUsageBit::OutputAttachment);
nxt::CommandBuffer commands = device.CreateCommandBufferBuilder()
.BeginRenderPass(renderpass, framebuffer)
.BeginRenderSubpass()
.SetRenderPipeline(basePipeline)
.SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 2>({ { base, base } })))
.DrawArrays(3, 1, 0, 0)
.SetRenderPipeline(testPipeline)
.SetBindGroup(0, MakeBindGroupForColors(std::array<RGBA8, 2>({ { triangle.color, color1 } })))
.SetBlendColor(triangle.blendFactor[0], triangle.blendFactor[1], triangle.blendFactor[2], triangle.blendFactor[3])
.DrawArrays(3, 1, 0, 0)
.EndRenderSubpass()
.EndRenderPass()
.GetResult();
queue.Submit(1, &commands);
EXPECT_PIXEL_RGBA8_EQ(expected, renderTarget, 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 // 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, nxt::BlendOperation operation, std::vector<std::pair<RGBA8, RGBA8>> tests) { void CheckBlendOperation(RGBA8 base, nxt::BlendOperation operation, std::vector<std::pair<RGBA8, RGBA8>> tests) {
nxt::BlendState blendState = device.CreateBlendStateBuilder() nxt::BlendState blendState = device.CreateBlendStateBuilder()
@ -552,72 +495,6 @@ TEST_P(BlendStateTest, SrcBlendFactorOneMinusBlendColor) {
CheckSrcBlendFactor(base, nxt::BlendFactor::OneMinusBlendColor, nxt::BlendFactor::OneMinusBlendColor, tests); CheckSrcBlendFactor(base, nxt::BlendFactor::OneMinusBlendColor, nxt::BlendFactor::OneMinusBlendColor, tests);
} }
TEST_P(BlendStateTest, SrcBlendFactorSrc1Color) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::Src1Color, nxt::BlendFactor::One)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, color1);
expected.a = color.a;
DoDualSourceTest(base, { color }, color1, expected);
}
}
TEST_P(BlendStateTest, SrcBlendFactorOneMinusSrc1Color) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::OneMinusSrc1Color, nxt::BlendFactor::One)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, RGBA8(255, 255, 255, 255) - color1);
expected.a = color.a;
DoDualSourceTest(base, { color }, color1, expected);
}
}
TEST_P(BlendStateTest, SrcBlendFactorSrc1Alpha) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::Src1Alpha, nxt::BlendFactor::One)
.SetAlphaBlend(nxt::BlendOperation::Add, nxt::BlendFactor::Src1Alpha, nxt::BlendFactor::One)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 fac(color1.a, color1.a, color1.a, color1.a);
RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
DoDualSourceTest(base, { color }, color1, expected);
}
}
TEST_P(BlendStateTest, SrcBlendFactorOneMinusSrc1Alpha) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::OneMinusSrc1Alpha, nxt::BlendFactor::One)
.SetAlphaBlend(nxt::BlendOperation::Add, nxt::BlendFactor::OneMinusSrc1Alpha, nxt::BlendFactor::One)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 fac = RGBA8(255, 255, 255, 255) - RGBA8(color1.a, color1.a, color1.a, color1.a);
RGBA8 expected = base + mix(RGBA8(0, 0, 0, 0), color, fac);
DoDualSourceTest(base, { color }, color1, expected);
}
}
// The following tests check that the Destination blend factor works // The following tests check that the Destination blend factor works
TEST_P(BlendStateTest, DstBlendFactorZero) { TEST_P(BlendStateTest, DstBlendFactorZero) {
RGBA8 base(32, 64, 128, 192); RGBA8 base(32, 64, 128, 192);
@ -764,72 +641,6 @@ TEST_P(BlendStateTest, DstBlendFactorOneMinusBlendColor) {
CheckDstBlendFactor(base, nxt::BlendFactor::OneMinusBlendColor, nxt::BlendFactor::OneMinusBlendColor, tests); CheckDstBlendFactor(base, nxt::BlendFactor::OneMinusBlendColor, nxt::BlendFactor::OneMinusBlendColor, tests);
} }
TEST_P(BlendStateTest, DstBlendFactorSrc1Color) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::One, nxt::BlendFactor::Src1Color)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, color1);
expected.a = color.a;
DoDualSourceTest(base, { color }, color1, expected);
}
}
TEST_P(BlendStateTest, DstBlendFactorOneMinusSrc1Color) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::One, nxt::BlendFactor::OneMinusSrc1Color)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, RGBA8(255, 255, 255, 255) - color1);
expected.a = color.a;
DoDualSourceTest(base, { color }, color1, expected);
}
}
TEST_P(BlendStateTest, DstBlendFactorSrc1Alpha) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::One, nxt::BlendFactor::Src1Alpha)
.SetAlphaBlend(nxt::BlendOperation::Add, nxt::BlendFactor::One, nxt::BlendFactor::Src1Alpha)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 fac(color1.a, color1.a, color1.a, color1.a);
RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
DoDualSourceTest(base, { color }, color1, expected);
}
}
TEST_P(BlendStateTest, DstBlendFactorOneMinusSrc1Alpha) {
nxt::BlendState blendState = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(nxt::BlendOperation::Add, nxt::BlendFactor::One, nxt::BlendFactor::OneMinusSrc1Alpha)
.SetAlphaBlend(nxt::BlendOperation::Add, nxt::BlendFactor::One, nxt::BlendFactor::OneMinusSrc1Alpha)
.GetResult();
SetupDualSourcePipelines(blendState);
RGBA8 base(0, 0, 0, 0);
for (auto& color : kColors) {
RGBA8 color1(64, 32, 192, 128);
RGBA8 fac = RGBA8(255, 255, 255, 255) - RGBA8(color1.a, color1.a, color1.a, color1.a);
RGBA8 expected = color + mix(RGBA8(0, 0, 0, 0), base, fac);
DoDualSourceTest(base, { color }, color1, expected);
}
}
// Check that the color write mask works // Check that the color write mask works
TEST_P(BlendStateTest, ColorWriteMask) { TEST_P(BlendStateTest, ColorWriteMask) {
{ {