blob: 112b027f812d99eb4c279eb1a549ad19462aabb1 [file] [log] [blame] [edit]
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
constexpr int kPixelColorThreshhold = 8;
class AdvancedBlendTest : public ANGLETest<>
{
protected:
AdvancedBlendTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
};
// Test that when blending is disabled, advanced blend is not applied.
// Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest, advancedBlendNotAppliedWhenBlendIsDisabled)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
const char *vertSrc = R"(#version 320 es
in highp vec4 a_position;
in mediump vec4 a_color;
out mediump vec4 v_color;
void main()
{
gl_Position = a_position;
v_color = a_color;
}
)";
const char *fragSrc = R"(#version 320 es
in mediump vec4 v_color;
layout(blend_support_colorburn) out;
layout(location = 0) out mediump vec4 o_color;
void main()
{
o_color = v_color;
}
)";
ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
glUseProgram(program);
std::array<GLfloat, 16> attribPosData = {1, 1, 0.5, 1, -1, 1, 0.5, 1,
1, -1, 0.5, 1, -1, -1, 0.5, 1};
GLint attribPosLoc = glGetAttribLocation(1, "a_position");
ASSERT(attribPosLoc >= 0);
glEnableVertexAttribArray(attribPosLoc);
glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
GLint attribColorLoc = glGetAttribLocation(1, "a_color");
ASSERT(attribColorLoc >= 0);
glEnableVertexAttribArray(attribColorLoc);
glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
glBlendEquation(GL_COLORBURN);
const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Disable the blend. The next glDrawElements() should not blend the a_color with clear color
glDisable(GL_BLEND);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 51, 128, 255), kPixelColorThreshhold);
}
// Test that when blending is disabled, advanced blend is not applied, but is applied after
// it is enabled.
// Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest, advancedBlendDisabledAndThenEnabled)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
const char *vertSrc = R"(#version 320 es
in highp vec4 a_position;
in mediump vec4 a_color;
out mediump vec4 v_color;
void main()
{
gl_Position = a_position;
v_color = a_color;
}
)";
const char *fragSrc = R"(#version 320 es
in mediump vec4 v_color;
layout(blend_support_colorburn) out;
layout(location = 0) out mediump vec4 o_color;
void main()
{
o_color = v_color;
}
)";
ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
glUseProgram(program);
std::array<GLfloat, 16> attribPosData = {1, 1, 0.5, 1, -1, 1, 0.5, 1,
1, -1, 0.5, 1, -1, -1, 0.5, 1};
GLint attribPosLoc = glGetAttribLocation(1, "a_position");
ASSERT(attribPosLoc >= 0);
glEnableVertexAttribArray(attribPosLoc);
glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
GLint attribColorLoc = glGetAttribLocation(1, "a_color");
ASSERT(attribColorLoc >= 0);
glEnableVertexAttribArray(attribColorLoc);
glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
glBlendEquation(GL_COLORBURN);
const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Disable the blend. The next glDrawElements() should not blend the a_color with clear color
glDisable(GL_BLEND);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
// Enable the blend. The next glDrawElements() should blend a_color
// with the the existing framebuffer output with GL_COLORBURN blend mode
glEnable(GL_BLEND);
// Test the blend with coherent blend disabled. This make the test cover both devices that
// support / do not support GL_KHR_blend_equation_advanced_coherent
if (IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"))
{
glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
}
glBlendBarrier();
std::array<GLfloat, 16> attribColorData2 = {0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1,
0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1};
glEnableVertexAttribArray(attribColorLoc);
glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData2.data());
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 0, 0, 255), kPixelColorThreshhold);
}
// Test that when blending is enabled, advanced blend is applied, but is not applied after
// it is disabled.
// Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest, advancedBlendEnabledAndThenDisabled)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
const char *vertSrc = R"(#version 320 es
in highp vec4 a_position;
in mediump vec4 a_color;
out mediump vec4 v_color;
void main()
{
gl_Position = a_position;
v_color = a_color;
}
)";
const char *fragSrc = R"(#version 320 es
in mediump vec4 v_color;
layout(blend_support_colorburn) out;
layout(location = 0) out mediump vec4 o_color;
void main()
{
o_color = v_color;
}
)";
ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
glUseProgram(program);
std::array<GLfloat, 16> attribPosData = {1, 1, 0.5, 1, -1, 1, 0.5, 1,
1, -1, 0.5, 1, -1, -1, 0.5, 1};
GLint attribPosLoc = glGetAttribLocation(1, "a_position");
ASSERT(attribPosLoc >= 0);
glEnableVertexAttribArray(attribPosLoc);
glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
GLint attribColorLoc = glGetAttribLocation(1, "a_color");
ASSERT(attribColorLoc >= 0);
glEnableVertexAttribArray(attribColorLoc);
glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
glBlendEquation(GL_COLORBURN);
const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Enable the blend. The next glDrawElements() should blend the a_color with clear color
// using the GL_COLORBURN blend mode
glEnable(GL_BLEND);
// Test the blend with coherent blend disabled. This make the test cover both devices that
// support / do not support GL_KHR_blend_equation_advanced_coherent
if (IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"))
{
glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
}
glBlendBarrier();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
// Disable the blend. The next glDrawElements() should not blend the a_color with
// the existing framebuffer output with GL_COLORBURN blend mode
glDisable(GL_BLEND);
std::array<GLfloat, 16> attribColorData2 = {0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1,
0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1};
glEnableVertexAttribArray(attribColorLoc);
glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData2.data());
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(128, 128, 0, 255), kPixelColorThreshhold);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AdvancedBlendTest);
ANGLE_INSTANTIATE_TEST_ES32(AdvancedBlendTest);