1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9
10 using namespace angle;
11
12 class BlendIntegerTest : public ANGLETest
13 {
14 protected:
BlendIntegerTest()15 BlendIntegerTest()
16 {
17 setWindowWidth(128);
18 setWindowHeight(128);
19 setConfigRedBits(8);
20 setConfigGreenBits(8);
21 setConfigBlueBits(8);
22 setConfigAlphaBits(8);
23 }
24
25 template <typename T, GLuint components>
compareValue(const T * value,const char * name,GLenum attachment)26 void compareValue(const T *value, const char *name, GLenum attachment)
27 {
28 T pixel[4];
29 glReadBuffer(attachment);
30 glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER,
31 std::is_same<T, int32_t>::value ? GL_INT : GL_UNSIGNED_INT, pixel);
32 for (size_t componentIdx = 0; componentIdx < components; componentIdx++)
33 {
34 EXPECT_EQ(value[componentIdx], pixel[componentIdx])
35 << " componentIdx=" << componentIdx << std::endl
36 << " " << name << "[0]=" << value[0] << " pixel[0]=" << pixel[0] << std::endl
37 << " " << name << "[1]=" << value[1] << " pixel[1]=" << pixel[1] << std::endl
38 << " " << name << "[2]=" << value[2] << " pixel[2]=" << pixel[2] << std::endl
39 << " " << name << "[3]=" << value[3] << " pixel[3]=" << pixel[3];
40 }
41 }
42
43 template <GLenum internalformat, GLuint components, bool isSigned>
runTest()44 void runTest()
45 {
46 constexpr char kFsui[] =
47 "#version 300 es\n"
48 "out highp uvec4 o_drawBuffer0;\n"
49 "void main(void)\n"
50 "{\n"
51 " o_drawBuffer0 = uvec4(1, 1, 1, 1);\n"
52 "}\n";
53
54 constexpr char kFssi[] =
55 "#version 300 es\n"
56 "out highp ivec4 o_drawBuffer0;\n"
57 "void main(void)\n"
58 "{\n"
59 " o_drawBuffer0 = ivec4(-1, -1, -1, -1);\n"
60 "}\n";
61
62 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), isSigned ? kFssi : kFsui);
63 glUseProgram(program);
64
65 GLFramebuffer framebuffer;
66 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
67
68 GLRenderbuffer colorRenderbuffer;
69 glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
70 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, getWindowWidth(), getWindowHeight());
71 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
72 colorRenderbuffer);
73
74 if (isSigned)
75 {
76 const int32_t clearValueSigned[4] = {-128, -128, -128, -128};
77 glClearBufferiv(GL_COLOR, 0, clearValueSigned);
78 ASSERT_GL_NO_ERROR();
79 compareValue<int32_t, components>(clearValueSigned, "clearValueSigned",
80 GL_COLOR_ATTACHMENT0);
81 }
82 else
83 {
84 const uint32_t clearValueUnsigned[4] = {127, 127, 127, 3};
85 glClearBufferuiv(GL_COLOR, 0, clearValueUnsigned);
86 ASSERT_GL_NO_ERROR();
87 compareValue<uint32_t, components>(clearValueUnsigned, "clearValueUnsigned",
88 GL_COLOR_ATTACHMENT0);
89 }
90
91 glEnable(GL_BLEND);
92 glBlendEquation(GL_FUNC_ADD);
93 glBlendFunc(GL_ONE, GL_ONE);
94
95 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
96
97 ASSERT_GL_NO_ERROR();
98
99 // Enabled blending must be ignored for integer color attachment.
100 if (isSigned)
101 {
102 const int32_t colorValueSigned[4] = {-1, -1, -1, -1};
103 compareValue<int32_t, components>(colorValueSigned, "colorValueSigned",
104 GL_COLOR_ATTACHMENT0);
105 }
106 else
107 {
108 const uint32_t colorValueUnsigned[4] = {1, 1, 1, 1};
109 compareValue<uint32_t, components>(colorValueUnsigned, "colorValueUnsigned",
110 GL_COLOR_ATTACHMENT0);
111 }
112 }
113
114 template <bool isSigned>
runTestMRT()115 void runTestMRT()
116 {
117 constexpr char kFragmentSigned[] = R"(#version 300 es
118 layout(location = 1) out highp vec4 o_drawBuffer1;
119 layout(location = 2) out highp ivec4 o_drawBuffer2;
120 layout(location = 3) out highp vec4 o_drawBuffer3;
121 void main(void)
122 {
123 o_drawBuffer1 = vec4(0, 0, 0, 0);
124 o_drawBuffer2 = ivec4(0, 0, 0, 0);
125 o_drawBuffer3 = vec4(0, 0, 0, 0);
126 })";
127
128 constexpr char kFragmentUnsigned[] = R"(#version 300 es
129 layout(location = 1) out highp vec4 o_drawBuffer1;
130 layout(location = 2) out highp uvec4 o_drawBuffer2;
131 layout(location = 3) out highp vec4 o_drawBuffer3;
132 void main(void)
133 {
134 o_drawBuffer1 = vec4(0, 0, 0, 0);
135 o_drawBuffer2 = uvec4(0, 0, 0, 0);
136 o_drawBuffer3 = vec4(0, 0, 0, 0);
137 })";
138
139 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(),
140 isSigned ? kFragmentSigned : kFragmentUnsigned);
141 glUseProgram(program);
142
143 GLFramebuffer framebuffer;
144 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
145
146 GLRenderbuffer colorRenderbuffer1;
147 glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer1);
148 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
149 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
150 colorRenderbuffer1);
151
152 GLRenderbuffer colorRenderbuffer2;
153 glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer2);
154 glRenderbufferStorage(GL_RENDERBUFFER, isSigned ? GL_RGBA32I : GL_RGBA32UI,
155 getWindowWidth(), getWindowHeight());
156 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER,
157 colorRenderbuffer2);
158
159 GLRenderbuffer colorRenderbuffer3;
160 glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer3);
161 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
162 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER,
163 colorRenderbuffer3);
164
165 GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2,
166 GL_COLOR_ATTACHMENT3};
167 glDrawBuffers(4, drawBuffers);
168
169 if (isSigned)
170 {
171 const int32_t clearValue[4] = {-1, 2, -3, 4};
172 glClearBufferiv(GL_COLOR, 2, clearValue);
173 ASSERT_GL_NO_ERROR();
174 compareValue<int32_t, 4>(clearValue, "clearValue", GL_COLOR_ATTACHMENT2);
175 }
176 else
177 {
178 const uint32_t clearValue[4] = {1, 2, 3, 4};
179 glClearBufferuiv(GL_COLOR, 2, clearValue);
180 ASSERT_GL_NO_ERROR();
181 compareValue<uint32_t, 4>(clearValue, "clearValue", GL_COLOR_ATTACHMENT2);
182 }
183
184 glBlendEquation(GL_MAX);
185 glEnable(GL_BLEND);
186
187 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
188 ASSERT_GL_NO_ERROR();
189
190 if (isSigned)
191 {
192 const int32_t drawValue[4] = {0, 0, 0, 0};
193 compareValue<int32_t, 4>(drawValue, "drawValue", GL_COLOR_ATTACHMENT2);
194 }
195 else
196 {
197 const uint32_t drawValue[4] = {0, 0, 0, 0};
198 compareValue<uint32_t, 4>(drawValue, "drawValue", GL_COLOR_ATTACHMENT2);
199 }
200 }
201 };
202
203 // Test that blending is not applied to signed integer attachments.
TEST_P(BlendIntegerTest,R8I)204 TEST_P(BlendIntegerTest, R8I)
205 {
206 runTest<GL_R8I, 1, true>();
207 }
208
TEST_P(BlendIntegerTest,R16I)209 TEST_P(BlendIntegerTest, R16I)
210 {
211 runTest<GL_R16I, 1, true>();
212 }
213
TEST_P(BlendIntegerTest,R32I)214 TEST_P(BlendIntegerTest, R32I)
215 {
216 runTest<GL_R32I, 1, true>();
217 }
218
TEST_P(BlendIntegerTest,RG8I)219 TEST_P(BlendIntegerTest, RG8I)
220 {
221 runTest<GL_RG8I, 2, true>();
222 }
223
TEST_P(BlendIntegerTest,RG16I)224 TEST_P(BlendIntegerTest, RG16I)
225 {
226 runTest<GL_RG16I, 2, true>();
227 }
228
TEST_P(BlendIntegerTest,RG32I)229 TEST_P(BlendIntegerTest, RG32I)
230 {
231 runTest<GL_RG32I, 2, true>();
232 }
233
TEST_P(BlendIntegerTest,RGBA8I)234 TEST_P(BlendIntegerTest, RGBA8I)
235 {
236 runTest<GL_RGBA8I, 4, true>();
237 }
238
TEST_P(BlendIntegerTest,RGBA16I)239 TEST_P(BlendIntegerTest, RGBA16I)
240 {
241 runTest<GL_RGBA16I, 4, true>();
242 }
243
TEST_P(BlendIntegerTest,RGBA32I)244 TEST_P(BlendIntegerTest, RGBA32I)
245 {
246 runTest<GL_RGBA32I, 4, true>();
247 }
248
249 // Test that blending is not applied to unsigned integer attachments.
TEST_P(BlendIntegerTest,R8UI)250 TEST_P(BlendIntegerTest, R8UI)
251 {
252 runTest<GL_R8UI, 1, false>();
253 }
254
TEST_P(BlendIntegerTest,R16UI)255 TEST_P(BlendIntegerTest, R16UI)
256 {
257 runTest<GL_R16UI, 1, false>();
258 }
259
TEST_P(BlendIntegerTest,R32UI)260 TEST_P(BlendIntegerTest, R32UI)
261 {
262 runTest<GL_R32UI, 1, false>();
263 }
264
TEST_P(BlendIntegerTest,RG8UI)265 TEST_P(BlendIntegerTest, RG8UI)
266 {
267 runTest<GL_RG8UI, 2, false>();
268 }
269
TEST_P(BlendIntegerTest,RG16UI)270 TEST_P(BlendIntegerTest, RG16UI)
271 {
272 runTest<GL_RG16UI, 2, false>();
273 }
274
TEST_P(BlendIntegerTest,RG32UI)275 TEST_P(BlendIntegerTest, RG32UI)
276 {
277 runTest<GL_RG32UI, 2, false>();
278 }
279
TEST_P(BlendIntegerTest,RGBA8UI)280 TEST_P(BlendIntegerTest, RGBA8UI)
281 {
282 runTest<GL_RGBA8UI, 4, false>();
283 }
284
TEST_P(BlendIntegerTest,RGBA16UI)285 TEST_P(BlendIntegerTest, RGBA16UI)
286 {
287 runTest<GL_RGBA16UI, 4, false>();
288 }
289
TEST_P(BlendIntegerTest,RGBA32UI)290 TEST_P(BlendIntegerTest, RGBA32UI)
291 {
292 runTest<GL_RGBA32UI, 4, false>();
293 }
294
TEST_P(BlendIntegerTest,RGB10_A2UI)295 TEST_P(BlendIntegerTest, RGB10_A2UI)
296 {
297 runTest<GL_RGB10_A2UI, 4, false>();
298 }
299
300 // Test that blending does not cancel draws on signed integer attachments.
TEST_P(BlendIntegerTest,MRTSigned)301 TEST_P(BlendIntegerTest, MRTSigned)
302 {
303 // http://anglebug.com/5071
304 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsIntel());
305
306 // http://anglebug.com/5125
307 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX() && IsIntel());
308
309 // http://anglebug.com/5126
310 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAdreno());
311
312 runTestMRT<true>();
313 }
314
315 // Test that blending does not cancel draws on unsigned integer attachments.
TEST_P(BlendIntegerTest,MRTUnsigned)316 TEST_P(BlendIntegerTest, MRTUnsigned)
317 {
318 // http://anglebug.com/5071
319 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsIntel());
320
321 // http://anglebug.com/5125
322 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX() && IsIntel());
323
324 // http://anglebug.com/5126
325 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAdreno());
326
327 runTestMRT<false>();
328 }
329
330 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
331 // tests should be run against.
332 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlendIntegerTest);
333 ANGLE_INSTANTIATE_TEST_ES3(BlendIntegerTest);
334