1 #include "test_utils/ANGLETest.h"
2 #include "test_utils/gl_raii.h"
3
4 using namespace angle;
5
6 namespace
7 {
8
9 const int GRID_SIZE = 3;
10
11 class ShaderAlgorithmTest : public ANGLETest<>
12 {
13 protected:
ShaderAlgorithmTest()14 ShaderAlgorithmTest()
15 {
16 setWindowWidth(64);
17 setWindowHeight(64);
18 setConfigRedBits(8);
19 setConfigGreenBits(8);
20 setConfigBlueBits(8);
21 setConfigAlphaBits(8);
22 }
23
~ShaderAlgorithmTest()24 ~ShaderAlgorithmTest() {}
25 };
26
27 // Simplied version of dEQP test dEQP?GLES2.functional.shaders.algorithm.rgb_to_hsl_vertex
TEST_P(ShaderAlgorithmTest,rgb_to_hsl_vertex_shader)28 TEST_P(ShaderAlgorithmTest, rgb_to_hsl_vertex_shader)
29 {
30 const char kVS[] =
31 "attribute highp vec3 a_position;\n"
32 "attribute highp vec3 a_unitCoords;\n"
33 "varying mediump vec3 v_color;\n"
34
35 "void main()\n"
36 "{\n"
37 " gl_Position =vec4(a_position.x, a_position.y, a_position.z, 1.0);\n"
38 " mediump vec3 coords = a_unitCoords;\n"
39 " mediump vec3 res = vec3(0.0);\n"
40 " mediump float r = coords.x, g = coords.y, b = coords.z;\n"
41 " mediump float minVal = min(min(r, g), b);\n"
42 " mediump float maxVal = max(max(r, g), b);\n"
43 " mediump float H = 0.0; \n"
44 " mediump float S = 0.0; \n"
45 " if (r == maxVal)\n"
46 " H = 1.0;\n"
47 " else\n"
48 " S = 1.0;\n"
49 " res = vec3(H, S, 0);\n"
50 " v_color = res;\n"
51 "}\n";
52
53 const char kFS[] =
54 "varying mediump vec3 v_color;\n"
55 "void main()\n"
56 "{\n"
57 " gl_FragColor = vec4(v_color, 1.0);\n"
58 "}\n";
59
60 ANGLE_GL_PROGRAM(program, kVS, kFS);
61
62 // compute a_position vertex data
63 std::vector<Vector3> positions{Vector3(-1.0f, -1.0f, 0.0f), Vector3(-1.0f, 1.0f, 0.0f),
64 Vector3(1.0f, 1.0f, 0.0f), Vector3(1.0f, -1.0f, 0.0f)};
65
66 // Pass the vertex data to VBO
67 GLBuffer posBuffer;
68 glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
69 glBufferData(GL_ARRAY_BUFFER, sizeof(positions[0]) * positions.size(), positions.data(),
70 GL_STATIC_DRAW);
71
72 // Link position data to "a_position" vertex attrib
73 GLint posLocation = glGetAttribLocation(program, "a_position");
74 ASSERT_NE(-1, posLocation);
75 glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
76 glEnableVertexAttribArray(posLocation);
77
78 // Pass the index data to EBO
79 std::vector<GLuint> indices{0, 1, 2, 0, 2, 3};
80 GLBuffer indexBuffer;
81 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
82 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
83 GL_STATIC_DRAW);
84
85 // Initialize the "a_unitCoords" vertex attributes data
86 std::vector<Vector3> unitcoords;
87 unitcoords.resize(4);
88 GLBuffer unitCoordBuffer;
89 GLint unitCoordLocation = glGetAttribLocation(program, "a_unitCoords");
90 ASSERT_NE(-1, unitCoordLocation);
91
92 const float epsilon = 1.0e-7;
93 int gridSize = GRID_SIZE;
94
95 for (int y = 0; y < gridSize + 1; y++)
96 {
97 for (int x = 0; x < gridSize + 1; x++)
98 {
99 float sx = (float)x / (float)gridSize;
100 float sy = (float)y / (float)gridSize;
101
102 // Pass the a_unitCoords data to VBO
103 for (int vtx = 0; vtx < 4; vtx++)
104 {
105 unitcoords[vtx] = Vector3(sx, sy, 0.33f * sx + 0.5f * sy);
106 }
107 glBindBuffer(GL_ARRAY_BUFFER, unitCoordBuffer);
108 glBufferData(GL_ARRAY_BUFFER, sizeof(unitcoords[0]) * unitcoords.size(),
109 unitcoords.data(), GL_STATIC_DRAW);
110
111 // Link the unitcoords data to "a_unitCoords" vertex attrib
112 glVertexAttribPointer(unitCoordLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
113 glEnableVertexAttribArray(unitCoordLocation);
114
115 // Draw and verify
116 glUseProgram(program);
117 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
118
119 ASSERT_GL_NO_ERROR();
120
121 float maxVal = std::max({sx, sy, 0.33f * sx + 0.5f * sy});
122 if (abs(maxVal - sx) <= epsilon)
123 {
124 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
125 }
126 else
127 {
128 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
129 }
130 }
131 }
132 }
133
134 ANGLE_INSTANTIATE_TEST_ES2_AND(
135 ShaderAlgorithmTest,
136 ES2_VULKAN().enable(Feature::AvoidOpSelectWithMismatchingRelaxedPrecision));
137
138 } // namespace
139