xref: /aosp_15_r20/external/angle/src/tests/gl_tests/PixelLocalStorageTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2022 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 <sstream>
8 #include <string>
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11 
12 using namespace angle;
13 
14 #define ASSERT_GL_INTEGER(pname, expected) \
15     {                                      \
16         GLint value;                       \
17         glGetIntegerv(pname, &value);      \
18         ASSERT_EQ(value, GLint(expected)); \
19     }
20 
21 #define EXPECT_GL_INTEGER(pname, expected) \
22     {                                      \
23         GLint value;                       \
24         glGetIntegerv(pname, &value);      \
25         EXPECT_EQ(value, GLint(expected)); \
26     }
27 
28 #define EXPECT_PLS_INTEGER(plane, pname, expected)                                                 \
29     {                                                                                              \
30         GLint value = 0xbaadc0de;                                                                  \
31         glGetFramebufferPixelLocalStorageParameterivRobustANGLE(plane, pname, 1, nullptr, &value); \
32         EXPECT_EQ(value, GLint(expected));                                                         \
33         value = 0xbaadc0de;                                                                        \
34         glGetFramebufferPixelLocalStorageParameterivANGLE(plane, pname, &value);                   \
35         EXPECT_EQ(value, GLint(expected));                                                         \
36     }
37 
38 #define EXPECT_GL_SINGLE_ERROR(err)                \
39     EXPECT_GL_ERROR(err);                          \
40     while (GLenum nextError = glGetError())        \
41     {                                              \
42         EXPECT_EQ(nextError, GLenum(GL_NO_ERROR)); \
43     }
44 
45 #define EXPECT_GL_SINGLE_ERROR_MSG(msg)                         \
46     if (mHasDebugKHR)                                           \
47     {                                                           \
48         EXPECT_EQ(mErrorMessages.size(), size_t(1));            \
49         if (mErrorMessages.size() == 1)                         \
50         {                                                       \
51             EXPECT_EQ(std::string(msg), mErrorMessages.back()); \
52         }                                                       \
53         mErrorMessages.clear();                                 \
54     }
55 
56 #define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(plane, rgba)                             \
57     {                                                                                 \
58         std::array<GLfloat, 4> expected rgba;                                         \
59         std::array<GLfloat, 4> value;                                                 \
60         value.fill(std::numeric_limits<GLfloat>::quiet_NaN());                        \
61         glGetFramebufferPixelLocalStorageParameterfvANGLE(                            \
62             plane, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, value.data());             \
63         EXPECT_EQ(value, expected);                                                   \
64         value.fill(std::numeric_limits<GLfloat>::quiet_NaN());                        \
65         glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(                      \
66             plane, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, nullptr, value.data()); \
67         EXPECT_EQ(value, expected);                                                   \
68     }
69 
70 #define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(plane, rgba)                             \
71     {                                                                               \
72         std::array<GLint, 4> expected rgba;                                         \
73         std::array<GLint, 4> value;                                                 \
74         value.fill(0xbaadc0de);                                                     \
75         glGetFramebufferPixelLocalStorageParameterivANGLE(                          \
76             plane, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE, value.data());             \
77         EXPECT_EQ(value, expected);                                                 \
78         value.fill(0xbaadc0de);                                                     \
79         glGetFramebufferPixelLocalStorageParameterivRobustANGLE(                    \
80             plane, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE, 4, nullptr, value.data()); \
81         EXPECT_EQ(value, expected);                                                 \
82     }
83 
84 #define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(plane, rgba)                              \
85     {                                                                                         \
86         std::array<GLuint, 4> expected rgba;                                                  \
87         std::array<GLuint, 4> value;                                                          \
88         std::array<GLint, 4> valuei;                                                          \
89         valuei.fill(0xbaadc0de);                                                              \
90         glGetFramebufferPixelLocalStorageParameterivANGLE(                                    \
91             plane, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, valuei.data());             \
92         memcpy(value.data(), valuei.data(), sizeof(value));                                   \
93         EXPECT_EQ(value, expected);                                                           \
94         valuei.fill(0xbaadc0de);                                                              \
95         glGetFramebufferPixelLocalStorageParameterivRobustANGLE(                              \
96             plane, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, 4, nullptr, valuei.data()); \
97         memcpy(value.data(), valuei.data(), sizeof(value));                                   \
98         EXPECT_EQ(value, expected);                                                           \
99     }
100 
101 #define EXPECT_FRAMEBUFFER_PARAMETER_INT_MESA(target, pname, expectedValue) \
102     {                                                                       \
103         GLint value = 0xbaadc0de;                                           \
104         glGetFramebufferParameterivMESA(target, pname, &value);             \
105         EXPECT_EQ(value, static_cast<GLint>(expectedValue));                \
106     }
107 
108 #define EXPECT_FRAMEBUFFER_PARAMETER_INT(target, pname, expectedValue) \
109     {                                                                  \
110         GLint value = 0xbaadc0de;                                      \
111         glGetFramebufferParameteriv(target, pname, &value);            \
112         EXPECT_EQ(value, static_cast<GLint>(expectedValue));           \
113     }
114 
115 #define EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(framebuffer, attachment, value)                    \
116     {                                                                                         \
117         GLint attachmentName = 0xbaadc0de;                                                    \
118         glGetFramebufferAttachmentParameteriv(                                                \
119             framebuffer, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attachmentName); \
120         EXPECT_EQ(attachmentName, static_cast<GLint>(value));                                 \
121     }
122 
123 #define EXPECT_GL_COLOR_MASK(r, g, b, a)                         \
124     {                                                            \
125         std::array<GLboolean, 4> mask;                           \
126         glGetBooleanv(GL_COLOR_WRITEMASK, mask.data());          \
127         EXPECT_EQ(mask, (std::array<GLboolean, 4>{r, g, b, a})); \
128     }
129 
130 // glGetBooleani_v is not in ES3.
131 #define EXPECT_GL_COLOR_MASK_INDEXED(index, r, g, b, a)          \
132     {                                                            \
133         std::array<GLint, 4> mask;                               \
134         glGetIntegeri_v(GL_COLOR_WRITEMASK, index, mask.data()); \
135         EXPECT_EQ(mask, (std::array<GLint, 4>{r, g, b, a}));     \
136     }
137 
138 constexpr static int W = 128, H = 128;
139 constexpr static std::array<float, 4> FULLSCREEN = {0, 0, W, H};
140 
141 // For building the <loadops> parameter of glBeginPixelLocalStorageANGLE.
142 template <typename T>
143 struct Array
144 {
ArrayArray145     Array(const std::initializer_list<T> &list) : mVec(list) {}
operator const T*Array146     operator const T *() const { return mVec.data(); }
147     std::vector<T> mVec;
148 };
149 
150 template <typename T>
MakeArray(const std::initializer_list<T> & list)151 static Array<T> MakeArray(const std::initializer_list<T> &list)
152 {
153     return Array<T>(list);
154 }
155 
GLenumArray(const std::initializer_list<GLenum> & list)156 static Array<GLenum> GLenumArray(const std::initializer_list<GLenum> &list)
157 {
158     return Array<GLenum>(list);
159 }
160 
ClearF(GLfloat r,GLfloat g,GLfloat b,GLfloat a)161 static Array<GLfloat> ClearF(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
162 {
163     return MakeArray({r, g, b, a});
164 }
165 
ClearI(GLint r,GLint g,GLint b,GLint a)166 static Array<GLint> ClearI(GLint r, GLint g, GLint b, GLint a)
167 {
168     return MakeArray({r, g, b, a});
169 }
170 
ClearUI(GLuint r,GLuint g,GLuint b,GLuint a)171 static Array<GLuint> ClearUI(GLuint r, GLuint g, GLuint b, GLuint a)
172 {
173     return MakeArray({r, g, b, a});
174 }
175 
176 class PLSTestTexture
177 {
178   public:
PLSTestTexture(GLenum internalformat)179     PLSTestTexture(GLenum internalformat) { reset(internalformat); }
PLSTestTexture(GLenum internalformat,int w,int h)180     PLSTestTexture(GLenum internalformat, int w, int h) { reset(internalformat, w, h); }
PLSTestTexture(PLSTestTexture && that)181     PLSTestTexture(PLSTestTexture &&that) : mID(std::exchange(that.mID, 0)) {}
reset()182     void reset()
183     {
184         glDeleteTextures(1, &mID);
185         mID = 0;
186     }
reset(GLenum internalformat)187     void reset(GLenum internalformat) { reset(internalformat, W, H); }
reset(GLenum internalformat,int w,int h)188     void reset(GLenum internalformat, int w, int h)
189     {
190         GLuint id;
191         glGenTextures(1, &id);
192         glBindTexture(GL_TEXTURE_2D, id);
193         glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, w, h);
194         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
195         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
196         if (mID)
197         {
198             glDeleteTextures(1, &mID);
199         }
200         mID = id;
201     }
~PLSTestTexture()202     ~PLSTestTexture()
203     {
204         if (mID)
205         {
206             glDeleteTextures(1, &mID);
207         }
208     }
operator GLuint() const209     operator GLuint() const { return mID; }
210 
211   private:
212     PLSTestTexture &operator=(const PLSTestTexture &) = delete;
213     PLSTestTexture(const PLSTestTexture &)            = delete;
214     GLuint mID                                        = 0;
215 };
216 
217 struct Box
218 {
219     using float4 = std::array<float, 4>;
BoxBox220     constexpr Box(float4 rect) : rect(rect), color{}, aux1{}, aux2{} {}
BoxBox221     constexpr Box(float4 rect, float4 incolor) : rect(rect), color(incolor), aux1{}, aux2{} {}
BoxBox222     constexpr Box(float4 rect, float4 incolor, float4 inaux1)
223         : rect(rect), color(incolor), aux1(inaux1), aux2{}
224     {}
BoxBox225     constexpr Box(float4 rect, float4 incolor, float4 inaux1, float4 inaux2)
226         : rect(rect), color(incolor), aux1(inaux1), aux2(inaux2)
227     {}
228     float4 rect;
229     float4 color;
230     float4 aux1;
231     float4 aux2;
232 };
233 
234 enum class UseBarriers : bool
235 {
236     No = false,
237     IfNotCoherent
238 };
239 
240 class PLSProgram
241 {
242   public:
243     enum class VertexArray
244     {
245         Default,
246         VAO
247     };
248 
PLSProgram(VertexArray vertexArray=VertexArray::VAO)249     PLSProgram(VertexArray vertexArray = VertexArray::VAO)
250     {
251         if (vertexArray == VertexArray::VAO)
252         {
253             glGenVertexArrays(1, &mVertexArray);
254             glGenBuffers(1, &mVertexBuffer);
255         }
256     }
257 
~PLSProgram()258     ~PLSProgram() { reset(); }
259 
reset()260     void reset()
261     {
262         if (mVertexArray != 0)
263         {
264             glDeleteVertexArrays(1, &mVertexArray);
265             mVertexArray = 0;
266         }
267         if (mVertexBuffer != 0)
268         {
269             glDeleteBuffers(1, &mVertexBuffer);
270             mVertexBuffer = 0;
271         }
272     }
273 
widthUniform() const274     int widthUniform() const { return mWidthUniform; }
heightUniform() const275     int heightUniform() const { return mHeightUniform; }
276 
compile(std::string fsMain)277     void compile(std::string fsMain) { compile("", fsMain); }
278 
compile(std::string extensions,std::string fsMain)279     void compile(std::string extensions, std::string fsMain)
280     {
281         glBindVertexArray(mVertexArray);
282         glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
283 
284         if (mVertexArray == 0)
285         {
286             if (mLTRBLocation >= 0)
287             {
288                 glDisableVertexAttribArray(mLTRBLocation);
289             }
290             if (mRGBALocation >= 0)
291             {
292                 glDisableVertexAttribArray(mRGBALocation);
293             }
294             if (mAux1Location >= 0)
295             {
296                 glDisableVertexAttribArray(mAux1Location);
297             }
298             if (mAux2Location >= 0)
299             {
300                 glDisableVertexAttribArray(mAux2Location);
301             }
302         }
303 
304         mProgram.makeRaster(
305             R"(#version 300 es
306             precision highp float;
307 
308             uniform float W, H;
309             in vec4 rect;
310             in vec4 incolor;
311             in vec4 inaux1;
312             in vec4 inaux2;
313             out vec4 color;
314             out vec4 aux1;
315             out vec4 aux2;
316 
317             void main()
318             {
319                 color = incolor;
320                 aux1 = inaux1;
321                 aux2 = inaux2;
322                 gl_Position.x = ((gl_VertexID & 1) == 0 ? rect.x : rect.z) * 2.0/W - 1.0;
323                 gl_Position.y = ((gl_VertexID & 2) == 0 ? rect.y : rect.w) * 2.0/H - 1.0;
324                 gl_Position.zw = vec2(0, 1);
325             })",
326 
327             std::string(R"(#version 300 es
328             #extension GL_ANGLE_shader_pixel_local_storage : require
329             )")
330                 .append(extensions)
331                 .append(R"(
332             precision highp float;
333             in vec4 color;
334             in vec4 aux1;
335             in vec4 aux2;)")
336                 .append(fsMain)
337                 .c_str());
338 
339         EXPECT_TRUE(mProgram.valid());
340 
341         glUseProgram(mProgram);
342 
343         mWidthUniform = glGetUniformLocation(mProgram, "W");
344         glUniform1f(mWidthUniform, W);
345 
346         mHeightUniform = glGetUniformLocation(mProgram, "H");
347         glUniform1f(mHeightUniform, H);
348 
349         mLTRBLocation = glGetAttribLocation(mProgram, "rect");
350         glEnableVertexAttribArray(mLTRBLocation);
351         glVertexAttribDivisor(mLTRBLocation, 1);
352 
353         mRGBALocation = glGetAttribLocation(mProgram, "incolor");
354         glEnableVertexAttribArray(mRGBALocation);
355         glVertexAttribDivisor(mRGBALocation, 1);
356 
357         mAux1Location = glGetAttribLocation(mProgram, "inaux1");
358         glEnableVertexAttribArray(mAux1Location);
359         glVertexAttribDivisor(mAux1Location, 1);
360 
361         mAux2Location = glGetAttribLocation(mProgram, "inaux2");
362         glEnableVertexAttribArray(mAux2Location);
363         glVertexAttribDivisor(mAux2Location, 1);
364     }
365 
get() const366     GLuint get() const { return mProgram; }
operator GLuint()367     operator GLuint() { return get(); }
operator GLuint() const368     operator GLuint() const { return get(); }
369 
bind()370     void bind()
371     {
372         glUseProgram(mProgram);
373         glBindVertexArray(mVertexArray);
374         glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
375     }
376 
drawBoxes(std::vector<Box> boxes,UseBarriers useBarriers=UseBarriers::IfNotCoherent)377     void drawBoxes(std::vector<Box> boxes, UseBarriers useBarriers = UseBarriers::IfNotCoherent)
378     {
379         uintptr_t base;
380         if (mVertexBuffer == 0)
381         {
382             base = reinterpret_cast<uintptr_t>(boxes.data());
383         }
384         else
385         {
386             glBufferData(GL_ARRAY_BUFFER, boxes.size() * sizeof(Box), boxes.data(), GL_STATIC_DRAW);
387             base = 0;
388         }
389         if (useBarriers == UseBarriers::IfNotCoherent &&
390             !IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"))
391         {
392             for (size_t i = 0; i < boxes.size(); ++i)
393             {
394                 glVertexAttribPointer(
395                     mLTRBLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
396                     reinterpret_cast<void *>(base + i * sizeof(Box) + offsetof(Box, rect)));
397                 glVertexAttribPointer(
398                     mRGBALocation, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
399                     reinterpret_cast<void *>(base + i * sizeof(Box) + offsetof(Box, color)));
400                 glVertexAttribPointer(
401                     mAux1Location, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
402                     reinterpret_cast<void *>(base + i * sizeof(Box) + offsetof(Box, aux1)));
403                 glVertexAttribPointer(
404                     mAux2Location, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
405                     reinterpret_cast<void *>(base + i * sizeof(Box) + offsetof(Box, aux2)));
406                 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
407                 glPixelLocalStorageBarrierANGLE();
408             }
409         }
410         else
411         {
412             glVertexAttribPointer(mLTRBLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
413                                   reinterpret_cast<void *>(base + offsetof(Box, rect)));
414             glVertexAttribPointer(mRGBALocation, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
415                                   reinterpret_cast<void *>(base + offsetof(Box, color)));
416             glVertexAttribPointer(mAux1Location, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
417                                   reinterpret_cast<void *>(base + offsetof(Box, aux1)));
418             glVertexAttribPointer(mAux2Location, 4, GL_FLOAT, GL_FALSE, sizeof(Box),
419                                   reinterpret_cast<void *>(base + offsetof(Box, aux2)));
420             glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, boxes.size());
421         }
422     }
423 
424   private:
425     GLProgram mProgram;
426     GLuint mVertexArray  = 0;
427     GLuint mVertexBuffer = 0;
428 
429     GLint mWidthUniform  = -1;
430     GLint mHeightUniform = -1;
431 
432     GLint mLTRBLocation = -1;
433     GLint mRGBALocation = -1;
434     GLint mAux1Location = -1;
435     GLint mAux2Location = -1;
436 };
437 
438 class ShaderInfoLog
439 {
440   public:
compileFragmentShader(const char * source)441     bool compileFragmentShader(const char *source)
442     {
443         return compileShader(source, GL_FRAGMENT_SHADER);
444     }
445 
compileShader(const char * source,GLenum shaderType)446     bool compileShader(const char *source, GLenum shaderType)
447     {
448         mInfoLog.clear();
449 
450         GLuint shader = glCreateShader(shaderType);
451         glShaderSource(shader, 1, &source, nullptr);
452         glCompileShader(shader);
453 
454         GLint compileResult;
455         glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
456 
457         if (compileResult == 0)
458         {
459             GLint infoLogLength;
460             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
461             // Info log length includes the null terminator; std::string::reserve does not.
462             mInfoLog.resize(std::max(infoLogLength - 1, 0));
463             glGetShaderInfoLog(shader, infoLogLength, nullptr, mInfoLog.data());
464         }
465 
466         glDeleteShader(shader);
467         return compileResult != 0;
468     }
469 
has(const char * subStr) const470     bool has(const char *subStr) const { return strstr(mInfoLog.c_str(), subStr); }
471 
c_str() const472     const char *c_str() const { return mInfoLog.c_str(); }
473 
474   private:
475     std::string mInfoLog;
476 };
477 
478 class PixelLocalStorageTest : public ANGLETest<>
479 {
480   public:
PixelLocalStorageTest()481     PixelLocalStorageTest()
482     {
483         setWindowWidth(W);
484         setWindowHeight(H);
485         setConfigRedBits(8);
486         setConfigGreenBits(8);
487         setConfigBlueBits(8);
488         setConfigAlphaBits(8);
489         setExtensionsEnabled(false);
490     }
491 
testTearDown()492     void testTearDown() override
493     {
494         mProgram.reset();
495         mRenderTextureProgram.reset();
496         if (mScratchFBO)
497         {
498             glDeleteFramebuffers(1, &mScratchFBO);
499         }
500     }
501 
testSetUp()502     void testSetUp() override
503     {
504         if (EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"))
505         {
506             glGetIntegerv(GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE, &MAX_PIXEL_LOCAL_STORAGE_PLANES);
507             glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE,
508                           &MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE);
509             glGetIntegerv(GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE,
510                           &MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES);
511             glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &MAX_COLOR_ATTACHMENTS);
512             glGetIntegerv(GL_MAX_DRAW_BUFFERS, &MAX_DRAW_BUFFERS);
513         }
514 
515         // INVALID_OPERATION is generated if DITHER is enabled.
516         glDisable(GL_DITHER);
517 
518         ANGLETest::testSetUp();
519     }
520 
isContextVersionAtLeast(int major,int minor)521     int isContextVersionAtLeast(int major, int minor)
522     {
523         return getClientMajorVersion() > major ||
524                (getClientMajorVersion() == major && getClientMinorVersion() >= minor);
525     }
526 
attachTexture2DToScratchFBO(GLuint tex,GLint level=0)527     void attachTexture2DToScratchFBO(GLuint tex, GLint level = 0)
528     {
529         if (!mScratchFBO)
530         {
531             glGenFramebuffers(1, &mScratchFBO);
532         }
533         glBindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
534         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, level);
535         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
536     }
537 
attachTextureLayerToScratchFBO(GLuint tex,int level,int layer)538     void attachTextureLayerToScratchFBO(GLuint tex, int level, int layer)
539     {
540         if (!mScratchFBO)
541         {
542             glGenFramebuffers(1, &mScratchFBO);
543         }
544         glBindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
545         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, level, layer);
546         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
547     }
548 
549     // Access texture contents by rendering them into FBO 0, rather than just grabbing them with
550     // glReadPixels.
renderTextureToDefaultFramebuffer(GLuint tex)551     void renderTextureToDefaultFramebuffer(GLuint tex)
552     {
553         glBindFramebuffer(GL_FRAMEBUFFER, 0);
554         // Reset the framebuffer contents to some value that might help debugging.
555         glClearColor(.1f, .4f, .6f, .9f);
556         glClear(GL_COLOR_BUFFER_BIT);
557 
558         GLint linked = 0;
559         glGetProgramiv(mRenderTextureProgram, GL_LINK_STATUS, &linked);
560         if (!linked)
561         {
562             constexpr char kVS[] =
563                 R"(#version 300 es
564                 precision highp float;
565                 out vec2 texcoord;
566                 void main()
567                 {
568                     texcoord.x = (gl_VertexID & 1) == 0 ? 0.0 : 1.0;
569                     texcoord.y = (gl_VertexID & 2) == 0 ? 0.0 : 1.0;
570                     gl_Position = vec4(texcoord * 2.0 - 1.0, 0, 1);
571                 })";
572 
573             constexpr char kFS[] =
574                 R"(#version 300 es
575                 precision highp float;
576                 uniform highp sampler2D tex;  // FIXME! layout(binding=0) causes an ANGLE crash!
577                 in vec2 texcoord;
578                 out vec4 fragcolor;
579                 void main()
580                 {
581                     fragcolor = texture(tex, texcoord);
582                 })";
583 
584             mRenderTextureProgram.makeRaster(kVS, kFS);
585             ASSERT_TRUE(mRenderTextureProgram.valid());
586             glUseProgram(mRenderTextureProgram);
587             glUniform1i(glGetUniformLocation(mRenderTextureProgram, "tex"), 0);
588         }
589 
590         glUseProgram(mRenderTextureProgram);
591         glBindTexture(GL_TEXTURE_2D, tex);
592         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
593     }
594 
595     // Implemented as a class members so we can run the test on ES3 and ES31 both.
596     void doStateRestorationTest();
597     void doDrawStateTest();
598     void doImplicitDisablesTest_Framebuffer();
599     void doImplicitDisablesTest_TextureAttachments();
600     void doImplicitDisablesTest_RenderbufferAttachments();
601 
602     GLint MAX_PIXEL_LOCAL_STORAGE_PLANES                           = 0;
603     GLint MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE    = 0;
604     GLint MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES = 0;
605     GLint MAX_COLOR_ATTACHMENTS                                    = 0;
606     GLint MAX_DRAW_BUFFERS                                         = 0;
607 
608     PLSProgram mProgram{PLSProgram::VertexArray::Default};
609 
610     GLuint mScratchFBO = 0;
611     GLProgram mRenderTextureProgram;
612 };
613 
614 // Verify conformant implementation-dependent PLS limits.
TEST_P(PixelLocalStorageTest,ImplementationDependentLimits)615 TEST_P(PixelLocalStorageTest, ImplementationDependentLimits)
616 {
617     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
618 
619     // Table 6.X: Impementation Dependent Pixel Local Storage Limits.
620     EXPECT_TRUE(MAX_PIXEL_LOCAL_STORAGE_PLANES >= 4);
621     EXPECT_TRUE(MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE >= 0);
622     EXPECT_TRUE(MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES >= 4);
623 
624     // Logical deductions based on 6.X.
625     EXPECT_TRUE(MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES >=
626                 MAX_PIXEL_LOCAL_STORAGE_PLANES);
627     EXPECT_TRUE(MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES >=
628                 MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE);
629     EXPECT_TRUE(MAX_COLOR_ATTACHMENTS + MAX_PIXEL_LOCAL_STORAGE_PLANES >=
630                 MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES);
631     EXPECT_TRUE(MAX_DRAW_BUFFERS + MAX_PIXEL_LOCAL_STORAGE_PLANES >=
632                 MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES);
633 }
634 
635 // Verify that rgba8, rgba8i, and rgba8ui pixel local storage behaves as specified.
TEST_P(PixelLocalStorageTest,RGBA8)636 TEST_P(PixelLocalStorageTest, RGBA8)
637 {
638     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
639 
640     mProgram.compile(R"(
641         layout(binding=0, rgba8) uniform lowp pixelLocalANGLE plane1;
642         layout(rgba8i, binding=1) uniform lowp ipixelLocalANGLE plane2;
643         layout(binding=2, rgba8ui) uniform lowp upixelLocalANGLE plane3;
644         void main()
645         {
646             pixelLocalStoreANGLE(plane1, color + pixelLocalLoadANGLE(plane1));
647             pixelLocalStoreANGLE(plane2, ivec4(aux1) + pixelLocalLoadANGLE(plane2));
648             pixelLocalStoreANGLE(plane3, uvec4(aux2) + pixelLocalLoadANGLE(plane3));
649         })");
650 
651     PLSTestTexture tex1(GL_RGBA8);
652     PLSTestTexture tex2(GL_RGBA8I);
653     PLSTestTexture tex3(GL_RGBA8UI);
654 
655     GLFramebuffer fbo;
656     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
657     glFramebufferTexturePixelLocalStorageANGLE(0, tex1, 0, 0);
658     glFramebufferTexturePixelLocalStorageANGLE(1, tex2, 0, 0);
659     glFramebufferTexturePixelLocalStorageANGLE(2, tex3, 0, 0);
660     glViewport(0, 0, W, H);
661     glDrawBuffers(0, nullptr);
662 
663     glBeginPixelLocalStorageANGLE(
664         3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
665 
666     // Accumulate R, G, B, A in 4 separate passes.
667     // Store out-of-range values to ensure they are properly clamped upon storage.
668     mProgram.drawBoxes({{FULLSCREEN, {2, -1, -2, -3}, {-500, 0, 0, 0}, {1, 0, 0, 0}},
669                         {FULLSCREEN, {0, 1, 0, 100}, {0, -129, 0, 0}, {0, 50, 0, 0}},
670                         {FULLSCREEN, {0, 0, 1, 0}, {0, 0, -70, 0}, {0, 0, 100, 0}},
671                         {FULLSCREEN, {0, 0, 0, -1}, {128, 0, 0, 500}, {0, 0, 0, 300}}});
672 
673     glEndPixelLocalStorageANGLE(3, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE,
674                                                 GL_STORE_OP_STORE_ANGLE}));
675 
676     attachTexture2DToScratchFBO(tex1);
677     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor(255, 255, 255, 0));
678 
679     attachTexture2DToScratchFBO(tex2);
680     EXPECT_PIXEL_RECT32I_EQ(0, 0, W, H, GLColor32I(0, -128, -70, 127));
681 
682     attachTexture2DToScratchFBO(tex3);
683     EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(1, 50, 100, 255));
684 
685     ASSERT_GL_NO_ERROR();
686 }
687 
688 // Verify that r32f and r32ui pixel local storage behaves as specified.
TEST_P(PixelLocalStorageTest,R32)689 TEST_P(PixelLocalStorageTest, R32)
690 {
691     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
692 
693     mProgram.compile(R"(
694         layout(r32f, binding=0) uniform highp pixelLocalANGLE plane1;
695         layout(binding=1, r32ui) uniform highp upixelLocalANGLE plane2;
696         void main()
697         {
698             pixelLocalStoreANGLE(plane1, color + pixelLocalLoadANGLE(plane1));
699             pixelLocalStoreANGLE(plane2, uvec4(aux1) + pixelLocalLoadANGLE(plane2));
700         })");
701 
702     PLSTestTexture tex1(GL_R32F);
703     PLSTestTexture tex2(GL_R32UI);
704 
705     GLFramebuffer fbo;
706     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
707     glFramebufferTexturePixelLocalStorageANGLE(0, tex1, 0, 0);
708     glFramebufferTexturePixelLocalStorageANGLE(1, tex2, 0, 0);
709     glViewport(0, 0, W, H);
710     glDrawBuffers(0, nullptr);
711 
712     glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
713 
714     // Accumulate R in 4 separate passes.
715     mProgram.drawBoxes({{FULLSCREEN, {-1.5, 0, 0, 0}, {0x000000ff, 0, 0, 0}},
716                         {FULLSCREEN, {-10.25, 0, 0, 0}, {0x0000ff00, 0, 0, 0}},
717                         {FULLSCREEN, {-100, 0, 0, 0}, {0x00ff0000, 0, 0, 0}},
718                         {FULLSCREEN, {.25, 0, 0, 0}, {0xff000000, 0, 0, 22}}});
719 
720     glEndPixelLocalStorageANGLE(2, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
721 
722     // These values should be exact matches.
723     //
724     // GL_R32F is spec'd as a 32-bit IEEE float, and GL_R32UI is a 32-bit unsigned integer.
725     // There is some affordance for fp32 fused operations, but "a + b" is required to be
726     // correctly rounded.
727     //
728     // From the GLSL ES 3.0 spec:
729     //
730     //   "Highp unsigned integers have exactly 32 bits of precision. Highp signed integers use
731     //    32 bits, including a sign bit, in two's complement form."
732     //
733     //   "Highp floating-point variables within a shader are encoded according to the IEEE 754
734     //    specification for single-precision floating-point values (logically, not necessarily
735     //    physically)."
736     //
737     //   "Operation: a + b, a - b, a * b
738     //    Precision: Correctly rounded."
739     attachTexture2DToScratchFBO(tex1);
740     EXPECT_PIXEL_RECT32F_EQ(0, 0, W, H, GLColor32F(-111.5, 0, 0, 1));
741 
742     attachTexture2DToScratchFBO(tex2);
743     EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0xffffffff, 0, 0, 1));
744 
745     ASSERT_GL_NO_ERROR();
746 }
747 
748 // Check proper functioning of the clear value state.
TEST_P(PixelLocalStorageTest,ClearValues_rgba8)749 TEST_P(PixelLocalStorageTest, ClearValues_rgba8)
750 {
751     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
752 
753     PLSTestTexture tex8f(GL_RGBA8, 1, 1);
754     PLSTestTexture tex8i(GL_RGBA8I, 1, 1);
755     PLSTestTexture tex8ui(GL_RGBA8UI, 1, 1);
756 
757     GLFramebuffer fbo;
758     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
759     glFramebufferTexturePixelLocalStorageANGLE(0, tex8f, 0, 0);
760     glFramebufferTexturePixelLocalStorageANGLE(1, tex8i, 0, 0);
761     glFramebufferTexturePixelLocalStorageANGLE(2, tex8ui, 0, 0);
762     auto clearLoads =
763         GLenumArray({GL_LOAD_OP_CLEAR_ANGLE, GL_LOAD_OP_CLEAR_ANGLE, GL_LOAD_OP_CLEAR_ANGLE});
764     auto storeStores =
765         GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE});
766 
767     // Clear values are initially zero.
768     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({0, 0, 0, 0}));
769     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(1, ({0, 0, 0, 0}));
770     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(2, ({0, 0, 0, 0}));
771     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
772     glBeginPixelLocalStorageANGLE(3, clearLoads);
773     glEndPixelLocalStorageANGLE(3, storeStores);
774     attachTexture2DToScratchFBO(tex8f);
775     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(0, 0, 0, 0));
776     attachTexture2DToScratchFBO(tex8i);
777     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(0, 0, 0, 0));
778     attachTexture2DToScratchFBO(tex8ui);
779     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0, 0, 0, 0));
780 
781     // Test custom RGBA8 clear values.
782     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
783     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(100.5, 0, 0, 0));
784     glFramebufferPixelLocalClearValueivANGLE(1, ClearI(-1, 2, -3, 4));
785     glFramebufferPixelLocalClearValueuivANGLE(2, ClearUI(5, 6, 7, 8));
786     glBeginPixelLocalStorageANGLE(3, clearLoads);
787     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({100.5, 0, 0, 0}));
788     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(1, ({-1, 2, -3, 4}));
789     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(2, ({5, 6, 7, 8}));
790     glEndPixelLocalStorageANGLE(3, storeStores);
791     attachTexture2DToScratchFBO(tex8f);
792     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(255, 0, 0, 0));
793     attachTexture2DToScratchFBO(tex8i);
794     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(-1, 2, -3, 4));
795     attachTexture2DToScratchFBO(tex8ui);
796     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(5, 6, 7, 8));
797 
798     // Rotate and test again.
799     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
800     glFramebufferTexturePixelLocalStorageANGLE(0, tex8ui, 0, 0);
801     glFramebufferTexturePixelLocalStorageANGLE(1, tex8f, 0, 0);
802     glFramebufferTexturePixelLocalStorageANGLE(2, tex8i, 0, 0);
803     glBeginPixelLocalStorageANGLE(3, clearLoads);
804     // Since each clear value type is separate state, these should all be zero again.
805     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(0, ({0, 0, 0, 0}));
806     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(1, ({0, 0, 0, 0}));
807     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(2, ({0, 0, 0, 0}));
808     glEndPixelLocalStorageANGLE(3, storeStores);
809     attachTexture2DToScratchFBO(tex8ui);
810     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0, 0, 0, 0));
811     attachTexture2DToScratchFBO(tex8f);
812     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(0, 0, 0, 0));
813     attachTexture2DToScratchFBO(tex8i);
814     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(0, 0, 0, 0));
815     // If any component of the clear value is larger than can be represented in plane's
816     // internalformat, it is clamped.
817     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
818     glFramebufferPixelLocalClearValueuivANGLE(0, ClearUI(254, 255, 256, 257));
819     glFramebufferPixelLocalClearValuefvANGLE(1, ClearF(-1, 0, 1, 2));
820     glFramebufferPixelLocalClearValueivANGLE(2, ClearI(-129, -128, 127, 128));
821     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(0, ({254, 255, 256, 257}));
822     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(1, ({-1, 0, 1, 2}));
823     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(2, ({-129, -128, 127, 128}));
824     glBeginPixelLocalStorageANGLE(3, clearLoads);
825     glEndPixelLocalStorageANGLE(3, storeStores);
826     attachTexture2DToScratchFBO(tex8ui);
827     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(254, 255, 255, 255));
828     attachTexture2DToScratchFBO(tex8f);
829     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(0, 0, 255, 255));
830     attachTexture2DToScratchFBO(tex8i);
831     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(-128, -128, 127, 127));
832 
833     // Final rotation.
834     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
835     glFramebufferTexturePixelLocalStorageANGLE(0, tex8i, 0, 0);
836     glFramebufferTexturePixelLocalStorageANGLE(1, tex8ui, 0, 0);
837     glFramebufferTexturePixelLocalStorageANGLE(2, tex8f, 0, 0);
838     // Since each clear value type is separate state, these should all be zero yet again.
839     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(0, ({0, 0, 0, 0}));
840     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(1, ({0, 0, 0, 0}));
841     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(2, ({0, 0, 0, 0}));
842     glBeginPixelLocalStorageANGLE(3, clearLoads);
843     glEndPixelLocalStorageANGLE(3, storeStores);
844     attachTexture2DToScratchFBO(tex8i);
845     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(0, 0, 0, 0));
846     attachTexture2DToScratchFBO(tex8ui);
847     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0, 0, 0, 0));
848     attachTexture2DToScratchFBO(tex8f);
849     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(0, 0, 0, 0));
850     // If any component of the clear value is larger than can be represented in plane's
851     // internalformat, it is clamped.
852     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
853     glFramebufferPixelLocalClearValueivANGLE(0, ClearI(999, 999, -999, -999));
854     glFramebufferPixelLocalClearValueuivANGLE(1, ClearUI(0, 0, 999, 999));
855     glFramebufferPixelLocalClearValuefvANGLE(2, ClearF(999, 999, -999, -999));
856     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(0, ({999, 999, -999, -999}));
857     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(1, ({0, 0, 999, 999}));
858     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(2, ({999, 999, -999, -999}));
859     glBeginPixelLocalStorageANGLE(3, clearLoads);
860     glEndPixelLocalStorageANGLE(3, storeStores);
861     attachTexture2DToScratchFBO(tex8i);
862     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(127, 127, -128, -128));
863     attachTexture2DToScratchFBO(tex8ui);
864     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0, 0, 255, 255));
865     attachTexture2DToScratchFBO(tex8f);
866     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(255, 255, 0, 0));
867 
868     // GL_LOAD_OP_ZERO_ANGLE shouldn't be affected by previous clear colors.
869     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
870     glBeginPixelLocalStorageANGLE(
871         3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
872     glEndPixelLocalStorageANGLE(3, storeStores);
873     attachTexture2DToScratchFBO(tex8f);
874     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(0, 0, 0, 0));
875     attachTexture2DToScratchFBO(tex8i);
876     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(0, 0, 0, 0));
877     attachTexture2DToScratchFBO(tex8ui);
878     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0, 0, 0, 0));
879 
880     // Cycle back to the original configuration and ensure that clear state hasn't changed.
881     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
882     glFramebufferTexturePixelLocalStorageANGLE(0, tex8f, 0, 0);
883     glFramebufferTexturePixelLocalStorageANGLE(1, tex8i, 0, 0);
884     glFramebufferTexturePixelLocalStorageANGLE(2, tex8ui, 0, 0);
885     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({100.5f, 0, 0, 0}));
886     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(1, ({-1, 2, -3, 4}));
887     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(2, ({5, 6, 7, 8}));
888     glBeginPixelLocalStorageANGLE(3, clearLoads);
889     glEndPixelLocalStorageANGLE(3, storeStores);
890     attachTexture2DToScratchFBO(tex8f);
891     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(255, 0, 0, 0));
892     attachTexture2DToScratchFBO(tex8i);
893     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(-1, 2, -3, 4));
894     attachTexture2DToScratchFBO(tex8ui);
895     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(5, 6, 7, 8));
896 
897     // Clear state is specific to the draw framebuffer; clear values on one framebuffer do not
898     // affect clear values on another.
899     GLFramebuffer fbo2;
900     glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
901     glFramebufferTexturePixelLocalStorageANGLE(0, tex8f, 0, 0);
902     glFramebufferTexturePixelLocalStorageANGLE(1, tex8i, 0, 0);
903     glFramebufferTexturePixelLocalStorageANGLE(2, tex8ui, 0, 0);
904     glBeginPixelLocalStorageANGLE(3, clearLoads);
905     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({0, 0, 0, 0}));
906     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(1, ({0, 0, 0, 0}));
907     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(2, ({0, 0, 0, 0}));
908     glEndPixelLocalStorageANGLE(3, storeStores);
909     attachTexture2DToScratchFBO(tex8f);
910     EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor(0, 0, 0, 0));
911     attachTexture2DToScratchFBO(tex8i);
912     EXPECT_PIXEL_RECT32I_EQ(0, 0, 1, 1, GLColor32I(0, 0, 0, 0));
913     attachTexture2DToScratchFBO(tex8ui);
914     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0, 0, 0, 0));
915 }
916 
917 // Check clear values for r32f and r32ui PLS format.
TEST_P(PixelLocalStorageTest,ClearValues_r32)918 TEST_P(PixelLocalStorageTest, ClearValues_r32)
919 {
920     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
921 
922     GLFramebuffer fbo;
923     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
924 
925     // Test custom R32 clear values.
926     PLSTestTexture tex32f(GL_R32F);
927     PLSTestTexture tex32ui(GL_R32UI);
928     glFramebufferTexturePixelLocalStorageANGLE(0, tex32f, 0, 0);
929     glFramebufferTexturePixelLocalStorageANGLE(1, tex32ui, 0, 0);
930     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(100.5, 0, 0, 0));
931     glFramebufferPixelLocalClearValueuivANGLE(1, ClearUI(0xbaadbeef, 1, 1, 0));
932     glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
933     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({100.5f, 0, 0, 0}));
934     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(1, ({0xbaadbeef, 1, 1, 0}));
935     glEndPixelLocalStorageANGLE(2, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
936     attachTexture2DToScratchFBO(tex32f);
937     EXPECT_PIXEL_RECT32F_EQ(0, 0, 1, 1, GLColor32F(100.5f, 0, 0, 1));
938     attachTexture2DToScratchFBO(tex32ui);
939     EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1, GLColor32UI(0xbaadbeef, 0, 0, 1));
940 }
941 
942 // Check proper support of GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_LOAD_ANGLE, and GL_LOAD_OP_CLEAR_ANGLE
943 // loadOps. Also verify that it works do draw with GL_MAX_LOCAL_STORAGE_PLANES_ANGLE planes.
TEST_P(PixelLocalStorageTest,LoadOps)944 TEST_P(PixelLocalStorageTest, LoadOps)
945 {
946     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
947 
948     std::stringstream fs;
949     for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
950     {
951         fs << "layout(binding=" << i << ", rgba8) uniform highp pixelLocalANGLE pls" << i << ";\n";
952     }
953     fs << "void main() {\n";
954     for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
955     {
956         fs << "pixelLocalStoreANGLE(pls" << i << ", color + pixelLocalLoadANGLE(pls" << i
957            << "));\n";
958     }
959     fs << "}";
960     mProgram.compile(fs.str().c_str());
961 
962     // Create pls textures and clear them to red.
963     glClearColor(1, 0, 0, 1);
964     std::vector<PLSTestTexture> texs;
965     for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
966     {
967         texs.emplace_back(GL_RGBA8);
968         attachTexture2DToScratchFBO(texs[i]);
969         glClear(GL_COLOR_BUFFER_BIT);
970     }
971 
972     // Turn on scissor to try and confuse the local storage clear step.
973     glEnable(GL_SCISSOR_TEST);
974     glScissor(0, 0, 20, H);
975 
976     // Set up pls color planes with a clear color of black. Odd units load with
977     // GL_LOAD_OP_CLEAR_ANGLE (cleared to black) and even load with GL_LOAD_OP_LOAD_ANGLE (preserved
978     // red).
979     GLFramebuffer fbo;
980     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
981     std::vector<GLenum> loadOps(MAX_PIXEL_LOCAL_STORAGE_PLANES);
982     for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
983     {
984         glFramebufferTexturePixelLocalStorageANGLE(i, texs[i], 0, 0);
985         glFramebufferPixelLocalClearValuefvANGLE(i, ClearF(0, 0, 0, 1));
986         loadOps[i] = (i & 1) ? GL_LOAD_OP_CLEAR_ANGLE : GL_LOAD_OP_LOAD_ANGLE;
987     }
988     std::vector<GLenum> storeOps(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_STORE_OP_STORE_ANGLE);
989     glViewport(0, 0, W, H);
990     glDrawBuffers(0, nullptr);
991 
992     // Draw transparent green into all pls attachments.
993     glBeginPixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, loadOps.data());
994     mProgram.drawBoxes({{{FULLSCREEN}, {0, 1, 0, 0}}});
995     glEndPixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, storeOps.data());
996 
997     for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
998     {
999         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texs[i], 0);
1000         // Check that the draw buffers didn't get perturbed by local storage -- GL_COLOR_ATTACHMENT0
1001         // is currently off, so glClear has no effect. This also verifies that local storage planes
1002         // didn't get left attached to the framebuffer somewhere with draw buffers on.
1003         glClear(GL_COLOR_BUFFER_BIT);
1004         EXPECT_PIXEL_RECT_EQ(0, 0, 20, H,
1005                              loadOps[i] == GL_LOAD_OP_CLEAR_ANGLE
1006                                  ? GLColor(0, 255, 0, 255)
1007                                  : /*GL_LOAD_OP_LOAD_ANGLE*/ GLColor(255, 255, 0, 255));
1008         // Check that the scissor didn't get perturbed by local storage.
1009         EXPECT_PIXEL_RECT_EQ(20, 0, W - 20, H,
1010                              loadOps[i] == GL_LOAD_OP_CLEAR_ANGLE
1011                                  ? GLColor(0, 0, 0, 255)
1012                                  : /*GL_LOAD_OP_LOAD_ANGLE*/ GLColor(255, 0, 0, 255));
1013     }
1014 
1015     // Detach the last read pls texture from the framebuffer.
1016     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1017 
1018     // Now test GL_LOAD_OP_ZERO_ANGLE, and leaving a plane deinitialized.
1019     for (int i = 0; i < 2; ++i)
1020     {
1021         loadOps[i] = GL_LOAD_OP_ZERO_ANGLE;
1022     }
1023 
1024     // Execute a pls pass without a draw.
1025     glBeginPixelLocalStorageANGLE(3, loadOps.data());
1026     glEndPixelLocalStorageANGLE(3, storeOps.data());
1027 
1028     for (int i = 0; i < 3; ++i)
1029     {
1030         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texs[i], 0);
1031         if (i < 2)
1032         {
1033             ASSERT(loadOps[i] == GL_LOAD_OP_ZERO_ANGLE);
1034             EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor(0, 0, 0, 0));
1035         }
1036         else
1037         {
1038             // Should have been left unchanged.
1039             EXPECT_PIXEL_RECT_EQ(0, 0, 20, H, GLColor(255, 255, 0, 255));
1040             EXPECT_PIXEL_RECT_EQ(20, 0, W - 20, H, GLColor(255, 0, 0, 255));
1041         }
1042     }
1043 
1044     // Now turn GL_COLOR_ATTACHMENT0 back on and check that the clear color and scissor didn't get
1045     // perturbed by local storage.
1046     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texs[1], 0);
1047     glDrawBuffers(1, GLenumArray({GL_COLOR_ATTACHMENT0}));
1048     glClear(GL_COLOR_BUFFER_BIT);
1049     EXPECT_PIXEL_RECT_EQ(0, 0, 20, H, GLColor(255, 0, 0, 255));
1050     EXPECT_PIXEL_RECT_EQ(20, 0, W - 20, H, GLColor(0, 0, 0, 0));
1051 
1052     ASSERT_GL_NO_ERROR();
1053 }
1054 
1055 // This next series of tests checks that GL utilities for rejecting fragments prevent stores to PLS:
1056 //
1057 //   * stencil test
1058 //   * depth test
1059 //   * viewport
1060 //
1061 // Some utilities are not legal in ANGLE_shader_pixel_local_storage:
1062 //
1063 //   * gl_SampleMask is disallowed by the spec
1064 //   * discard, after potential calls to pixelLocalLoadANGLE/Store, is disallowed by the spec
1065 //   * pixelLocalLoadANGLE/Store after a return from main is disallowed by the spec
1066 //
1067 // To run the tests, bind a FragmentRejectTestFBO and draw {FRAG_REJECT_TEST_BOX}:
1068 //
1069 //   * {0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT} should be green
1070 //   * Fragments outside should have been rejected, leaving the pixels black
1071 //
1072 struct FragmentRejectTestFBO : GLFramebuffer
1073 {
FragmentRejectTestFBOFragmentRejectTestFBO1074     FragmentRejectTestFBO(GLuint tex)
1075     {
1076         glBindFramebuffer(GL_FRAMEBUFFER, *this);
1077         glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
1078         glFramebufferPixelLocalClearValuefvANGLE(0, MakeArray<float>({0, 0, 0, 1}));
1079         glViewport(0, 0, W, H);
1080         glDrawBuffers(0, nullptr);
1081     }
1082 };
1083 constexpr static int FRAG_REJECT_TEST_WIDTH  = 64;
1084 constexpr static int FRAG_REJECT_TEST_HEIGHT = 64;
1085 constexpr static Box FRAG_REJECT_TEST_BOX(FULLSCREEN,
1086                                           {0, 1, 0, 0},  // draw color
1087                                           {0, 0, FRAG_REJECT_TEST_WIDTH,
1088                                            FRAG_REJECT_TEST_HEIGHT});  // reject pixels outside aux1
1089 
1090 // Check that the stencil test prevents stores to PLS.
TEST_P(PixelLocalStorageTest,FragmentReject_stencil)1091 TEST_P(PixelLocalStorageTest, FragmentReject_stencil)
1092 {
1093     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1094 
1095     PLSTestTexture tex(GL_RGBA8);
1096     FragmentRejectTestFBO fbo(tex);
1097 
1098     mProgram.compile(R"(
1099     layout(binding=0, rgba8) uniform highp pixelLocalANGLE pls;
1100     void main()
1101     {
1102         pixelLocalStoreANGLE(pls, color + pixelLocalLoadANGLE(pls));
1103     })");
1104     GLuint depthStencil;
1105     glGenRenderbuffers(1, &depthStencil);
1106     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
1107     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
1108     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1109                               depthStencil);
1110 
1111     // glStencilFunc(GL_NEVER, ...) should not update pls.
1112     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
1113     glEnable(GL_STENCIL_TEST);
1114     glStencilFunc(GL_NEVER, 1, ~0u);
1115     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1116     GLint zero = 0;
1117     glClearBufferiv(GL_STENCIL, 0, &zero);
1118     mProgram.drawBoxes({{{0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT}}});
1119     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1120     glDisable(GL_STENCIL_TEST);
1121     attachTexture2DToScratchFBO(tex);
1122     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::black);
1123 
1124     // Stencil should be preserved after PLS, and only pixels that pass the stencil test should
1125     // update PLS next.
1126     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1127     glEnable(GL_STENCIL_TEST);
1128     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_LOAD_ANGLE}));
1129     glStencilFunc(GL_NOTEQUAL, 0, ~0u);
1130     glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
1131     mProgram.drawBoxes({FRAG_REJECT_TEST_BOX});
1132     glDisable(GL_STENCIL_TEST);
1133     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1134     renderTextureToDefaultFramebuffer(tex);
1135     EXPECT_PIXEL_RECT_EQ(0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT, GLColor::green);
1136     EXPECT_PIXEL_RECT_EQ(FRAG_REJECT_TEST_WIDTH, 0, W - FRAG_REJECT_TEST_WIDTH,
1137                          FRAG_REJECT_TEST_HEIGHT, GLColor::black);
1138     EXPECT_PIXEL_RECT_EQ(0, FRAG_REJECT_TEST_HEIGHT, W, H - FRAG_REJECT_TEST_HEIGHT,
1139                          GLColor::black);
1140 
1141     ASSERT_GL_NO_ERROR();
1142 }
1143 
1144 // Check that the depth test prevents stores to PLS.
TEST_P(PixelLocalStorageTest,FragmentReject_depth)1145 TEST_P(PixelLocalStorageTest, FragmentReject_depth)
1146 {
1147     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1148 
1149     PLSTestTexture tex(GL_RGBA8);
1150     FragmentRejectTestFBO fbo(tex);
1151 
1152     mProgram.compile(R"(
1153     layout(binding=0, rgba8) uniform highp pixelLocalANGLE pls;
1154     void main()
1155     {
1156         pixelLocalStoreANGLE(pls, pixelLocalLoadANGLE(pls) + color);
1157     })");
1158     GLuint depth;
1159     glGenRenderbuffers(1, &depth);
1160     glBindRenderbuffer(GL_RENDERBUFFER, depth);
1161     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, W, H);
1162     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
1163     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
1164     GLfloat zero = 0;
1165     glClearBufferfv(GL_DEPTH, 0, &zero);
1166     glEnable(GL_DEPTH_TEST);
1167     glEnable(GL_SCISSOR_TEST);
1168     glScissor(0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT);
1169     GLfloat one = 1;
1170     glClearBufferfv(GL_DEPTH, 0, &one);
1171     glDisable(GL_SCISSOR_TEST);
1172     glDepthFunc(GL_LESS);
1173     mProgram.drawBoxes({FRAG_REJECT_TEST_BOX});
1174     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1175     glDisable(GL_DEPTH_TEST);
1176 
1177     renderTextureToDefaultFramebuffer(tex);
1178     EXPECT_PIXEL_RECT_EQ(0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT, GLColor::green);
1179     EXPECT_PIXEL_RECT_EQ(FRAG_REJECT_TEST_WIDTH, 0, W - FRAG_REJECT_TEST_WIDTH,
1180                          FRAG_REJECT_TEST_HEIGHT, GLColor::black);
1181     EXPECT_PIXEL_RECT_EQ(0, FRAG_REJECT_TEST_HEIGHT, W, H - FRAG_REJECT_TEST_HEIGHT,
1182                          GLColor::black);
1183     ASSERT_GL_NO_ERROR();
1184 }
1185 
1186 // Check that restricting the viewport also restricts stores to PLS.
TEST_P(PixelLocalStorageTest,FragmentReject_viewport)1187 TEST_P(PixelLocalStorageTest, FragmentReject_viewport)
1188 {
1189     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1190 
1191     PLSTestTexture tex(GL_RGBA8);
1192     FragmentRejectTestFBO fbo(tex);
1193 
1194     mProgram.compile(R"(
1195     layout(binding=0, rgba8) uniform highp pixelLocalANGLE pls;
1196     void main()
1197     {
1198         vec4 dst = pixelLocalLoadANGLE(pls);
1199         pixelLocalStoreANGLE(pls, color + dst);
1200     })");
1201     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
1202     glViewport(0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT);
1203     mProgram.drawBoxes({FRAG_REJECT_TEST_BOX});
1204     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1205     glViewport(0, 0, W, H);
1206 
1207     renderTextureToDefaultFramebuffer(tex);
1208     EXPECT_PIXEL_RECT_EQ(0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT, GLColor::green);
1209     EXPECT_PIXEL_RECT_EQ(FRAG_REJECT_TEST_WIDTH, 0, W - FRAG_REJECT_TEST_WIDTH,
1210                          FRAG_REJECT_TEST_HEIGHT, GLColor::black);
1211     EXPECT_PIXEL_RECT_EQ(0, FRAG_REJECT_TEST_HEIGHT, W, H - FRAG_REJECT_TEST_HEIGHT,
1212                          GLColor::black);
1213     ASSERT_GL_NO_ERROR();
1214 }
1215 
1216 // Check that results are only nondeterministic within predictable constraints, and that no data is
1217 // random or leaked from other contexts when we forget to insert a barrier.
TEST_P(PixelLocalStorageTest,ForgetBarrier)1218 TEST_P(PixelLocalStorageTest, ForgetBarrier)
1219 {
1220     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1221 
1222     mProgram.compile(R"(
1223     layout(binding=0, r32f) uniform highp pixelLocalANGLE framebuffer;
1224     void main()
1225     {
1226         vec4 dst = pixelLocalLoadANGLE(framebuffer);
1227         pixelLocalStoreANGLE(framebuffer, color + dst * 2.0);
1228     })");
1229 
1230     // Draw r=100, one pixel at a time, in random order.
1231     constexpr static int NUM_PIXELS = H * W;
1232     std::vector<Box> boxesA_100;
1233     int pixelIdx = 0;
1234     for (int i = 0; i < NUM_PIXELS; ++i)
1235     {
1236         int iy  = pixelIdx / W;
1237         float y = iy;
1238         int ix  = pixelIdx % W;
1239         float x = ix;
1240         pixelIdx =
1241             (pixelIdx + 69484171) % NUM_PIXELS;  // Prime numbers guarantee we hit every pixel once.
1242         boxesA_100.push_back(Box{{x, y, x + 1, y + 1}, {100, 0, 0, 0}});
1243     }
1244 
1245     // Draw r=7, one pixel at a time, in random order.
1246     std::vector<Box> boxesB_7;
1247     for (int i = 0; i < NUM_PIXELS; ++i)
1248     {
1249         int iy  = pixelIdx / W;
1250         float y = iy;
1251         int ix  = pixelIdx % W;
1252         float x = ix;
1253         pixelIdx =
1254             (pixelIdx + 97422697) % NUM_PIXELS;  // Prime numbers guarantee we hit every pixel once.
1255         boxesB_7.push_back(Box{{x, y, x + 1, y + 1}, {7, 0, 0, 0}});
1256     }
1257 
1258     PLSTestTexture tex(GL_R32F);
1259 
1260     GLFramebuffer fbo;
1261     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1262     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
1263     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(1, 0, 0, 0));
1264     glViewport(0, 0, W, H);
1265     glDrawBuffers(0, nullptr);
1266 
1267     // First make sure it works properly with a barrier.
1268     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
1269     mProgram.drawBoxes(boxesA_100, UseBarriers::No);
1270     glPixelLocalStorageBarrierANGLE();
1271     mProgram.drawBoxes(boxesB_7, UseBarriers::No);
1272     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1273 
1274     attachTexture2DToScratchFBO(tex);
1275     EXPECT_PIXEL_RECT32F_EQ(0, 0, W, H, GLColor32F(211, 0, 0, 1));
1276 
1277     ASSERT_GL_NO_ERROR();
1278 
1279     // Vulkan generates rightful "SYNC-HAZARD-READ_AFTER_WRITE" validation errors when we omit the
1280     // barrier.
1281     ANGLE_SKIP_TEST_IF(IsVulkan() &&
1282                        !IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
1283 
1284     // Now forget to insert the barrier and ensure our nondeterminism still falls within predictable
1285     // constraints.
1286     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1287     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
1288     mProgram.drawBoxes(boxesA_100, UseBarriers::No);
1289     // OOPS! We forgot to insert a barrier!
1290     mProgram.drawBoxes(boxesB_7, UseBarriers::No);
1291     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1292 
1293     float pixels[H * W * 4];
1294     attachTexture2DToScratchFBO(tex);
1295     glReadPixels(0, 0, W, H, GL_RGBA, GL_FLOAT, pixels);
1296     for (int r = 0; r < NUM_PIXELS * 4; r += 4)
1297     {
1298         // When two fragments, A and B, touch a pixel, there are 6 possible orderings of operations:
1299         //
1300         //   * Read A, Write A, Read B, Write B
1301         //   * Read B, Write B, Read A, Write A
1302         //   * Read A, Read B, Write A, Write B
1303         //   * Read A, Read B, Write B, Write A
1304         //   * Read B, Read A, Write B, Write A
1305         //   * Read B, Read A, Write A, Write B
1306         //
1307         // Which (assumimg the read and/or write operations themselves are atomic), is equivalent to
1308         // 1 of 4 potential effects:
1309         bool isAcceptableValue = pixels[r] == 211 ||  // A, then B  (  7 + (100 + 1 * 2) * 2 == 211)
1310                                  pixels[r] == 118 ||  // B, then A  (100 + (  7 + 1 * 2) * 2 == 118)
1311                                  pixels[r] == 102 ||  // A only     (100 +             1 * 2 == 102)
1312                                  pixels[r] == 9;
1313         if (!isAcceptableValue)
1314         {
1315             printf(__FILE__ "(%i): UNACCEPTABLE value at pixel location [%i, %i]\n", __LINE__,
1316                    (r / 4) % W, (r / 4) / W);
1317             printf("              Got: %f\n", pixels[r]);
1318             printf("  Expected one of: { 211, 118, 102, 9 }\n");
1319         }
1320         ASSERT_TRUE(isAcceptableValue);
1321     }
1322 
1323     ASSERT_GL_NO_ERROR();
1324 }
1325 
1326 // Check loading and storing from memoryless local storage planes.
TEST_P(PixelLocalStorageTest,MemorylessStorage)1327 TEST_P(PixelLocalStorageTest, MemorylessStorage)
1328 {
1329     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1330 
1331     // Bind the texture, but don't call glTexStorage until after creating the memoryless plane.
1332     GLTexture tex;
1333     glBindTexture(GL_TEXTURE_2D, tex);
1334 
1335     GLFramebuffer fbo;
1336     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1337     // Create a memoryless plane.
1338     glFramebufferMemorylessPixelLocalStorageANGLE(1, GL_RGBA8);
1339     // Define the persistent texture now, after attaching the memoryless pixel local storage. This
1340     // verifies that the GL_TEXTURE_2D binding doesn't get perturbed by local storage.
1341     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, W, H);
1342     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
1343     glViewport(0, 0, W, H);
1344     glDrawBuffers(0, nullptr);
1345 
1346     PLSProgram drawMemorylessProgram;
1347     drawMemorylessProgram.compile(R"(
1348     layout(binding=0, rgba8) uniform highp pixelLocalANGLE framebuffer;
1349     layout(binding=1, rgba8) uniform highp pixelLocalANGLE memoryless;
1350     void main()
1351     {
1352         pixelLocalStoreANGLE(memoryless, color + pixelLocalLoadANGLE(memoryless));
1353     })");
1354 
1355     PLSProgram transferToTextureProgram;
1356     transferToTextureProgram.compile(R"(
1357     layout(binding=0, rgba8) uniform highp pixelLocalANGLE framebuffer;
1358     layout(binding=1, rgba8) uniform highp pixelLocalANGLE memoryless;
1359     void main()
1360     {
1361         pixelLocalStoreANGLE(framebuffer, vec4(1) - pixelLocalLoadANGLE(memoryless));
1362     })");
1363 
1364     glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
1365 
1366     // Draw into memoryless storage.
1367     drawMemorylessProgram.bind();
1368     drawMemorylessProgram.drawBoxes({{{0, 20, W, H}, {1, 0, 0, 0}},
1369                                      {{0, 40, W, H}, {0, 1, 0, 0}},
1370                                      {{0, 60, W, H}, {0, 0, 1, 0}}});
1371 
1372     ASSERT_GL_NO_ERROR();
1373 
1374     // Transfer to a texture.
1375     transferToTextureProgram.bind();
1376     transferToTextureProgram.drawBoxes({{FULLSCREEN}});
1377 
1378     glEndPixelLocalStorageANGLE(2, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_DONT_CARE}));
1379 
1380     attachTexture2DToScratchFBO(tex);
1381     EXPECT_PIXEL_RECT_EQ(0, 60, W, H - 60, GLColor(0, 0, 0, 255));
1382     EXPECT_PIXEL_RECT_EQ(0, 40, W, 20, GLColor(0, 0, 255, 255));
1383     EXPECT_PIXEL_RECT_EQ(0, 20, W, 20, GLColor(0, 255, 255, 255));
1384     EXPECT_PIXEL_RECT_EQ(0, 0, W, 20, GLColor(255, 255, 255, 255));
1385 
1386     // Ensure the GL_TEXTURE_2D binding still hasn't been perturbed by local storage.
1387     GLint textureBinding2D;
1388     glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding2D);
1389     ASSERT_EQ((GLuint)textureBinding2D, tex);
1390 
1391     ASSERT_GL_NO_ERROR();
1392 }
1393 
1394 // Check that it works to render with the maximum supported data payload:
1395 //
1396 //   GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE
1397 //
TEST_P(PixelLocalStorageTest,MaxCombinedDrawBuffersAndPLSPlanes)1398 TEST_P(PixelLocalStorageTest, MaxCombinedDrawBuffersAndPLSPlanes)
1399 {
1400     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1401 
1402     for (int numDrawBuffers : {0, 1, MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - 1})
1403     {
1404         numDrawBuffers =
1405             std::min(numDrawBuffers, MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE);
1406         int numPLSPlanes =
1407             MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - numDrawBuffers;
1408         numPLSPlanes = std::min(numPLSPlanes, MAX_PIXEL_LOCAL_STORAGE_PLANES);
1409 
1410         std::stringstream fs;
1411         for (int i = 0; i < numPLSPlanes; ++i)
1412         {
1413             fs << "layout(binding=" << i << ", rgba8ui) uniform highp upixelLocalANGLE pls" << i
1414                << ";\n";
1415         }
1416         for (int i = 0; i < numDrawBuffers; ++i)
1417         {
1418             if (numDrawBuffers > 1)
1419             {
1420                 fs << "layout(location=" << i << ") ";
1421             }
1422             fs << "out uvec4 out" << i << ";\n";
1423         }
1424         fs << "void main() {\n";
1425         int c = 0;
1426         for (; c < std::min(numPLSPlanes, numDrawBuffers); ++c)
1427         {
1428             // Nest an expression involving a fragment output, which will have an unspecified
1429             // location when numDrawBuffers is 1, in pixelLocalStoreANGLE().
1430             fs << "pixelLocalStoreANGLE(pls" << c << ", uvec4(color) - (out" << c
1431                << " = uvec4(aux1) + uvec4(" << c << ")));\n";
1432         }
1433         for (int i = c; i < numPLSPlanes; ++i)
1434         {
1435             fs << "pixelLocalStoreANGLE(pls" << i << ", uvec4(color) - (uvec4(aux1) + uvec4(" << i
1436                << ")));\n";
1437         }
1438         for (int i = c; i < numDrawBuffers; ++i)
1439         {
1440             fs << "out" << i << " = uvec4(aux1) + uvec4(" << i << ");\n";
1441         }
1442         fs << "}";
1443         mProgram.compile(fs.str().c_str());
1444 
1445         glViewport(0, 0, W, H);
1446 
1447         GLFramebuffer fbo;
1448         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1449         std::vector<PLSTestTexture> localTexs;
1450         localTexs.reserve(numPLSPlanes);
1451         for (int i = 0; i < numPLSPlanes; ++i)
1452         {
1453             localTexs.emplace_back(GL_RGBA8UI);
1454             glFramebufferTexturePixelLocalStorageANGLE(i, localTexs[i], 0, 0);
1455         }
1456         std::vector<PLSTestTexture> renderTexs;
1457         renderTexs.reserve(numDrawBuffers);
1458         std::vector<GLenum> drawBuffers(numDrawBuffers);
1459         for (int i = 0; i < numDrawBuffers; ++i)
1460         {
1461             renderTexs.emplace_back(GL_RGBA32UI);
1462             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
1463                                    renderTexs[i], 0);
1464             drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
1465         }
1466         glDrawBuffers(drawBuffers.size(), drawBuffers.data());
1467 
1468         glBeginPixelLocalStorageANGLE(
1469             numPLSPlanes, std::vector<GLenum>(numPLSPlanes, GL_LOAD_OP_ZERO_ANGLE).data());
1470         mProgram.drawBoxes({{FULLSCREEN, {255, 254, 253, 252}, {0, 1, 2, 3}}});
1471         glEndPixelLocalStorageANGLE(
1472             numPLSPlanes, std::vector<GLenum>(numPLSPlanes, GL_STORE_OP_STORE_ANGLE).data());
1473 
1474         for (int i = 0; i < numPLSPlanes; ++i)
1475         {
1476             attachTexture2DToScratchFBO(localTexs[i]);
1477             EXPECT_PIXEL_RECT32UI_EQ(
1478                 0, 0, W, H,
1479                 GLColor32UI(255u - i - 0u, 254u - i - 1u, 253u - i - 2u, 252u - i - 3u));
1480         }
1481         for (int i = 0; i < numDrawBuffers; ++i)
1482         {
1483             attachTexture2DToScratchFBO(renderTexs[i]);
1484             EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0u + i, 1u + i, 2u + i, 3u + i));
1485         }
1486 
1487         ASSERT_GL_NO_ERROR();
1488     }
1489 }
1490 
1491 // Verifies that program caching works for programs that use pixel local storage.
TEST_P(PixelLocalStorageTest,ProgramCache)1492 TEST_P(PixelLocalStorageTest, ProgramCache)
1493 {
1494     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1495 
1496     GLFramebuffer fbo;
1497     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1498     PLSTestTexture pls0(GL_RGBA8UI, 1, 1);
1499     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
1500     PLSTestTexture pls1(GL_RGBA8UI, 1, 1);
1501     glFramebufferTexturePixelLocalStorageANGLE(1, pls1, 0, 0);
1502     PLSTestTexture pls3(GL_RGBA8UI, 1, 1);
1503     glFramebufferTexturePixelLocalStorageANGLE(2, pls3, 0, 0);
1504     glDrawBuffers(0, nullptr);
1505     glViewport(0, 0, 1, 1);
1506 
1507     // Compile the same program multiple times and verify it works each time.
1508     for (int j = 0; j < 10; ++j)
1509     {
1510         mProgram.compile(R"(
1511         layout(binding=0, rgba8ui) uniform highp upixelLocalANGLE pls0;
1512         layout(binding=1, rgba8ui) uniform highp upixelLocalANGLE pls1;
1513         layout(binding=2, rgba8ui) uniform highp upixelLocalANGLE pls3;
1514         void main()
1515         {
1516             pixelLocalStoreANGLE(pls0, uvec4(color) - uvec4(aux1));
1517             pixelLocalStoreANGLE(pls1, uvec4(color) - uvec4(aux2));
1518             pixelLocalStoreANGLE(pls3, uvec4(color) - uvec4(aux1) - uvec4(aux2));
1519         })");
1520         glUniform1f(mProgram.widthUniform(), 1);
1521         glUniform1f(mProgram.heightUniform(), 1);
1522 
1523         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1524         glBeginPixelLocalStorageANGLE(
1525             3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
1526         mProgram.drawBoxes({{FULLSCREEN, {255, 254, 253, 252}, {0, 1, 2, 3}, {4, 5, 6, 7}}});
1527         glEndPixelLocalStorageANGLE(
1528             3, GLenumArray(
1529                    {GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
1530 
1531         attachTexture2DToScratchFBO(pls0);
1532         EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1,
1533                                  GLColor32UI(255u - 0u, 254u - 1u, 253u - 2u, 252u - 3u));
1534 
1535         attachTexture2DToScratchFBO(pls1);
1536         EXPECT_PIXEL_RECT32UI_EQ(0, 0, 1, 1,
1537                                  GLColor32UI(255u - 4u, 254u - 5u, 253u - 6u, 252u - 7u));
1538 
1539         attachTexture2DToScratchFBO(pls3);
1540         EXPECT_PIXEL_RECT32UI_EQ(
1541             0, 0, 1, 1,
1542             GLColor32UI(255u - 0u - 4u, 254u - 1u - 5u, 253u - 2u - 6u, 252u - 3u - 7u));
1543 
1544         ASSERT_GL_NO_ERROR();
1545     }
1546 }
1547 
1548 // Check that pls is preserved when a shader does not call pixelLocalStoreANGLE(). (Whether that's
1549 // because a conditional branch failed or because the shader didn't write to it at all.)
1550 //
1551 //   * The framebuffer fetch implementation needs to make sure every active plane's output variable
1552 //     gets written during every invocation, or else its value will become undefined.
1553 //
1554 //   * The native pixel local storage implementation needs to declare a variable for every active
1555 //     plane, even if it is unused in a particular shader invocation.
1556 //
1557 // Also check that a pixelLocalLoadANGLE() of an r32f texture returns (r, 0, 0, 1).
TEST_P(PixelLocalStorageTest,LoadOnly)1558 TEST_P(PixelLocalStorageTest, LoadOnly)
1559 {
1560     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1561 
1562     PLSTestTexture tex(GL_RGBA8);
1563 
1564     GLFramebuffer fbo;
1565     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1566     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32F);
1567     glFramebufferTexturePixelLocalStorageANGLE(1, tex, 0, 0);
1568     glViewport(0, 0, W, H);
1569     glDrawBuffers(0, nullptr);
1570 
1571     // Pass 1: draw to memoryless conditionally.
1572     PLSProgram pass1;
1573     pass1.compile(R"(
1574     layout(binding=0, r32f) uniform highp pixelLocalANGLE memoryless;
1575     layout(binding=1, rgba8) uniform highp pixelLocalANGLE tex;
1576     void main()
1577     {
1578         // Omit braces on the 'if' to ensure proper insertion of memoryBarriers in the translator.
1579         if (gl_FragCoord.x < 64.0)
1580             pixelLocalStoreANGLE(memoryless, vec4(1, -.1, .2, -.3));  // Only stores r.
1581     })");
1582 
1583     // Pass 2: draw to tex conditionally.
1584     // Don't touch memoryless -- make sure it gets preserved!
1585     PLSProgram pass2;
1586     pass2.compile(R"(
1587     layout(binding=0, r32f) uniform highp pixelLocalANGLE memoryless;
1588     layout(binding=1, rgba8) uniform highp pixelLocalANGLE tex;
1589     void main()
1590     {
1591         // Omit braces on the 'if' to ensure proper insertion of memoryBarriers in the translator.
1592         if (gl_FragCoord.y < 64.0)
1593             pixelLocalStoreANGLE(tex, vec4(0, 1, 1, 0));
1594     })");
1595 
1596     // Pass 3: combine memoryless and tex.
1597     PLSProgram pass3;
1598     pass3.compile(R"(
1599     layout(binding=0, r32f) uniform highp pixelLocalANGLE memoryless;
1600     layout(binding=1, rgba8) uniform highp pixelLocalANGLE tex;
1601     void main()
1602     {
1603         pixelLocalStoreANGLE(tex, pixelLocalLoadANGLE(tex) + pixelLocalLoadANGLE(memoryless));
1604     })");
1605 
1606     // Leave unit 0 with the default clear value of zero.
1607     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(0, 0, 0, 0));
1608     glFramebufferPixelLocalClearValuefvANGLE(1, ClearF(0, 1, 0, 0));
1609     glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
1610 
1611     pass1.bind();
1612     pass1.drawBoxes({{FULLSCREEN}});
1613 
1614     pass2.bind();
1615     pass2.drawBoxes({{FULLSCREEN}});
1616 
1617     pass3.bind();
1618     pass3.drawBoxes({{FULLSCREEN}});
1619 
1620     glEndPixelLocalStorageANGLE(2, GLenumArray({GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE}));
1621 
1622     attachTexture2DToScratchFBO(tex);
1623     EXPECT_PIXEL_RECT_EQ(0, 0, 64, 64, GLColor(255, 255, 255, 255));
1624     EXPECT_PIXEL_RECT_EQ(64, 0, W - 64, 64, GLColor(0, 255, 255, 255));
1625     EXPECT_PIXEL_RECT_EQ(0, 64, 64, H - 64, GLColor(255, 255, 0, 255));
1626     EXPECT_PIXEL_RECT_EQ(64, 64, W - 64, H - 64, GLColor(0, 255, 0, 255));
1627 
1628     ASSERT_GL_NO_ERROR();
1629 
1630     // Now treat "tex" as entirely readonly for an entire local storage render pass.
1631     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1632     PLSTestTexture tex2(GL_RGBA8);
1633 
1634     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
1635     {
1636         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
1637         glDrawBuffers(1, GLenumArray({GL_COLOR_ATTACHMENT0}));
1638         glClear(GL_COLOR_BUFFER_BIT);
1639 
1640         mProgram.compile(R"(
1641         layout(binding=0, r32f) uniform highp pixelLocalANGLE memoryless;
1642         layout(binding=1, rgba8) uniform highp pixelLocalANGLE tex;
1643         out vec4 fragcolor;
1644         void main()
1645         {
1646             fragcolor = 1.0 - pixelLocalLoadANGLE(tex);
1647         })");
1648 
1649         glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_DONT_CARE, GL_LOAD_OP_LOAD_ANGLE}));
1650     }
1651     else
1652     {
1653         glFramebufferTexturePixelLocalStorageANGLE(2, tex2, 0, 0);
1654 
1655         mProgram.compile(R"(
1656         layout(binding=0, r32f) uniform highp pixelLocalANGLE memoryless;
1657         layout(binding=1, rgba8) uniform highp pixelLocalANGLE tex;
1658         layout(binding=2, rgba8) uniform highp pixelLocalANGLE fragcolor;
1659         void main()
1660         {
1661             pixelLocalStoreANGLE(fragcolor, 1.0 - pixelLocalLoadANGLE(tex));
1662         })");
1663 
1664         glBeginPixelLocalStorageANGLE(
1665             3, GLenumArray({GL_DONT_CARE, GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
1666     }
1667 
1668     mProgram.drawBoxes({{FULLSCREEN}});
1669 
1670     int n;
1671     glGetIntegerv(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, &n);
1672     glEndPixelLocalStorageANGLE(
1673         n, GLenumArray({GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
1674 
1675     // Ensure "tex" was properly read in the shader.
1676     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE == 0)
1677     {
1678         attachTexture2DToScratchFBO(tex2);
1679     }
1680     EXPECT_PIXEL_RECT_EQ(0, 0, 64, 64, GLColor(0, 0, 0, 0));
1681     EXPECT_PIXEL_RECT_EQ(64, 0, W - 64, 64, GLColor(255, 0, 0, 0));
1682     EXPECT_PIXEL_RECT_EQ(0, 64, 64, H - 64, GLColor(0, 0, 255, 0));
1683     EXPECT_PIXEL_RECT_EQ(64, 64, W - 64, H - 64, GLColor(255, 0, 255, 0));
1684 
1685     // Ensure "tex" was preserved after the shader.
1686     attachTexture2DToScratchFBO(tex);
1687     EXPECT_PIXEL_RECT_EQ(0, 0, 64, 64, GLColor(255, 255, 255, 255));
1688     EXPECT_PIXEL_RECT_EQ(64, 0, W - 64, 64, GLColor(0, 255, 255, 255));
1689     EXPECT_PIXEL_RECT_EQ(0, 64, 64, H - 64, GLColor(255, 255, 0, 255));
1690     EXPECT_PIXEL_RECT_EQ(64, 64, W - 64, H - 64, GLColor(0, 255, 0, 255));
1691 
1692     ASSERT_GL_NO_ERROR();
1693 }
1694 
1695 // Check that stores and loads in a single shader invocation are coherent.
TEST_P(PixelLocalStorageTest,LoadAfterStore)1696 TEST_P(PixelLocalStorageTest, LoadAfterStore)
1697 {
1698     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1699 
1700     // Run a fibonacci loop that stores and loads the same PLS multiple times.
1701     mProgram.compile(R"(
1702     layout(binding=0, rgba8ui) uniform highp upixelLocalANGLE fibonacci;
1703     void main()
1704     {
1705         pixelLocalStoreANGLE(fibonacci, uvec4(1, 0, 0, 0));  // fib(1, 0, 0, 0)
1706         for (int i = 0; i < 3; ++i)
1707         {
1708             uvec4 fib0 = pixelLocalLoadANGLE(fibonacci);
1709             uvec4 fib1;
1710             fib1.w = fib0.x + fib0.y;
1711             fib1.z = fib1.w + fib0.x;
1712             fib1.y = fib1.z + fib1.w;
1713             fib1.x = fib1.y + fib1.z;  // fib(i*4 + (5, 4, 3, 2))
1714             pixelLocalStoreANGLE(fibonacci, fib1);
1715         }
1716         // fib is at indices (13, 12, 11, 10)
1717     })");
1718 
1719     PLSTestTexture tex(GL_RGBA8UI);
1720 
1721     GLFramebuffer fbo;
1722     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1723     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
1724     glViewport(0, 0, W, H);
1725     glDrawBuffers(0, nullptr);
1726 
1727     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
1728     mProgram.drawBoxes({{FULLSCREEN}});
1729     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
1730 
1731     attachTexture2DToScratchFBO(tex);
1732     EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(233, 144, 89, 55));  // fib(13, 12, 11, 10)
1733 
1734     ASSERT_GL_NO_ERROR();
1735 
1736     // Now verify that r32f and r32ui still reload as (r, 0, 0, 1), even after an in-shader store.
1737     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
1738     {
1739         mProgram.compile(R"(
1740         layout(binding=0, r32f) uniform highp pixelLocalANGLE pls32f;
1741         layout(binding=1, r32ui) uniform highp upixelLocalANGLE pls32ui;
1742 
1743         out vec4 fragcolor;
1744         void main()
1745         {
1746             pixelLocalStoreANGLE(pls32f, vec4(1, .5, .5, .5));
1747             pixelLocalStoreANGLE(pls32ui, uvec4(1, 1, 1, 0));
1748             if ((int(floor(gl_FragCoord.x)) & 1) == 0)
1749                 fragcolor = pixelLocalLoadANGLE(pls32f);
1750             else
1751                 fragcolor = vec4(pixelLocalLoadANGLE(pls32ui));
1752         })");
1753 
1754         tex.reset(GL_RGBA8);
1755         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1756         glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32F);
1757         glFramebufferMemorylessPixelLocalStorageANGLE(1, GL_R32UI);
1758         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1759         glDrawBuffers(1, GLenumArray({GL_COLOR_ATTACHMENT0}));
1760 
1761         glBeginPixelLocalStorageANGLE(2,
1762                                       GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
1763     }
1764     else
1765     {
1766         mProgram.compile(R"(
1767         layout(binding=0, r32f) uniform highp pixelLocalANGLE pls32f;
1768         layout(binding=1, r32ui) uniform highp upixelLocalANGLE pls32ui;
1769         layout(binding=2, rgba8) uniform highp pixelLocalANGLE fragcolor;
1770         void main()
1771         {
1772             pixelLocalStoreANGLE(pls32f, vec4(1, .5, .5, .5));
1773             pixelLocalStoreANGLE(pls32ui, uvec4(1, 1, 1, 0));
1774             if ((int(floor(gl_FragCoord.x)) & 1) == 0)
1775                 pixelLocalStoreANGLE(fragcolor, pixelLocalLoadANGLE(pls32f));
1776             else
1777                 pixelLocalStoreANGLE(fragcolor, vec4(pixelLocalLoadANGLE(pls32ui)));
1778         })");
1779 
1780         tex.reset(GL_RGBA8);
1781         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1782         glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32F);
1783         glFramebufferMemorylessPixelLocalStorageANGLE(1, GL_R32UI);
1784         glFramebufferTexturePixelLocalStorageANGLE(2, tex, 0, 0);
1785 
1786         glBeginPixelLocalStorageANGLE(
1787             3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_DONT_CARE}));
1788     }
1789 
1790     mProgram.drawBoxes({{FULLSCREEN}});
1791 
1792     int n;
1793     glGetIntegerv(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, &n);
1794     glEndPixelLocalStorageANGLE(n,
1795                                 GLenumArray({GL_DONT_CARE, GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE}));
1796 
1797     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE == 0)
1798     {
1799         attachTexture2DToScratchFBO(tex);
1800     }
1801     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor(255, 0, 0, 255));
1802     ASSERT_GL_NO_ERROR();
1803 }
1804 
1805 // Check that PLS handles can be passed as function arguments.
TEST_P(PixelLocalStorageTest,FunctionArguments)1806 TEST_P(PixelLocalStorageTest, FunctionArguments)
1807 {
1808     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1809 
1810     mProgram.compile(R"(
1811     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE dst;
1812     layout(binding=1, rgba8) uniform mediump pixelLocalANGLE src1;
1813     void store2(lowp pixelLocalANGLE d);
1814     void store(highp pixelLocalANGLE d, lowp pixelLocalANGLE s)
1815     {
1816         pixelLocalStoreANGLE(d, pixelLocalLoadANGLE(s));
1817     }
1818     void main()
1819     {
1820         if (gl_FragCoord.x < 25.0)
1821             store(dst, src1);
1822         else
1823             store2(dst);
1824     }
1825     // Ensure inlining still works on a uniform declared after main().
1826     layout(binding=2, r32f) uniform highp pixelLocalANGLE src2;
1827     void store2(lowp pixelLocalANGLE d)
1828     {
1829         pixelLocalStoreANGLE(d, pixelLocalLoadANGLE(src2));
1830     })");
1831 
1832     PLSTestTexture dst(GL_RGBA8);
1833 
1834     GLFramebuffer fbo;
1835     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1836     glFramebufferTexturePixelLocalStorageANGLE(0, dst, 0, 0);
1837     glFramebufferMemorylessPixelLocalStorageANGLE(1, GL_RGBA8);
1838     glFramebufferMemorylessPixelLocalStorageANGLE(2, GL_R32F);
1839 
1840     glViewport(0, 0, W, H);
1841     glDrawBuffers(0, nullptr);
1842 
1843     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(1, 1, 1, 1));  // ignored
1844     glFramebufferPixelLocalClearValuefvANGLE(1, ClearF(0, 1, 1, 0));
1845     glFramebufferPixelLocalClearValuefvANGLE(2, ClearF(1, 0, 0, 1));
1846     glBeginPixelLocalStorageANGLE(
1847         3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_CLEAR_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
1848     mProgram.drawBoxes({{FULLSCREEN}});
1849     glEndPixelLocalStorageANGLE(3,
1850                                 GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_DONT_CARE, GL_DONT_CARE}));
1851 
1852     attachTexture2DToScratchFBO(dst);
1853     EXPECT_PIXEL_RECT_EQ(0, 0, 25, H, GLColor(0, 255, 255, 0));
1854     EXPECT_PIXEL_RECT_EQ(25, 0, W - 25, H, GLColor(255, 0, 0, 255));
1855 
1856     ASSERT_GL_NO_ERROR();
1857 }
1858 
1859 // Check that if the "_coherent" extension is advertised, PLS operations are ordered and coherent.
TEST_P(PixelLocalStorageTest,Coherency)1860 TEST_P(PixelLocalStorageTest, Coherency)
1861 {
1862     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1863 
1864     mProgram.compile(R"(
1865     layout(binding=0, rgba8ui) uniform lowp upixelLocalANGLE framebuffer;
1866     layout(binding=1, rgba8) uniform lowp pixelLocalANGLE tmp;
1867     // The application shouldn't be able to override internal synchronization functions used by
1868     // the compiler.
1869     //
1870     // If the compiler accidentally calls any of these functions, stomp out the framebuffer to make
1871     // the test fail.
1872     void endInvocationInterlockNV() { pixelLocalStoreANGLE(framebuffer, uvec4(0)); }
1873     void beginFragmentShaderOrderingINTEL() { pixelLocalStoreANGLE(framebuffer, uvec4(0)); }
1874     void beginInvocationInterlockARB() { pixelLocalStoreANGLE(framebuffer, uvec4(0)); }
1875 
1876     // Give these functions a side effect so they don't get pruned, then call them from main().
1877     void beginInvocationInterlockNV() { pixelLocalStoreANGLE(tmp, vec4(0)); }
1878     void endInvocationInterlockARB() { pixelLocalStoreANGLE(tmp, vec4(0)); }
1879 
1880     void main()
1881     {
1882         highp uvec4 d = pixelLocalLoadANGLE(framebuffer) >> 1;
1883         pixelLocalStoreANGLE(framebuffer, uvec4(color) + d);
1884         beginInvocationInterlockNV();
1885         endInvocationInterlockARB();
1886     })");
1887 
1888     PLSTestTexture tex(GL_RGBA8UI);
1889 
1890     GLFramebuffer fbo;
1891     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1892     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
1893     glFramebufferMemorylessPixelLocalStorageANGLE(1, GL_RGBA8);
1894     glViewport(0, 0, W, H);
1895     glDrawBuffers(0, nullptr);
1896 
1897     std::vector<uint8_t> expected(H * W * 4);
1898     memset(expected.data(), 0, H * W * 4);
1899 
1900     // This test times out on Swiftshader and noncoherent backends if we draw anywhere near the
1901     // same number of boxes as we do on coherent, hardware backends.
1902     int boxesPerList = !IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent") ||
1903                                strstr((const char *)glGetString(GL_RENDERER), "SwiftShader")
1904                            ? 200
1905                            : H * W * 3;
1906 
1907     // Prepare a ton of random sized boxes in various draws.
1908     std::vector<Box> boxesList[5];
1909     srand(17);
1910     uint32_t boxID = 1;
1911     for (auto &boxes : boxesList)
1912     {
1913         for (int i = 0; i < boxesPerList; ++i)
1914         {
1915             // Define a box.
1916             int w     = rand() % 10 + 1;
1917             int h     = rand() % 10 + 1;
1918             float x   = rand() % (W - w);
1919             float y   = rand() % (H - h);
1920             uint8_t r = boxID & 0x7f;
1921             uint8_t g = (boxID >> 7) & 0x7f;
1922             uint8_t b = (boxID >> 14) & 0x7f;
1923             uint8_t a = (boxID >> 21) & 0x7f;
1924             ++boxID;
1925             // Update expectations.
1926             for (int yy = y; yy < y + h; ++yy)
1927             {
1928                 for (int xx = x; xx < x + w; ++xx)
1929                 {
1930                     int p           = (yy * W + xx) * 4;
1931                     expected[p]     = r + (expected[p] >> 1);
1932                     expected[p + 1] = g + (expected[p + 1] >> 1);
1933                     expected[p + 2] = b + (expected[p + 2] >> 1);
1934                     expected[p + 3] = a + (expected[p + 3] >> 1);
1935                 }
1936             }
1937             // Set up the gpu draw.
1938             float x0 = x;
1939             float x1 = x + w;
1940             float y0 = y;
1941             float y1 = y + h;
1942             // Allow boxes to have negative widths and heights. This adds randomness by making the
1943             // diagonals go in different directions.
1944             if (rand() & 1)
1945                 std::swap(x0, x1);
1946             if (rand() & 1)
1947                 std::swap(y0, y1);
1948             boxes.push_back({{x0, y0, x1, y1}, {(float)r, (float)g, (float)b, (float)a}});
1949         }
1950     }
1951 
1952     glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
1953     for (const std::vector<Box> &boxes : boxesList)
1954     {
1955         mProgram.drawBoxes(boxes);
1956     }
1957     glEndPixelLocalStorageANGLE(2, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_DONT_CARE}));
1958 
1959     attachTexture2DToScratchFBO(tex);
1960     std::vector<uint8_t> actual(H * W * 4);
1961     glReadPixels(0, 0, W, H, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, actual.data());
1962     EXPECT_EQ(expected, actual);
1963 
1964     ASSERT_GL_NO_ERROR();
1965 }
1966 
1967 // Check that binding mipmap levels to PLS is supported.
TEST_P(PixelLocalStorageTest,MipMapLevels)1968 TEST_P(PixelLocalStorageTest, MipMapLevels)
1969 {
1970     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
1971 
1972     mProgram.compile(R"(
1973         layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;
1974         void main()
1975         {
1976             pixelLocalStoreANGLE(pls, color + pixelLocalLoadANGLE(pls));
1977         })");
1978 
1979     constexpr int LEVELS = 3;
1980     int levelWidth = 179, levelHeight = 313;
1981     std::vector<GLColor> redData(levelHeight * levelWidth, GLColor::black);
1982     GLuint tex;
1983     glGenTextures(1, &tex);
1984     glBindTexture(GL_TEXTURE_2D, tex);
1985     glTexStorage2D(GL_TEXTURE_2D, LEVELS, GL_RGBA8, levelWidth, levelHeight);
1986 
1987     GLFramebuffer fbo;
1988     for (int level = 0; level < LEVELS; ++level)
1989     {
1990         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1991 
1992         glUniform1f(mProgram.widthUniform(), levelWidth);
1993         glUniform1f(mProgram.heightUniform(), levelHeight);
1994         glViewport(0, 0, levelWidth, levelHeight);
1995         glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelWidth, levelHeight, GL_RGBA,
1996                         GL_UNSIGNED_BYTE, redData.data());
1997 
1998         glFramebufferTexturePixelLocalStorageANGLE(0, tex, level, 0);
1999         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_LOAD_ANGLE}));
2000         mProgram.drawBoxes({{{0, 0, (float)levelWidth - 3, (float)levelHeight}, {0, 0, 1, 0}},
2001                             {{0, 0, (float)levelWidth - 2, (float)levelHeight}, {0, 1, 0, 0}},
2002                             {{0, 0, (float)levelWidth - 1, (float)levelHeight}, {1, 0, 0, 0}}});
2003         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
2004         attachTexture2DToScratchFBO(tex, level);
2005         EXPECT_PIXEL_RECT_EQ(0, 0, levelWidth - 3, levelHeight, GLColor::white);
2006         EXPECT_PIXEL_RECT_EQ(levelWidth - 3, 0, 1, levelHeight, GLColor::yellow);
2007         EXPECT_PIXEL_RECT_EQ(levelWidth - 2, 0, 1, levelHeight, GLColor::red);
2008         EXPECT_PIXEL_RECT_EQ(levelWidth - 1, 0, 1, levelHeight, GLColor::black);
2009 
2010         levelWidth >>= 1;
2011         levelHeight >>= 1;
2012         ASSERT_GL_NO_ERROR();
2013     }
2014 
2015     // Delete fbo.
2016     // Don't delete tex -- exercise pixel local storage in a way that it has to clean itself up when
2017     // the context is torn down. (It has internal assertions that validate it is torn down
2018     // correctly.)
2019 }
2020 
2021 // Check that all supported texture types work at various levels and layers.
TEST_P(PixelLocalStorageTest,TextureLevelsAndLayers)2022 TEST_P(PixelLocalStorageTest, TextureLevelsAndLayers)
2023 {
2024     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2025 
2026     mProgram.compile(R"(
2027         layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;
2028         void main()
2029         {
2030             pixelLocalStoreANGLE(pls, vec4(0, 1, 0, 0) + pixelLocalLoadANGLE(pls));
2031         })");
2032 
2033     std::array<float, 4> HALFSCREEN = {0, 0, W / 2.f, H};
2034 
2035     int D = 5;
2036     std::vector<GLColor> redImg(H * W * D, GLColor::red);
2037 
2038     // GL_TEXTURE_2D
2039     {
2040         // Level 2.
2041         GLTexture tex;
2042         glBindTexture(GL_TEXTURE_2D, tex);
2043         glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, W * 4, H * 4);
2044         glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, W, H, GL_RGBA, GL_UNSIGNED_BYTE, redImg.data());
2045         GLFramebuffer fbo;
2046         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2047         glFramebufferTexturePixelLocalStorageANGLE(0, tex, 2, 0);
2048         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_LOAD_ANGLE}));
2049         mProgram.drawBoxes({{HALFSCREEN}});
2050         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
2051         attachTexture2DToScratchFBO(tex, 2);
2052         EXPECT_PIXEL_RECT_EQ(0, 0, W / 2.f, H, GLColor::yellow);
2053         EXPECT_PIXEL_RECT_EQ(W / 2.f, 0, W / 2.f, H, GLColor::red);
2054         ASSERT_GL_NO_ERROR();
2055     }
2056 
2057     // GL_TEXTURE_2D_ARRAY
2058     {
2059         // Level 1, layer 0.
2060         GLTexture tex;
2061         glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
2062         glTexStorage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, W * 2, H * 2, D);
2063         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, W, H, D, GL_RGBA, GL_UNSIGNED_BYTE,
2064                         redImg.data());
2065         GLFramebuffer fbo;
2066         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2067         glFramebufferTexturePixelLocalStorageANGLE(0, tex, 1, 0);
2068         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_LOAD_ANGLE}));
2069         mProgram.drawBoxes({{HALFSCREEN}});
2070         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
2071         attachTextureLayerToScratchFBO(tex, 1, 0);
2072         EXPECT_PIXEL_RECT_EQ(0, 0, W / 2.f, H, GLColor::yellow);
2073         EXPECT_PIXEL_RECT_EQ(W / 2.f, 0, W / 2.f, H, GLColor::red);
2074         ASSERT_GL_NO_ERROR();
2075 
2076         // Level 1, layer D - 1.
2077         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2078         glFramebufferTexturePixelLocalStorageANGLE(0, tex, 1, D - 1);
2079         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_LOAD_ANGLE}));
2080         mProgram.drawBoxes({{HALFSCREEN}});
2081         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
2082         attachTextureLayerToScratchFBO(tex, 1, D - 1);
2083         EXPECT_PIXEL_RECT_EQ(0, 0, W / 2.f, H, GLColor::yellow);
2084         EXPECT_PIXEL_RECT_EQ(W / 2.f, 0, W / 2.f, H, GLColor::red);
2085         ASSERT_GL_NO_ERROR();
2086     }
2087 }
2088 
doStateRestorationTest()2089 void PixelLocalStorageTest::doStateRestorationTest()
2090 {
2091     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2092 
2093     // Setup state.
2094     PLSTestTexture plsTex(GL_RGBA8UI, 32, 33);
2095     GLFramebuffer fbo;
2096     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2097 
2098     glViewport(1, 1, 5, 5);
2099     glScissor(2, 2, 4, 4);
2100     glEnable(GL_SCISSOR_TEST);
2101 
2102     bool hasDrawBuffersIndexedOES = IsGLExtensionEnabled("GL_OES_draw_buffers_indexed");
2103     if (hasDrawBuffersIndexedOES)
2104     {
2105         for (int i = 0; i < MAX_DRAW_BUFFERS; ++i)
2106         {
2107             if (i % 2 == 1)
2108             {
2109                 glEnableiOES(GL_BLEND, i);
2110             }
2111             glColorMaskiOES(i, i % 3 == 0, i % 3 == 1, i % 3 == 2, i % 2 == 0);
2112         }
2113     }
2114     else
2115     {
2116         glEnable(GL_BLEND);
2117         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
2118     }
2119 
2120     std::vector<GLenum> drawBuffers(MAX_DRAW_BUFFERS);
2121     for (int i = 0; i < MAX_DRAW_BUFFERS; ++i)
2122     {
2123         drawBuffers[i] = i % 3 == 0 ? GL_NONE : GL_COLOR_ATTACHMENT0 + i;
2124     }
2125     glDrawBuffers(MAX_DRAW_BUFFERS, drawBuffers.data());
2126 
2127     GLenum imageAccesses[] = {GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE};
2128     GLenum imageFormats[]  = {GL_RGBA8, GL_R32UI, GL_R32I, GL_R32F};
2129     std::vector<GLTexture> images;
2130     if (isContextVersionAtLeast(3, 1))
2131     {
2132         for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
2133         {
2134             GLuint tex = images.emplace_back();
2135             glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
2136             glTexStorage3D(GL_TEXTURE_2D_ARRAY, 3, GL_RGBA8, 8, 8, 5);
2137             GLboolean layered = i % 2;
2138             glBindImageTexture(i, images.back(), i % 3, layered, layered == GL_FALSE ? i % 5 : 0,
2139                                imageAccesses[i % 3], imageFormats[i % 4]);
2140         }
2141 
2142         glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 17);
2143         glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
2144     }
2145 
2146     PLSTestTexture boundTex(GL_RGBA8, 1, 1);
2147     glBindTexture(GL_TEXTURE_2D, boundTex);
2148 
2149     // Run pixel local storage.
2150     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA8);
2151     glFramebufferTexturePixelLocalStorageANGLE(1, plsTex, 0, 0);
2152     glFramebufferMemorylessPixelLocalStorageANGLE(2, GL_RGBA8);
2153     glFramebufferMemorylessPixelLocalStorageANGLE(3, GL_RGBA8);
2154     glFramebufferPixelLocalClearValuefvANGLE(2, ClearF(.1, .2, .3, .4));
2155     glBeginPixelLocalStorageANGLE(4, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_LOAD_ANGLE,
2156                                                   GL_LOAD_OP_CLEAR_ANGLE, GL_DONT_CARE}));
2157     glPixelLocalStorageBarrierANGLE();
2158     glEndPixelLocalStorageANGLE(
2159         4, GLenumArray({GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE, GL_DONT_CARE, GL_DONT_CARE}));
2160     int firstOverriddenDrawBuffer =
2161         std::min(MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE,
2162                  MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - 4);
2163 
2164     // Check state.
2165     GLint textureBinding2D;
2166     glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding2D);
2167     EXPECT_EQ(static_cast<GLuint>(textureBinding2D), boundTex);
2168 
2169     if (isContextVersionAtLeast(3, 1))
2170     {
2171         for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
2172         {
2173             GLint name, level, layer, access, format;
2174             GLboolean layered;
2175             glGetIntegeri_v(GL_IMAGE_BINDING_NAME, i, &name);
2176             glGetIntegeri_v(GL_IMAGE_BINDING_LEVEL, i, &level);
2177             glGetBooleani_v(GL_IMAGE_BINDING_LAYERED, i, &layered);
2178             glGetIntegeri_v(GL_IMAGE_BINDING_LAYER, i, &layer);
2179             glGetIntegeri_v(GL_IMAGE_BINDING_ACCESS, i, &access);
2180             glGetIntegeri_v(GL_IMAGE_BINDING_FORMAT, i, &format);
2181             EXPECT_EQ(static_cast<GLuint>(name), images[i]);
2182             EXPECT_EQ(level, i % 3);
2183             EXPECT_EQ(layered, i % 2);
2184             EXPECT_EQ(layer, layered == GL_FALSE ? i % 5 : 0);
2185             EXPECT_EQ(static_cast<GLuint>(access), imageAccesses[i % 3]);
2186             EXPECT_EQ(static_cast<GLuint>(format), imageFormats[i % 4]);
2187         }
2188 
2189         GLint defaultWidth, defaultHeight;
2190         glGetFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH,
2191                                     &defaultWidth);
2192         glGetFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT,
2193                                     &defaultHeight);
2194         EXPECT_EQ(defaultWidth, 17);
2195         EXPECT_EQ(defaultHeight, 1);
2196     }
2197 
2198     for (int i = 0; i < MAX_COLOR_ATTACHMENTS; ++i)
2199     {
2200         GLint attachmentType;
2201         glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
2202                                               GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
2203                                               &attachmentType);
2204         EXPECT_EQ(attachmentType, GL_NONE);
2205     }
2206 
2207     for (int i = 0; i < MAX_DRAW_BUFFERS; ++i)
2208     {
2209         GLint drawBuffer;
2210         glGetIntegerv(GL_DRAW_BUFFER0 + i, &drawBuffer);
2211         if (i % 3 == 0)
2212         {
2213             EXPECT_EQ(drawBuffer, GL_NONE);
2214         }
2215         else
2216         {
2217             EXPECT_EQ(drawBuffer, GL_COLOR_ATTACHMENT0 + i);
2218         }
2219     }
2220 
2221     if (hasDrawBuffersIndexedOES)
2222     {
2223         for (int i = 0; i < firstOverriddenDrawBuffer; ++i)
2224         {
2225             EXPECT_EQ(glIsEnablediOES(GL_BLEND, i), i % 2 == 1);
2226             EXPECT_GL_COLOR_MASK_INDEXED(i, i % 3 == 0, i % 3 == 1, i % 3 == 2, i % 2 == 0);
2227         }
2228         for (int i = firstOverriddenDrawBuffer; i < MAX_DRAW_BUFFERS; ++i)
2229         {
2230             EXPECT_FALSE(glIsEnablediOES(GL_BLEND, i));
2231             EXPECT_GL_COLOR_MASK_INDEXED(i, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2232         }
2233     }
2234     else
2235     {
2236         EXPECT_FALSE(glIsEnabled(GL_BLEND));
2237         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
2238     }
2239 
2240     EXPECT_TRUE(glIsEnabled(GL_SCISSOR_TEST));
2241 
2242     std::array<GLint, 4> scissorBox;
2243     glGetIntegerv(GL_SCISSOR_BOX, scissorBox.data());
2244     EXPECT_EQ(scissorBox, (std::array<GLint, 4>{2, 2, 4, 4}));
2245 
2246     std::array<GLint, 4> viewport;
2247     glGetIntegerv(GL_VIEWPORT, viewport.data());
2248     EXPECT_EQ(viewport, (std::array<GLint, 4>{1, 1, 5, 5}));
2249 
2250     GLint drawFramebuffer;
2251     glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFramebuffer);
2252     EXPECT_EQ(static_cast<GLuint>(drawFramebuffer), fbo);
2253 
2254     ASSERT_GL_NO_ERROR();
2255 }
2256 
2257 // Check that application-facing ES3 state is not perturbed by pixel local storage.
TEST_P(PixelLocalStorageTest,StateRestoration)2258 TEST_P(PixelLocalStorageTest, StateRestoration)
2259 {
2260     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2261 
2262     doStateRestorationTest();
2263 }
2264 
doDrawStateTest()2265 void PixelLocalStorageTest::doDrawStateTest()
2266 {
2267     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2268 
2269     glEnable(GL_BLEND);
2270     glBlendFunc(GL_ZERO, GL_ONE);
2271 
2272     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
2273 
2274     glEnable(GL_CULL_FACE);
2275     glCullFace(GL_FRONT_AND_BACK);
2276 
2277     glEnable(GL_DEPTH_TEST);
2278     glDepthFunc(GL_NEVER);
2279 
2280     glEnable(GL_POLYGON_OFFSET_FILL);
2281     glPolygonOffset(1e9f, 1e9f);
2282 
2283     glEnable(GL_SCISSOR_TEST);
2284     glScissor(0, 0, 1, 1);
2285 
2286     glEnable(GL_STENCIL_TEST);
2287     glStencilFunc(GL_NEVER, 0, 0);
2288 
2289     if (isContextVersionAtLeast(3, 1))
2290     {
2291         glEnable(GL_SAMPLE_MASK);
2292         glSampleMaski(0, 0);
2293     }
2294 
2295     glViewport(0, 0, 1, 1);
2296 
2297     glClearColor(.1f, .2f, .3f, .4f);
2298 
2299     // Issue a draw to ensure GL state gets synced.
2300     PLSTestTexture tex(GL_RGBA8);
2301     renderTextureToDefaultFramebuffer(tex);
2302 
2303     GLFramebuffer fbo;
2304     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2305 
2306     GLuint depthStencil;
2307     glGenRenderbuffers(1, &depthStencil);
2308     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2309     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
2310     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2311                               depthStencil);
2312 
2313     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
2314 
2315     mProgram.compile(R"(
2316         layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;
2317         void main()
2318         {
2319             pixelLocalStoreANGLE(pls, vec4(1, 0, 0, 1));
2320         })");
2321 
2322     // Clear to green. This should work regardless of draw state.
2323     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(0, 1, 0, 1));
2324     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
2325 
2326     // Draw a red box. This should not go through because the blocking draw state should have been
2327     // restored after the clear.
2328     mProgram.drawBoxes({{FULLSCREEN}});
2329 
2330     // Store PLS to the texture. This should work again even though the blocking draw state was
2331     // synced for the previous draw.
2332     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
2333 
2334     attachTexture2DToScratchFBO(tex);
2335     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor(0, 255, 0, 255));
2336 
2337     ASSERT_GL_NO_ERROR();
2338 }
2339 
2340 #define SETUP_IMPLICIT_DISABLES_TEST(framebufferTarget)                                        \
2341     GLFramebuffer fbo, readFBO;                                                                \
2342     glBindFramebuffer(framebufferTarget, fbo);                                                 \
2343                                                                                                \
2344     PLSTestTexture tex0(GL_RGBA8);                                                             \
2345     PLSTestTexture tex1(GL_RGBA8);                                                             \
2346     PLSTestTexture tex2(GL_RGBA8);                                                             \
2347     PLSTestTexture tex3(GL_RGBA8);                                                             \
2348     glFramebufferTexturePixelLocalStorageANGLE(0, tex0, 0, 0);                                 \
2349     glFramebufferTexturePixelLocalStorageANGLE(1, tex1, 0, 0);                                 \
2350     glFramebufferTexturePixelLocalStorageANGLE(2, tex2, 0, 0);                                 \
2351     glFramebufferTexturePixelLocalStorageANGLE(3, tex3, 0, 0);                                 \
2352     GLenum loadOps[4]  = {GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, \
2353                           GL_LOAD_OP_ZERO_ANGLE};                                              \
2354     GLenum storeOps[4] = {GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, GL_DONT_CARE,      \
2355                           GL_DONT_CARE};                                                       \
2356                                                                                                \
2357     glDrawBuffers(0, nullptr);                                                                 \
2358                                                                                                \
2359     EXPECT_GL_NO_ERROR()
2360 
2361 #define CHECK_PLS_ENABLED() \
2362     EXPECT_GL_NO_ERROR();   \
2363     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 4)
2364 
2365 #define CHECK_PLS_DISABLED() \
2366     EXPECT_GL_NO_ERROR();    \
2367     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0)
2368 
2369 #define BEGIN_PLS()                            \
2370     glBeginPixelLocalStorageANGLE(4, loadOps); \
2371     CHECK_PLS_ENABLED()
2372 
2373 #define CHECK_ENDS_PLS(cmd) \
2374     BEGIN_PLS();            \
2375     cmd;                    \
2376     CHECK_PLS_DISABLED()
2377 
2378 #define CHECK_DOES_NOT_END_PLS(cmd)           \
2379     BEGIN_PLS();                              \
2380     cmd;                                      \
2381     CHECK_PLS_ENABLED();                      \
2382     glEndPixelLocalStorageANGLE(4, storeOps); \
2383     CHECK_PLS_DISABLED()
2384 
2385 #define CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(cmd)    \
2386     BEGIN_PLS();                                     \
2387     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO); \
2388     cmd;                                             \
2389     CHECK_PLS_ENABLED();                             \
2390     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);     \
2391     CHECK_PLS_ENABLED();                             \
2392     glEndPixelLocalStorageANGLE(4, storeOps);        \
2393     CHECK_PLS_DISABLED()
2394 
doImplicitDisablesTest_Framebuffer()2395 void PixelLocalStorageTest::doImplicitDisablesTest_Framebuffer()
2396 {
2397     SETUP_IMPLICIT_DISABLES_TEST(GL_DRAW_FRAMEBUFFER);
2398 
2399     // Binding a READ_FRAMEBUFFER does not end PLS.
2400     CHECK_DOES_NOT_END_PLS(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
2401     EXPECT_GL_INTEGER(GL_READ_FRAMEBUFFER_BINDING, 0);
2402     EXPECT_GL_INTEGER(GL_DRAW_FRAMEBUFFER_BINDING, fbo);
2403     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2404     // Binding the same framebuffer still ends PLS.
2405     CHECK_ENDS_PLS(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo));
2406     EXPECT_GL_INTEGER(GL_DRAW_FRAMEBUFFER_BINDING, fbo);
2407     EXPECT_GL_INTEGER(GL_READ_FRAMEBUFFER_BINDING, fbo);
2408     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2409     CHECK_ENDS_PLS(glBindFramebuffer(GL_FRAMEBUFFER, fbo));
2410     EXPECT_GL_INTEGER(GL_DRAW_FRAMEBUFFER_BINDING, fbo);
2411     EXPECT_GL_INTEGER(GL_READ_FRAMEBUFFER_BINDING, fbo);
2412     CHECK_ENDS_PLS(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
2413     EXPECT_GL_INTEGER(GL_DRAW_FRAMEBUFFER_BINDING, 0);
2414     EXPECT_GL_INTEGER(GL_READ_FRAMEBUFFER_BINDING, fbo);
2415     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2416     CHECK_ENDS_PLS(glBindFramebuffer(GL_FRAMEBUFFER, 0));
2417     EXPECT_GL_INTEGER(GL_DRAW_FRAMEBUFFER_BINDING, 0);
2418     EXPECT_GL_INTEGER(GL_READ_FRAMEBUFFER_BINDING, 0);
2419     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2420 
2421     CHECK_ENDS_PLS(glFramebufferMemorylessPixelLocalStorageANGLE(3, GL_RGBA8));
2422     GLuint tex3ID = tex3;
2423     CHECK_DOES_NOT_END_PLS(glDeleteTextures(1, &tex3ID));
2424 
2425     CHECK_ENDS_PLS(glDrawBuffers(1, GLenumArray({GL_COLOR_ATTACHMENT0})));
2426     glDrawBuffers(0, nullptr);
2427 
2428     CHECK_ENDS_PLS(glDrawBuffers(0, nullptr));
2429 
2430     if (EnsureGLExtensionEnabled("GL_MESA_framebuffer_flip_y"))
2431     {
2432         CHECK_ENDS_PLS(
2433             glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_TRUE));
2434         EXPECT_FRAMEBUFFER_PARAMETER_INT_MESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_TRUE);
2435         glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_FALSE);
2436         CHECK_ENDS_PLS(
2437             glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_TRUE));
2438         EXPECT_FRAMEBUFFER_PARAMETER_INT_MESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
2439                                               GL_TRUE);
2440         glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_FALSE);
2441         CHECK_ENDS_PLS(
2442             glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_TRUE));
2443         EXPECT_FRAMEBUFFER_PARAMETER_INT_MESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
2444                                               GL_TRUE);
2445         glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_FALSE);
2446         CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(
2447             glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, GL_TRUE));
2448     }
2449 
2450     if (isContextVersionAtLeast(3, 1))
2451     {
2452         CHECK_ENDS_PLS(glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 23));
2453         EXPECT_FRAMEBUFFER_PARAMETER_INT(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 23);
2454         glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
2455         CHECK_ENDS_PLS(
2456             glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 24));
2457         EXPECT_FRAMEBUFFER_PARAMETER_INT(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 24);
2458         glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
2459         CHECK_ENDS_PLS(
2460             glFramebufferParameteri(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 25));
2461         EXPECT_FRAMEBUFFER_PARAMETER_INT(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 25);
2462         glFramebufferParameteri(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
2463         CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(
2464             glFramebufferParameteri(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 23));
2465     }
2466 
2467     glFramebufferMemorylessPixelLocalStorageANGLE(2, GL_RGBA8);
2468     CHECK_ENDS_PLS(glFramebufferTexturePixelLocalStorageANGLE(2, tex2, 0, 0););
2469     EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex2);
2470 
2471     GLuint tex2ID = tex2;
2472     CHECK_ENDS_PLS(glDeleteTextures(1, &tex2ID));
2473     EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
2474     glFramebufferMemorylessPixelLocalStorageANGLE(2, GL_RGBA8);
2475 
2476     GLuint fboID = fbo;
2477     CHECK_ENDS_PLS(glDeleteFramebuffers(1, &fboID));
2478 }
2479 
doImplicitDisablesTest_TextureAttachments()2480 void PixelLocalStorageTest::doImplicitDisablesTest_TextureAttachments()
2481 {
2482     SETUP_IMPLICIT_DISABLES_TEST(GL_FRAMEBUFFER);
2483 
2484     GLTexture tex2D;
2485     glBindTexture(GL_TEXTURE_2D, tex2D);
2486     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2487     CHECK_ENDS_PLS(
2488         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0));
2489     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D);
2490     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2491     CHECK_ENDS_PLS(
2492         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0));
2493     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D);
2494     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2495     CHECK_ENDS_PLS(
2496         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0));
2497     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D);
2498     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2499     CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(
2500         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0));
2501 
2502     GLTexture tex2DArray;
2503     glBindTexture(GL_TEXTURE_2D_ARRAY, tex2DArray);
2504     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, W, H, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2505     CHECK_ENDS_PLS(
2506         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0));
2507     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray);
2508     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2509     CHECK_ENDS_PLS(
2510         glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0));
2511     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray);
2512     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2513     CHECK_ENDS_PLS(
2514         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0));
2515     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray);
2516     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2517     CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(
2518         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0));
2519 
2520     GLTexture tex3d;
2521     glBindTexture(GL_TEXTURE_3D, tex3d);
2522     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, W, H, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2523     CHECK_ENDS_PLS(glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d, 0, 0));
2524     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d);
2525     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2526     CHECK_ENDS_PLS(
2527         glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d, 0, 0));
2528     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d);
2529     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2530     CHECK_ENDS_PLS(
2531         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d, 0, 0));
2532     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d);
2533     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2534     CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(
2535         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d, 0, 0));
2536 
2537     if (EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"))
2538     {
2539         PLSTestTexture texMSAA(GL_RGBA8);
2540         CHECK_ENDS_PLS(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2541                                                             GL_TEXTURE_2D, texMSAA, 0, 4));
2542         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texMSAA);
2543         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2544         CHECK_ENDS_PLS(glFramebufferTexture2DMultisampleEXT(
2545             GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texMSAA, 0, 4));
2546         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texMSAA);
2547         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2548         CHECK_ENDS_PLS(glFramebufferTexture2DMultisampleEXT(
2549             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texMSAA, 0, 4));
2550         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texMSAA);
2551         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2552         CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(glFramebufferTexture2DMultisampleEXT(
2553             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texMSAA, 0, 4));
2554         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2555         ASSERT_GL_NO_ERROR();
2556     }
2557 
2558     if (EnsureGLExtensionEnabled("GL_OVR_multiview2"))
2559     {
2560         CHECK_ENDS_PLS(glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2561                                                         tex2DArray, 0, 0, 1));
2562         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray);
2563         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2564         CHECK_ENDS_PLS(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2565                                                         tex2DArray, 0, 0, 1));
2566         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray);
2567         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2568         CHECK_ENDS_PLS(glFramebufferTextureMultiviewOVR(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2569                                                         tex2DArray, 0, 0, 1));
2570         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray);
2571         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2572         CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(glFramebufferTextureMultiviewOVR(
2573             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0, 1));
2574         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2575     }
2576 
2577     if (EnsureGLExtensionEnabled("GL_OES_texture_3D"))
2578     {
2579         CHECK_ENDS_PLS(glFramebufferTexture3DOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2580                                                  GL_TEXTURE_3D, tex3d, 0, 0));
2581         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d);
2582         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2583         CHECK_ENDS_PLS(glFramebufferTexture3DOES(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2584                                                  GL_TEXTURE_3D, tex3d, 0, 0));
2585         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d);
2586         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2587         CHECK_ENDS_PLS(glFramebufferTexture3DOES(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2588                                                  GL_TEXTURE_3D, tex3d, 0, 0));
2589         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3d);
2590         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
2591         CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(glFramebufferTexture3DOES(
2592             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, tex3d, 0, 0));
2593     }
2594 }
2595 
doImplicitDisablesTest_RenderbufferAttachments()2596 void PixelLocalStorageTest::doImplicitDisablesTest_RenderbufferAttachments()
2597 {
2598     SETUP_IMPLICIT_DISABLES_TEST(GL_FRAMEBUFFER);
2599 
2600     GLuint colorBuffer;
2601     glGenRenderbuffers(1, &colorBuffer);
2602     glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
2603     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W, H);
2604     CHECK_ENDS_PLS(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2605                                              colorBuffer));
2606     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorBuffer);
2607     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
2608     CHECK_ENDS_PLS(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2609                                              GL_RENDERBUFFER, colorBuffer));
2610     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorBuffer);
2611     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
2612     CHECK_ENDS_PLS(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2613                                              GL_RENDERBUFFER, colorBuffer));
2614     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorBuffer);
2615     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
2616     CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(glFramebufferRenderbuffer(
2617         GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer));
2618 
2619     GLuint depthStencilBuffer;
2620     glGenRenderbuffers(1, &depthStencilBuffer);
2621     glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
2622     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
2623     CHECK_ENDS_PLS(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2624                                              GL_RENDERBUFFER, depthStencilBuffer));
2625     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2626                                        depthStencilBuffer);
2627     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
2628     CHECK_ENDS_PLS(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2629                                              GL_RENDERBUFFER, depthStencilBuffer));
2630     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2631                                        depthStencilBuffer);
2632     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
2633     CHECK_ENDS_PLS(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2634                                              GL_RENDERBUFFER, depthStencilBuffer));
2635     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2636                                        depthStencilBuffer);
2637     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
2638     CHECK_DOES_NOT_END_PLS_WITH_READ_FBO(glFramebufferRenderbuffer(
2639         GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilBuffer));
2640 }
2641 
2642 #undef CHECK_DOES_NOT_END_PLS_WITH_READ_FBO
2643 #undef CHECK_DOES_NOT_END_PLS
2644 #undef BEGIN_PLS
2645 #undef CHECK_PLS_DISABLED
2646 #undef CHECK_PLS_ENABLED
2647 #undef CHECK_ENDS_PLS
2648 
2649 // Check that draw state does not affect PLS loads and stores, particularly for
2650 // EXT_shader_pixel_local_storage, where they are implemented as fullscreen draws.
TEST_P(PixelLocalStorageTest,DrawStateReset)2651 TEST_P(PixelLocalStorageTest, DrawStateReset)
2652 {
2653     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2654 
2655     doDrawStateTest();
2656 }
2657 
2658 // Check that blend & color mask state and glClearBuffers{u,i,ui}v do not affect
2659 // pixel local storage, and that PLS does not affect blend or color mask on the
2660 // application's draw buffers.
TEST_P(PixelLocalStorageTest,BlendColorMaskAndClear)2661 TEST_P(PixelLocalStorageTest, BlendColorMaskAndClear)
2662 {
2663     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2664 
2665     PLSTestTexture tex1(GL_RGBA8);
2666     PLSTestTexture tex2(GL_RGBA8);
2667     PLSTestTexture tex3(GL_RGBA8);
2668     PLSTestTexture tex4(GL_RGBA8);
2669 
2670     GLFramebuffer fbo;
2671     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2672     glViewport(0, 0, W, H);
2673 
2674     const bool drawBuffersIndexed = IsGLExtensionEnabled("GL_OES_draw_buffers_indexed") &&
2675                                     MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE >= 2;
2676     GLint firstClearBuffer             = 0;
2677     GLint firstPLSOverriddenDrawBuffer = 0;
2678     if (!drawBuffersIndexed)
2679     {
2680         // Blend should not affect pixel local storage.
2681         glBlendFunc(GL_ZERO, GL_ZERO);
2682         // Color mask should not affect pixel local storage.
2683         glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
2684 
2685         mProgram.compile(R"(
2686         layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls1;
2687         layout(binding=1, rgba8) uniform lowp pixelLocalANGLE pls2;
2688         layout(binding=2, rgba8) uniform lowp pixelLocalANGLE pls3;
2689         layout(binding=3, rgba8) uniform lowp pixelLocalANGLE pls4;
2690         void main()
2691         {
2692             pixelLocalStoreANGLE(pls1, vec4(1, 0, 0, 1));
2693             pixelLocalStoreANGLE(pls2, vec4(0, 1, 0, 1));
2694             pixelLocalStoreANGLE(pls3, vec4(0, 0, 1, 1));
2695             pixelLocalStoreANGLE(pls4, vec4(0, 0, 0, 1));
2696         })");
2697 
2698         glFramebufferTexturePixelLocalStorageANGLE(0, tex1, 0, 0);
2699         glFramebufferTexturePixelLocalStorageANGLE(1, tex2, 0, 0);
2700         glFramebufferTexturePixelLocalStorageANGLE(2, tex3, 0, 0);
2701         glFramebufferTexturePixelLocalStorageANGLE(3, tex4, 0, 0);
2702 
2703         glBeginPixelLocalStorageANGLE(
2704             4, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE,
2705                             GL_LOAD_OP_ZERO_ANGLE}));
2706 
2707         // Blend should not affect pixel local storage.
2708         EXPECT_FALSE(glIsEnabled(GL_BLEND));
2709         glEnable(GL_BLEND);
2710 
2711         // Enabling GL_BLEND is ignored while PLS is active.
2712         EXPECT_FALSE(glIsEnabled(GL_BLEND));
2713 
2714         // BlendFunc has no effect as long as GL_BLEND stays disabled on our PLS draw buffers.
2715         glBlendFunc(GL_ZERO, GL_ONE);
2716 
2717         EXPECT_GL_NO_ERROR();
2718 
2719         // Color is ignored when PLS is active.
2720         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2721         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
2722         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2723 
2724         EXPECT_GL_NO_ERROR();
2725 
2726         EXPECT_GL_NO_ERROR();
2727     }
2728     else
2729     {
2730         mProgram.compile(R"(
2731         layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls1;
2732         layout(binding=1, rgba8) uniform lowp pixelLocalANGLE pls2;
2733         layout(location=0) out lowp vec4 out1;
2734         layout(location=1) out lowp vec4 out2;
2735         void main()
2736         {
2737             out1 = vec4(0, 1, 1, 0);
2738             out2 = vec4(1, 1, 0, 0);
2739             pixelLocalStoreANGLE(pls1, vec4(0, 0, 1, 1));
2740             pixelLocalStoreANGLE(pls2, vec4(0, 0, 0, 1));
2741         })");
2742 
2743         std::vector<GLColor> whiteData(H * W, GLColor::white);
2744         glBindTexture(GL_TEXTURE_2D, tex1);
2745         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, W, H, GL_RGBA, GL_UNSIGNED_BYTE, whiteData.data());
2746 
2747         // Blend should not affect pixel local storage.
2748         glEnablei(GL_BLEND, 0);
2749         glBlendEquationi(0, GL_FUNC_REVERSE_SUBTRACT);
2750         glBlendFunci(0, GL_ONE, GL_ONE);
2751 
2752         std::vector<GLColor> blackData(H * W, GLColor::black);
2753         glBindTexture(GL_TEXTURE_2D, tex2);
2754         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, W, H, GL_RGBA, GL_UNSIGNED_BYTE, blackData.data());
2755 
2756         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
2757         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex2, 0);
2758         glFramebufferTexturePixelLocalStorageANGLE(0, tex3, 0, 0);
2759         glFramebufferTexturePixelLocalStorageANGLE(1, tex4, 0, 0);
2760         glDrawBuffers(2, GLenumArray({GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}));
2761         firstClearBuffer = 2;
2762         firstPLSOverriddenDrawBuffer =
2763             std::min(MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE,
2764                      MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - 2);
2765 
2766         glBeginPixelLocalStorageANGLE(2,
2767                                       GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
2768 
2769         // Color mask should not affect pixel local storage.
2770         glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
2771         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
2772         EXPECT_GL_COLOR_MASK_INDEXED(1, GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
2773 
2774         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
2775         EXPECT_FALSE(glIsEnabledi(GL_BLEND, 1));
2776         for (int i = 2; i < MAX_DRAW_BUFFERS; ++i)
2777         {
2778             // Blend cannot be enabled on an overridden PLS plane.
2779             EXPECT_FALSE(glIsEnabledi(GL_BLEND, i));
2780             glEnablei(GL_BLEND, i);
2781             glBlendFunci(i, GL_ZERO, GL_ONE);
2782             if (i >= firstPLSOverriddenDrawBuffer)
2783             {
2784                 EXPECT_FALSE(glIsEnabledi(GL_BLEND, i));
2785             }
2786             else
2787             {
2788                 EXPECT_TRUE(glIsEnabledi(GL_BLEND, i));
2789             }
2790 
2791             // Color mask cannot be enabled on an overridden PLS plane.
2792             if (i >= firstPLSOverriddenDrawBuffer)
2793             {
2794                 EXPECT_GL_COLOR_MASK_INDEXED(i, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2795             }
2796             else
2797             {
2798                 EXPECT_GL_COLOR_MASK_INDEXED(i, GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
2799             }
2800             glColorMaski(i, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
2801             if (i >= firstPLSOverriddenDrawBuffer)
2802             {
2803                 EXPECT_GL_COLOR_MASK_INDEXED(i, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2804             }
2805             else
2806             {
2807                 EXPECT_GL_COLOR_MASK_INDEXED(i, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
2808             }
2809         }
2810 
2811         ASSERT_GL_NO_ERROR();
2812     }
2813 
2814     mProgram.drawBoxes({{FULLSCREEN}});
2815 
2816     // glClearBuffer{f,i,ui}v are ignored for reserved PLS draw buffers when PLS is active.
2817     for (GLint i = firstClearBuffer; i < MAX_DRAW_BUFFERS; ++i)
2818     {
2819         constexpr static GLfloat zerof[4] = {0, 0, 0, 0};
2820         constexpr static GLint zeroi[4]   = {0, 0, 0, 0};
2821         constexpr static GLuint zeroui[4] = {0, 0, 0, 0};
2822         glClearBufferfv(GL_COLOR, i, zerof);
2823         glClearBufferiv(GL_COLOR, i, zeroi);
2824         glClearBufferuiv(GL_COLOR, i, zeroui);
2825         ASSERT_GL_NO_ERROR();
2826     }
2827 
2828     int n;
2829     glGetIntegerv(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, &n);
2830     glEndPixelLocalStorageANGLE(n, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE,
2831                                                 GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
2832 
2833     attachTexture2DToScratchFBO(tex1);
2834     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::red);
2835 
2836     attachTexture2DToScratchFBO(tex2);
2837     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::green);
2838 
2839     attachTexture2DToScratchFBO(tex3);
2840     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::blue);
2841 
2842     attachTexture2DToScratchFBO(tex4);
2843     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::black);
2844 
2845     // Blend state attempted to be set on overridden draw buffers during PLS should not have taken
2846     // effect afterward.
2847     if (!drawBuffersIndexed)
2848     {
2849         EXPECT_FALSE(glIsEnabled(GL_BLEND));
2850         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2851     }
2852     else
2853     {
2854         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
2855         EXPECT_FALSE(glIsEnabledi(GL_BLEND, 1));
2856         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
2857         EXPECT_GL_COLOR_MASK_INDEXED(1, GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
2858         for (GLint i = 2; i < MAX_DRAW_BUFFERS; ++i)
2859         {
2860             if (i >= firstPLSOverriddenDrawBuffer)
2861             {
2862                 EXPECT_FALSE(glIsEnabledi(GL_BLEND, i));
2863             }
2864             else
2865             {
2866                 EXPECT_TRUE(glIsEnabledi(GL_BLEND, i));
2867             }
2868             if (i >= firstPLSOverriddenDrawBuffer)
2869             {
2870                 EXPECT_GL_COLOR_MASK_INDEXED(i, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2871             }
2872             else
2873             {
2874                 EXPECT_GL_COLOR_MASK_INDEXED(i, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
2875             }
2876         }
2877     }
2878 
2879     // Now ensure that clears *do* occur on non-PLS draw buffers.
2880     if (firstClearBuffer != 0)
2881     {
2882         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2883         glBeginPixelLocalStorageANGLE(
2884             n, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_LOAD_ANGLE,
2885                             GL_LOAD_OP_LOAD_ANGLE}));
2886 
2887         constexpr static GLfloat one[4] = {1, 1, 1, 1};
2888         glColorMaski(0, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
2889         glClearBufferfv(GL_COLOR, 0, one);
2890 
2891         glColorMaski(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
2892         glClearBufferfv(GL_COLOR, 1, one);
2893 
2894         ASSERT_GL_NO_ERROR();
2895 
2896         glEndPixelLocalStorageANGLE(
2897             n, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE,
2898                             GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
2899 
2900         attachTexture2DToScratchFBO(tex1);
2901         EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::magenta);
2902 
2903         attachTexture2DToScratchFBO(tex2);
2904         EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::yellow);
2905     }
2906 
2907     ASSERT_GL_NO_ERROR();
2908 }
2909 
2910 // Check that changing framebuffer state implicitly disable pixel local storage.
TEST_P(PixelLocalStorageTest,ImplicitDisables_Framebuffer)2911 TEST_P(PixelLocalStorageTest, ImplicitDisables_Framebuffer)
2912 {
2913     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2914 
2915     doImplicitDisablesTest_Framebuffer();
2916 }
2917 
2918 // Check that changing framebuffer texture attachments implicitly disable pixel
2919 // local storage.
TEST_P(PixelLocalStorageTest,ImplicitDisables_TextureAttachments)2920 TEST_P(PixelLocalStorageTest, ImplicitDisables_TextureAttachments)
2921 {
2922     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2923 
2924     doImplicitDisablesTest_TextureAttachments();
2925 }
2926 
2927 // Check that changing framebuffer renderbuffer attachments implicitly disable
2928 // pixel local storage.
TEST_P(PixelLocalStorageTest,ImplicitDisables_RenderbufferAttachments)2929 TEST_P(PixelLocalStorageTest, ImplicitDisables_RenderbufferAttachments)
2930 {
2931     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2932 
2933     doImplicitDisablesTest_RenderbufferAttachments();
2934 }
2935 
2936 // Check that PLS and EXT_shader_framebuffer_fetch can be used together.
TEST_P(PixelLocalStorageTest,ParallelFramebufferFetch)2937 TEST_P(PixelLocalStorageTest, ParallelFramebufferFetch)
2938 {
2939     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2940     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2941     ANGLE_SKIP_TEST_IF(MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE == 0);
2942 
2943     mProgram.compile("#extension GL_EXT_shader_framebuffer_fetch : require", R"(
2944     layout(binding=0, rgba8) uniform mediump pixelLocalANGLE pls;
2945     inout highp vec4 fbfetch;
2946     void main()
2947     {
2948         // Swap pls and fbfetch.
2949         vec4 tmp = pixelLocalLoadANGLE(pls);
2950         pixelLocalStoreANGLE(pls, fbfetch);
2951         fbfetch = tmp;
2952     })");
2953 
2954     PLSTestTexture pls(GL_RGBA8), fbfetch(GL_RGBA8);
2955 
2956     GLFramebuffer fbo;
2957     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2958     glFramebufferTexturePixelLocalStorageANGLE(0, pls, 0, 0);
2959     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbfetch, 0);
2960 
2961     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(0, 1, 0, 1));
2962     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
2963 
2964     GLfloat red[] = {1, 0, 0, 1};
2965     glClearBufferfv(GL_COLOR, 0, red);
2966 
2967     // Swap pls and fbfetch.
2968     mProgram.drawBoxes({{FULLSCREEN}});
2969 
2970     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
2971 
2972     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::green);
2973 
2974     attachTexture2DToScratchFBO(pls);
2975     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::red);
2976 }
2977 
2978 // Check that PLS gets properly cleaned up when its framebuffer and textures are never deleted.
TEST_P(PixelLocalStorageTest,LeakFramebufferAndTexture)2979 TEST_P(PixelLocalStorageTest, LeakFramebufferAndTexture)
2980 {
2981     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
2982 
2983     GLuint fbo;
2984     glGenFramebuffers(1, &fbo);
2985     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2986 
2987     GLuint tex0;
2988     glGenTextures(1, &tex0);
2989     glBindTexture(GL_TEXTURE_2D, tex0);
2990     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8UI, 10, 10);
2991     glFramebufferTexturePixelLocalStorageANGLE(0, tex0, 0, 0);
2992 
2993     PLSTestTexture tex1(GL_R32F);
2994     glFramebufferTexturePixelLocalStorageANGLE(1, tex1, 0, 0);
2995 
2996     glFramebufferMemorylessPixelLocalStorageANGLE(3, GL_RGBA8I);
2997 
2998     // Delete tex1.
2999     // Don't delete tex0.
3000     // Don't delete fbo.
3001 
3002     // The PixelLocalStorage frontend implementation has internal assertions that verify all its GL
3003     // context objects are properly disposed of.
3004 }
3005 
3006 // Check that sampler, texture, and PLS bindings all work when they are used in the same shader.
TEST_P(PixelLocalStorageTest,PLSWithSamplers)3007 TEST_P(PixelLocalStorageTest, PLSWithSamplers)
3008 {
3009     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3010 
3011     GLFramebuffer fbo;
3012     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3013 
3014     PLSTestTexture tex0(GL_RGBA8);
3015     std::vector<GLColor> redData(H * H, GLColor::red);
3016     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, W, H, GL_RGBA, GL_UNSIGNED_BYTE, redData.data());
3017 
3018     PLSTestTexture tex1(GL_RGBA8);
3019     std::vector<GLColor> blueData(H * H, GLColor::blue);
3020     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, W, H, GL_RGBA, GL_UNSIGNED_BYTE, blueData.data());
3021 
3022     PLSTestTexture pls0(GL_RGBA8);
3023     std::vector<GLColor> greenData(H * H, GLColor::green);
3024     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, W, H, GL_RGBA, GL_UNSIGNED_BYTE, greenData.data());
3025 
3026     PLSTestTexture pls1(GL_RGBA8);
3027     PLSTestTexture pls2(GL_RGBA8);
3028 
3029     glViewport(0, 0, W, H);
3030 
3031     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
3032     glFramebufferTexturePixelLocalStorageANGLE(1, pls1, 0, 0);
3033     glFramebufferTexturePixelLocalStorageANGLE(2, pls2, 0, 0);
3034 
3035     mProgram.compile(R"(
3036     layout(binding=0, rgba8) uniform mediump pixelLocalANGLE pls0;
3037     layout(binding=1, rgba8) uniform mediump pixelLocalANGLE pls1;
3038     layout(binding=2, rgba8) uniform mediump pixelLocalANGLE pls2;
3039     uniform mediump sampler2D tex0;
3040     uniform mediump sampler2D tex1;
3041     void main()
3042     {
3043         vec4 value;
3044         if (gl_FragCoord.y > 50.0)
3045         {
3046             if (gl_FragCoord.x > 50.0)
3047                 value = texture(tex1, color.xy);
3048             else
3049                 value = texture(tex0, color.xy);
3050         }
3051         else
3052         {
3053             if (gl_FragCoord.x > 50.0)
3054                 value = pixelLocalLoadANGLE(pls1);
3055             else
3056                 value = pixelLocalLoadANGLE(pls0);
3057         }
3058         pixelLocalStoreANGLE(pls2, value);
3059         pixelLocalStoreANGLE(pls1, vec4(0, 1, 1, 1));
3060     })");
3061     glUniform1i(glGetUniformLocation(mProgram, "tex0"), 0);
3062     glUniform1i(glGetUniformLocation(mProgram, "tex1"), 3);
3063 
3064     glFramebufferPixelLocalClearValuefvANGLE(1, ClearF(1, 1, 0, 1));
3065     glBeginPixelLocalStorageANGLE(
3066         3, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_CLEAR_ANGLE, GL_DONT_CARE}));
3067 
3068     glBindTexture(GL_TEXTURE_2D, tex0);
3069 
3070     glActiveTexture(GL_TEXTURE3);
3071     glBindTexture(GL_TEXTURE_2D, tex1);
3072 
3073     mProgram.drawBoxes({{FULLSCREEN, {0, 0, 1, 1}}});
3074     glEndPixelLocalStorageANGLE(3, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE,
3075                                                 GL_STORE_OP_STORE_ANGLE}));
3076 
3077     attachTexture2DToScratchFBO(pls2);
3078     EXPECT_PIXEL_RECT_EQ(0, 0, 50, 50, GLColor::green);
3079     EXPECT_PIXEL_RECT_EQ(50, 0, W - 50, 50, GLColor::yellow);
3080     EXPECT_PIXEL_RECT_EQ(0, 50, 50, H - 50, GLColor::red);
3081     EXPECT_PIXEL_RECT_EQ(50, 50, W - 50, H - 50, GLColor::blue);
3082 
3083     attachTexture2DToScratchFBO(pls1);
3084     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::cyan);
3085 
3086     attachTexture2DToScratchFBO(pls0);
3087     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::green);
3088 
3089     ASSERT_GL_NO_ERROR();
3090 }
3091 
3092 // Check the PLS interruption mechanism.
TEST_P(PixelLocalStorageTest,Interrupt)3093 TEST_P(PixelLocalStorageTest, Interrupt)
3094 {
3095     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3096 
3097     PLSTestTexture t(GL_RGBA8);
3098     PLSTestTexture u0(GL_R32UI);
3099     PLSTestTexture u1(GL_R32UI);
3100     PLSTestTexture u2(GL_R32UI);
3101 
3102     GLFramebuffer f;
3103     glBindFramebuffer(GL_FRAMEBUFFER, f);
3104     glFramebufferTexturePixelLocalStorageANGLE(0, t, 0, 0);
3105 
3106     GLFramebuffer g;
3107     glBindFramebuffer(GL_FRAMEBUFFER, g);
3108     glFramebufferTexturePixelLocalStorageANGLE(0, u0, 0, 0);
3109     glFramebufferTexturePixelLocalStorageANGLE(1, u1, 0, 0);
3110     glFramebufferTexturePixelLocalStorageANGLE(2, u2, 0, 0);
3111 
3112     glViewport(0, 0, W, H);
3113     glDrawBuffers(0, nullptr);
3114 
3115     PLSProgram p;
3116     p.compile(R"(
3117     layout(binding=0, rgba8) uniform highp pixelLocalANGLE t;
3118     void main()
3119     {
3120         pixelLocalStoreANGLE(t, color + pixelLocalLoadANGLE(t));
3121     })");
3122 
3123     PLSProgram q;
3124     q.compile(R"(
3125     layout(binding=0, r32ui) uniform highp upixelLocalANGLE u0;
3126     layout(binding=1, r32ui) uniform highp upixelLocalANGLE u1;
3127     layout(binding=2, r32ui) uniform highp upixelLocalANGLE u2;
3128     void main()
3129     {
3130         pixelLocalStoreANGLE(u0, (pixelLocalLoadANGLE(u1) << 8) | 0xau);
3131         pixelLocalStoreANGLE(u1, (pixelLocalLoadANGLE(u2) << 8) | 0xbu);
3132         pixelLocalStoreANGLE(u2, (pixelLocalLoadANGLE(u0) << 8) | 0xcu);
3133     })");
3134 
3135     // Interleave 2 PLS rendering passes.
3136     glBindFramebuffer(GL_FRAMEBUFFER, f);
3137     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
3138     p.bind();
3139     p.drawBoxes({{{FULLSCREEN}, {1, 0, 0, 0}}});
3140     glFramebufferPixelLocalStorageInterruptANGLE();
3141 
3142     glBindFramebuffer(GL_FRAMEBUFFER, g);
3143     q.bind();
3144     glBeginPixelLocalStorageANGLE(
3145         3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
3146     q.drawBoxes({{{FULLSCREEN}}});
3147     glFramebufferPixelLocalStorageInterruptANGLE();
3148 
3149     p.bind();
3150     glBindFramebuffer(GL_FRAMEBUFFER, f);
3151     glFramebufferPixelLocalStorageRestoreANGLE();
3152     p.drawBoxes({{{FULLSCREEN}, {0, 0, 0, 1}}});
3153     glFramebufferPixelLocalStorageInterruptANGLE();
3154 
3155     glBindFramebuffer(GL_FRAMEBUFFER, g);
3156     glFramebufferPixelLocalStorageRestoreANGLE();
3157     q.bind();
3158     q.drawBoxes({{{FULLSCREEN}}});
3159     glFramebufferPixelLocalStorageInterruptANGLE();
3160 
3161     glBindFramebuffer(GL_FRAMEBUFFER, f);
3162     glFramebufferPixelLocalStorageRestoreANGLE();
3163     p.bind();
3164     p.drawBoxes({{{FULLSCREEN}, {0, 0, 1, 0}}});
3165     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
3166 
3167     q.bind();
3168     glBindFramebuffer(GL_FRAMEBUFFER, g);
3169     glFramebufferPixelLocalStorageRestoreANGLE();
3170     q.drawBoxes({{{FULLSCREEN}}});
3171     glEndPixelLocalStorageANGLE(3, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE,
3172                                                 GL_STORE_OP_STORE_ANGLE}));
3173 
3174     attachTexture2DToScratchFBO(t);
3175     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor(255, 0, 255, 255));
3176     ASSERT_GL_NO_ERROR();
3177 
3178     attachTexture2DToScratchFBO(u0);
3179     EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0x0a0c0b0a, 0, 0, 1));
3180 
3181     attachTexture2DToScratchFBO(u1);
3182     EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0x0b0a0c0b, 0, 0, 1));
3183 
3184     attachTexture2DToScratchFBO(u2);
3185     EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0x0c0b0a0c, 0, 0, 1));
3186 
3187     ASSERT_GL_NO_ERROR();
3188 }
3189 
3190 // Check that deleting attachments and PLS bindings on the current draw framebuffer implicitly
3191 // deactivates pixel local storage.
TEST_P(PixelLocalStorageTest,DeleteAttachments_draw_framebuffer)3192 TEST_P(PixelLocalStorageTest, DeleteAttachments_draw_framebuffer)
3193 {
3194     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3195 
3196     GLFramebuffer fbo;
3197     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3198 
3199     GLuint depthStencil;
3200     glGenRenderbuffers(1, &depthStencil);
3201     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
3202     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
3203     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3204                               depthStencil);
3205     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthStencil);
3206     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthStencil);
3207 
3208     PLSTestTexture colorTex(GL_RGBA8);
3209     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
3210     {
3211         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
3212         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTex);
3213     }
3214 
3215     GLuint colorRenderbuffer;
3216     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
3217     {
3218         glGenRenderbuffers(1, &colorRenderbuffer);
3219         glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
3220         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W, H);
3221         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
3222                                   colorRenderbuffer);
3223         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colorRenderbuffer);
3224     }
3225 
3226     PLSTestTexture pls0(GL_RGBA8);
3227     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
3228     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, pls0);
3229 
3230     PLSTestTexture pls1(GL_RGBA8);
3231     glFramebufferTexturePixelLocalStorageANGLE(1, pls1, 0, 0);
3232     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, pls1);
3233 
3234     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3235     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
3236     ASSERT_GL_NO_ERROR();
3237 
3238     // Deleting the depth/stencil will implicitly end pixel local storage.
3239     glDeleteRenderbuffers(1, &depthStencil);
3240     EXPECT_GL_NO_ERROR();
3241     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
3242     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0);
3243     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 0);
3244 
3245     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
3246     {
3247         // Deleting the color texture will implicitly end pixel local storage.
3248         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3249         colorTex.reset();
3250         EXPECT_GL_NO_ERROR();
3251         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
3252         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0);
3253     }
3254 
3255     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
3256     {
3257         // Deleting the color renderbuffer will implicitly end pixel local storage.
3258         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3259         glDeleteRenderbuffers(1, &colorRenderbuffer);
3260         EXPECT_GL_NO_ERROR();
3261         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
3262         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0);
3263     }
3264 
3265     // Pixel local storage can't be ended because it's already deactivated.
3266     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3267     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3268 
3269     // Deleting an inactive PLS plane will implicitly end pixel local storage.
3270     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3271     pls1.reset();
3272     EXPECT_GL_NO_ERROR();
3273     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
3274     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
3275 
3276     // Deleting an active PLS plane will implicitly end pixel local storage.
3277     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3278     pls0.reset();
3279     EXPECT_GL_NO_ERROR();
3280     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
3281     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
3282 
3283     // Deleting the textures deinitialized the planes.
3284     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3285     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3286     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
3287 }
3288 
3289 // Check that deleting attachments and PLS bindings on the current read framebuffer does *not*
3290 // deactivate pixel local storage.
TEST_P(PixelLocalStorageTest,DeleteAttachments_read_framebuffer)3291 TEST_P(PixelLocalStorageTest, DeleteAttachments_read_framebuffer)
3292 {
3293     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3294 
3295     // Deleting attachments on the read framebuffer does not turn off PLS.
3296     GLFramebuffer readFBO;
3297     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
3298 
3299     GLuint depthStencil;
3300     glGenRenderbuffers(1, &depthStencil);
3301     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
3302     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
3303     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3304                               depthStencil);
3305     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthStencil);
3306     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthStencil);
3307 
3308     PLSTestTexture colorTex(GL_RGBA8);
3309     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
3310     {
3311         colorTex.reset(GL_RGBA8);
3312         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex,
3313                                0);
3314         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTex);
3315     }
3316 
3317     GLuint colorRenderbuffer;
3318     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
3319     {
3320         glGenRenderbuffers(1, &colorRenderbuffer);
3321         glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
3322         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W, H);
3323         glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
3324                                   colorRenderbuffer);
3325         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
3326                                            colorRenderbuffer);
3327     }
3328 
3329     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFBO);
3330 
3331     PLSTestTexture inactivePLS0(GL_RGBA8);
3332     glFramebufferTexturePixelLocalStorageANGLE(0, inactivePLS0, 0, 0);
3333     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, inactivePLS0);
3334 
3335     PLSTestTexture inactivePLS1(GL_RGBA8);
3336     glFramebufferTexturePixelLocalStorageANGLE(1, inactivePLS1, 0, 0);
3337     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, inactivePLS1);
3338 
3339     GLFramebuffer fbo;
3340     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3341 
3342     PLSTestTexture activePLS(GL_RGBA8);
3343     glFramebufferTexturePixelLocalStorageANGLE(0, activePLS, 0, 0);
3344     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3345     EXPECT_GL_NO_ERROR();
3346     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
3347 
3348     glDeleteRenderbuffers(1, &depthStencil);
3349     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0);
3350     EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 0);
3351     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
3352     {
3353         colorTex.reset();
3354         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0);
3355     }
3356 
3357     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
3358     {
3359         glDeleteRenderbuffers(1, &colorRenderbuffer);
3360         EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0);
3361     }
3362     inactivePLS0.reset();
3363     inactivePLS1.reset();
3364 
3365     EXPECT_GL_NO_ERROR();
3366     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
3367 
3368     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
3369     EXPECT_GL_NO_ERROR();
3370 
3371     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFBO);
3372     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
3373     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
3374 }
3375 
3376 // Checks that draw commands validate current PLS state against the shader's PLS uniforms.
3377 class DrawCommandValidationTest
3378 {
3379   public:
DrawCommandValidationTest()3380     DrawCommandValidationTest()
3381     {
3382         mHasDebugKHR = EnsureGLExtensionEnabled("GL_KHR_debug");
3383         if (mHasDebugKHR)
3384         {
3385             glDebugMessageControlKHR(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
3386                                      GL_DEBUG_SEVERITY_HIGH, 0, NULL, GL_TRUE);
3387             glDebugMessageCallbackKHR(&ErrorMessageCallback, this);
3388             glEnable(GL_DEBUG_OUTPUT);
3389             glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
3390         }
3391     }
3392 
run()3393     void run()
3394     {
3395         PLSProgram p2;
3396         p2.compile(R"(
3397             layout(binding=0, rgba8) uniform lowp pixelLocalANGLE plane0;
3398             layout(binding=2, r32ui) uniform highp upixelLocalANGLE plane2;
3399             void main()
3400             {
3401                 pixelLocalStoreANGLE(plane0, vec4(pixelLocalLoadANGLE(plane2).r));
3402             })");
3403 
3404         PLSProgram p;
3405         p.compile(R"(
3406             layout(binding=0, rgba8) uniform lowp pixelLocalANGLE plane0;
3407             layout(binding=1, rgba8) uniform lowp pixelLocalANGLE plane1;
3408             layout(binding=2, r32ui) uniform highp upixelLocalANGLE plane2;
3409             void main()
3410             {
3411                 pixelLocalStoreANGLE(plane0, pixelLocalLoadANGLE(plane1) *
3412                                              vec4(pixelLocalLoadANGLE(plane2).r));
3413             })");
3414 
3415         ForAllDrawCalls([this]() {
3416             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that has a
3417             // pixel local uniform bound to an inactive pixel local storage plane.
3418             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3419             EXPECT_GL_SINGLE_ERROR_MSG(
3420                 "Draw program references pixel local storage plane(s) that are not currently "
3421                 "active.");
3422         });
3423 
3424         PLSTestTexture tex0(GL_RGBA8);
3425         PLSTestTexture tex1(GL_RGBA8);
3426         PLSTestTexture tex2(GL_R32UI);
3427         PLSTestTexture tex3(GL_R32UI);
3428 
3429         GLFramebuffer fbo;
3430         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3431         glFramebufferTexturePixelLocalStorageANGLE(0, tex0, 0, 0);
3432         glFramebufferTexturePixelLocalStorageANGLE(1, tex1, 0, 0);
3433         glFramebufferTexturePixelLocalStorageANGLE(2, tex2, 0, 0);
3434         glFramebufferTexturePixelLocalStorageANGLE(3, tex3, 0, 0);
3435         glViewport(0, 0, W, H);
3436         glDrawBuffers(0, nullptr);
3437 
3438         glBeginPixelLocalStorageANGLE(2,
3439                                       GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
3440         ASSERT_GL_NO_ERROR();
3441 
3442         ForAllDrawCalls([this]() {
3443             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that has a
3444             // pixel local uniform bound to an inactive pixel local storage plane.
3445             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3446             EXPECT_GL_SINGLE_ERROR_MSG(
3447                 "Draw program references pixel local storage plane(s) that are not currently "
3448                 "active.");
3449         });
3450 
3451         glEndPixelLocalStorageANGLE(
3452             2, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
3453 
3454         ASSERT_GL_NO_ERROR();
3455 
3456         glBeginPixelLocalStorageANGLE(
3457             4, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE,
3458                             GL_LOAD_OP_ZERO_ANGLE}));
3459         ASSERT_GL_NO_ERROR();
3460 
3461         ForAllDrawCalls([this]() {
3462             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that does
3463             // _not_ have a pixel local uniform bound to an _active_ pixel local storage plane
3464             // (i.e., the fragment shader must declare uniforms bound to every single active pixel
3465             // local storage plane).
3466             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3467             EXPECT_GL_SINGLE_ERROR_MSG(
3468                 "Active pixel local storage plane(s) are not referenced by the draw program.");
3469         });
3470 
3471         glEndPixelLocalStorageANGLE(
3472             4, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE,
3473                             GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
3474 
3475         ASSERT_GL_NO_ERROR();
3476 
3477         glBeginPixelLocalStorageANGLE(
3478             3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
3479         ASSERT_GL_NO_ERROR();
3480 
3481         p2.bind();
3482         ForAllDrawCalls([this]() {
3483             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that does
3484             // _not_ have a pixel local uniform bound to an _active_ pixel local storage plane
3485             // (i.e., the fragment shader must declare uniforms bound to every single active pixel
3486             // local storage plane).
3487             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3488             EXPECT_GL_SINGLE_ERROR_MSG(
3489                 "Active pixel local storage plane(s) are not referenced by the draw program.");
3490         });
3491         p.bind();
3492 
3493         glEndPixelLocalStorageANGLE(
3494             3, GLenumArray(
3495                    {GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
3496 
3497         PLSTestTexture texWrongFormat(GL_RGBA8I);
3498         glFramebufferTexturePixelLocalStorageANGLE(2, texWrongFormat, 0, 0);
3499 
3500         glBeginPixelLocalStorageANGLE(
3501             3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
3502         ASSERT_GL_NO_ERROR();
3503 
3504         ForAllDrawCalls([this]() {
3505             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that has a
3506             // pixel local storage uniform whose format layout qualifier does not identically match
3507             // the internalformat of its associated pixel local storage plane on the current draw
3508             // framebuffer.
3509             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
3510             EXPECT_GL_SINGLE_ERROR_MSG(
3511                 "Pixel local storage formats in the draw program do not match actively bound "
3512                 "planes.");
3513         });
3514 
3515         glEndPixelLocalStorageANGLE(
3516             3, GLenumArray(
3517                    {GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
3518 
3519         ASSERT_GL_NO_ERROR();
3520     }
3521 
3522   private:
ForAllDrawCalls(std::function<void ()> checks)3523     static void ForAllDrawCalls(std::function<void()> checks)
3524     {
3525         glDrawArrays(GL_TRIANGLES, 0, 3);
3526         checks();
3527         ASSERT_GL_NO_ERROR();
3528 
3529         glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, nullptr);
3530         checks();
3531         ASSERT_GL_NO_ERROR();
3532 
3533         glDrawRangeElements(GL_TRIANGLES, 0, 0, 0, GL_UNSIGNED_SHORT, nullptr);
3534         checks();
3535         ASSERT_GL_NO_ERROR();
3536 
3537         glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1);
3538         checks();
3539         ASSERT_GL_NO_ERROR();
3540 
3541         glDrawElementsInstanced(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, nullptr, 0);
3542         checks();
3543         ASSERT_GL_NO_ERROR();
3544     }
3545 
ErrorMessageCallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)3546     static void GL_APIENTRY ErrorMessageCallback(GLenum source,
3547                                                  GLenum type,
3548                                                  GLuint id,
3549                                                  GLenum severity,
3550                                                  GLsizei length,
3551                                                  const GLchar *message,
3552                                                  const void *userParam)
3553     {
3554         auto test = const_cast<DrawCommandValidationTest *>(
3555             static_cast<const DrawCommandValidationTest *>(userParam));
3556         test->mErrorMessages.emplace_back(message);
3557     }
3558 
3559     bool mHasDebugKHR;
3560     std::vector<std::string> mErrorMessages;
3561 };
3562 
3563 // Check that draw commands validate current PLS state against the shader's PLS uniforms.
TEST_P(PixelLocalStorageTest,DrawCommandValidation)3564 TEST_P(PixelLocalStorageTest, DrawCommandValidation)
3565 {
3566     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3567     DrawCommandValidationTest().run();
3568 }
3569 
3570 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageTest);
3571 #define PLATFORM(API, BACKEND) API##_##BACKEND()
3572 #define PLS_INSTANTIATE_RENDERING_TEST_AND(TEST, API, ...)                                \
3573     ANGLE_INSTANTIATE_TEST(                                                               \
3574         TEST,                                                                             \
3575         PLATFORM(API, D3D11) /* D3D coherent. */                                          \
3576             .enable(Feature::EmulatePixelLocalStorage),                                   \
3577         PLATFORM(API, D3D11) /* D3D noncoherent. */                                       \
3578             .enable(Feature::DisableRasterizerOrderViews)                                 \
3579             .enable(Feature::EmulatePixelLocalStorage),                                   \
3580         PLATFORM(API, OPENGL) /* OpenGL coherent. */                                      \
3581             .enable(Feature::EmulatePixelLocalStorage),                                   \
3582         PLATFORM(API, OPENGL) /* OpenGL noncoherent. */                                   \
3583             .enable(Feature::EmulatePixelLocalStorage)                                    \
3584             .disable(Feature::SupportsFragmentShaderInterlockNV)                          \
3585             .disable(Feature::SupportsFragmentShaderOrderingINTEL)                        \
3586             .disable(Feature::SupportsFragmentShaderInterlockARB),                        \
3587         PLATFORM(API, OPENGLES) /* OpenGL ES coherent */                                  \
3588             .enable(Feature::EmulatePixelLocalStorage),                                   \
3589         PLATFORM(API, OPENGLES) /* OpenGL ES noncoherent                                  \
3590                                    (EXT_shader_framebuffer_fetch_non_coherent). */        \
3591             .enable(Feature::EmulatePixelLocalStorage)                                    \
3592             .disable(Feature::SupportsShaderFramebufferFetchEXT),                         \
3593         PLATFORM(API, OPENGLES) /* OpenGL ES noncoherent (shader images). */              \
3594             .enable(Feature::EmulatePixelLocalStorage)                                    \
3595             .disable(Feature::SupportsShaderFramebufferFetchEXT)                          \
3596             .disable(Feature::SupportsShaderFramebufferFetchNonCoherentEXT),              \
3597         PLATFORM(API, VULKAN) /* Vulkan coherent. */                                      \
3598             .enable(Feature::AsyncCommandQueue)                                           \
3599             .enable(Feature::EmulatePixelLocalStorage),                                   \
3600         PLATFORM(API, VULKAN) /* Vulkan noncoherent. */                                   \
3601             .disable(Feature::SupportsShaderFramebufferFetch)                             \
3602             .disable(Feature::SupportsFragmentShaderPixelInterlock)                       \
3603             .enable(Feature::EmulatePixelLocalStorage),                                   \
3604         PLATFORM(API, VULKAN_SWIFTSHADER) /* Swiftshader coherent (framebuffer fetch). */ \
3605             .enable(Feature::AsyncCommandQueue)                                           \
3606             .enable(Feature::EmulatePixelLocalStorage),                                   \
3607         PLATFORM(API, VULKAN_SWIFTSHADER) /* Swiftshader noncoherent. */                  \
3608             .disable(Feature::SupportsShaderFramebufferFetch)                             \
3609             .disable(Feature::SupportsFragmentShaderPixelInterlock)                       \
3610             .enable(Feature::AsyncCommandQueue)                                           \
3611             .enable(Feature::EmulatePixelLocalStorage),                                   \
3612         PLATFORM(API, VULKAN_SWIFTSHADER) /* Test PLS not having access to                \
3613                                              glEnablei/glDisablei/glColorMaski. */        \
3614             .enable(Feature::EmulatePixelLocalStorage)                                    \
3615             .enable(Feature::DisableDrawBuffersIndexed),                                  \
3616         __VA_ARGS__)
3617 
3618 #define PLS_INSTANTIATE_RENDERING_TEST_ES3(TEST)                                                   \
3619     PLS_INSTANTIATE_RENDERING_TEST_AND(                                                            \
3620         TEST, ES3, /* Metal, coherent (in tiled memory on Apple Silicon).*/                        \
3621         ES3_METAL().enable(Feature::EmulatePixelLocalStorage), /* Metal, coherent via raster order \
3622                                                                   groups + read_write textures.*/  \
3623         ES3_METAL()                                                                                \
3624             .enable(Feature::EmulatePixelLocalStorage)                                             \
3625             .enable(Feature::DisableProgrammableBlending), /* Metal, coherent, r32 packed          \
3626                                                               read_write texture formats.*/        \
3627         ES3_METAL()                                                                                \
3628             .enable(Feature::EmulatePixelLocalStorage)                                             \
3629             .enable(Feature::DisableProgrammableBlending)                                          \
3630             .enable(Feature::DisableRWTextureTier2Support), /* Metal, noncoherent if not on Apple  \
3631                                                                Silicon. (Apple GPUs don't support  \
3632                                                                fragment-to-fragment memory         \
3633                                                                barriers.)*/                        \
3634         ES3_METAL()                                                                                \
3635             .enable(Feature::EmulatePixelLocalStorage)                                             \
3636             .enable(Feature::DisableRasterOrderGroups))
3637 
3638 #define PLS_INSTANTIATE_RENDERING_TEST_ES31(TEST) PLS_INSTANTIATE_RENDERING_TEST_AND(TEST, ES31)
3639 
3640 PLS_INSTANTIATE_RENDERING_TEST_ES3(PixelLocalStorageTest);
3641 
3642 class PixelLocalStorageTestES31 : public PixelLocalStorageTest
3643 {};
3644 
3645 // Check that early_fragment_tests are not triggered when PLS uniforms are not declared.
TEST_P(PixelLocalStorageTestES31,EarlyFragmentTests)3646 TEST_P(PixelLocalStorageTestES31, EarlyFragmentTests)
3647 {
3648     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3649 
3650     PLSTestTexture tex(GL_RGBA8);
3651     GLFramebuffer fbo;
3652     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3653     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3654 
3655     GLuint stencil;
3656     glGenRenderbuffers(1, &stencil);
3657     glBindRenderbuffer(GL_RENDERBUFFER, stencil);
3658     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, W, H);
3659     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
3660     glClearStencil(0);
3661     glClear(GL_STENCIL_BUFFER_BIT);
3662 
3663     glEnable(GL_STENCIL_TEST);
3664     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
3665 
3666     // Emits a fullscreen quad.
3667     constexpr char kFullscreenVS[] = R"(#version 310 es
3668     precision highp float;
3669     void main()
3670     {
3671         gl_Position.x = (gl_VertexID & 1) == 0 ? -1.0 : 1.0;
3672         gl_Position.y = (gl_VertexID & 2) == 0 ? -1.0 : 1.0;
3673         gl_Position.zw = vec2(0, 1);
3674     })";
3675 
3676     // Renders green to the framebuffer.
3677     constexpr char kDrawRed[] = R"(#version 310 es
3678     out mediump vec4 fragColor;
3679     void main()
3680     {
3681         fragColor = vec4(1, 0, 0, 1);
3682     })";
3683 
3684     ANGLE_GL_PROGRAM(drawGreen, kFullscreenVS, kDrawRed);
3685 
3686     // Render to stencil without PLS uniforms and with a discard. Since we discard, and since the
3687     // shader shouldn't enable early_fragment_tests, stencil should not be affected.
3688     constexpr char kNonPLSDiscard[] = R"(#version 310 es
3689     #extension GL_ANGLE_shader_pixel_local_storage : enable
3690     void f(highp ipixelLocalANGLE pls)
3691     {
3692         // Function arguments don't trigger PLS restrictions.
3693         pixelLocalStoreANGLE(pls, ivec4(8));
3694     }
3695     void main()
3696     {
3697         discard;
3698     })";
3699     ANGLE_GL_PROGRAM(lateDiscard, kFullscreenVS, kNonPLSDiscard);
3700     glUseProgram(lateDiscard);
3701     glStencilFunc(GL_ALWAYS, 1, ~0u);
3702     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3703 
3704     // Clear the framebuffer to green.
3705     glClearColor(0, 1, 0, 1);
3706     glClear(GL_COLOR_BUFFER_BIT);
3707 
3708     // Render red to the framebuffer with a stencil test. This should have no effect because the
3709     // stencil buffer should be all zeros.
3710     glUseProgram(drawGreen);
3711     glStencilFunc(GL_NOTEQUAL, 0, ~0u);
3712     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3713     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::green);
3714 
3715     // Now double check that this test would have failed if the shader had enabled
3716     // early_fragment_tests. Render to stencil *with* early_fragment_tests and a discard. Stencil
3717     // should be affected this time even though we discard.
3718     ANGLE_GL_PROGRAM(earlyDiscard, kFullscreenVS,
3719                      (std::string(kNonPLSDiscard) + "layout(early_fragment_tests) in;").c_str());
3720     glUseProgram(earlyDiscard);
3721     glStencilFunc(GL_ALWAYS, 1, ~0u);
3722     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3723 
3724     // Clear the framebuffer to green.
3725     glClearColor(0, 1, 0, 1);
3726     glClear(GL_COLOR_BUFFER_BIT);
3727 
3728     // Render red to the framebuffer again. This time the stencil test should pass because the
3729     // stencil buffer should be all ones.
3730     glUseProgram(drawGreen);
3731     glStencilFunc(GL_NOTEQUAL, 0, ~0u);
3732     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3733     EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor::red);
3734 
3735     ASSERT_GL_NO_ERROR();
3736 }
3737 
3738 // Check that application-facing ES31 state is not perturbed by pixel local storage.
TEST_P(PixelLocalStorageTestES31,StateRestoration)3739 TEST_P(PixelLocalStorageTestES31, StateRestoration)
3740 {
3741     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3742 
3743     doStateRestorationTest();
3744 }
3745 
3746 // Check that draw state does not affect PLS loads and stores, particularly for
3747 // EXT_shader_pixel_local_storage, where they are implemented as fullscreen draws.
TEST_P(PixelLocalStorageTestES31,DrawStateReset)3748 TEST_P(PixelLocalStorageTestES31, DrawStateReset)
3749 {
3750     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3751 
3752     doDrawStateTest();
3753 }
3754 
3755 // Check that changing framebuffer state implicitly disable pixel local storage.
TEST_P(PixelLocalStorageTestES31,ImplicitDisables_Framebuffer)3756 TEST_P(PixelLocalStorageTestES31, ImplicitDisables_Framebuffer)
3757 {
3758     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3759 
3760     doImplicitDisablesTest_Framebuffer();
3761 }
3762 
3763 // Check that changing framebuffer texture attachments implicitly disable pixel
3764 // local storage.
TEST_P(PixelLocalStorageTestES31,ImplicitDisables_TextureAttachments)3765 TEST_P(PixelLocalStorageTestES31, ImplicitDisables_TextureAttachments)
3766 {
3767     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3768 
3769     doImplicitDisablesTest_TextureAttachments();
3770 }
3771 
3772 // Check that changing framebuffer renderbuffer attachments implicitly disable
3773 // pixel local storage.
TEST_P(PixelLocalStorageTestES31,ImplicitDisables_RenderbufferAttachments)3774 TEST_P(PixelLocalStorageTestES31, ImplicitDisables_RenderbufferAttachments)
3775 {
3776     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3777 
3778     doImplicitDisablesTest_RenderbufferAttachments();
3779 }
3780 
3781 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageTestES31);
3782 PLS_INSTANTIATE_RENDERING_TEST_ES31(PixelLocalStorageTestES31);
3783 
3784 class PixelLocalStorageRequestableExtensionTest : public ANGLETest<>
3785 {
3786   protected:
PixelLocalStorageRequestableExtensionTest()3787     PixelLocalStorageRequestableExtensionTest() { setExtensionsEnabled(false); }
3788 };
3789 
do_implicitly_enabled_extensions_test(const char * plsExtensionToRequest)3790 static void do_implicitly_enabled_extensions_test(const char *plsExtensionToRequest)
3791 {
3792     bool hasDrawBuffersIndexedOES = IsGLExtensionRequestable("GL_OES_draw_buffers_indexed");
3793     bool hasDrawBuffersIndexedEXT = IsGLExtensionRequestable("GL_EXT_draw_buffers_indexed");
3794     bool hasColorBufferFloat      = IsGLExtensionRequestable("GL_EXT_color_buffer_float");
3795     bool hasColorBufferHalfFloat  = IsGLExtensionRequestable("GL_EXT_color_buffer_half_float");
3796     bool hasCoherent = IsGLExtensionRequestable("GL_ANGLE_shader_pixel_local_storage_coherent");
3797 
3798     EXPECT_TRUE(!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
3799     EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_draw_buffers_indexed"));
3800     EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
3801     EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
3802     EXPECT_TRUE(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3803     EXPECT_TRUE(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3804 
3805     glRequestExtensionANGLE(plsExtensionToRequest);
3806     EXPECT_GL_NO_ERROR();
3807 
3808     if (hasDrawBuffersIndexedOES)
3809     {
3810         EXPECT_TRUE(IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
3811     }
3812     if (hasDrawBuffersIndexedEXT)
3813     {
3814         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_draw_buffers_indexed"));
3815     }
3816     if (hasColorBufferFloat)
3817     {
3818         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
3819     }
3820     if (hasColorBufferHalfFloat)
3821     {
3822         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
3823     }
3824     if (hasCoherent)
3825     {
3826         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3827     }
3828     EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3829 
3830     if (hasDrawBuffersIndexedOES)
3831     {
3832         // If OES_draw_buffers_indexed ever becomes disablable, it will have to implicitly disable
3833         // ANGLE_shader_pixel_local_storage.
3834         glDisableExtensionANGLE("GL_OES_draw_buffers_indexed");
3835         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3836         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3837         EXPECT_TRUE(IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
3838     }
3839 
3840     if (hasDrawBuffersIndexedEXT)
3841     {
3842         // If EXT_draw_buffers_indexed ever becomes disablable, it will have to implicitly disable
3843         // ANGLE_shader_pixel_local_storage.
3844         glDisableExtensionANGLE("GL_EXT_draw_buffers_indexed");
3845         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3846         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3847         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_draw_buffers_indexed"));
3848     }
3849 
3850     if (hasColorBufferFloat)
3851     {
3852         // If EXT_color_buffer_float ever becomes disablable, it will have to implicitly disable
3853         // ANGLE_shader_pixel_local_storage.
3854         glDisableExtensionANGLE("GL_EXT_color_buffer_float");
3855         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3856         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3857         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
3858     }
3859 
3860     if (hasColorBufferHalfFloat)
3861     {
3862         // If EXT_color_buffer_half_float ever becomes disablable, it will have to implicitly
3863         // disable ANGLE_shader_pixel_local_storage.
3864         glDisableExtensionANGLE("GL_EXT_color_buffer_half_float");
3865         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3866         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3867         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
3868     }
3869 
3870     if (hasCoherent)
3871     {
3872         // ANGLE_shader_pixel_local_storage_coherent is not disablable.
3873         glDisableExtensionANGLE("GL_ANGLE_shader_pixel_local_storage_coherent");
3874         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3875         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3876         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3877     }
3878 
3879     // ANGLE_shader_pixel_local_storage is not disablable.
3880     glDisableExtensionANGLE("GL_ANGLE_shader_pixel_local_storage");
3881     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3882 
3883     // All dependency extensions should have remained enabled.
3884     if (hasDrawBuffersIndexedOES)
3885     {
3886         EXPECT_TRUE(IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
3887     }
3888     if (hasDrawBuffersIndexedEXT)
3889     {
3890         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_draw_buffers_indexed"));
3891     }
3892     if (hasColorBufferFloat)
3893     {
3894         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
3895     }
3896     if (hasColorBufferHalfFloat)
3897     {
3898         EXPECT_TRUE(IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
3899     }
3900     if (hasCoherent)
3901     {
3902         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3903     }
3904     EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3905 }
3906 
3907 // Check that ANGLE_shader_pixel_local_storage implicitly enables its dependency extensions.
TEST_P(PixelLocalStorageRequestableExtensionTest,ImplicitlyEnabledExtensions)3908 TEST_P(PixelLocalStorageRequestableExtensionTest, ImplicitlyEnabledExtensions)
3909 {
3910     EXPECT_TRUE(IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
3911                                              "EGL_ANGLE_create_context_extensions_enabled"));
3912     ANGLE_SKIP_TEST_IF(!IsGLExtensionRequestable("GL_ANGLE_shader_pixel_local_storage"));
3913     do_implicitly_enabled_extensions_test("GL_ANGLE_shader_pixel_local_storage");
3914 }
3915 
3916 // Check that ANGLE_shader_pixel_local_storage_coherent implicitly enables its
3917 // dependency extensions.
TEST_P(PixelLocalStorageRequestableExtensionTest,ImplicitlyEnabledExtensionsCoherent)3918 TEST_P(PixelLocalStorageRequestableExtensionTest, ImplicitlyEnabledExtensionsCoherent)
3919 {
3920     EXPECT_TRUE(IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
3921                                              "EGL_ANGLE_create_context_extensions_enabled"));
3922     ANGLE_SKIP_TEST_IF(!IsGLExtensionRequestable("GL_ANGLE_shader_pixel_local_storage"));
3923     if (!IsGLExtensionRequestable("GL_ANGLE_shader_pixel_local_storage_coherent"))
3924     {
3925         // Requesting GL_ANGLE_shader_pixel_local_storage_coherent should not implicitly enable any
3926         // other extensions if the extension itself is not supported.
3927         glRequestExtensionANGLE("GL_ANGLE_shader_pixel_local_storage_coherent");
3928         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3929         EXPECT_TRUE(!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
3930         EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_draw_buffers_indexed"));
3931         EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
3932         EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
3933         EXPECT_TRUE(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3934         EXPECT_TRUE(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3935     }
3936     else
3937     {
3938         do_implicitly_enabled_extensions_test("GL_ANGLE_shader_pixel_local_storage_coherent");
3939     }
3940 }
3941 
3942 // Check that the dependency extensions of ANGLE_shader_pixel_local_storage do not enable it.
TEST_P(PixelLocalStorageRequestableExtensionTest,ANGLEShaderPixelLocalStorageNotImplicitlyEnabled)3943 TEST_P(PixelLocalStorageRequestableExtensionTest, ANGLEShaderPixelLocalStorageNotImplicitlyEnabled)
3944 {
3945     EXPECT_TRUE(IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
3946                                              "EGL_ANGLE_create_context_extensions_enabled"));
3947     ANGLE_SKIP_TEST_IF(!IsGLExtensionRequestable("GL_ANGLE_shader_pixel_local_storage"));
3948 
3949     EnsureGLExtensionEnabled("GL_OES_draw_buffers_indexed");
3950     EnsureGLExtensionEnabled("GL_EXT_draw_buffers_indexed");
3951     EnsureGLExtensionEnabled("GL_EXT_color_buffer_float");
3952     EnsureGLExtensionEnabled("GL_EXT_color_buffer_half_float");
3953     EXPECT_TRUE(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3954     EXPECT_TRUE(!IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3955 
3956     if (IsGLExtensionRequestable("GL_ANGLE_shader_pixel_local_storage_coherent"))
3957     {
3958         glRequestExtensionANGLE("GL_ANGLE_shader_pixel_local_storage_coherent");
3959         EXPECT_GL_NO_ERROR();
3960         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
3961         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3962     }
3963     else
3964     {
3965         glRequestExtensionANGLE("GL_ANGLE_shader_pixel_local_storage");
3966         EXPECT_GL_NO_ERROR();
3967         EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3968     }
3969 }
3970 
3971 PLS_INSTANTIATE_RENDERING_TEST_ES3(PixelLocalStorageRequestableExtensionTest);
3972 
3973 class PixelLocalStorageValidationTest : public ANGLETest<>
3974 {
3975   public:
PixelLocalStorageValidationTest()3976     PixelLocalStorageValidationTest() { setExtensionsEnabled(false); }
3977 
3978   protected:
testSetUp()3979     void testSetUp() override
3980     {
3981         ASSERT(EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
3982         glGetIntegerv(GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE, &MAX_PIXEL_LOCAL_STORAGE_PLANES);
3983         glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE,
3984                       &MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE);
3985         glGetIntegerv(GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE,
3986                       &MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES);
3987         glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &MAX_COLOR_ATTACHMENTS);
3988         glGetIntegerv(GL_MAX_DRAW_BUFFERS, &MAX_DRAW_BUFFERS);
3989 
3990         mHasDebugKHR = EnsureGLExtensionEnabled("GL_KHR_debug");
3991         if (mHasDebugKHR)
3992         {
3993             glDebugMessageControlKHR(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
3994                                      GL_DEBUG_SEVERITY_HIGH, 0, NULL, GL_TRUE);
3995             glDebugMessageCallbackKHR(&ErrorMessageCallback, this);
3996             glEnable(GL_DEBUG_OUTPUT);
3997             glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
3998         }
3999 
4000         // INVALID_OPERATION is generated if DITHER is enabled.
4001         glDisable(GL_DITHER);
4002 
4003         ANGLETest::testSetUp();
4004     }
4005 
isContextVersionAtLeast(int major,int minor)4006     int isContextVersionAtLeast(int major, int minor)
4007     {
4008         return getClientMajorVersion() > major ||
4009                (getClientMajorVersion() == major && getClientMinorVersion() >= minor);
4010     }
4011 
ErrorMessageCallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)4012     static void GL_APIENTRY ErrorMessageCallback(GLenum source,
4013                                                  GLenum type,
4014                                                  GLuint id,
4015                                                  GLenum severity,
4016                                                  GLsizei length,
4017                                                  const GLchar *message,
4018                                                  const void *userParam)
4019     {
4020         auto test = const_cast<PixelLocalStorageValidationTest *>(
4021             static_cast<const PixelLocalStorageValidationTest *>(userParam));
4022         test->mErrorMessages.emplace_back(message);
4023     }
4024 
4025     GLint MAX_PIXEL_LOCAL_STORAGE_PLANES                           = 0;
4026     GLint MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE    = 0;
4027     GLint MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES = 0;
4028     GLint MAX_COLOR_ATTACHMENTS                                    = 0;
4029     GLint MAX_DRAW_BUFFERS                                         = 0;
4030 
4031     bool mHasDebugKHR;
4032     std::vector<std::string> mErrorMessages;
4033 };
4034 
4035 class ScopedEnable
4036 {
4037   public:
ScopedEnable(GLenum feature)4038     ScopedEnable(GLenum feature) : mFeature(feature) { glEnable(mFeature); }
~ScopedEnable()4039     ~ScopedEnable() { glDisable(mFeature); }
4040 
4041   private:
4042     GLenum mFeature;
4043 };
4044 
4045 // Check that PLS state has the correct initial values.
TEST_P(PixelLocalStorageValidationTest,InitialValues)4046 TEST_P(PixelLocalStorageValidationTest, InitialValues)
4047 {
4048     // It's valid to query GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE even when fbo 0 is bound.
4049     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4050     EXPECT_GL_NO_ERROR();
4051 
4052     // Table 6.Y: Pixel Local Storage State
4053     GLFramebuffer fbo;
4054     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4055     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4056     for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
4057     {
4058         EXPECT_PLS_INTEGER(i, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4059         EXPECT_PLS_INTEGER(i, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4060         EXPECT_PLS_INTEGER(i, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4061         EXPECT_PLS_INTEGER(i, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4062     }
4063     EXPECT_GL_NO_ERROR();
4064 }
4065 
4066 // Check that glFramebufferMemorylessPixelLocalStorageANGLE validates as specified.
TEST_P(PixelLocalStorageValidationTest,FramebufferMemorylessPixelLocalStorageANGLE)4067 TEST_P(PixelLocalStorageValidationTest, FramebufferMemorylessPixelLocalStorageANGLE)
4068 {
4069     GLFramebuffer fbo;
4070     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4071 
4072     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32F);
4073     EXPECT_GL_NO_ERROR();
4074     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_R32F);
4075     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_NONE);
4076     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, GL_NONE);
4077     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, GL_NONE);
4078 
4079     // If <internalformat> is NONE, the pixel local storage plane at index <plane> is deinitialized
4080     // and any internal storage is released.
4081     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_NONE);
4082     EXPECT_GL_NO_ERROR();
4083     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4084     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_NONE);
4085     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, GL_NONE);
4086     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, GL_NONE);
4087 
4088     // Set back to GL_RGBA8I.
4089     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA8I);
4090     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I);
4091 
4092     // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound
4093     // to DRAW_FRAMEBUFFER.
4094     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4095     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32UI);
4096     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4097     EXPECT_GL_SINGLE_ERROR_MSG(
4098         "Default framebuffer object name 0 does not support pixel local storage.");
4099     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4100     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I);
4101 
4102     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
4103     // in an interrupted state.
4104     EXPECT_GL_NO_ERROR();
4105     glFramebufferPixelLocalStorageInterruptANGLE();
4106     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32UI);
4107     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4108     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
4109     glFramebufferPixelLocalStorageRestoreANGLE();
4110     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I);
4111 
4112     // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
4113     glFramebufferMemorylessPixelLocalStorageANGLE(-1, GL_R32UI);
4114     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4115     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
4116     glFramebufferMemorylessPixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_R32UI);
4117     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4118     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
4119     glFramebufferMemorylessPixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, GL_R32UI);
4120     EXPECT_GL_NO_ERROR();
4121     EXPECT_PLS_INTEGER(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_R32UI);
4122 
4123     // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
4124     // X.2, or NONE.
4125     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA16F);
4126     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
4127     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage internal format.");
4128     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA32UI);
4129     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
4130     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage internal format.");
4131     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA8_SNORM);
4132     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
4133     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage internal format.");
4134 
4135     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I);
4136     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_NONE);
4137     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, GL_NONE);
4138     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, GL_NONE);
4139 
4140     ASSERT_GL_NO_ERROR();
4141 }
4142 
4143 // Check that glFramebufferTexturePixelLocalStorageANGLE validates as specified.
TEST_P(PixelLocalStorageValidationTest,FramebufferTexturePixelLocalStorageANGLE)4144 TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE)
4145 {
4146     GLFramebuffer fbo;
4147     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4148 
4149     // Initially, pixel local storage planes are in a deinitialized state and are unusable.
4150     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4151     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4152     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4153     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4154 
4155     GLTexture tex;
4156     glBindTexture(GL_TEXTURE_2D, tex);
4157     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8UI, 10, 10);
4158     glFramebufferTexturePixelLocalStorageANGLE(1, tex, 1, 0);
4159     EXPECT_GL_NO_ERROR();
4160     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8UI);
4161     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex);
4162     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 1);
4163     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4164 
4165     // If <backingtexture> is 0, <level> and <layer> are ignored and the pixel local storage plane
4166     // <plane> is deinitialized.
4167     glFramebufferTexturePixelLocalStorageANGLE(1, 0, 1, 2);
4168     EXPECT_GL_NO_ERROR();
4169     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4170     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4171     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4172     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4173 
4174     // Set back to GL_RGBA8I.
4175     glFramebufferTexturePixelLocalStorageANGLE(1, tex, 1, 0);
4176     EXPECT_GL_NO_ERROR();
4177     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8UI);
4178     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex);
4179     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 1);
4180     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4181 
4182     {
4183         // When a texture object is deleted, any pixel local storage plane to which it was bound is
4184         // automatically deinitialized.
4185         GLFramebuffer keepalive;  // Keep the underlying texture alive after deleting its ID by
4186                                   // binding it to a framebuffer.
4187         glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
4188         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4189         ASSERT_GL_NO_ERROR();
4190         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4191         tex.reset();
4192         PLSTestTexture newTextureMaybeRecycledID(GL_RGBA8, 1, 1);
4193         EXPECT_GL_NO_ERROR();
4194         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4195         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4196         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4197         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4198     }
4199     glBindTexture(GL_TEXTURE_2D, tex);
4200     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8UI, 10, 10);
4201 
4202     // Same as above, but with orphaning.
4203     glFramebufferTexturePixelLocalStorageANGLE(1, tex, 1, 0);
4204     EXPECT_GL_NO_ERROR();
4205     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8UI);
4206     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex);
4207     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 1);
4208     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4209     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4210     {
4211         GLFramebuffer keepalive;  // Keep the underlying texture alive after deleting its ID by
4212                                   // binding it to a framebuffer.
4213         glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
4214         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4215         ASSERT_GL_NO_ERROR();
4216         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4217         tex.reset();
4218         PLSTestTexture newTextureMaybeRecycledID(GL_RGBA8, 1, 1);
4219         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4220         EXPECT_GL_NO_ERROR();
4221         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4222         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4223         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4224         EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4225     }
4226     glBindTexture(GL_TEXTURE_2D, tex);
4227     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8UI, 10, 10);
4228 
4229     // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound
4230     // to DRAW_FRAMEBUFFER.
4231     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4232     glFramebufferTexturePixelLocalStorageANGLE(1, tex, 1, 0);
4233     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4234     EXPECT_GL_SINGLE_ERROR_MSG(
4235         "Default framebuffer object name 0 does not support pixel local storage.");
4236     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4237 
4238     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
4239     // in an interrupted state.
4240     EXPECT_GL_NO_ERROR();
4241     glFramebufferTexturePixelLocalStorageANGLE(1, tex, 1, 0);
4242     glFramebufferPixelLocalStorageInterruptANGLE();
4243     glFramebufferTexturePixelLocalStorageANGLE(1, 0, 0, 0);
4244     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4245     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
4246     glFramebufferPixelLocalStorageRestoreANGLE();
4247     EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex);
4248 
4249     // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
4250     glFramebufferTexturePixelLocalStorageANGLE(-1, tex, 1, 0);
4251     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4252     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
4253     glFramebufferTexturePixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, tex, 1, 0);
4254     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4255     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
4256     glFramebufferTexturePixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, tex, 2, 0);
4257     EXPECT_GL_NO_ERROR();
4258     EXPECT_PLS_INTEGER(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex);
4259     EXPECT_PLS_INTEGER(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 2);
4260 
4261     // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing immutable
4262     // texture object, or zero.
4263     GLTexture badTex;
4264     glFramebufferTexturePixelLocalStorageANGLE(2, badTex, 0, 0);
4265     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4266     EXPECT_GL_SINGLE_ERROR_MSG("Not a valid texture object name.");
4267     glBindTexture(GL_TEXTURE_2D, badTex);
4268     glFramebufferTexturePixelLocalStorageANGLE(2, badTex, 0, 0);
4269     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4270     EXPECT_GL_SINGLE_ERROR_MSG("Texture is not immutable.");
4271     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4272     EXPECT_GL_NO_ERROR();
4273     glFramebufferTexturePixelLocalStorageANGLE(2, badTex, 0, 0);
4274     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4275     EXPECT_GL_SINGLE_ERROR_MSG("Texture is not immutable.");
4276 
4277     // INVALID_OPERATION is generated if <backingtexture> is nonzero
4278     // and not of type TEXTURE_2D or TEXTURE_2D_ARRAY.
4279     GLTexture texCube;
4280     glBindTexture(GL_TEXTURE_CUBE_MAP, texCube);
4281     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 10, 10);
4282     EXPECT_GL_NO_ERROR();
4283     glFramebufferTexturePixelLocalStorageANGLE(0, texCube, 0, 1);
4284     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4285     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage texture type.");
4286     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4287     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4288     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4289     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4290 
4291     GLTexture tex2DMultisample;
4292     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex2DMultisample);
4293     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 10, 10, 1);
4294     EXPECT_GL_NO_ERROR();
4295     glFramebufferTexturePixelLocalStorageANGLE(0, tex2DMultisample, 0, 0);
4296     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4297     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage texture type.");
4298     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4299     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4300     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4301     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4302 
4303     GLTexture tex3D;
4304     glBindTexture(GL_TEXTURE_3D, tex3D);
4305     glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 5, 5, 5);
4306     EXPECT_GL_NO_ERROR();
4307     glFramebufferTexturePixelLocalStorageANGLE(0, tex3D, 0, 0);
4308     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4309     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage texture type.");
4310     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4311     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4312     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4313     EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4314 
4315     // INVALID_VALUE is generated if <level> < 0.
4316     tex.reset();
4317     glBindTexture(GL_TEXTURE_2D, tex);
4318     glTexStorage2D(GL_TEXTURE_2D, 3, GL_R32UI, 10, 10);
4319     glFramebufferTexturePixelLocalStorageANGLE(2, tex, -1, 0);
4320     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4321     EXPECT_GL_SINGLE_ERROR_MSG("Level is negative.");
4322 
4323     // GL_INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the immutable
4324     // number of mipmap levels in <backingtexture>.
4325     glFramebufferTexturePixelLocalStorageANGLE(2, tex, 3, 0);
4326     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4327     EXPECT_GL_SINGLE_ERROR_MSG("Level is larger than texture level count.");
4328 
4329     // INVALID_VALUE is generated if <layer> < 0.
4330     glFramebufferTexturePixelLocalStorageANGLE(2, tex, 1, -1);
4331     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4332     EXPECT_GL_SINGLE_ERROR_MSG("Negative layer.");
4333 
4334     // GL_INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
4335     // number of texture layers in <backingtexture>.
4336     glFramebufferTexturePixelLocalStorageANGLE(2, tex, 1, 1);
4337     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4338     EXPECT_GL_SINGLE_ERROR_MSG("Layer is larger than texture depth.");
4339 
4340     GLTexture tex2DArray;
4341     glBindTexture(GL_TEXTURE_2D_ARRAY, tex2DArray);
4342     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8I, 10, 10, 7);
4343     EXPECT_GL_NO_ERROR();
4344     glFramebufferTexturePixelLocalStorageANGLE(2, tex2DArray, 1, 7);
4345     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4346     EXPECT_GL_SINGLE_ERROR_MSG("Layer is larger than texture depth.");
4347     glFramebufferTexturePixelLocalStorageANGLE(2, tex2DArray, 2, 6);
4348     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4349     EXPECT_GL_SINGLE_ERROR_MSG("Level is larger than texture level count.");
4350     glFramebufferTexturePixelLocalStorageANGLE(2, tex2DArray, 1, 6);
4351     EXPECT_GL_NO_ERROR();
4352     EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I);
4353     EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex2DArray);
4354     EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 1);
4355     EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 6);
4356     // When a texture object is deleted, any pixel local storage plane to which it was bound is
4357     // automatically deinitialized.
4358     {
4359         GLFramebuffer keepalive;  // Keep the underlying texture alive after deleting its ID by
4360                                   // binding it to a framebuffer.
4361         glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
4362         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0);
4363         ASSERT_GL_NO_ERROR();
4364         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4365         tex2DArray.reset();
4366         PLSTestTexture newTextureMaybeRecycledID(GL_RGBA8, 1, 1);
4367         EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_NONE);
4368         EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
4369         EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 0);
4370         EXPECT_PLS_INTEGER(2, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
4371     }
4372 
4373     // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
4374     // one of the acceptable values in Table X.2.
4375     tex.reset();
4376     glBindTexture(GL_TEXTURE_2D, tex);
4377     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RG32F, 10, 10);
4378     EXPECT_GL_NO_ERROR();
4379     glFramebufferTexturePixelLocalStorageANGLE(2, tex, 1, 0);
4380     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
4381     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage internal format.");
4382 
4383     ASSERT_GL_NO_ERROR();
4384 }
4385 
4386 // Check that FramebufferPixelLocalClearValue{f,i,ui}vANGLE validate as specified.
TEST_P(PixelLocalStorageValidationTest,glFramebufferPixelLocalClearValuesANGLE)4387 TEST_P(PixelLocalStorageValidationTest, glFramebufferPixelLocalClearValuesANGLE)
4388 {
4389     // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound
4390     // to DRAW_FRAMEBUFFER.
4391     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(0, 0, 0, 0));
4392     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4393     EXPECT_GL_SINGLE_ERROR_MSG(
4394         "Default framebuffer object name 0 does not support pixel local storage.");
4395 
4396     glFramebufferPixelLocalClearValueivANGLE(1, ClearI(0, 0, 0, 0));
4397     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4398     EXPECT_GL_SINGLE_ERROR_MSG(
4399         "Default framebuffer object name 0 does not support pixel local storage.");
4400 
4401     glFramebufferPixelLocalClearValueuivANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1,
4402                                               ClearUI(0, 0, 0, 0));
4403     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4404     EXPECT_GL_SINGLE_ERROR_MSG(
4405         "Default framebuffer object name 0 does not support pixel local storage.");
4406 
4407     ASSERT_GL_NO_ERROR();
4408 
4409     GLFramebuffer fbo;
4410     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4411 
4412     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
4413     // in an interrupted state.
4414     glFramebufferPixelLocalStorageInterruptANGLE();
4415 
4416     glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(1, 1, 1, 1));
4417     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4418     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
4419 
4420     glFramebufferPixelLocalClearValueivANGLE(1, ClearI(1, 1, 1, 1));
4421     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4422     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
4423 
4424     glFramebufferPixelLocalClearValueuivANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1,
4425                                               ClearUI(1, 1, 1, 1));
4426     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4427     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
4428 
4429     glFramebufferPixelLocalStorageRestoreANGLE();
4430     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({0, 0, 0, 0}));
4431     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(1, ({0, 0, 0, 0}));
4432     EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, ({0, 0, 0, 0}));
4433     ASSERT_GL_NO_ERROR();
4434 
4435     // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
4436     glFramebufferPixelLocalClearValuefvANGLE(-1, ClearF(0, 0, 0, 0));
4437     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4438     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
4439 
4440     glFramebufferPixelLocalClearValueivANGLE(-1, ClearI(0, 0, 0, 0));
4441     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4442     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
4443 
4444     glFramebufferPixelLocalClearValueuivANGLE(-1, ClearUI(0, 0, 0, 0));
4445     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4446     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
4447 
4448     glFramebufferPixelLocalClearValuefvANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, ClearF(0, 0, 0, 0));
4449     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4450     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
4451 
4452     glFramebufferPixelLocalClearValueivANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, ClearI(0, 0, 0, 0));
4453     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4454     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
4455 
4456     glFramebufferPixelLocalClearValueuivANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, ClearUI(0, 0, 0, 0));
4457     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4458     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
4459 
4460     ASSERT_GL_NO_ERROR();
4461 
4462     // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is TRUE.
4463     PLSTestTexture tex(GL_R32UI);
4464     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
4465     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4466     ASSERT_GL_NO_ERROR();
4467 
4468     glFramebufferPixelLocalClearValuefvANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1,
4469                                              ClearF(0, 0, 0, 0));
4470     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4471     EXPECT_GL_SINGLE_ERROR_MSG("Operation not permitted while pixel local storage is active.");
4472 
4473     glFramebufferPixelLocalClearValuefvANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 2,
4474                                              ClearF(0, 0, 0, 0));
4475     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4476     EXPECT_GL_SINGLE_ERROR_MSG("Operation not permitted while pixel local storage is active.");
4477 
4478     glFramebufferPixelLocalClearValueuivANGLE(0, ClearUI(0, 0, 0, 0));
4479     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4480     EXPECT_GL_SINGLE_ERROR_MSG("Operation not permitted while pixel local storage is active.");
4481 
4482     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4483     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE}));
4484     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4485 
4486     ASSERT_GL_NO_ERROR();
4487 }
4488 
4489 #define EXPECT_BANNED(cmd, msg)                   \
4490     cmd;                                          \
4491     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION); \
4492     EXPECT_GL_SINGLE_ERROR_MSG(msg)
4493 
4494 #define EXPECT_BANNED_DEFAULT_MSG(cmd) \
4495     EXPECT_BANNED(cmd, "Operation not permitted while pixel local storage is active.")
4496 
FormatBannedCapMsg(GLenum cap)4497 static std::vector<char> FormatBannedCapMsg(GLenum cap)
4498 {
4499     constexpr char format[] =
4500         "Cap 0x%04X cannot be enabled or disabled while pixel local storage is active.";
4501     std::vector<char> msg(std::snprintf(nullptr, 0, format, cap) + 1);
4502     std::snprintf(msg.data(), msg.size(), format, cap);
4503     return msg;
4504 }
4505 
4506 #define EXPECT_ALLOWED_CAP(cap) \
4507     {                           \
4508         glEnable(cap);          \
4509         glDisable(cap);         \
4510         glIsEnabled(cap);       \
4511         EXPECT_GL_NO_ERROR();   \
4512     }
4513 
4514 #define EXPECT_BANNED_CAP(cap)                           \
4515     {                                                    \
4516         std::vector<char> msg = FormatBannedCapMsg(cap); \
4517         EXPECT_BANNED(glEnable(cap), msg.data());        \
4518         EXPECT_BANNED(glDisable(cap), msg.data());       \
4519         glIsEnabled(cap);                                \
4520         EXPECT_GL_NO_ERROR();                            \
4521     }
4522 
4523 #define EXPECT_BANNED_CAP_INDEXED(cap)                   \
4524     {                                                    \
4525         std::vector<char> msg = FormatBannedCapMsg(cap); \
4526         EXPECT_BANNED(glEnablei(cap, 0), msg.data());    \
4527         EXPECT_BANNED(glDisablei(cap, 0), msg.data());   \
4528         EXPECT_GL_NO_ERROR();                            \
4529     }
4530 
4531 // Check that glBeginPixelLocalStorageANGLE validates non-PLS context state as specified.
TEST_P(PixelLocalStorageValidationTest,BeginPixelLocalStorageANGLE_context_state)4532 TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_context_state)
4533 {
4534     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4535 
4536     // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound
4537     // to DRAW_FRAMEBUFFER.
4538     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4539     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4540     EXPECT_GL_SINGLE_ERROR_MSG(
4541         "Default framebuffer object name 0 does not support pixel local storage.");
4542     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4543 
4544     GLFramebuffer fbo;
4545     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4546 
4547     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
4548     // in an interrupted state.
4549     glFramebufferPixelLocalStorageInterruptANGLE();
4550     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4551     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4552     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
4553     glFramebufferPixelLocalStorageRestoreANGLE();
4554     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4555     ASSERT_GL_NO_ERROR();
4556 
4557     PLSTestTexture pls0(GL_RGBA8, 100, 100);
4558     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
4559     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4560     EXPECT_GL_NO_ERROR();
4561     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4562 
4563     // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero.
4564     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4565     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4566     EXPECT_GL_SINGLE_ERROR_MSG("Operation not permitted while pixel local storage is active.");
4567     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4568     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
4569     EXPECT_GL_NO_ERROR();
4570     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4571 
4572     // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
4573     // multisampled framebuffer).
4574     {
4575         GLRenderbuffer msaa;
4576         glBindRenderbuffer(GL_RENDERBUFFER, msaa);
4577         glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 100, 100);
4578         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaa);
4579         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4580         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4581         EXPECT_GL_SINGLE_ERROR_MSG(
4582             "Attempted to begin pixel local storage with a multisampled framebuffer.");
4583         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4584     }
4585 
4586     // INVALID_OPERATION is generated if DITHER is enabled.
4587     {
4588         ScopedEnable scopedEnable(GL_DITHER);
4589         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4590         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4591         EXPECT_GL_SINGLE_ERROR_MSG(
4592             "Attempted to begin pixel local storage with GL_DITHER enabled.");
4593         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4594     }
4595 
4596     // INVALID_OPERATION is generated if RASTERIZER_DISCARD is enabled.
4597     {
4598         ScopedEnable scopedEnable(GL_RASTERIZER_DISCARD);
4599         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4600         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4601         EXPECT_GL_SINGLE_ERROR_MSG(
4602             "Attempted to begin pixel local storage with GL_RASTERIZER_DISCARD enabled.");
4603         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4604     }
4605 }
4606 
4607 // Check that transform feedback is banned when PLS is active.
TEST_P(PixelLocalStorageValidationTest,PLSActive_bans_transform_feedback)4608 TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_transform_feedback)
4609 {
4610     GLFramebuffer fbo;
4611     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4612 
4613     PLSTestTexture pls0(GL_RGBA8, 100, 100);
4614     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
4615 
4616     // INVALID_OPERATION is generated if TRANSFORM_FEEDBACK_ACTIVE is true.
4617     constexpr char kFS[] = R"(#version 300 es
4618         out mediump vec4 color;
4619         void main()
4620         {
4621             color = vec4(0.6, 0.0, 0.0, 1.0);
4622         })";
4623     std::vector<std::string> xfVaryings;
4624     xfVaryings.push_back("gl_Position");
4625     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(xfProgram, essl3_shaders::vs::Simple(), kFS, xfVaryings,
4626                                         GL_INTERLEAVED_ATTRIBS);
4627     glUseProgram(xfProgram);
4628     GLuint xfBuffer;
4629     glGenBuffers(1, &xfBuffer);
4630     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfBuffer);
4631     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
4632     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfBuffer);
4633     glBeginTransformFeedback(GL_TRIANGLES);
4634     ASSERT_GL_NO_ERROR();
4635     ASSERT_GL_INTEGER(GL_TRANSFORM_FEEDBACK_ACTIVE, 1);
4636 
4637     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4638     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4639     EXPECT_GL_SINGLE_ERROR_MSG(
4640         "Attempted to begin pixel local storage with transform feedback active.");
4641     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4642 
4643     glEndTransformFeedback();
4644 
4645     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4646     EXPECT_GL_NO_ERROR();
4647     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4648 
4649     // glBeginTransformFeedback is not on the PLS allow list.
4650     EXPECT_BANNED_DEFAULT_MSG(glBeginTransformFeedback(GL_TRIANGLES))
4651     ASSERT_GL_INTEGER(GL_TRANSFORM_FEEDBACK_ACTIVE, 0);
4652 
4653     glUseProgram(0);
4654     EXPECT_GL_NO_ERROR();
4655 
4656     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
4657     EXPECT_GL_NO_ERROR();
4658 }
4659 
4660 // Check that EXT_blend_func_extended is banned when PLS is active.
TEST_P(PixelLocalStorageValidationTest,PLSActive_bans_blend_func_extended)4661 TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_blend_func_extended)
4662 {
4663     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_blend_func_extended"));
4664 
4665     GLFramebuffer fbo;
4666     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4667 
4668     PLSTestTexture pls0(GL_RGBA8, 100, 100);
4669     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
4670 
4671     // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
4672     // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
4673     // as specified in EXT_blend_func_extended (SRC1_COLOR_EXT, ONE_MINUS_SRC1_COLOR_EXT,
4674     // SRC1_ALPHA_EXT, ONE_MINUS_SRC1_ALPHA_EXT).
4675     for (auto blendFunc : {GL_SRC1_COLOR_EXT, GL_ONE_MINUS_SRC1_COLOR_EXT, GL_SRC1_ALPHA_EXT,
4676                            GL_ONE_MINUS_SRC1_ALPHA_EXT})
4677     {
4678         glBlendFunc(blendFunc, GL_ONE);
4679         ASSERT_GL_NO_ERROR();
4680         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4681         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4682         EXPECT_GL_SINGLE_ERROR_MSG(
4683             "Attempted to begin pixel local storage with a blend function requiring the secondary "
4684             "color input.");
4685         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4686         glBlendFunc(GL_ONE, GL_ZERO);
4687 
4688         if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4689         {
4690             glBlendFunci(MAX_DRAW_BUFFERS - 1, GL_ZERO, blendFunc);
4691             ASSERT_GL_NO_ERROR();
4692             glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4693             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4694             EXPECT_GL_SINGLE_ERROR_MSG(
4695                 "Attempted to begin pixel local storage with a blend function requiring the "
4696                 "secondary color input.");
4697             EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4698             glBlendFunc(GL_ONE, GL_ZERO);
4699         }
4700 
4701         glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, blendFunc);
4702         ASSERT_GL_NO_ERROR();
4703         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4704         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4705         EXPECT_GL_SINGLE_ERROR_MSG(
4706             "Attempted to begin pixel local storage with a blend function requiring the secondary "
4707             "color input.");
4708         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4709         glBlendFunc(GL_ONE, GL_ZERO);
4710 
4711         if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4712         {
4713             glBlendFuncSeparatei(MAX_DRAW_BUFFERS - 1, blendFunc, GL_ONE, GL_ONE, GL_ONE);
4714             ASSERT_GL_NO_ERROR();
4715             glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4716             EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4717             EXPECT_GL_SINGLE_ERROR_MSG(
4718                 "Attempted to begin pixel local storage with a blend function requiring the "
4719                 "secondary color input.");
4720             EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4721             glBlendFunc(GL_ONE, GL_ZERO);
4722         }
4723 
4724         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4725         ASSERT_GL_NO_ERROR();
4726         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4727 
4728         // INVALID_OPERATION is generated by BlendFunc*() if <srcRGB>, <dstRGB>,
4729         // <srcAlpha>, or <dstAlpha> is a blend function requiring the secondary
4730         // color input, as specified in EXT_blend_func_extended (SRC1_COLOR_EXT,
4731         // ONE_MINUS_SRC1_COLOR_EXT, SRC1_ALPHA_EXT, ONE_MINUS_SRC1_ALPHA_EXT).
4732         constexpr char kErrMsg[] =
4733             "Blend functions requiring the secondary color input are not supported when pixel "
4734             "local storage is active.";
4735 
4736         glBlendFunc(GL_ONE, blendFunc);
4737         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4738         EXPECT_GL_SINGLE_ERROR_MSG(kErrMsg);
4739 
4740         glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, blendFunc);
4741         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4742         EXPECT_GL_SINGLE_ERROR_MSG(kErrMsg);
4743 
4744         if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4745         {
4746             for (GLint i : {0, MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE - 1,
4747                             MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - 1,
4748                             MAX_DRAW_BUFFERS - 1})
4749             {
4750                 glBlendFunci(i, blendFunc, GL_ZERO);
4751                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4752                 EXPECT_GL_SINGLE_ERROR_MSG(kErrMsg);
4753 
4754                 glBlendFuncSeparatei(i, GL_ONE, GL_ONE, GL_ONE, blendFunc);
4755                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4756                 EXPECT_GL_SINGLE_ERROR_MSG(kErrMsg);
4757             }
4758         }
4759 
4760         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
4761         EXPECT_GL_NO_ERROR();
4762     }
4763 
4764     // GL_SRC_ALPHA_SATURATE_EXT is ok.
4765     glBlendFuncSeparate(GL_SRC_ALPHA_SATURATE_EXT, GL_SRC_ALPHA_SATURATE_EXT,
4766                         GL_SRC_ALPHA_SATURATE_EXT, GL_SRC_ALPHA_SATURATE_EXT);
4767     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4768     EXPECT_GL_NO_ERROR();
4769     EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4770     glBlendFuncSeparate(GL_SRC_ALPHA_SATURATE_EXT, GL_SRC_ALPHA_SATURATE_EXT,
4771                         GL_SRC_ALPHA_SATURATE_EXT, GL_SRC_ALPHA_SATURATE_EXT);
4772     EXPECT_GL_NO_ERROR();
4773     if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4774     {
4775         for (GLint i = 0; i < MAX_DRAW_BUFFERS; ++i)
4776         {
4777             glBlendFuncSeparatei(i, GL_SRC_ALPHA_SATURATE_EXT, GL_SRC_ALPHA_SATURATE_EXT,
4778                                  GL_SRC_ALPHA_SATURATE_EXT, GL_SRC_ALPHA_SATURATE_EXT);
4779             EXPECT_GL_NO_ERROR();
4780         }
4781     }
4782     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
4783     EXPECT_GL_NO_ERROR();
4784 }
4785 
4786 // Check that KHR_blend_equation_advanced is banned when PLS is active.
TEST_P(PixelLocalStorageValidationTest,PLSActive_bans_blend_equation_advanced)4787 TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_blend_equation_advanced)
4788 {
4789     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
4790 
4791     GLFramebuffer fbo;
4792     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4793 
4794     PLSTestTexture pls0(GL_RGBA8, 100, 100);
4795     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
4796 
4797     // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA are one of
4798     // the advanced blend equations defined in KHR_blend_equation_advanced.
4799     for (auto blendEquation : {
4800              GL_MULTIPLY_KHR,
4801              GL_SCREEN_KHR,
4802              GL_OVERLAY_KHR,
4803              GL_DARKEN_KHR,
4804              GL_LIGHTEN_KHR,
4805              GL_COLORDODGE_KHR,
4806              GL_COLORBURN_KHR,
4807              GL_HARDLIGHT_KHR,
4808              GL_SOFTLIGHT_KHR,
4809              GL_DIFFERENCE_KHR,
4810              GL_EXCLUSION_KHR,
4811              GL_HSL_HUE_KHR,
4812              GL_HSL_SATURATION_KHR,
4813              GL_HSL_COLOR_KHR,
4814              GL_HSL_LUMINOSITY_KHR,
4815          })
4816     {
4817         glBlendEquation(blendEquation);
4818         ASSERT_GL_NO_ERROR();
4819 
4820         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4821         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4822         EXPECT_GL_SINGLE_ERROR_MSG(
4823             "Attempted to begin pixel local storage with an advanced blend equation enabled.");
4824         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4825 
4826         glBlendEquation(GL_FUNC_ADD);
4827         if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4828         {
4829             glBlendEquationi(0, blendEquation);
4830         }
4831         else
4832         {
4833             glBlendEquation(blendEquation);
4834         }
4835         ASSERT_GL_NO_ERROR();
4836         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4837         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
4838         EXPECT_GL_SINGLE_ERROR_MSG(
4839             "Attempted to begin pixel local storage with an advanced blend equation enabled.");
4840 
4841         if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4842         {
4843             glBlendEquationi(0, GL_FUNC_ADD);
4844         }
4845         else
4846         {
4847             glBlendEquation(GL_FUNC_ADD);
4848         }
4849         ASSERT_GL_NO_ERROR();
4850 
4851         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
4852         EXPECT_GL_NO_ERROR();
4853         EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
4854 
4855         // INVALID_OPERATION is generated by BlendEquation*() if <mode> is one of the advanced
4856         // blend equations defined in KHR_blend_equation_advanced.
4857         glBlendEquation(blendEquation);
4858         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4859         EXPECT_GL_SINGLE_ERROR_MSG(
4860             "Advanced blend equations are not supported when pixel local storage is "
4861             "active.");
4862 
4863         if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
4864         {
4865             for (GLint i : {0, MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE - 1,
4866 
4867                             MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - 1,
4868                             MAX_DRAW_BUFFERS - 1})
4869             {
4870                 glBlendEquationi(i, blendEquation);
4871                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4872                 EXPECT_GL_SINGLE_ERROR_MSG(
4873                     "Advanced blend equations are not supported when pixel local storage is "
4874                     "active.");
4875             }
4876         }
4877 
4878         EXPECT_GL_INTEGER(GL_BLEND_EQUATION_RGB, GL_FUNC_ADD);
4879         EXPECT_GL_INTEGER(GL_BLEND_EQUATION_ALPHA, GL_FUNC_ADD);
4880         ASSERT_GL_NO_ERROR();
4881 
4882         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
4883         EXPECT_GL_NO_ERROR();
4884     }
4885 }
4886 
4887 // Check that glBeginPixelLocalStorageANGLE validates the draw framebuffer's state as specified.
TEST_P(PixelLocalStorageValidationTest,BeginPixelLocalStorageANGLE_framebuffer_state)4888 TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_framebuffer_state)
4889 {
4890     GLFramebuffer fbo;
4891     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4892     PLSTestTexture pls0(GL_RGBA8, 100, 100);
4893     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
4894 
4895     // INVALID_VALUE is generated if <n> < 1 or <n> > MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
4896     glBeginPixelLocalStorageANGLE(0, nullptr);
4897     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4898     EXPECT_GL_SINGLE_ERROR_MSG("Planes must be greater than 0.");
4899     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4900 
4901     glBeginPixelLocalStorageANGLE(
4902         MAX_PIXEL_LOCAL_STORAGE_PLANES + 1,
4903         std::vector<GLenum>(MAX_PIXEL_LOCAL_STORAGE_PLANES + 1, GL_DONT_CARE).data());
4904     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4905     EXPECT_GL_SINGLE_ERROR_MSG(
4906         "Planes must be less than or equal to GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
4907     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4908 
4909     // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
4910     // any color attachment point on or after:
4911     //
4912     //   COLOR_ATTACHMENT0 +
4913     //   MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE
4914     //
4915     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE < MAX_COLOR_ATTACHMENTS)
4916     {
4917         for (int reservedAttachment :
4918              {MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE, MAX_COLOR_ATTACHMENTS - 1})
4919         {
4920             PLSTestTexture tmp(GL_RGBA8, 100, 100);
4921             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + reservedAttachment,
4922                                    GL_TEXTURE_2D, tmp, 0);
4923             glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
4924             EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4925             EXPECT_GL_SINGLE_ERROR_MSG(
4926                 "Framebuffer cannot have images attached to color attachment points on or after "
4927                 "COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE.");
4928             ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4929         }
4930     }
4931 
4932     // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
4933     // any color attachment point on or after:
4934     //
4935     //   COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <n>
4936     //
4937     int maxColorAttachmentsWithMaxPLSPlanes =
4938         MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - MAX_PIXEL_LOCAL_STORAGE_PLANES;
4939     if (maxColorAttachmentsWithMaxPLSPlanes < MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE)
4940     {
4941         for (int reservedAttachment : {maxColorAttachmentsWithMaxPLSPlanes,
4942                                        MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE - 1})
4943         {
4944             PLSTestTexture tmp(GL_RGBA8, 100, 100);
4945             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + reservedAttachment,
4946                                    GL_TEXTURE_2D, tmp, 0);
4947             glBeginPixelLocalStorageANGLE(
4948                 MAX_PIXEL_LOCAL_STORAGE_PLANES,
4949                 std::vector<GLenum>(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_DONT_CARE).data());
4950             EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4951             EXPECT_GL_SINGLE_ERROR_MSG(
4952                 "Framebuffer cannot have images attached to color attachment points on or after "
4953                 "COLOR_ATTACHMENT0 + "
4954                 "MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <n>.");
4955             ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4956         }
4957     }
4958 }
4959 
4960 // Check that glBeginPixelLocalStorageANGLE validates its loadops as specified.
TEST_P(PixelLocalStorageValidationTest,BeginPixelLocalStorageANGLE_loadops)4961 TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_loadops)
4962 {
4963     GLFramebuffer fbo;
4964     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4965     PLSTestTexture pls0(GL_RGBA8, 100, 100);
4966     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
4967 
4968     // INVALID_VALUE is generated if <loadops> is NULL.
4969     glBeginPixelLocalStorageANGLE(1, nullptr);
4970     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
4971     EXPECT_GL_SINGLE_ERROR_MSG("<loadops> cannot be null.");
4972 
4973     // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations enumerated
4974     // in Table X.1.
4975     {
4976         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_REPLACE}));
4977 
4978         EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
4979         EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage Load Operation: 0x1E01.");
4980         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4981 
4982         for (int i = 1; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
4983         {
4984             glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_RGBA8);
4985         }
4986         std::vector<GLenum> loadops(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_DONT_CARE);
4987         loadops.back() = GL_SCISSOR_BOX;
4988         glBeginPixelLocalStorageANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES, loadops.data());
4989         EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
4990         EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage Load Operation: 0x0C10.");
4991         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
4992         for (int i = 1; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
4993         {
4994             glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_NONE);
4995         }
4996     }
4997 
4998     // INVALID_OPERATION is generated if <loadops>[0..<n>-1] is not DISABLE_ANGLE, and the pixel
4999     // local storage plane at that same index is is in a deinitialized state.
5000     {
5001         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
5002         EXPECT_GL_NO_ERROR();
5003         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
5004         EXPECT_GL_NO_ERROR();
5005 
5006         glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE, GL_DONT_CARE}));
5007         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5008         EXPECT_GL_SINGLE_ERROR_MSG(
5009             "Attempted to enable a pixel local storage plane that is in a deinitialized state.");
5010         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5011 
5012         // If <backingtexture> is 0, <level> and <layer> are ignored and the pixel local storage
5013         // plane <plane> is deinitialized.
5014         glFramebufferTexturePixelLocalStorageANGLE(0, 0, -1, 999);
5015         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
5016         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5017         EXPECT_GL_SINGLE_ERROR_MSG(
5018             "Attempted to enable a pixel local storage plane that is in a deinitialized state.");
5019         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5020 
5021         glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
5022         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE}));
5023         EXPECT_GL_NO_ERROR();
5024         glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
5025         EXPECT_GL_NO_ERROR();
5026 
5027         // If <internalformat> is NONE, the pixel local storage plane at index <plane> is
5028         // deinitialized and any internal storage is released.
5029         glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_NONE);
5030         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE}));
5031         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5032         EXPECT_GL_SINGLE_ERROR_MSG(
5033             "Attempted to enable a pixel local storage plane that is in a deinitialized state.");
5034         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5035     }
5036 
5037     // INVALID_OPERATION is generated if <loadops>[0..<n>-1] is LOAD_OP_LOAD_ANGLE and
5038     // the pixel local storage plane at that same index is memoryless.
5039     glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA8);
5040     glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_LOAD_ANGLE}));
5041     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5042     EXPECT_GL_SINGLE_ERROR_MSG(
5043         "Load Operation GL_LOAD_OP_LOAD_ANGLE is invalid for memoryless planes.");
5044     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5045 }
5046 
5047 // Check that glBeginPixelLocalStorageANGLE validates the pixel local storage planes as specified.
TEST_P(PixelLocalStorageValidationTest,BeginPixelLocalStorageANGLE_pls_planes)5048 TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_pls_planes)
5049 {
5050     GLFramebuffer fbo;
5051     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5052     PLSTestTexture pls0(GL_RGBA8, 100, 100);
5053     glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
5054 
5055     // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage planes do
5056     // not have the same width and height.
5057     {
5058         PLSTestTexture pls1(GL_RGBA8, 100, 100);
5059         GLTexture pls2;
5060         glBindTexture(GL_TEXTURE_2D, pls2);
5061         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 101);
5062 
5063         glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
5064         glFramebufferTexturePixelLocalStorageANGLE(1, pls1, 0, 0);
5065         glFramebufferTexturePixelLocalStorageANGLE(2, pls2, 0, 0);
5066 
5067         // Disabling the mismatched size plane is fine.
5068         glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_DONT_CARE}));
5069         EXPECT_GL_NO_ERROR();
5070         glEndPixelLocalStorageANGLE(2, GLenumArray({GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE}));
5071         EXPECT_GL_NO_ERROR();
5072 
5073         // Enabling the mismatched size plane errors.
5074         glBeginPixelLocalStorageANGLE(
5075             3, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_LOAD_ANGLE}));
5076         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5077         EXPECT_GL_SINGLE_ERROR_MSG("Mismatched pixel local storage backing texture sizes.");
5078         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5079 
5080         // Deleting a texture deinitializes the plane.
5081         pls2.reset();
5082         PLSTestTexture newTextureMaybeRecycledID(GL_RGBA8, 1, 1);
5083         glBeginPixelLocalStorageANGLE(
5084             3, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5085         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5086         EXPECT_GL_SINGLE_ERROR_MSG(
5087             "Attempted to enable a pixel local storage plane that is in a deinitialized state.");
5088 
5089         // Converting the mismatched size plane to memoryless also works.
5090         glFramebufferMemorylessPixelLocalStorageANGLE(2, GL_RGBA8);
5091         glBeginPixelLocalStorageANGLE(
5092             3, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5093         EXPECT_GL_NO_ERROR();
5094         glEndPixelLocalStorageANGLE(
5095             3, GLenumArray(
5096                    {GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE}));
5097         EXPECT_GL_NO_ERROR();
5098 
5099         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5100     }
5101 
5102     {
5103         // pls1 going out of scope deinitialized the PLS plane.
5104         PLSTestTexture newTextureMaybeRecycledID(GL_RGBA8, 1, 1);
5105         glBeginPixelLocalStorageANGLE(
5106             2, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5107         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5108         EXPECT_GL_SINGLE_ERROR_MSG(
5109             "Attempted to enable a pixel local storage plane that is in a deinitialized state.");
5110     }
5111 
5112     // Convert to memoryless.
5113     glFramebufferMemorylessPixelLocalStorageANGLE(1, GL_RGBA8);
5114 
5115     // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
5116     // enabled, texture-backed pixel local storage planes do not have identical dimensions with the
5117     // rendering area.
5118     if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
5119     {
5120         PLSTestTexture rt0(GL_RGBA8, 200, 100);
5121         PLSTestTexture rt1(GL_RGBA8, 100, 200);
5122 
5123         // rt0 is wider than the PLS extents.
5124         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt0, 0);
5125         glBeginPixelLocalStorageANGLE(2,
5126                                       GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5127         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5128         EXPECT_GL_SINGLE_ERROR_MSG(
5129             "Pixel local storage backing texture dimensions not equal to the rendering area.");
5130         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5131 
5132         // rt1 is taller than the PLS extents.
5133         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt1, 0);
5134         glBeginPixelLocalStorageANGLE(2,
5135                                       GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5136         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5137         EXPECT_GL_SINGLE_ERROR_MSG(
5138             "Pixel local storage backing texture dimensions not equal to the rendering area.");
5139         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5140 
5141         // The intersection of rt0 and rt1 is equal to the PLS extents.
5142         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt0, 0);
5143         glBeginPixelLocalStorageANGLE(2,
5144                                       GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5145         EXPECT_GL_NO_ERROR();
5146         glEndPixelLocalStorageANGLE(2, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_DONT_CARE}));
5147 
5148         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5149     }
5150 
5151     // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no enabled,
5152     // texture-backed pixel local storage planes.
5153     {
5154         for (int i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
5155         {
5156             glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_RGBA8);
5157         }
5158         glBeginPixelLocalStorageANGLE(
5159             MAX_PIXEL_LOCAL_STORAGE_PLANES,
5160             std::vector<GLenum>(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_LOAD_OP_ZERO_ANGLE).data());
5161         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5162         EXPECT_GL_SINGLE_ERROR_MSG(
5163             "Draw framebuffer has no attachments and no enabled, texture-backed pixel local "
5164             "storage planes.");
5165         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5166 
5167         glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_RGBA8);
5168         glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
5169         EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5170         EXPECT_GL_SINGLE_ERROR_MSG(
5171             "Draw framebuffer has no attachments and no enabled, texture-backed pixel local "
5172             "storage planes.");
5173         ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5174     }
5175 }
5176 
5177 // TODO(anglebug.com/40096838): Block feedback loops
5178 // Check glBeginPixelLocalStorageANGLE validates feedback loops as specified.
5179 // TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_feedback_loops)
5180 // {
5181 //     // INVALID_OPERATION is generated if a single texture image is bound to more than one pixel
5182 //     // local storage plane.
5183 //
5184 //     // INVALID_OPERATION is generated if a single texture image is simultaneously bound to a
5185 //     // pixel local storage plane and attached to the draw framebuffer.
5186 //
5187 //     ASSERT_GL_NO_ERROR();
5188 // }
5189 
5190 // Check that glEndPixelLocalStorageANGLE and glPixelLocalStorageBarrierANGLE validate as specified.
TEST_P(PixelLocalStorageValidationTest,EndAndBarrierANGLE)5191 TEST_P(PixelLocalStorageValidationTest, EndAndBarrierANGLE)
5192 {
5193     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
5194     // in an interrupted state.
5195     GLFramebuffer fbo;
5196     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
5197     glFramebufferPixelLocalStorageInterruptANGLE();
5198     glEndPixelLocalStorageANGLE(0, nullptr);
5199     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5200     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
5201     glFramebufferPixelLocalStorageRestoreANGLE();
5202     ASSERT_GL_NO_ERROR();
5203 
5204     // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero.
5205     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
5206     glEndPixelLocalStorageANGLE(0, nullptr);
5207     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5208     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5209     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5210 
5211     glPixelLocalStorageBarrierANGLE();
5212     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5213     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5214     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5215 
5216     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
5217     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5218 
5219     glEndPixelLocalStorageANGLE(1, nullptr);
5220     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5221     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5222 
5223     glPixelLocalStorageBarrierANGLE();
5224     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5225     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5226 
5227     glBeginPixelLocalStorageANGLE(0, nullptr);
5228     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5229     EXPECT_GL_SINGLE_ERROR_MSG("Planes must be greater than 0.");
5230     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5231 
5232     glPixelLocalStorageBarrierANGLE();
5233     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5234     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5235 
5236     glEndPixelLocalStorageANGLE(2, nullptr);
5237     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5238     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5239 
5240     PLSTestTexture tex(GL_RGBA8);
5241     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
5242     for (int i = 1; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
5243     {
5244         glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_RGBA8);
5245     }
5246     glBeginPixelLocalStorageANGLE(
5247         MAX_PIXEL_LOCAL_STORAGE_PLANES,
5248         std::vector<GLenum>(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_LOAD_OP_ZERO_ANGLE).data());
5249     EXPECT_GL_NO_ERROR();
5250     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, MAX_PIXEL_LOCAL_STORAGE_PLANES);
5251 
5252     glPixelLocalStorageBarrierANGLE();
5253     EXPECT_GL_NO_ERROR();
5254 
5255     glEndPixelLocalStorageANGLE(
5256         MAX_PIXEL_LOCAL_STORAGE_PLANES,
5257         std::vector<GLenum>(MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_DONT_CARE).data());
5258     EXPECT_GL_NO_ERROR();
5259 
5260     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
5261     EXPECT_GL_NO_ERROR();
5262 
5263     glEndPixelLocalStorageANGLE(0, nullptr);
5264     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5265     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5266 
5267     glPixelLocalStorageBarrierANGLE();
5268     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5269     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active.");
5270 
5271     ASSERT_GL_NO_ERROR();
5272 
5273     // INVALID_VALUE is generated if <n> != PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE.
5274     glBeginPixelLocalStorageANGLE(2, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_LOAD_OP_CLEAR_ANGLE}));
5275     ASSERT_GL_NO_ERROR();
5276 
5277     glEndPixelLocalStorageANGLE(3, GLenumArray({GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE}));
5278     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5279     EXPECT_GL_SINGLE_ERROR_MSG("<n> != ACTIVE_PIXEL_LOCAL_STORAGE_PLANES_ANGLE");
5280 
5281     glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
5282     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5283     EXPECT_GL_SINGLE_ERROR_MSG("<n> != ACTIVE_PIXEL_LOCAL_STORAGE_PLANES_ANGLE");
5284 
5285     glEndPixelLocalStorageANGLE(2, GLenumArray({GL_DONT_CARE, GL_DONT_CARE}));
5286     ASSERT_GL_NO_ERROR();
5287 
5288     // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
5289     // one of the Store Operations enumerated in Table X.2.
5290     glBeginPixelLocalStorageANGLE(
5291         3, GLenumArray({GL_LOAD_OP_LOAD_ANGLE, GL_DONT_CARE, GL_LOAD_OP_CLEAR_ANGLE}));
5292     ASSERT_GL_NO_ERROR();
5293 
5294     glEndPixelLocalStorageANGLE(
5295         3, GLenumArray({GL_LOAD_OP_CLEAR_ANGLE, GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE}));
5296     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5297     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage Store Operation: 0x96E5.");
5298 
5299     glEndPixelLocalStorageANGLE(
5300         3, GLenumArray({GL_DONT_CARE, GL_LOAD_OP_LOAD_ANGLE, GL_STORE_OP_STORE_ANGLE}));
5301     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5302     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage Store Operation: 0x96E6.");
5303 
5304     glEndPixelLocalStorageANGLE(
5305         3, GLenumArray({GL_DONT_CARE, GL_STORE_OP_STORE_ANGLE, GL_LOAD_OP_ZERO_ANGLE}));
5306     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5307     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage Store Operation: 0x96E4.");
5308 
5309     glEndPixelLocalStorageANGLE(
5310         3, GLenumArray({GL_DONT_CARE, GL_SCISSOR_BOX, GL_STORE_OP_STORE_ANGLE}));
5311     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5312     EXPECT_GL_SINGLE_ERROR_MSG("Invalid pixel local storage Store Operation: 0x0C10.");
5313 
5314     ASSERT_GL_NO_ERROR();
5315 }
5316 
5317 // Check that FramebufferPixelLocalStorageInterruptANGLE validates as specified.
TEST_P(PixelLocalStorageValidationTest,InterruptMechanism)5318 TEST_P(PixelLocalStorageValidationTest, InterruptMechanism)
5319 {
5320     // These commands are ignored when the default framebuffer object name 0 is bound.
5321     glFramebufferPixelLocalStorageRestoreANGLE();
5322     glFramebufferPixelLocalStorageInterruptANGLE();
5323     glFramebufferPixelLocalStorageInterruptANGLE();
5324     glFramebufferPixelLocalStorageInterruptANGLE();
5325     glFramebufferPixelLocalStorageRestoreANGLE();
5326     glFramebufferPixelLocalStorageRestoreANGLE();
5327     glFramebufferPixelLocalStorageRestoreANGLE();
5328     glFramebufferPixelLocalStorageRestoreANGLE();
5329     EXPECT_GL_NO_ERROR();
5330 
5331     for (size_t i = 0; i < 256; ++i)
5332     {
5333         glFramebufferPixelLocalStorageInterruptANGLE();
5334     }
5335     EXPECT_GL_NO_ERROR();
5336 
5337     GLFramebuffer fbo;
5338     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
5339 
5340     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
5341     // not in an interrupted state.
5342     glFramebufferPixelLocalStorageRestoreANGLE();
5343     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5344     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is not interrupted.");
5345 
5346     for (size_t i = 0; i < 255; ++i)
5347     {
5348         glFramebufferPixelLocalStorageInterruptANGLE();
5349     }
5350     EXPECT_GL_NO_ERROR();
5351 
5352     // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw
5353     // framebuffer is greater than or equal to 255.
5354     glFramebufferPixelLocalStorageInterruptANGLE();
5355     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5356     EXPECT_GL_SINGLE_ERROR_MSG(
5357         "Pixel local storage does not support more than 255 nested interruptions.");
5358 
5359     for (size_t i = 0; i < 255; ++i)
5360     {
5361         glFramebufferPixelLocalStorageRestoreANGLE();
5362     }
5363     EXPECT_GL_NO_ERROR();
5364 
5365     glFramebufferPixelLocalStorageRestoreANGLE();
5366     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5367     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is not interrupted.");
5368 
5369     glFramebufferPixelLocalStorageInterruptANGLE();
5370     glFramebufferPixelLocalStorageInterruptANGLE();
5371     ASSERT_GL_NO_ERROR();
5372 
5373     glFramebufferPixelLocalStorageRestoreANGLE();
5374     glFramebufferPixelLocalStorageRestoreANGLE();
5375     ASSERT_GL_NO_ERROR();
5376 
5377     glFramebufferPixelLocalStorageRestoreANGLE();
5378     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5379     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is not interrupted.");
5380 }
5381 
5382 // Check that glGetFramebufferPixelLocalStorageParameter(f|i|ui)(Robust)?ANGLE validate as
5383 // specified.
TEST_P(PixelLocalStorageValidationTest,GetFramebufferPixelLocalStorageParametersANGLE)5384 TEST_P(PixelLocalStorageValidationTest, GetFramebufferPixelLocalStorageParametersANGLE)
5385 {
5386     // The "Get.*Robust" variants require ANGLE_robust_client_memory. ANGLE_robust_client_memory is
5387     // not disableable and is therefore supported in every ANGLE context.
5388     //
5389     // If ANGLE ever does find itself in a situation where ANGLE_robust_client_memory is not
5390     // supported, we will need to hide the "Get.*Robust" variants in order to be spec compliant.
5391     EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_robust_client_memory"));
5392 
5393     GLfloat floats[5];
5394     GLint ints[5];
5395     GLsizei length;
5396 
5397     // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound
5398     // to DRAW_FRAMEBUFFER.
5399     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5400         0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, floats);
5401     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5402     EXPECT_GL_SINGLE_ERROR_MSG(
5403         "Default framebuffer object name 0 does not support pixel local storage.");
5404     glGetFramebufferPixelLocalStorageParameterfvANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE,
5405                                                       floats);
5406     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5407     EXPECT_GL_SINGLE_ERROR_MSG(
5408         "Default framebuffer object name 0 does not support pixel local storage.");
5409     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, 4,
5410                                                             &length, ints);
5411     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5412     EXPECT_GL_SINGLE_ERROR_MSG(
5413         "Default framebuffer object name 0 does not support pixel local storage.");
5414     glGetFramebufferPixelLocalStorageParameterivANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, ints);
5415     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5416     EXPECT_GL_SINGLE_ERROR_MSG(
5417         "Default framebuffer object name 0 does not support pixel local storage.");
5418 
5419     GLFramebuffer fbo;
5420     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
5421 
5422     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
5423     // in an interrupted state.
5424     glFramebufferPixelLocalStorageInterruptANGLE();
5425     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5426         0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, floats);
5427     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5428     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
5429     glGetFramebufferPixelLocalStorageParameterfvANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE,
5430                                                       floats);
5431     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5432     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
5433     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, 4,
5434                                                             &length, ints);
5435     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5436     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
5437     glGetFramebufferPixelLocalStorageParameterivANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, ints);
5438     EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
5439     EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted.");
5440     glFramebufferPixelLocalStorageRestoreANGLE();
5441     ASSERT_GL_NO_ERROR();
5442 
5443     // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
5444     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5445         -1, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, floats);
5446     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5447     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
5448     glGetFramebufferPixelLocalStorageParameterfvANGLE(-1, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE,
5449                                                       floats);
5450     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5451     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
5452 
5453     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(-1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE,
5454                                                             4, &length, ints);
5455     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5456     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
5457     glGetFramebufferPixelLocalStorageParameterivANGLE(-1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, ints);
5458     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5459     EXPECT_GL_SINGLE_ERROR_MSG("Plane cannot be less than 0.");
5460 
5461     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5462         MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, floats);
5463     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5464     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
5465     glGetFramebufferPixelLocalStorageParameterfvANGLE(
5466         MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, floats);
5467     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5468     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
5469 
5470     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(
5471         MAX_PIXEL_LOCAL_STORAGE_PLANES, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, 1, &length, ints);
5472     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5473     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
5474     glGetFramebufferPixelLocalStorageParameterivANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES,
5475                                                       GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, ints);
5476     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5477     EXPECT_GL_SINGLE_ERROR_MSG("Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.");
5478 
5479     // INVALID_ENUM is generated if the command issued is not the associated "Get Command" for
5480     // <pname> in Table 6.Y.
5481     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(
5482         0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, ints);
5483     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5484     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EC is currently not supported.");
5485     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE,
5486                                                       ints);
5487     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5488     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EC is currently not supported.");
5489     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(
5490         0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, 4, &length, ints);
5491     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5492     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x8CD0 is currently not supported.");
5493     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
5494                                                       ints);
5495     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5496     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x8CD0 is currently not supported.");
5497     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, 4,
5498                                                             &length, floats);
5499     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5500     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96E8 is currently not supported.");
5501     glGetFramebufferPixelLocalStorageParameterfvANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, floats);
5502     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5503     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96E8 is currently not supported.");
5504     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 1,
5505                                                             &length, floats);
5506     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5507     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96E9 is currently not supported.");
5508     glGetFramebufferPixelLocalStorageParameterfvANGLE(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, floats);
5509     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5510     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96E9 is currently not supported.");
5511     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE,
5512                                                             1, &length, floats);
5513     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5514     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EA is currently not supported.");
5515     glGetFramebufferPixelLocalStorageParameterfvANGLE(1, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE,
5516                                                       floats);
5517     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5518     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EA is currently not supported.");
5519     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE,
5520                                                             1, &length, floats);
5521     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5522     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EB is currently not supported.");
5523     glGetFramebufferPixelLocalStorageParameterfvANGLE(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE,
5524                                                       floats);
5525     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5526     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EB is currently not supported.");
5527     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(1, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE,
5528                                                             1, &length, floats);
5529     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5530     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96ED is currently not supported.");
5531     glGetFramebufferPixelLocalStorageParameterfvANGLE(1, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE,
5532                                                       floats);
5533     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5534     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96ED is currently not supported.");
5535     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5536         1, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, 1, &length, floats);
5537     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5538     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EE is currently not supported.");
5539     glGetFramebufferPixelLocalStorageParameterfvANGLE(
5540         1, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, floats);
5541     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5542     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x96EE is currently not supported.");
5543     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5544         1, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 1, &length, floats);
5545     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5546     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x8CD3 is currently not supported.");
5547     glGetFramebufferPixelLocalStorageParameterfvANGLE(
5548         1, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, floats);
5549     EXPECT_GL_SINGLE_ERROR(GL_INVALID_ENUM);
5550     EXPECT_GL_SINGLE_ERROR_MSG("Enum 0x8CD3 is currently not supported.");
5551 
5552     // INVALID_OPERATION is generated if <bufSize> is not large enough to receive the requested
5553     // parameter.
5554     //
5555     // ... When an error is generated, nothing is written to <length>.
5556     constexpr GLsizei kLengthInitValue = 0xbaadc0de;
5557     length                             = kLengthInitValue;
5558     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, 0,
5559                                                             &length, ints);
5560     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5561     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5562     EXPECT_EQ(length, kLengthInitValue);
5563 
5564     length = kLengthInitValue;
5565     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0,
5566                                                             &length, ints);
5567     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5568     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5569     EXPECT_EQ(length, kLengthInitValue);
5570 
5571     length = kLengthInitValue;
5572     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE,
5573                                                             0, &length, ints);
5574     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5575     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5576     EXPECT_EQ(length, kLengthInitValue);
5577 
5578     length = kLengthInitValue;
5579     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE,
5580                                                             0, &length, ints);
5581     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5582     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5583     EXPECT_EQ(length, kLengthInitValue);
5584 
5585     length = kLengthInitValue;
5586     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE,
5587                                                             3, &length, ints);
5588     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5589     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5590     EXPECT_EQ(length, kLengthInitValue);
5591 
5592     length = kLengthInitValue;
5593     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(
5594         0, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, 3, &length, ints);
5595     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5596     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5597     EXPECT_EQ(length, kLengthInitValue);
5598 
5599     length = kLengthInitValue;
5600     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5601         0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 3, &length, floats);
5602     EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
5603     EXPECT_GL_SINGLE_ERROR_MSG("More parameters are required than were provided.");
5604     EXPECT_EQ(length, kLengthInitValue);
5605 
5606     // Not quite pure validation, but also ensure that <length> gets written properly.
5607     length = kLengthInitValue;
5608     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, 5,
5609                                                             &length, ints);
5610     EXPECT_GL_NO_ERROR();
5611     EXPECT_EQ(length, 1);
5612 
5613     length = kLengthInitValue;
5614     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 5,
5615                                                             &length, ints);
5616     EXPECT_GL_NO_ERROR();
5617     EXPECT_EQ(length, 1);
5618 
5619     length = kLengthInitValue;
5620     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE,
5621                                                             5, &length, ints);
5622     EXPECT_GL_NO_ERROR();
5623     EXPECT_EQ(length, 1);
5624 
5625     length = kLengthInitValue;
5626     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE,
5627                                                             5, &length, ints);
5628     EXPECT_GL_NO_ERROR();
5629     EXPECT_EQ(length, 1);
5630 
5631     length = kLengthInitValue;
5632     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE,
5633                                                             5, &length, ints);
5634     EXPECT_GL_NO_ERROR();
5635     EXPECT_EQ(length, 4);
5636 
5637     length = kLengthInitValue;
5638     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(
5639         0, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, 5, &length, ints);
5640     EXPECT_GL_NO_ERROR();
5641     EXPECT_EQ(length, 4);
5642 
5643     length = kLengthInitValue;
5644     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5645         0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 5, &length, floats);
5646     EXPECT_GL_NO_ERROR();
5647     EXPECT_EQ(length, 4);
5648 
5649     // INVALID_VALUE is generated if <params> is NULL.
5650     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, 5,
5651                                                             &length, nullptr);
5652     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5653     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5654     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, nullptr);
5655     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5656     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5657 
5658     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 5,
5659                                                             &length, nullptr);
5660     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5661     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5662     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE,
5663                                                       nullptr);
5664     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5665     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5666 
5667     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE,
5668                                                             5, &length, nullptr);
5669     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5670     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5671     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE,
5672                                                       nullptr);
5673     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5674     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5675 
5676     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE,
5677                                                             5, &length, nullptr);
5678     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5679     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5680     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE,
5681                                                       nullptr);
5682     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5683     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5684 
5685     glGetFramebufferPixelLocalStorageParameterivRobustANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE,
5686                                                             5, &length, nullptr);
5687     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5688     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5689     glGetFramebufferPixelLocalStorageParameterivANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE,
5690                                                       nullptr);
5691     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5692     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5693 
5694     glGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
5695         0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 5, &length, nullptr);
5696     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5697     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5698     glGetFramebufferPixelLocalStorageParameterfvANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE,
5699                                                       nullptr);
5700     EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE);
5701     EXPECT_GL_SINGLE_ERROR_MSG("<params> cannot be null.");
5702 }
5703 
5704 // Check command-specific errors that go into effect when PLS is active, as well as commands
5705 // specifically called out by EXT_shader_pixel_local_storage for flushing tiled memory.
TEST_P(PixelLocalStorageValidationTest,BannedCommands)5706 TEST_P(PixelLocalStorageValidationTest, BannedCommands)
5707 {
5708     PLSTestTexture tex(GL_RGBA8);
5709     GLFramebuffer fbo;
5710     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
5711     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
5712     int numActivePlanes = MAX_PIXEL_LOCAL_STORAGE_PLANES - 1;
5713     for (int i = 1; i < numActivePlanes; ++i)
5714     {
5715         glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_RGBA8);
5716     }
5717     glBeginPixelLocalStorageANGLE(
5718         numActivePlanes, std::vector<GLenum>(numActivePlanes, GL_LOAD_OP_ZERO_ANGLE).data());
5719     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, numActivePlanes);
5720     ASSERT_GL_NO_ERROR();
5721 
5722     // Check commands called out by EXT_shader_pixel_local_storage for flushing tiled memory.
5723     EXPECT_BANNED_DEFAULT_MSG(glFlush());
5724     EXPECT_BANNED_DEFAULT_MSG(glFinish());
5725     EXPECT_BANNED_DEFAULT_MSG(glClientWaitSync(nullptr, 0, 0));
5726     EXPECT_BANNED_DEFAULT_MSG(
5727         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
5728     EXPECT_BANNED_DEFAULT_MSG(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 0));
5729     EXPECT_BANNED_DEFAULT_MSG(glBlitFramebuffer(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
5730 
5731     // INVALID_OPERATION is generated by Enable(), Disable() if <cap> is not one of: CULL_FACE,
5732     // DEPTH_CLAMP_EXT, DEPTH_TEST, POLYGON_OFFSET_POINT_NV, POLYGON_OFFSET_LINE_NV,
5733     // POLYGON_OFFSET_LINE_ANGLE, POLYGON_OFFSET_FILL, PRIMITIVE_RESTART_FIXED_INDEX,
5734     // SCISSOR_TEST, STENCIL_TEST, CLIP_DISTANCE[0..7]_EXT
5735     EXPECT_ALLOWED_CAP(GL_CULL_FACE);
5736     if (EnsureGLExtensionEnabled("GL_KHR_debug"))
5737     {
5738         EXPECT_ALLOWED_CAP(GL_DEBUG_OUTPUT);
5739         EXPECT_ALLOWED_CAP(GL_DEBUG_OUTPUT_SYNCHRONOUS);
5740         // Now turn them back on since the test actually uses these caps...
5741         glEnable(GL_DEBUG_OUTPUT);
5742         glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
5743     }
5744     EXPECT_ALLOWED_CAP(GL_DEPTH_TEST);
5745     if (EnsureGLExtensionEnabled("GL_EXT_depth_clamp"))
5746     {
5747         EXPECT_ALLOWED_CAP(GL_DEPTH_CLAMP_EXT);
5748     }
5749     if (EnsureGLExtensionEnabled("GL_ANGLE_polygon_mode"))
5750     {
5751         EXPECT_ALLOWED_CAP(GL_POLYGON_OFFSET_LINE_ANGLE);
5752         glPolygonModeANGLE(GL_FRONT_AND_BACK, GL_FILL_ANGLE);
5753         EXPECT_GL_NO_ERROR();
5754     }
5755     if (EnsureGLExtensionEnabled("GL_NV_polygon_mode"))
5756     {
5757         EXPECT_ALLOWED_CAP(GL_POLYGON_OFFSET_POINT_NV);
5758         EXPECT_ALLOWED_CAP(GL_POLYGON_OFFSET_LINE_NV);
5759         glPolygonModeNV(GL_FRONT_AND_BACK, GL_FILL_NV);
5760         EXPECT_GL_NO_ERROR();
5761     }
5762     if (EnsureGLExtensionEnabled("GL_EXT_polygon_offset_clamp"))
5763     {
5764         glPolygonOffsetClampEXT(0.0f, 0.0f, 0.0f);
5765         EXPECT_GL_NO_ERROR();
5766     }
5767     EXPECT_ALLOWED_CAP(GL_POLYGON_OFFSET_FILL);
5768     EXPECT_ALLOWED_CAP(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5769     EXPECT_ALLOWED_CAP(GL_SCISSOR_TEST);
5770     EXPECT_ALLOWED_CAP(GL_STENCIL_TEST);
5771     if (EnsureGLExtensionEnabled("GL_EXT_clip_cull_distance"))
5772     {
5773         for (GLenum i = 0; i < 8; ++i)
5774         {
5775             EXPECT_ALLOWED_CAP(GL_CLIP_DISTANCE0_EXT + i);
5776         }
5777     }
5778     EXPECT_BANNED_CAP(GL_SAMPLE_ALPHA_TO_COVERAGE);
5779     EXPECT_BANNED_CAP(GL_SAMPLE_COVERAGE);
5780     EXPECT_BANNED_CAP(GL_DITHER);
5781     EXPECT_BANNED_CAP(GL_RASTERIZER_DISCARD);
5782     if (isContextVersionAtLeast(3, 1))
5783     {
5784         EXPECT_BANNED_CAP(GL_SAMPLE_MASK);
5785     }
5786     if (EnsureGLExtensionEnabled("GL_EXT_multisample_compatibility"))
5787     {
5788         EXPECT_BANNED_CAP(GL_MULTISAMPLE_EXT);
5789         EXPECT_BANNED_CAP(GL_SAMPLE_ALPHA_TO_ONE_EXT);
5790     }
5791     if (EnsureGLExtensionEnabled("GL_OES_sample_shading"))
5792     {
5793         EXPECT_BANNED_CAP(GL_SAMPLE_SHADING);
5794     }
5795     if (EnsureGLExtensionEnabled("GL_QCOM_shading_rate"))
5796     {
5797         EXPECT_BANNED_CAP(GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM);
5798     }
5799     if (EnsureGLExtensionEnabled("GL_ANGLE_logic_op"))
5800     {
5801         EXPECT_BANNED_CAP(GL_COLOR_LOGIC_OP);
5802     }
5803     // BLEND is the only indexed capability in ANGLE, but we can at least use SHADING_RATE_IMAGE_NV
5804     // to check the debug output and verify that PLS validation is banning it, which ensures it is
5805     // future proof against hypothetical future extensions that add indexed capabilities.
5806     EXPECT_BANNED_CAP_INDEXED(GL_SHADING_RATE_IMAGE_NV);
5807 
5808     // The validation tests are expected to run in a configuration where the draw buffers are
5809     // restricted by PLS (e.g., not shader images).
5810     int bannedColorAttachment = MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE;
5811     ASSERT(bannedColorAttachment < MAX_DRAW_BUFFERS);
5812 
5813     int bannedCombinedAttachment =
5814         MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - numActivePlanes;
5815 
5816     // glClearBuffer{f,i,ui}v are ignored for all attachments at or beyond
5817     // MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE when PLS is active.
5818     GLfloat clearf[4]{};
5819     GLint cleari[4]{};
5820     GLuint clearui[4]{};
5821     {
5822         glClearBufferfv(GL_COLOR, bannedColorAttachment, clearf);
5823         glClearBufferiv(GL_COLOR, bannedColorAttachment, cleari);
5824         glClearBufferuiv(GL_COLOR, bannedColorAttachment, clearui);
5825         glClearBufferfv(GL_COLOR, MAX_DRAW_BUFFERS - 1, clearf);
5826         glClearBufferiv(GL_COLOR, MAX_DRAW_BUFFERS - 1, cleari);
5827         glClearBufferuiv(GL_COLOR, MAX_DRAW_BUFFERS - 1, clearui);
5828         EXPECT_GL_NO_ERROR();
5829     }
5830     if (bannedCombinedAttachment < bannedColorAttachment)
5831     {
5832         glClearBufferfv(GL_COLOR, bannedCombinedAttachment, clearf);
5833         glClearBufferiv(GL_COLOR, bannedCombinedAttachment, cleari);
5834         glClearBufferuiv(GL_COLOR, bannedCombinedAttachment, clearui);
5835         EXPECT_GL_NO_ERROR();
5836     }
5837     glClearBufferfv(GL_DEPTH, 0, clearf);
5838     EXPECT_GL_NO_ERROR();
5839     glClearBufferiv(GL_STENCIL, 0, cleari);
5840     EXPECT_GL_NO_ERROR();
5841 
5842     if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
5843     {
5844         // Enabling and disabling GL_BLEND is valid while PLS is active.
5845         {
5846             glEnableiOES(GL_BLEND, bannedColorAttachment);
5847             glDisableiOES(GL_BLEND, bannedColorAttachment);
5848             glEnableiOES(GL_BLEND, MAX_DRAW_BUFFERS - 1);
5849             glDisableiOES(GL_BLEND, MAX_DRAW_BUFFERS - 1);
5850             EXPECT_GL_NO_ERROR();
5851         }
5852         if (bannedCombinedAttachment < bannedColorAttachment)
5853         {
5854             glEnableiOES(GL_BLEND, bannedCombinedAttachment);
5855             glDisableiOES(GL_BLEND, bannedCombinedAttachment);
5856             EXPECT_GL_NO_ERROR();
5857         }
5858     }
5859 
5860     // INVALID_OPERATION is generated if a draw is issued with a fragment shader that accesses a
5861     // texture bound to pixel local storage.
5862     //
5863     // TODO(anglebug.com/40096838).
5864 
5865     ASSERT_GL_NO_ERROR();
5866 }
5867 
5868 // Check that glBlendFunc and glBlendEquation updates are valid while PLS is active, and still take
5869 // effect after PLS is ended.
TEST_P(PixelLocalStorageValidationTest,BlendFuncDuringPLS)5870 TEST_P(PixelLocalStorageValidationTest, BlendFuncDuringPLS)
5871 {
5872     const GLint drawBufferIndexCount =
5873         IsGLExtensionEnabled("GL_OES_draw_buffers_indexed") ? MAX_DRAW_BUFFERS : 1;
5874     PLSTestTexture tex(GL_RGBA8);
5875     GLFramebuffer fbo;
5876     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
5877     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
5878     int numActivePlanes = MAX_PIXEL_LOCAL_STORAGE_PLANES - 1;
5879     for (int i = 1; i < numActivePlanes; ++i)
5880     {
5881         glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_RGBA8);
5882     }
5883 
5884     glBeginPixelLocalStorageANGLE(
5885         numActivePlanes, std::vector<GLenum>(numActivePlanes, GL_LOAD_OP_ZERO_ANGLE).data());
5886     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, numActivePlanes);
5887     ASSERT_GL_NO_ERROR();
5888 
5889     for (GLint i = 0; i < drawBufferIndexCount; ++i)
5890     {
5891         if (drawBufferIndexCount > 1)
5892         {
5893             glBlendEquationiOES(i, GL_FUNC_SUBTRACT);
5894             glBlendFunciOES(i, GL_ONE, GL_CONSTANT_COLOR);
5895         }
5896         else
5897         {
5898             glBlendEquation(GL_FUNC_SUBTRACT);
5899             glBlendFunc(GL_ONE, GL_CONSTANT_COLOR);
5900         }
5901         ASSERT_GL_NO_ERROR();
5902     }
5903 
5904     glEndPixelLocalStorageANGLE(numActivePlanes,
5905                                 std::vector<GLenum>(numActivePlanes, GL_DONT_CARE).data());
5906     ASSERT_GL_NO_ERROR();
5907 
5908     for (GLint i = 0; i < drawBufferIndexCount; ++i)
5909     {
5910         GLint blendEquationRGB, blendEquationAlpha;
5911         if (drawBufferIndexCount > 1)
5912         {
5913             glGetIntegeri_v(GL_BLEND_EQUATION_RGB, i, &blendEquationRGB);
5914             glGetIntegeri_v(GL_BLEND_EQUATION_ALPHA, i, &blendEquationAlpha);
5915         }
5916         else
5917         {
5918             glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
5919             glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
5920         }
5921         EXPECT_EQ(blendEquationRGB, GL_FUNC_SUBTRACT);
5922         EXPECT_EQ(blendEquationAlpha, GL_FUNC_SUBTRACT);
5923 
5924         GLint blendSrcRGB, blendSrcAlpha, blendDstRGB, blendDstAlpha;
5925         if (drawBufferIndexCount > 1)
5926         {
5927             glGetIntegeri_v(GL_BLEND_SRC_RGB, i, &blendSrcRGB);
5928             glGetIntegeri_v(GL_BLEND_SRC_ALPHA, i, &blendSrcAlpha);
5929             glGetIntegeri_v(GL_BLEND_DST_RGB, i, &blendDstRGB);
5930             glGetIntegeri_v(GL_BLEND_DST_ALPHA, i, &blendDstAlpha);
5931         }
5932         else
5933         {
5934             glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
5935             glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
5936             glGetIntegerv(GL_BLEND_DST_RGB, &blendDstRGB);
5937             glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDstAlpha);
5938         }
5939         EXPECT_EQ(blendSrcRGB, GL_ONE);
5940         EXPECT_EQ(blendSrcAlpha, GL_ONE);
5941         EXPECT_EQ(blendDstRGB, GL_CONSTANT_COLOR);
5942         EXPECT_EQ(blendDstAlpha, GL_CONSTANT_COLOR);
5943     }
5944 
5945     glBeginPixelLocalStorageANGLE(
5946         numActivePlanes, std::vector<GLenum>(numActivePlanes, GL_LOAD_OP_ZERO_ANGLE).data());
5947     ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, numActivePlanes);
5948     ASSERT_GL_NO_ERROR();
5949 
5950     for (GLint i = 0; i < drawBufferIndexCount; ++i)
5951     {
5952         if (drawBufferIndexCount > 1)
5953         {
5954             glBlendEquationSeparateiOES(i, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD);
5955             glBlendFuncSeparateiOES(i, GL_ZERO, GL_DST_COLOR, GL_DST_ALPHA, GL_SRC_COLOR);
5956         }
5957         else
5958         {
5959             glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD);
5960             glBlendFuncSeparate(GL_ZERO, GL_DST_COLOR, GL_DST_ALPHA, GL_SRC_COLOR);
5961         }
5962         ASSERT_GL_NO_ERROR();
5963     }
5964 
5965     glEndPixelLocalStorageANGLE(numActivePlanes,
5966                                 std::vector<GLenum>(numActivePlanes, GL_DONT_CARE).data());
5967     ASSERT_GL_NO_ERROR();
5968 
5969     for (GLint i = 0; i < drawBufferIndexCount; ++i)
5970     {
5971         GLint blendEquationRGB, blendEquationAlpha;
5972         if (drawBufferIndexCount > 1)
5973         {
5974             glGetIntegeri_v(GL_BLEND_EQUATION_RGB, i, &blendEquationRGB);
5975             glGetIntegeri_v(GL_BLEND_EQUATION_ALPHA, i, &blendEquationAlpha);
5976         }
5977         else
5978         {
5979             glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
5980             glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
5981         }
5982         EXPECT_EQ(blendEquationRGB, GL_FUNC_REVERSE_SUBTRACT);
5983         EXPECT_EQ(blendEquationAlpha, GL_FUNC_ADD);
5984 
5985         GLint blendSrcRGB, blendDstRGB, blendSrcAlpha, blendDstAlpha;
5986         if (drawBufferIndexCount > 1)
5987         {
5988             glGetIntegeri_v(GL_BLEND_SRC_RGB, i, &blendSrcRGB);
5989             glGetIntegeri_v(GL_BLEND_SRC_ALPHA, i, &blendSrcAlpha);
5990             glGetIntegeri_v(GL_BLEND_DST_RGB, i, &blendDstRGB);
5991             glGetIntegeri_v(GL_BLEND_DST_ALPHA, i, &blendDstAlpha);
5992         }
5993         else
5994         {
5995             glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
5996             glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
5997             glGetIntegerv(GL_BLEND_DST_RGB, &blendDstRGB);
5998             glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDstAlpha);
5999         }
6000         EXPECT_EQ(blendSrcRGB, GL_ZERO);
6001         EXPECT_EQ(blendDstRGB, GL_DST_COLOR);
6002         EXPECT_EQ(blendSrcAlpha, GL_DST_ALPHA);
6003         EXPECT_EQ(blendDstAlpha, GL_SRC_COLOR);
6004     }
6005 }
6006 
6007 // Check that glEnable(GL_BLEND) and glColorMask() do not generate errors, and are ignored for
6008 // overridden draw buffers during PLS.
TEST_P(PixelLocalStorageValidationTest,BlendMaskDuringPLS)6009 TEST_P(PixelLocalStorageValidationTest, BlendMaskDuringPLS)
6010 {
6011     // Make sure we're given a context where this test is relevant.
6012     ASSERT(MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE < MAX_DRAW_BUFFERS);
6013 
6014     PLSTestTexture tex(GL_RGBA8);
6015     GLFramebuffer fbo;
6016     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
6017     glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0);
6018     int numActivePlanes = MAX_PIXEL_LOCAL_STORAGE_PLANES - 1;
6019     for (int i = 1; i < numActivePlanes; ++i)
6020     {
6021         glFramebufferMemorylessPixelLocalStorageANGLE(i, GL_RGBA8);
6022     }
6023     auto beginPLS = [=]() {
6024         glBeginPixelLocalStorageANGLE(
6025             numActivePlanes, std::vector<GLenum>(numActivePlanes, GL_LOAD_OP_ZERO_ANGLE).data());
6026     };
6027     auto endPLS = [=]() {
6028         glEndPixelLocalStorageANGLE(numActivePlanes,
6029                                     std::vector<GLenum>(numActivePlanes, GL_DONT_CARE).data());
6030     };
6031     int firstOverriddenDrawBuffer =
6032         std::min(MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE,
6033                  MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES - numActivePlanes);
6034 
6035 #define CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED()                         \
6036     for (int i = firstOverriddenDrawBuffer; i < MAX_DRAW_BUFFERS; ++i) \
6037     {                                                                  \
6038         EXPECT_FALSE(glIsEnabledi(GL_BLEND, i));                       \
6039     }
6040 
6041 #define EXPECT_NON_OVERRIDDEN_BLEND_MASK(ENABLED)             \
6042     if (!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed")) \
6043     {                                                         \
6044         EXPECT_FALSE(glIsEnabled(GL_BLEND));                  \
6045     }                                                         \
6046     else                                                      \
6047     {                                                         \
6048         EXPECT_EQ(glIsEnabled(GL_BLEND), ENABLED);            \
6049         for (int i = 0; i < firstOverriddenDrawBuffer; ++i)   \
6050         {                                                     \
6051             EXPECT_EQ(glIsEnabledi(GL_BLEND, i), ENABLED);    \
6052         }                                                     \
6053         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();               \
6054     }
6055 
6056 #define CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED()                               \
6057     for (int i = firstOverriddenDrawBuffer; i < MAX_DRAW_BUFFERS; ++i)       \
6058     {                                                                        \
6059         EXPECT_GL_COLOR_MASK_INDEXED(i, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
6060     }
6061 
6062 #define EXPECT_NON_OVERRIDDEN_COLOR_MASK(R, G, B, A)              \
6063     if (!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))     \
6064     {                                                             \
6065         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
6066     }                                                             \
6067     else                                                          \
6068     {                                                             \
6069         EXPECT_GL_COLOR_MASK(R, G, B, A);                         \
6070         for (int i = 0; i < firstOverriddenDrawBuffer; ++i)       \
6071         {                                                         \
6072             EXPECT_GL_COLOR_MASK_INDEXED(i, R, G, B, A);          \
6073         }                                                         \
6074         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();                   \
6075     }
6076 
6077     // Set before.
6078     glEnable(GL_BLEND);
6079     EXPECT_TRUE(glIsEnabled(GL_BLEND));
6080     beginPLS();
6081     EXPECT_NON_OVERRIDDEN_BLEND_MASK(GL_TRUE);
6082     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE);
6083     EXPECT_GL_NO_ERROR();
6084     EXPECT_NON_OVERRIDDEN_COLOR_MASK(GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE);
6085     endPLS();
6086     // Blend & color mask shouldn't change after endPLS().
6087     EXPECT_NON_OVERRIDDEN_BLEND_MASK(GL_TRUE);
6088     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE);
6089     glDisable(GL_BLEND);
6090     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6091     EXPECT_GL_NO_ERROR();
6092 
6093     // Set during.
6094     beginPLS();
6095     EXPECT_NON_OVERRIDDEN_BLEND_MASK(GL_FALSE);
6096     EXPECT_NON_OVERRIDDEN_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6097     glEnable(GL_BLEND);
6098     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
6099     EXPECT_GL_NO_ERROR();
6100     EXPECT_NON_OVERRIDDEN_BLEND_MASK(GL_TRUE);
6101     EXPECT_NON_OVERRIDDEN_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
6102     endPLS();
6103     // Blend & color mask shouldn't change after endPLS().
6104     EXPECT_NON_OVERRIDDEN_BLEND_MASK(GL_TRUE);
6105     EXPECT_NON_OVERRIDDEN_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
6106     glDisable(GL_BLEND);
6107     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6108     EXPECT_GL_NO_ERROR();
6109 
6110     if (IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"))
6111     {
6112         ASSERT(firstOverriddenDrawBuffer > 0);
6113         GLint highestPLSDrawBuffer =
6114             std::min(MAX_DRAW_BUFFERS, MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES) -
6115             1;
6116 
6117         // Indexed before, non-indexed during.
6118         glEnablei(GL_BLEND, 0);
6119         glEnablei(GL_BLEND, highestPLSDrawBuffer);
6120         glColorMaski(0, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
6121         glColorMaski(highestPLSDrawBuffer, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
6122 
6123         beginPLS();
6124 
6125         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
6126         if (firstOverriddenDrawBuffer > 1)
6127         {
6128             EXPECT_TRUE(!glIsEnabledi(GL_BLEND, 1));
6129         }
6130         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();
6131 
6132         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
6133         if (firstOverriddenDrawBuffer > 1)
6134         {
6135             EXPECT_GL_COLOR_MASK_INDEXED(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6136         }
6137         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();
6138 
6139         glEnable(GL_BLEND);
6140         EXPECT_TRUE(glIsEnabled(GL_BLEND));
6141         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
6142         if (firstOverriddenDrawBuffer > 1)
6143         {
6144             EXPECT_TRUE(glIsEnabledi(GL_BLEND, 1));
6145         }
6146         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();
6147 
6148         glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6149         EXPECT_GL_COLOR_MASK(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6150         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6151         if (firstOverriddenDrawBuffer > 1)
6152         {
6153             EXPECT_GL_COLOR_MASK_INDEXED(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6154         }
6155         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();
6156 
6157         endPLS();
6158 
6159         EXPECT_TRUE(glIsEnabled(GL_BLEND));
6160         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
6161         if (firstOverriddenDrawBuffer > 1)
6162         {
6163             EXPECT_TRUE(glIsEnabledi(GL_BLEND, 1));
6164         }
6165         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();
6166 
6167         EXPECT_GL_COLOR_MASK(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6168         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6169         if (firstOverriddenDrawBuffer > 1)
6170         {
6171             EXPECT_GL_COLOR_MASK_INDEXED(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
6172         }
6173         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();
6174 
6175         glDisable(GL_BLEND);
6176         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6177 
6178         EXPECT_GL_NO_ERROR();
6179 
6180         // Non-indexed before, indexed during.
6181         glColorMaski(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
6182         glEnable(GL_BLEND);
6183 
6184         beginPLS();
6185 
6186         EXPECT_TRUE(glIsEnabled(GL_BLEND));
6187         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
6188         if (firstOverriddenDrawBuffer > 1)
6189         {
6190             EXPECT_TRUE(glIsEnabledi(GL_BLEND, 1));
6191         }
6192         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();
6193 
6194         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6195         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6196         if (firstOverriddenDrawBuffer > 1)
6197         {
6198             EXPECT_GL_COLOR_MASK_INDEXED(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
6199         }
6200         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();
6201 
6202         glDisablei(GL_BLEND, 1);
6203         glDisablei(GL_BLEND, highestPLSDrawBuffer);
6204         EXPECT_TRUE(glIsEnabled(GL_BLEND));
6205         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
6206         if (firstOverriddenDrawBuffer > 1)
6207         {
6208             EXPECT_FALSE(glIsEnabledi(GL_BLEND, 1));
6209         }
6210         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();
6211 
6212         glColorMaski(2, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
6213         glColorMaski(highestPLSDrawBuffer, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
6214         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6215         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6216         if (firstOverriddenDrawBuffer > 2)
6217         {
6218             EXPECT_GL_COLOR_MASK_INDEXED(2, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
6219         }
6220         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();
6221 
6222         endPLS();
6223 
6224         EXPECT_TRUE(glIsEnabled(GL_BLEND));
6225         EXPECT_TRUE(glIsEnabledi(GL_BLEND, 0));
6226         if (firstOverriddenDrawBuffer > 1)
6227         {
6228             EXPECT_FALSE(glIsEnabledi(GL_BLEND, 1));
6229         }
6230         CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED();
6231 
6232         EXPECT_GL_COLOR_MASK(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6233         EXPECT_GL_COLOR_MASK_INDEXED(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6234         if (firstOverriddenDrawBuffer > 2)
6235         {
6236             EXPECT_GL_COLOR_MASK_INDEXED(2, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
6237         }
6238         CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED();
6239 
6240         glDisable(GL_BLEND);
6241         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
6242 
6243         EXPECT_GL_NO_ERROR();
6244     }
6245 
6246     EXPECT_GL_NO_ERROR();
6247 
6248 #undef CHECK_OVERRIDDEN_COLOR_MASKS_INDEXED
6249 #undef EXPECT_NON_OVERRIDDEN_COLOR_MASK
6250 #undef CHECK_OVERRIDDEN_BLEND_MASKS_INDEXED
6251 #undef EXPECT_NON_OVERRIDDEN_BLEND_MASK
6252 }
6253 
6254 // Check that draw commands validate current PLS state against the shader's PLS uniforms.
TEST_P(PixelLocalStorageValidationTest,DrawCommandValidation)6255 TEST_P(PixelLocalStorageValidationTest, DrawCommandValidation)
6256 {
6257     DrawCommandValidationTest().run();
6258 }
6259 
6260 // Check that PLS gets properly cleaned up when its framebuffer and textures are never deleted.
TEST_P(PixelLocalStorageValidationTest,LeakFramebufferAndTexture)6261 TEST_P(PixelLocalStorageValidationTest, LeakFramebufferAndTexture)
6262 {
6263     GLuint fbo;
6264     glGenFramebuffers(1, &fbo);
6265     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6266 
6267     GLuint tex0;
6268     glGenTextures(1, &tex0);
6269     glBindTexture(GL_TEXTURE_2D, tex0);
6270     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8UI, 10, 10);
6271     glFramebufferTexturePixelLocalStorageANGLE(0, tex0, 0, 0);
6272 
6273     PLSTestTexture tex1(GL_R32F);
6274     glFramebufferTexturePixelLocalStorageANGLE(1, tex1, 0, 0);
6275 
6276     glFramebufferMemorylessPixelLocalStorageANGLE(3, GL_RGBA8I);
6277 
6278     // Delete tex1.
6279     // Don't delete tex0.
6280     // Don't delete fbo.
6281 
6282     // The PixelLocalStorage frontend implementation has internal assertions that verify all its GL
6283     // context objects are properly disposed of.
6284 }
6285 
6286 // Check that PLS gets properly cleaned up when the context is lost.
TEST_P(PixelLocalStorageValidationTest,LoseContext)6287 TEST_P(PixelLocalStorageValidationTest, LoseContext)
6288 {
6289     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
6290 
6291     GLuint fbo0;
6292     glGenFramebuffers(1, &fbo0);
6293 
6294     GLFramebuffer fbo1;
6295 
6296     GLuint tex0;
6297     glGenTextures(1, &tex0);
6298     glBindTexture(GL_TEXTURE_2D, tex0);
6299     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8UI, 10, 10);
6300 
6301     PLSTestTexture tex1(GL_R32F);
6302 
6303     glBindFramebuffer(GL_FRAMEBUFFER, fbo0);
6304     glFramebufferTexturePixelLocalStorageANGLE(0, tex0, 0, 0);
6305     glFramebufferTexturePixelLocalStorageANGLE(1, tex1, 0, 0);
6306     glFramebufferMemorylessPixelLocalStorageANGLE(3, GL_RGBA8I);
6307 
6308     glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
6309     glFramebufferTexturePixelLocalStorageANGLE(0, tex0, 0, 0);
6310     glFramebufferTexturePixelLocalStorageANGLE(1, tex1, 0, 0);
6311     glFramebufferMemorylessPixelLocalStorageANGLE(3, GL_RGBA8I);
6312 
6313     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6314 
6315     glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
6316 
6317     // Delete tex1.
6318     // Don't delete tex0.
6319     // Delete fbo1.
6320     // Don't delete fbo0.
6321 
6322     // The PixelLocalStorage frontend implementation has internal assertions that verify all its GL
6323     // context objects are properly disposed of.
6324 }
6325 
6326 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageValidationTest);
6327 ANGLE_INSTANTIATE_TEST(PixelLocalStorageValidationTest,
6328                        WithRobustness(ES31_NULL()).enable(Feature::EmulatePixelLocalStorage),
6329                        WithRobustness(ES31_NULL())
6330                            .enable(Feature::EmulatePixelLocalStorage)
6331                            .enable(Feature::DisableDrawBuffersIndexed));
6332 
6333 class PixelLocalStorageCompilerTest : public ANGLETest<>
6334 {
6335   public:
PixelLocalStorageCompilerTest()6336     PixelLocalStorageCompilerTest() { setExtensionsEnabled(false); }
6337 
6338   protected:
testSetUp()6339     void testSetUp() override
6340     {
6341         ASSERT(EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
6342 
6343         // INVALID_OPERATION is generated if DITHER is enabled.
6344         glDisable(GL_DITHER);
6345 
6346         ANGLETest::testSetUp();
6347     }
6348     ShaderInfoLog log;
6349 };
6350 
6351 // Check that PLS #extension support is properly implemented.
TEST_P(PixelLocalStorageCompilerTest,Extension)6352 TEST_P(PixelLocalStorageCompilerTest, Extension)
6353 {
6354     // GL_ANGLE_shader_pixel_local_storage_coherent isn't a shader extension. Shaders must always
6355     // use GL_ANGLE_shader_pixel_local_storage, regardless of coherency.
6356     constexpr char kNonexistentPLSCoherentExtension[] = R"(#version 310 es
6357     #extension GL_ANGLE_shader_pixel_local_storage_coherent : require
6358     void main()
6359     {
6360     })";
6361     EXPECT_FALSE(log.compileFragmentShader(kNonexistentPLSCoherentExtension));
6362     EXPECT_TRUE(log.has(
6363         "ERROR: 0:2: 'GL_ANGLE_shader_pixel_local_storage_coherent' : extension is not supported"));
6364 
6365     // PLS type names cannot be used as variable names when the extension is enabled.
6366     constexpr char kPLSEnabledTypesAsNames[] = R"(#version 310 es
6367     #extension all : warn
6368     void main()
6369     {
6370         int pixelLocalANGLE = 0;
6371         int ipixelLocalANGLE = 0;
6372         int upixelLocalANGLE = 0;
6373     })";
6374     EXPECT_FALSE(log.compileFragmentShader(kPLSEnabledTypesAsNames));
6375     EXPECT_TRUE(log.has("ERROR: 0:5: 'pixelLocalANGLE' : syntax error"));
6376 
6377     // PLS type names are fair game when the extension is disabled.
6378     constexpr char kPLSDisabledTypesAsNames[] = R"(#version 310 es
6379     #extension GL_ANGLE_shader_pixel_local_storage : disable
6380     void main()
6381     {
6382         int pixelLocalANGLE = 0;
6383         int ipixelLocalANGLE = 0;
6384         int upixelLocalANGLE = 0;
6385     })";
6386     EXPECT_TRUE(log.compileFragmentShader(kPLSDisabledTypesAsNames));
6387 
6388     // PLS is not allowed in a vertex shader.
6389     constexpr char kPLSInVertexShader[] = R"(#version 310 es
6390     #extension GL_ANGLE_shader_pixel_local_storage : enable
6391     layout(binding=0, rgba8) lowp uniform pixelLocalANGLE pls;
6392     void main()
6393     {
6394         pixelLocalStoreANGLE(pls, vec4(0));
6395     })";
6396     EXPECT_FALSE(log.compileShader(kPLSInVertexShader, GL_VERTEX_SHADER));
6397     EXPECT_TRUE(
6398         log.has("ERROR: 0:3: 'pixelLocalANGLE' : undefined use of pixel local storage outside a "
6399                 "fragment shader"));
6400 
6401     // Internal synchronization functions used by the compiler shouldn't be visible in ESSL.
6402     EXPECT_FALSE(log.compileFragmentShader(R"(#version 310 es
6403     #extension GL_ANGLE_shader_pixel_local_storage : require
6404     void main()
6405     {
6406         beginInvocationInterlockNV();
6407         endInvocationInterlockNV();
6408     })"));
6409     EXPECT_TRUE(log.has(
6410         "ERROR: 0:5: 'beginInvocationInterlockNV' : no matching overloaded function found"));
6411     EXPECT_TRUE(
6412         log.has("ERROR: 0:6: 'endInvocationInterlockNV' : no matching overloaded function found"));
6413 
6414     EXPECT_FALSE(log.compileFragmentShader(R"(#version 310 es
6415     #extension GL_ANGLE_shader_pixel_local_storage : require
6416     void main()
6417     {
6418         beginFragmentShaderOrderingINTEL();
6419     })"));
6420     EXPECT_TRUE(log.has(
6421         "ERROR: 0:5: 'beginFragmentShaderOrderingINTEL' : no matching overloaded function found"));
6422 
6423     EXPECT_FALSE(log.compileFragmentShader(R"(#version 310 es
6424     #extension GL_ANGLE_shader_pixel_local_storage : require
6425     void main()
6426     {
6427         beginInvocationInterlockARB();
6428         endInvocationInterlockARB();
6429     })"));
6430     EXPECT_TRUE(log.has(
6431         "ERROR: 0:5: 'beginInvocationInterlockARB' : no matching overloaded function found"));
6432     EXPECT_TRUE(
6433         log.has("ERROR: 0:6: 'endInvocationInterlockARB' : no matching overloaded function found"));
6434 
6435     ASSERT_GL_NO_ERROR();
6436 }
6437 
6438 // Check proper validation of PLS handle declarations.
TEST_P(PixelLocalStorageCompilerTest,Declarations)6439 TEST_P(PixelLocalStorageCompilerTest, Declarations)
6440 {
6441     // PLS handles must be uniform.
6442     constexpr char kPLSTypesMustBeUniform[] = R"(#version 310 es
6443     #extension GL_ANGLE_shader_pixel_local_storage : enable
6444     layout(binding=0, rgba8) highp pixelLocalANGLE pls1;
6445     void main()
6446     {
6447         highp ipixelLocalANGLE pls2;
6448         highp upixelLocalANGLE pls3;
6449     })";
6450     EXPECT_FALSE(log.compileFragmentShader(kPLSTypesMustBeUniform));
6451     EXPECT_TRUE(log.has("ERROR: 0:3: 'pixelLocalANGLE' : pixelLocalANGLEs must be uniform"));
6452     EXPECT_TRUE(log.has("ERROR: 0:6: 'ipixelLocalANGLE' : ipixelLocalANGLEs must be uniform"));
6453     EXPECT_TRUE(log.has("ERROR: 0:7: 'upixelLocalANGLE' : upixelLocalANGLEs must be uniform"));
6454 
6455     // Memory qualifiers are not allowed on PLS handles.
6456     constexpr char kPLSMemoryQualifiers[] = R"(#version 310 es
6457     #extension GL_ANGLE_shader_pixel_local_storage : require
6458     layout(binding=0, rgba8) uniform lowp volatile coherent restrict pixelLocalANGLE pls1;
6459     layout(binding=1, rgba8i) uniform mediump readonly ipixelLocalANGLE pls2;
6460     void f(uniform highp writeonly upixelLocalANGLE pls);
6461     void main()
6462     {
6463     })";
6464     EXPECT_FALSE(log.compileFragmentShader(kPLSMemoryQualifiers));
6465     EXPECT_TRUE(log.has("ERROR: 0:3: 'coherent' : "));
6466     EXPECT_TRUE(log.has("ERROR: 0:3: 'restrict' : "));
6467     EXPECT_TRUE(log.has("ERROR: 0:3: 'volatile' : "));
6468     EXPECT_TRUE(log.has("ERROR: 0:4: 'readonly' : "));
6469     EXPECT_TRUE(log.has("ERROR: 0:5: 'writeonly' : "));
6470 
6471     // PLS handles must specify precision.
6472     constexpr char kPLSNoPrecision[] = R"(#version 310 es
6473     #extension GL_ANGLE_shader_pixel_local_storage : enable
6474     layout(binding=0, rgba8) uniform pixelLocalANGLE pls1;
6475     layout(binding=1, rgba8i) uniform ipixelLocalANGLE pls2;
6476     void f(upixelLocalANGLE pls3)
6477     {
6478     }
6479     void main()
6480     {
6481     })";
6482     EXPECT_FALSE(log.compileFragmentShader(kPLSNoPrecision));
6483     EXPECT_TRUE(log.has("ERROR: 0:3: 'pixelLocalANGLE' : No precision specified"));
6484     EXPECT_TRUE(log.has("ERROR: 0:4: 'ipixelLocalANGLE' : No precision specified"));
6485     EXPECT_TRUE(log.has("ERROR: 0:5: 'upixelLocalANGLE' : No precision specified"));
6486 
6487     // PLS handles cannot cannot be aggregated in arrays.
6488     constexpr char kPLSArrays[] = R"(#version 310 es
6489     #extension GL_ANGLE_shader_pixel_local_storage : require
6490     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls1[1];
6491     layout(binding=1, rgba8i) uniform mediump ipixelLocalANGLE pls2[2];
6492     layout(binding=2, rgba8ui) uniform highp upixelLocalANGLE pls3[3];
6493     void main()
6494     {
6495     })";
6496     EXPECT_FALSE(log.compileFragmentShader(kPLSArrays));
6497     EXPECT_TRUE(log.has(
6498         "ERROR: 0:3: 'array' : pixel local storage handles cannot be aggregated in arrays"));
6499     EXPECT_TRUE(log.has(
6500         "ERROR: 0:4: 'array' : pixel local storage handles cannot be aggregated in arrays"));
6501     EXPECT_TRUE(log.has(
6502         "ERROR: 0:5: 'array' : pixel local storage handles cannot be aggregated in arrays"));
6503 
6504     // If PLS handles could be used before their declaration, then we would need to update the PLS
6505     // rewriters to make two passes.
6506     constexpr char kPLSUseBeforeDeclaration[] = R"(#version 310 es
6507     #extension GL_ANGLE_shader_pixel_local_storage : require
6508     void f()
6509     {
6510         pixelLocalStoreANGLE(pls, vec4(0));
6511         pixelLocalStoreANGLE(pls2, ivec4(0));
6512     }
6513     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;
6514     void main()
6515     {
6516         pixelLocalStoreANGLE(pls, vec4(0));
6517         pixelLocalStoreANGLE(pls2, ivec4(0));
6518     }
6519     layout(binding=1, rgba8i) uniform lowp ipixelLocalANGLE pls2;)";
6520     EXPECT_FALSE(log.compileFragmentShader(kPLSUseBeforeDeclaration));
6521     EXPECT_TRUE(log.has("ERROR: 0:5: 'pls' : undeclared identifier"));
6522     EXPECT_TRUE(log.has("ERROR: 0:6: 'pls2' : undeclared identifier"));
6523     EXPECT_TRUE(log.has("ERROR: 0:12: 'pls2' : undeclared identifier"));
6524 
6525     // PLS unimorms must be declared at global scope; they cannot be declared in structs or
6526     // interface blocks.
6527     constexpr char kPLSInStruct[] = R"(#version 310 es
6528     #extension GL_ANGLE_shader_pixel_local_storage : require
6529     struct Foo
6530     {
6531         lowp pixelLocalANGLE pls;
6532     };
6533     uniform Foo foo;
6534     uniform PLSBlock
6535     {
6536         lowp pixelLocalANGLE blockpls;
6537     };
6538     void main()
6539     {
6540         pixelLocalStoreANGLE(foo.pls, pixelLocalLoadANGLE(blockpls));
6541     })";
6542     EXPECT_FALSE(log.compileFragmentShader(kPLSInStruct));
6543     EXPECT_TRUE(log.has("ERROR: 0:5: 'pixelLocalANGLE' : disallowed type in struct"));
6544     EXPECT_TRUE(
6545         log.has("ERROR: 0:10: 'PLSBlock' : Opaque types are not allowed in interface blocks"));
6546 
6547     ASSERT_GL_NO_ERROR();
6548 }
6549 
6550 // Check proper validation of PLS layout qualifiers.
TEST_P(PixelLocalStorageCompilerTest,LayoutQualifiers)6551 TEST_P(PixelLocalStorageCompilerTest, LayoutQualifiers)
6552 {
6553     // PLS handles must use a supported format and binding.
6554     constexpr char kPLSUnsupportedFormatsAndBindings[] = R"(#version 310 es
6555     #extension GL_ANGLE_shader_pixel_local_storage : require
6556     layout(binding=0, rgba32f) highp uniform pixelLocalANGLE pls0;
6557     layout(binding=1, rgba16f) highp uniform pixelLocalANGLE pls1;
6558     layout(binding=2, rgba8_snorm) highp uniform pixelLocalANGLE pls2;
6559     layout(binding=3, rgba32ui) highp uniform upixelLocalANGLE pls3;
6560     layout(binding=4, rgba16ui) highp uniform upixelLocalANGLE pls4;
6561     layout(binding=5, rgba32i) highp uniform ipixelLocalANGLE pls5;
6562     layout(binding=6, rgba16i) highp uniform ipixelLocalANGLE pls6;
6563     layout(binding=7, r32i) highp uniform ipixelLocalANGLE pls7;
6564     layout(binding=999999999, rgba) highp uniform ipixelLocalANGLE pls8;
6565     highp uniform pixelLocalANGLE pls9;
6566     void main()
6567     {
6568     })";
6569     EXPECT_FALSE(log.compileFragmentShader(kPLSUnsupportedFormatsAndBindings));
6570     EXPECT_TRUE(log.has("ERROR: 0:3: 'rgba32f' : illegal pixel local storage format"));
6571     EXPECT_TRUE(log.has("ERROR: 0:4: 'rgba16f' : illegal pixel local storage format"));
6572     EXPECT_TRUE(log.has("ERROR: 0:5: 'rgba8_snorm' : illegal pixel local storage format"));
6573     EXPECT_TRUE(log.has("ERROR: 0:6: 'rgba32ui' : illegal pixel local storage format"));
6574     EXPECT_TRUE(log.has("ERROR: 0:7: 'rgba16ui' : illegal pixel local storage format"));
6575     EXPECT_TRUE(log.has("ERROR: 0:8: 'rgba32i' : illegal pixel local storage format"));
6576     EXPECT_TRUE(log.has("ERROR: 0:9: 'rgba16i' : illegal pixel local storage format"));
6577     EXPECT_TRUE(log.has("ERROR: 0:10: 'r32i' : illegal pixel local storage format"));
6578     EXPECT_TRUE(log.has("ERROR: 0:11: 'rgba' : invalid layout qualifier"));
6579     EXPECT_TRUE(log.has(
6580         "ERROR: 0:11: 'layout qualifier' : pixel local storage requires a format specifier"));
6581     EXPECT_TRUE(log.has(
6582         "ERROR: 0:12: 'layout qualifier' : pixel local storage requires a format specifier"));
6583     EXPECT_TRUE(
6584         log.has("ERROR: 0:12: 'layout qualifier' : pixel local storage requires a binding index"));
6585 
6586     // PLS handles must be within MAX_PIXEL_LOCAL_STORAGE_PLANES.
6587     GLint MAX_PIXEL_LOCAL_STORAGE_PLANES;
6588     glGetIntegerv(GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE, &MAX_PIXEL_LOCAL_STORAGE_PLANES);
6589     std::ostringstream bindingTooLarge;
6590     bindingTooLarge << "#version 310 es\n";
6591     bindingTooLarge << "#extension GL_ANGLE_shader_pixel_local_storage : require\n";
6592     bindingTooLarge << "layout(binding=" << MAX_PIXEL_LOCAL_STORAGE_PLANES
6593                     << ", rgba8) highp uniform pixelLocalANGLE pls;\n";
6594     bindingTooLarge << "void main() {}\n";
6595     EXPECT_FALSE(log.compileFragmentShader(bindingTooLarge.str().c_str()));
6596     EXPECT_TRUE(
6597         log.has("ERROR: 0:3: 'layout qualifier' : pixel local storage binding out of range"));
6598 
6599     // PLS handles must use the correct type for the given format.
6600     constexpr char kPLSInvalidTypeForFormat[] = R"(#version 310 es
6601     #extension GL_ANGLE_shader_pixel_local_storage : require
6602     layout(binding=0) highp uniform pixelLocalANGLE pls0;
6603     layout(binding=1) highp uniform upixelLocalANGLE pls1;
6604     layout(binding=2) highp uniform ipixelLocalANGLE pls2;
6605     layout(binding=3, rgba8) highp uniform ipixelLocalANGLE pls3;
6606     layout(binding=4, rgba8) highp uniform upixelLocalANGLE pls4;
6607     layout(binding=5, rgba8ui) highp uniform pixelLocalANGLE pls5;
6608     layout(binding=6, rgba8ui) highp uniform ipixelLocalANGLE pls6;
6609     layout(binding=7, rgba8i) highp uniform upixelLocalANGLE pls7;
6610     layout(binding=8, rgba8i) highp uniform pixelLocalANGLE pls8;
6611     layout(binding=9, r32f) highp uniform ipixelLocalANGLE pls9;
6612     layout(binding=10, r32f) highp uniform upixelLocalANGLE pls10;
6613     layout(binding=11, r32ui) highp uniform pixelLocalANGLE pls11;
6614     layout(binding=12, r32ui) highp uniform ipixelLocalANGLE pls12;
6615     void main()
6616     {
6617     })";
6618     EXPECT_FALSE(log.compileFragmentShader(kPLSInvalidTypeForFormat));
6619     EXPECT_TRUE(log.has(
6620         "ERROR: 0:3: 'layout qualifier' : pixel local storage requires a format specifier"));
6621     EXPECT_TRUE(log.has(
6622         "ERROR: 0:4: 'layout qualifier' : pixel local storage requires a format specifier"));
6623     EXPECT_TRUE(log.has(
6624         "ERROR: 0:5: 'layout qualifier' : pixel local storage requires a format specifier"));
6625     EXPECT_TRUE(
6626         log.has("ERROR: 0:6: 'rgba8' : pixel local storage format requires pixelLocalANGLE"));
6627     EXPECT_TRUE(
6628         log.has("ERROR: 0:7: 'rgba8' : pixel local storage format requires pixelLocalANGLE"));
6629     EXPECT_TRUE(
6630         log.has("ERROR: 0:8: 'rgba8ui' : pixel local storage format requires upixelLocalANGLE"));
6631     EXPECT_TRUE(
6632         log.has("ERROR: 0:9: 'rgba8ui' : pixel local storage format requires upixelLocalANGLE"));
6633     EXPECT_TRUE(
6634         log.has("ERROR: 0:10: 'rgba8i' : pixel local storage format requires ipixelLocalANGLE"));
6635     EXPECT_TRUE(
6636         log.has("ERROR: 0:11: 'rgba8i' : pixel local storage format requires ipixelLocalANGLE"));
6637     EXPECT_TRUE(
6638         log.has("ERROR: 0:12: 'r32f' : pixel local storage format requires pixelLocalANGLE"));
6639     EXPECT_TRUE(
6640         log.has("ERROR: 0:13: 'r32f' : pixel local storage format requires pixelLocalANGLE"));
6641     EXPECT_TRUE(
6642         log.has("ERROR: 0:14: 'r32ui' : pixel local storage format requires upixelLocalANGLE"));
6643     EXPECT_TRUE(
6644         log.has("ERROR: 0:15: 'r32ui' : pixel local storage format requires upixelLocalANGLE"));
6645 
6646     // PLS handles cannot have duplicate binding indices.
6647     constexpr char kPLSDuplicateBindings[] = R"(#version 310 es
6648     #extension GL_ANGLE_shader_pixel_local_storage : require
6649     layout(binding=0, rgba) uniform highp pixelLocalANGLE pls0;
6650     layout(rgba8i, binding=1) uniform highp ipixelLocalANGLE pls1;
6651     layout(binding=2, rgba8ui) uniform highp upixelLocalANGLE pls2;
6652     layout(binding=1, rgba) uniform highp ipixelLocalANGLE pls3;
6653     layout(rgba8i, binding=0) uniform mediump ipixelLocalANGLE pls4;
6654     void main()
6655     {
6656     })";
6657     EXPECT_FALSE(log.compileFragmentShader(kPLSDuplicateBindings));
6658     EXPECT_TRUE(log.has("ERROR: 0:6: '1' : duplicate pixel local storage binding index"));
6659     EXPECT_TRUE(log.has("ERROR: 0:7: '0' : duplicate pixel local storage binding index"));
6660 
6661     // PLS handles cannot have duplicate binding indices.
6662     constexpr char kPLSIllegalLayoutQualifiers[] = R"(#version 310 es
6663     #extension GL_ANGLE_shader_pixel_local_storage : require
6664     layout(foo) highp uniform pixelLocalANGLE pls1;
6665     layout(binding=0, location=0, rgba8ui) highp uniform upixelLocalANGLE pls2;
6666     void main()
6667     {
6668     })";
6669     EXPECT_FALSE(log.compileFragmentShader(kPLSIllegalLayoutQualifiers));
6670     EXPECT_TRUE(log.has("ERROR: 0:3: 'foo' : invalid layout qualifier"));
6671     EXPECT_TRUE(
6672         log.has("ERROR: 0:4: 'location' : location must only be specified for a single input or "
6673                 "output variable"));
6674 
6675     // Check that binding is not allowed in ES3, other than pixel local storage. ES3 doesn't have
6676     // blocks, and only has one opaque type: samplers. So we just need to make sure binding isn't
6677     // allowed on samplers.
6678     constexpr char kBindingOnSampler[] = R"(#version 300 es
6679     #extension GL_ANGLE_shader_pixel_local_storage : require
6680     layout(binding=0) uniform mediump sampler2D sampler;
6681     void main()
6682     {
6683     })";
6684     EXPECT_FALSE(log.compileFragmentShader(kBindingOnSampler));
6685     EXPECT_TRUE(
6686         log.has("ERROR: 0:3: 'binding' : invalid layout qualifier: only valid when used with pixel "
6687                 "local storage"));
6688 
6689     // Binding qualifiers generate different error messages depending on ES3 and ES31.
6690     constexpr char kBindingOnOutput[] = R"(#version 310 es
6691     layout(binding=0) out mediump vec4 color;
6692     void main()
6693     {
6694     })";
6695     EXPECT_FALSE(log.compileFragmentShader(kBindingOnOutput));
6696     EXPECT_TRUE(
6697         log.has("ERROR: 0:2: 'binding' : invalid layout qualifier: only valid when used with "
6698                 "opaque types or blocks"));
6699 
6700     // Check that internalformats are not allowed in ES3 except for PLS.
6701     constexpr char kFormatOnSamplerES3[] = R"(#version 300 es
6702     layout(rgba8) uniform mediump sampler2D sampler1;
6703     layout(rgba8_snorm) uniform mediump sampler2D sampler2;
6704     void main()
6705     {
6706     })";
6707     EXPECT_FALSE(log.compileFragmentShader(kFormatOnSamplerES3));
6708     EXPECT_TRUE(
6709         log.has("ERROR: 0:2: 'rgba8' : invalid layout qualifier: not supported before GLSL ES "
6710                 "3.10, except pixel local storage"));
6711     EXPECT_TRUE(log.has(
6712         "ERROR: 0:3: 'rgba8_snorm' : invalid layout qualifier: not supported before GLSL ES 3.10"));
6713 
6714     // Format qualifiers generate different error messages depending on whether they can be used
6715     // with PLS.
6716     constexpr char kFormatOnSamplerES31[] = R"(#version 310 es
6717     layout(rgba8) uniform mediump sampler2D sampler1;
6718     layout(rgba8_snorm) uniform mediump sampler2D sampler2;
6719     void main()
6720     {
6721     })";
6722     EXPECT_FALSE(log.compileFragmentShader(kFormatOnSamplerES31));
6723     EXPECT_TRUE(
6724         log.has("ERROR: 0:2: 'rgba8' : invalid layout qualifier: only valid when used with images "
6725                 "or pixel local storage"));
6726     EXPECT_TRUE(log.has(
6727         "ERROR: 0:3: 'rgba8_snorm' : invalid layout qualifier: only valid when used with images"));
6728 
6729     ASSERT_GL_NO_ERROR();
6730 }
6731 
6732 // Check proper validation of the discard statement when pixel local storage is(n't) declared.
TEST_P(PixelLocalStorageCompilerTest,Discard)6733 TEST_P(PixelLocalStorageCompilerTest, Discard)
6734 {
6735     // Discard is not allowed when pixel local storage has been declared. When polyfilled with
6736     // shader images, pixel local storage requires early_fragment_tests, which causes discard to
6737     // interact differently with the depth and stencil tests.
6738     //
6739     // To ensure identical behavior across all backends (some of which may not have access to
6740     // early_fragment_tests), we disallow discard if pixel local storage has been declared.
6741     constexpr char kDiscardWithPLS[] = R"(#version 310 es
6742     #extension GL_ANGLE_shader_pixel_local_storage : require
6743     layout(binding=0, rgba8) highp uniform pixelLocalANGLE pls;
6744     void a()
6745     {
6746         discard;
6747     }
6748     void b();
6749     void main()
6750     {
6751         if (gl_FragDepth == 3.14)
6752             discard;
6753         discard;
6754     }
6755     void b()
6756     {
6757         discard;
6758     })";
6759     EXPECT_FALSE(log.compileFragmentShader(kDiscardWithPLS));
6760     EXPECT_TRUE(
6761         log.has("ERROR: 0:6: 'discard' : illegal discard when pixel local storage is declared"));
6762     EXPECT_TRUE(
6763         log.has("ERROR: 0:12: 'discard' : illegal discard when pixel local storage is declared"));
6764     EXPECT_TRUE(
6765         log.has("ERROR: 0:13: 'discard' : illegal discard when pixel local storage is declared"));
6766     EXPECT_TRUE(
6767         log.has("ERROR: 0:17: 'discard' : illegal discard when pixel local storage is declared"));
6768 
6769     // Discard is OK when pixel local storage has _not_ been declared.
6770     constexpr char kDiscardNoPLS[] = R"(#version 310 es
6771     #extension GL_ANGLE_shader_pixel_local_storage : require
6772     void f(lowp pixelLocalANGLE pls);  // Function arguments don't trigger PLS restrictions.
6773     void a()
6774     {
6775         discard;
6776     }
6777     void b();
6778     void main()
6779     {
6780         if (gl_FragDepth == 3.14)
6781             discard;
6782         discard;
6783     }
6784     void b()
6785     {
6786         discard;
6787     })";
6788     EXPECT_TRUE(log.compileFragmentShader(kDiscardNoPLS));
6789 
6790     // Ensure discard is caught even if it happens before PLS is declared.
6791     constexpr char kDiscardBeforePLS[] = R"(#version 310 es
6792     #extension GL_ANGLE_shader_pixel_local_storage : require
6793     void a()
6794     {
6795         discard;
6796     }
6797     void main()
6798     {
6799     }
6800     layout(binding=0, rgba8) highp uniform pixelLocalANGLE pls;)";
6801     EXPECT_FALSE(log.compileFragmentShader(kDiscardBeforePLS));
6802     EXPECT_TRUE(
6803         log.has("ERROR: 0:5: 'discard' : illegal discard when pixel local storage is declared"));
6804 
6805     ASSERT_GL_NO_ERROR();
6806 }
6807 
6808 // Check proper validation of the return statement when pixel local storage is(n't) declared.
TEST_P(PixelLocalStorageCompilerTest,Return)6809 TEST_P(PixelLocalStorageCompilerTest, Return)
6810 {
6811     // Returning from main isn't allowed when pixel local storage has been declared.
6812     // (ARB_fragment_shader_interlock isn't allowed after return from main.)
6813     constexpr char kReturnFromMainWithPLS[] = R"(#version 310 es
6814     #extension GL_ANGLE_shader_pixel_local_storage : require
6815     layout(binding=0, rgba8) highp uniform pixelLocalANGLE pls;
6816     void main()
6817     {
6818         if (gl_FragDepth == 3.14)
6819             return;
6820         return;
6821     })";
6822     EXPECT_FALSE(log.compileFragmentShader(kReturnFromMainWithPLS));
6823     EXPECT_TRUE(log.has(
6824         "ERROR: 0:7: 'return' : illegal return from main when pixel local storage is declared"));
6825     EXPECT_TRUE(log.has(
6826         "ERROR: 0:8: 'return' : illegal return from main when pixel local storage is declared"));
6827 
6828     // Returning from main is OK when pixel local storage has _not_ been declared.
6829     constexpr char kReturnFromMainNoPLS[] = R"(#version 310 es
6830     #extension GL_ANGLE_shader_pixel_local_storage : require
6831     void main()
6832     {
6833         if (gl_FragDepth == 3.14)
6834             return;
6835         return;
6836     })";
6837     EXPECT_TRUE(log.compileFragmentShader(kReturnFromMainNoPLS));
6838 
6839     // Returning from subroutines is OK when pixel local storage has been declared.
6840     constexpr char kReturnFromSubroutinesWithPLS[] = R"(#version 310 es
6841     #extension GL_ANGLE_shader_pixel_local_storage : require
6842     layout(rgba8ui, binding=0) highp uniform upixelLocalANGLE pls;
6843     void a()
6844     {
6845         return;
6846     }
6847     void b();
6848     void main()
6849     {
6850         a();
6851         b();
6852     }
6853     void b()
6854     {
6855         return;
6856     })";
6857     EXPECT_TRUE(log.compileFragmentShader(kReturnFromSubroutinesWithPLS));
6858 
6859     // Ensure return from main is caught even if it happens before PLS is declared.
6860     constexpr char kDiscardBeforePLS[] = R"(#version 310 es
6861     #extension GL_ANGLE_shader_pixel_local_storage : require
6862     void main()
6863     {
6864         return;
6865     }
6866     layout(binding=0, rgba8) highp uniform pixelLocalANGLE pls;)";
6867     EXPECT_FALSE(log.compileFragmentShader(kDiscardBeforePLS));
6868     EXPECT_TRUE(log.has(
6869         "ERROR: 0:5: 'return' : illegal return from main when pixel local storage is declared"));
6870 
6871     ASSERT_GL_NO_ERROR();
6872 }
6873 
6874 // Check that gl_FragDepth(EXT) and gl_SampleMask are not assignable when PLS is declared.
TEST_P(PixelLocalStorageCompilerTest,FragmentTestVariables)6875 TEST_P(PixelLocalStorageCompilerTest, FragmentTestVariables)
6876 {
6877     // gl_FragDepth is not assignable when pixel local storage has been declared. When polyfilled
6878     // with shader images, pixel local storage requires early_fragment_tests, which causes
6879     // assignments to gl_FragDepth(EXT) and gl_SampleMask to be ignored.
6880     //
6881     // To ensure identical behavior across all backends, we disallow assignment to these values if
6882     // pixel local storage has been declared.
6883     constexpr char kAssignFragDepthWithPLS[] = R"(#version 310 es
6884     #extension GL_ANGLE_shader_pixel_local_storage : require
6885     void set(out mediump float x, mediump float val)
6886     {
6887         x = val;
6888     }
6889     void set2(inout mediump float x, mediump float val)
6890     {
6891         x = val;
6892     }
6893     void main()
6894     {
6895         gl_FragDepth = 0.0;
6896         gl_FragDepth -= 1.0;
6897         set(gl_FragDepth, 0.0);
6898         set2(gl_FragDepth, 0.1);
6899     }
6900     layout(binding=0, rgba8i) lowp uniform ipixelLocalANGLE pls;)";
6901     EXPECT_FALSE(log.compileFragmentShader(kAssignFragDepthWithPLS));
6902     EXPECT_TRUE(log.has(
6903         "ERROR: 0:13: 'gl_FragDepth' : value not assignable when pixel local storage is declared"));
6904     EXPECT_TRUE(log.has(
6905         "ERROR: 0:14: 'gl_FragDepth' : value not assignable when pixel local storage is declared"));
6906     EXPECT_TRUE(log.has(
6907         "ERROR: 0:15: 'gl_FragDepth' : value not assignable when pixel local storage is declared"));
6908     EXPECT_TRUE(log.has(
6909         "ERROR: 0:16: 'gl_FragDepth' : value not assignable when pixel local storage is declared"));
6910 
6911     // Assigning gl_FragDepth is OK if we don't declare any PLS.
6912     constexpr char kAssignFragDepthNoPLS[] = R"(#version 310 es
6913     #extension GL_ANGLE_shader_pixel_local_storage : require
6914     void f(highp ipixelLocalANGLE pls)
6915     {
6916         // Function arguments don't trigger PLS restrictions.
6917         pixelLocalStoreANGLE(pls, ivec4(8));
6918     }
6919     void set(out mediump float x, mediump float val)
6920     {
6921         x = val;
6922     }
6923     void main()
6924     {
6925         gl_FragDepth = 0.0;
6926         gl_FragDepth /= 2.0;
6927         set(gl_FragDepth, 0.0);
6928     })";
6929     EXPECT_TRUE(log.compileFragmentShader(kAssignFragDepthNoPLS));
6930 
6931     // Reading gl_FragDepth is OK.
6932     constexpr char kReadFragDepth[] = R"(#version 310 es
6933     #extension GL_ANGLE_shader_pixel_local_storage : require
6934     layout(r32f, binding=0) highp uniform pixelLocalANGLE pls;
6935     highp vec4 get(in mediump float x)
6936     {
6937         return vec4(x);
6938     }
6939     void set(inout mediump float x, mediump float val)
6940     {
6941         x = val;
6942     }
6943     void main()
6944     {
6945         pixelLocalStoreANGLE(pls, get(gl_FragDepth));
6946         // Check when gl_FragDepth is involved in an l-value expression, but not assigned to.
6947         highp float x[2];
6948         x[int(gl_FragDepth)] = 1.0;
6949         set(x[1 - int(gl_FragDepth)], 2.0);
6950     })";
6951     EXPECT_TRUE(log.compileFragmentShader(kReadFragDepth));
6952 
6953     if (EnsureGLExtensionEnabled("GL_OES_sample_variables"))
6954     {
6955         // gl_SampleMask is not assignable when pixel local storage has been declared. The shader
6956         // image polyfill requires early_fragment_tests, which causes gl_SampleMask to be ignored.
6957         //
6958         // To ensure identical behavior across all implementations (some of which may not have
6959         // access to early_fragment_tests), we disallow assignment to these values if pixel local
6960         // storage has been declared.
6961         constexpr char kAssignSampleMaskWithPLS[] = R"(#version 310 es
6962         #extension GL_ANGLE_shader_pixel_local_storage : require
6963         #extension GL_OES_sample_variables : require
6964         void set(out highp int x, highp int val)
6965         {
6966             x = val;
6967         }
6968         void set2(inout highp int x, highp int val)
6969         {
6970             x = val;
6971         }
6972         void main()
6973         {
6974             gl_SampleMask[0] = 0;
6975             gl_SampleMask[0] ^= 1;
6976             set(gl_SampleMask[0], 9);
6977             set2(gl_SampleMask[0], 10);
6978         }
6979         layout(binding=0, rgba8i) highp uniform ipixelLocalANGLE pls;)";
6980         EXPECT_FALSE(log.compileFragmentShader(kAssignSampleMaskWithPLS));
6981         EXPECT_TRUE(
6982             log.has("ERROR: 0:14: 'gl_SampleMask' : value not assignable when pixel local storage "
6983                     "is declared"));
6984         EXPECT_TRUE(
6985             log.has("ERROR: 0:15: 'gl_SampleMask' : value not assignable when pixel local storage "
6986                     "is declared"));
6987         EXPECT_TRUE(
6988             log.has("ERROR: 0:16: 'gl_SampleMask' : value not assignable when pixel local storage "
6989                     "is declared"));
6990         EXPECT_TRUE(
6991             log.has("ERROR: 0:17: 'gl_SampleMask' : value not assignable when pixel local storage "
6992                     "is declared"));
6993 
6994         // Assigning gl_SampleMask is OK if we don't declare any PLS.
6995         constexpr char kAssignSampleMaskNoPLS[] = R"(#version 310 es
6996         #extension GL_ANGLE_shader_pixel_local_storage : require
6997         #extension GL_OES_sample_variables : require
6998         void set(out highp int x, highp int val)
6999         {
7000             x = val;
7001         }
7002         void main()
7003         {
7004             gl_SampleMask[0] = 0;
7005             gl_SampleMask[0] ^= 1;
7006             set(gl_SampleMask[0], 9);
7007         })";
7008         EXPECT_TRUE(log.compileFragmentShader(kAssignSampleMaskNoPLS));
7009 
7010         // Reading gl_SampleMask is OK enough (even though it's technically output only).
7011         constexpr char kReadSampleMask[] = R"(#version 310 es
7012         #extension GL_ANGLE_shader_pixel_local_storage : require
7013         #extension GL_OES_sample_variables : require
7014         layout(binding=0, rgba8i) highp uniform ipixelLocalANGLE pls;
7015         highp int get(in highp int x)
7016         {
7017             return x;
7018         }
7019         void set(out highp int x, highp int val)
7020         {
7021             x = val;
7022         }
7023         void main()
7024         {
7025             pixelLocalStoreANGLE(pls, ivec4(get(gl_SampleMask[0]), gl_SampleMaskIn[0], 0, 1));
7026             // Check when gl_SampleMask is involved in an l-value expression, but not assigned to.
7027             highp int x[2];
7028             x[gl_SampleMask[0]] = 1;
7029             set(x[gl_SampleMask[0]], 2);
7030         })";
7031         EXPECT_TRUE(log.compileFragmentShader(kReadSampleMask));
7032     }
7033 
7034     ASSERT_GL_NO_ERROR();
7035 }
7036 
7037 // Check that the "blend_support" layout qualifiers defined in KHR_blend_equation_advanced are
7038 // illegal when PLS is declared.
TEST_P(PixelLocalStorageCompilerTest,BlendFuncExtended_illegal_with_PLS)7039 TEST_P(PixelLocalStorageCompilerTest, BlendFuncExtended_illegal_with_PLS)
7040 {
7041     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_blend_func_extended"));
7042 
7043     // Just declaring the extension is ok.
7044     constexpr char kRequireBlendFuncExtended[] = R"(#version 300 es
7045     #extension GL_ANGLE_shader_pixel_local_storage : require
7046     #extension GL_EXT_blend_func_extended : require
7047     void main()
7048     {}
7049     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;)";
7050     EXPECT_TRUE(log.compileFragmentShader(kRequireBlendFuncExtended));
7051 
7052     // The <index> layout qualifier from EXT_blend_func_extended is illegal.
7053     constexpr char kBlendFuncExtendedIndex[] = R"(#version 300 es
7054     #extension GL_ANGLE_shader_pixel_local_storage : require
7055     #extension GL_EXT_blend_func_extended : require
7056     layout(location=0, index=1) out lowp vec4 out1;
7057     void main()
7058     {}
7059     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;)";
7060     EXPECT_FALSE(log.compileFragmentShader(kBlendFuncExtendedIndex));
7061     EXPECT_TRUE(
7062         log.has("ERROR: 0:4: 'layout' : illegal nonzero index qualifier when pixel local storage "
7063                 "is declared"));
7064 
7065     // Multiple unassigned fragment output locations are illegal, even if EXT_blend_func_extended is
7066     // enabled.
7067     constexpr char kBlendFuncExtendedNoLocation[] = R"(#version 300 es
7068     #extension GL_ANGLE_shader_pixel_local_storage : require
7069     #extension GL_EXT_blend_func_extended : require
7070     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;
7071     out lowp vec4 out1;
7072     out lowp vec4 out0;
7073     void main()
7074     {})";
7075     EXPECT_FALSE(log.compileFragmentShader(kBlendFuncExtendedNoLocation));
7076     EXPECT_TRUE(log.has(
7077         "ERROR: 0:5: 'out1' : must explicitly specify all locations when using multiple fragment "
7078         "outputs and pixel local storage, even if EXT_blend_func_extended is enabled"));
7079     EXPECT_TRUE(log.has(
7080         "ERROR: 0:6: 'out0' : must explicitly specify all locations when using multiple fragment "
7081         "outputs and pixel local storage, even if EXT_blend_func_extended is enabled"));
7082 
7083     // index=0 is ok.
7084     constexpr char kValidFragmentIndex0[] = R"(#version 300 es
7085     #extension all : warn
7086     layout(binding=0, rgba8) uniform lowp pixelLocalANGLE plane1;
7087     layout(location=0, index=0) out lowp vec4 outColor0;
7088     layout(location=1, index=0) out lowp vec4 outColor1;
7089     layout(location=2, index=0) out lowp vec4 outColor2;
7090     void main()
7091     {})";
7092     EXPECT_TRUE(log.compileFragmentShader(kValidFragmentIndex0));
7093 }
7094 
7095 // Check that the "blend_support" layout qualifiers defined in KHR_blend_equation_advanced are
7096 // illegal when PLS is declared.
TEST_P(PixelLocalStorageCompilerTest,BlendEquationAdvanced_illegal_with_PLS)7097 TEST_P(PixelLocalStorageCompilerTest, BlendEquationAdvanced_illegal_with_PLS)
7098 {
7099     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
7100 
7101     // Just declaring the extension is ok.
7102     constexpr char kRequireBlendAdvanced[] = R"(#version 300 es
7103     #extension GL_ANGLE_shader_pixel_local_storage : require
7104     #extension GL_KHR_blend_equation_advanced : require
7105     void main()
7106     {}
7107     layout(binding=0, rgba8i) uniform lowp ipixelLocalANGLE pls;)";
7108     EXPECT_TRUE(log.compileFragmentShader(kRequireBlendAdvanced));
7109 
7110     bool before = true;
7111     for (const char *layoutQualifier : {
7112              "blend_support_multiply",
7113              "blend_support_screen",
7114              "blend_support_overlay",
7115              "blend_support_darken",
7116              "blend_support_lighten",
7117              "blend_support_colordodge",
7118              "blend_support_colorburn",
7119              "blend_support_hardlight",
7120              "blend_support_softlight",
7121              "blend_support_difference",
7122              "blend_support_exclusion",
7123              "blend_support_hsl_hue",
7124              "blend_support_hsl_saturation",
7125              "blend_support_hsl_color",
7126              "blend_support_hsl_luminosity",
7127              "blend_support_all_equations",
7128          })
7129     {
7130         constexpr char kRequireBlendAdvancedBeforePLS[] = R"(#version 300 es
7131         #extension GL_ANGLE_shader_pixel_local_storage : require
7132         #extension GL_KHR_blend_equation_advanced : require
7133         layout(%s) out;
7134         void main()
7135         {}
7136         layout(binding=0, rgba8i) uniform lowp ipixelLocalANGLE pls;)";
7137 
7138         constexpr char kRequireBlendAdvancedAfterPLS[] = R"(#version 300 es
7139         #extension GL_ANGLE_shader_pixel_local_storage : require
7140         #extension GL_KHR_blend_equation_advanced : require
7141         layout(binding=0, rgba8i) uniform lowp ipixelLocalANGLE pls;
7142         layout(%s) out;
7143         void main()
7144         {})";
7145 
7146         const char *formatStr =
7147             before ? kRequireBlendAdvancedBeforePLS : kRequireBlendAdvancedAfterPLS;
7148         size_t buffSize =
7149             snprintf(nullptr, 0, formatStr, layoutQualifier) + 1;  // Extra space for '\0'
7150         std::unique_ptr<char[]> shader(new char[buffSize]);
7151         std::snprintf(shader.get(), buffSize, formatStr, layoutQualifier);
7152         EXPECT_FALSE(log.compileFragmentShader(shader.get()));
7153         if (before)
7154         {
7155             EXPECT_TRUE(
7156                 log.has("ERROR: 0:4: 'layout' : illegal advanced blend equation when pixel local "
7157                         "storage is declared"));
7158         }
7159         else
7160         {
7161             EXPECT_TRUE(
7162                 log.has("ERROR: 0:5: 'layout' : illegal advanced blend equation when pixel local "
7163                         "storage is declared"));
7164         }
7165 
7166         before = !before;
7167     }
7168 }
7169 
7170 // Check proper validation of PLS function arguments.
TEST_P(PixelLocalStorageCompilerTest,FunctionArguments)7171 TEST_P(PixelLocalStorageCompilerTest, FunctionArguments)
7172 {
7173     // Ensure PLS handles can't be the result of complex expressions.
7174     constexpr char kPLSHandleComplexExpression[] = R"(#version 310 es
7175     #extension GL_ANGLE_shader_pixel_local_storage : require
7176     layout(rgba8, binding=0) mediump uniform pixelLocalANGLE pls0;
7177     layout(rgba8, binding=1) mediump uniform pixelLocalANGLE pls1;
7178     void clear(mediump pixelLocalANGLE pls)
7179     {
7180         pixelLocalStoreANGLE(pls, vec4(0));
7181     }
7182     void main()
7183     {
7184         highp float x = gl_FragDepth;
7185         clear(((x += 50.0) < 100.0) ? pls0 : pls1);
7186     })";
7187     EXPECT_FALSE(log.compileFragmentShader(kPLSHandleComplexExpression));
7188     EXPECT_TRUE(log.has("ERROR: 0:12: '?:' : ternary operator is not allowed for opaque types"));
7189 
7190     // As function arguments, PLS handles cannot have layout qualifiers.
7191     constexpr char kPLSFnArgWithLayoutQualifiers[] = R"(#version 310 es
7192     #extension GL_ANGLE_shader_pixel_local_storage : require
7193     void f(layout(rgba8, binding=1) mediump pixelLocalANGLE pls)
7194     {
7195     }
7196     void g(layout(rgba8) lowp pixelLocalANGLE pls);
7197     void main()
7198     {
7199     })";
7200     EXPECT_FALSE(log.compileFragmentShader(kPLSFnArgWithLayoutQualifiers));
7201     EXPECT_TRUE(log.has("ERROR: 0:3: 'layout' : only allowed at global scope"));
7202     EXPECT_TRUE(log.has("ERROR: 0:6: 'layout' : only allowed at global scope"));
7203 
7204     ASSERT_GL_NO_ERROR();
7205 }
7206 
7207 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageCompilerTest);
7208 ANGLE_INSTANTIATE_TEST(PixelLocalStorageCompilerTest,
7209                        ES31_NULL().enable(Feature::EmulatePixelLocalStorage),
7210                        ES31_NULL()
7211                            .enable(Feature::EmulatePixelLocalStorage)
7212                            .enable(Feature::DisableDrawBuffersIndexed));
7213 
7214 class PixelLocalStorageTestPreES3 : public ANGLETest<>
7215 {
7216   public:
PixelLocalStorageTestPreES3()7217     PixelLocalStorageTestPreES3() { setExtensionsEnabled(false); }
7218 };
7219 
7220 // Check that GL_ANGLE_shader_pixel_local_storage is not advertised before ES 3.0.
TEST_P(PixelLocalStorageTestPreES3,UnsupportedClientVersion)7221 TEST_P(PixelLocalStorageTestPreES3, UnsupportedClientVersion)
7222 {
7223     EXPECT_FALSE(EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
7224     EXPECT_FALSE(EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage_coherent"));
7225 
7226     ShaderInfoLog log;
7227 
7228     constexpr char kRequireUnsupportedPLS[] = R"(#version 300 es
7229     #extension GL_ANGLE_shader_pixel_local_storage : require
7230     void main()
7231     {
7232     })";
7233     EXPECT_FALSE(log.compileFragmentShader(kRequireUnsupportedPLS));
7234     EXPECT_TRUE(
7235         log.has("ERROR: 0:2: 'GL_ANGLE_shader_pixel_local_storage' : extension is not supported"));
7236 
7237     ASSERT_GL_NO_ERROR();
7238 }
7239 
7240 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageTestPreES3);
7241 ANGLE_INSTANTIATE_TEST(PixelLocalStorageTestPreES3,
7242                        ES1_NULL().enable(Feature::EmulatePixelLocalStorage),
7243                        ES2_NULL().enable(Feature::EmulatePixelLocalStorage));
7244