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