1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9
10 #include "common/mathutil.h"
11 #include "platform/autogen/FeaturesD3D_autogen.h"
12
13 using namespace angle;
14
15 struct ReadbackTestParam
16 {
17 GLuint attachment;
18 GLuint format;
19 GLuint type;
20 void *data;
21 int depthBits;
22 int stencilBits;
23 };
24
25 class DepthStencilFormatsTestBase : public ANGLETest<>
26 {
27 protected:
DepthStencilFormatsTestBase()28 DepthStencilFormatsTestBase()
29 {
30 setWindowWidth(128);
31 setWindowHeight(128);
32 setConfigRedBits(8);
33 setConfigGreenBits(8);
34 setConfigBlueBits(8);
35 setConfigAlphaBits(8);
36 }
37
checkTexImageFormatSupport(GLenum format,GLenum type)38 bool checkTexImageFormatSupport(GLenum format, GLenum type)
39 {
40 EXPECT_GL_NO_ERROR();
41
42 GLuint tex = 0;
43 glGenTextures(1, &tex);
44 glBindTexture(GL_TEXTURE_2D, tex);
45 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
46 glDeleteTextures(1, &tex);
47
48 return (glGetError() == GL_NO_ERROR);
49 }
50
checkTexStorageFormatSupport(GLenum internalFormat)51 bool checkTexStorageFormatSupport(GLenum internalFormat)
52 {
53 EXPECT_GL_NO_ERROR();
54
55 GLuint tex = 0;
56 glGenTextures(1, &tex);
57 glBindTexture(GL_TEXTURE_2D, tex);
58 glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
59 glDeleteTextures(1, &tex);
60
61 return (glGetError() == GL_NO_ERROR);
62 }
63
checkRenderbufferFormatSupport(GLenum internalFormat)64 bool checkRenderbufferFormatSupport(GLenum internalFormat)
65 {
66 EXPECT_GL_NO_ERROR();
67
68 GLuint rb = 0;
69 glGenRenderbuffers(1, &rb);
70 glBindRenderbuffer(GL_RENDERBUFFER, rb);
71 glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
72 glDeleteRenderbuffers(1, &rb);
73
74 return (glGetError() == GL_NO_ERROR);
75 }
76
verifyDepthRenderBuffer(GLenum internalFormat)77 void verifyDepthRenderBuffer(GLenum internalFormat)
78 {
79 GLTexture tex;
80 glBindTexture(GL_TEXTURE_2D, tex);
81 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
82 ASSERT_GL_NO_ERROR();
83
84 GLRenderbuffer rbDepth;
85 glBindRenderbuffer(GL_RENDERBUFFER, rbDepth);
86 glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
87 ASSERT_GL_NO_ERROR();
88
89 GLFramebuffer fbo;
90 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
91 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
92 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbDepth);
93
94 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
95 ASSERT_GL_NO_ERROR();
96
97 ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
98 glEnable(GL_DEPTH_TEST);
99 glDepthFunc(GL_GEQUAL);
100 glClearDepthf(0.99f);
101 glClearColor(0, 0, 0, 1);
102 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
103
104 // Pass Depth Test and draw red
105 float depthValue = 1.0f;
106 drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
107 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
108
109 ASSERT_GL_NO_ERROR();
110
111 ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
112
113 // Fail Depth Test and color buffer is unchanged
114 depthValue = 0.98f;
115 drawQuad(programGreen, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
116 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
117
118 ASSERT_GL_NO_ERROR();
119
120 ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
121 glClearDepthf(0.0f);
122 glClear(GL_DEPTH_BUFFER_BIT);
123
124 // Pass Depth Test and draw blue
125 depthValue = 0.01f;
126 drawQuad(programBlue, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
127 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
128
129 glDisable(GL_DEPTH_TEST);
130 ASSERT_GL_NO_ERROR();
131 }
132
testSetUp()133 void testSetUp() override
134 {
135 constexpr char kVS[] = R"(precision highp float;
136 attribute vec4 position;
137 varying vec2 texcoord;
138
139 void main()
140 {
141 gl_Position = position;
142 texcoord = (position.xy * 0.5) + 0.5;
143 })";
144
145 constexpr char kFS[] = R"(precision highp float;
146 uniform sampler2D tex;
147 varying vec2 texcoord;
148
149 void main()
150 {
151 gl_FragColor = texture2D(tex, texcoord);
152 })";
153
154 mProgram = CompileProgram(kVS, kFS);
155 if (mProgram == 0)
156 {
157 FAIL() << "shader compilation failed.";
158 }
159
160 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
161 EXPECT_NE(-1, mTextureUniformLocation);
162
163 glGenTextures(1, &mTexture);
164 ASSERT_GL_NO_ERROR();
165 }
166
testTearDown()167 void testTearDown() override
168 {
169 glDeleteProgram(mProgram);
170 glDeleteTextures(1, &mTexture);
171 }
172
hasReadDepthSupport() const173 bool hasReadDepthSupport() const { return IsGLExtensionEnabled("GL_NV_read_depth"); }
174
hasReadDepthStencilSupport() const175 bool hasReadDepthStencilSupport() const
176 {
177 return IsGLExtensionEnabled("GL_NV_read_depth_stencil");
178 }
179
hasReadStencilSupport() const180 bool hasReadStencilSupport() const { return IsGLExtensionEnabled("GL_NV_read_stencil"); }
181
hasFloatDepthSupport() const182 bool hasFloatDepthSupport() const { return IsGLExtensionEnabled("GL_NV_depth_buffer_float2"); }
183
184 void depthStencilReadbackCase(const ReadbackTestParam &type);
185
186 GLuint mProgram;
187 GLuint mTexture;
188 GLint mTextureUniformLocation;
189 };
190
191 class DepthStencilFormatsTest : public DepthStencilFormatsTestBase
192 {};
193
194 class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase
195 {};
196
TEST_P(DepthStencilFormatsTest,DepthTexture)197 TEST_P(DepthStencilFormatsTest, DepthTexture)
198 {
199 bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_ANGLE_depth_texture") ||
200 IsGLExtensionEnabled("GL_OES_depth_texture"));
201
202 EXPECT_EQ(shouldHaveTextureSupport,
203 checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));
204 EXPECT_EQ(shouldHaveTextureSupport,
205 checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));
206
207 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
208 {
209 EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));
210 EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));
211 }
212 }
213
TEST_P(DepthStencilFormatsTest,PackedDepthStencil)214 TEST_P(DepthStencilFormatsTest, PackedDepthStencil)
215 {
216 // Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.
217 // Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not
218 // present.
219
220 bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil");
221 EXPECT_EQ(shouldHaveRenderbufferSupport,
222 checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));
223
224 bool shouldHaveTextureSupport = ((IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
225 IsGLExtensionEnabled("GL_OES_depth_texture_cube_map")) &&
226 IsGLExtensionEnabled("GL_OES_depth_texture")) ||
227 IsGLExtensionEnabled("GL_ANGLE_depth_texture");
228 EXPECT_EQ(shouldHaveTextureSupport,
229 checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
230
231 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
232 {
233 bool shouldHaveTexStorageSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
234 IsGLExtensionEnabled("GL_ANGLE_depth_texture");
235 EXPECT_EQ(shouldHaveTexStorageSupport,
236 checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));
237 }
238 }
239
depthStencilReadbackCase(const ReadbackTestParam & type)240 void DepthStencilFormatsTestBase::depthStencilReadbackCase(const ReadbackTestParam &type)
241 {
242 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
243
244 const bool hasFloatDepth = (type.type == GL_FLOAT);
245 ANGLE_SKIP_TEST_IF(hasFloatDepth && !hasFloatDepthSupport());
246
247 const bool hasStencil = (type.format != GL_DEPTH_COMPONENT);
248
249 const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;
250
251 const int res = 2;
252 const int destRes = 4;
253
254 GLTexture tex;
255 glBindTexture(GL_TEXTURE_2D, tex);
256 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
259 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
260
261 // test level > 0
262 glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
263 EXPECT_GL_NO_ERROR();
264
265 // test with data
266 glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
267 EXPECT_GL_NO_ERROR();
268
269 // test real thing
270 glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type, nullptr);
271 EXPECT_GL_NO_ERROR();
272
273 // test texSubImage2D
274 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
275 EXPECT_GL_NO_ERROR();
276
277 GLuint fbo = 0;
278 glGenFramebuffers(1, &fbo);
279 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
280 if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
281 {
282 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
283 EXPECT_GL_NO_ERROR();
284 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
285 EXPECT_GL_NO_ERROR();
286 }
287 else
288 {
289 glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
290 EXPECT_GL_NO_ERROR();
291 }
292
293 // Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
294 // UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
295 // UNSIGNED_INT_24_8_WEBGL.
296
297 GLint depthBits = 0;
298 glGetIntegerv(GL_DEPTH_BITS, &depthBits);
299 EXPECT_GE(depthBits, type.depthBits);
300
301 GLint stencilBits = 0;
302 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
303 EXPECT_GE(stencilBits, type.stencilBits);
304
305 // TODO: remove this check if the spec is updated to require these combinations to work.
306 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
307 {
308 // try adding a color buffer.
309 GLuint colorTex = 0;
310 glGenTextures(1, &colorTex);
311 glBindTexture(GL_TEXTURE_2D, colorTex);
312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
316 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
317 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
318 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
319 }
320
321 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
322
323 // use the default texture to render with while we return to the depth texture.
324 glBindTexture(GL_TEXTURE_2D, 0);
325
326 /* Setup 2x2 depth texture:
327 * 1 0.6 0.8
328 * |
329 * 0 0.2 0.4
330 * 0---1
331 */
332 GLbitfield clearBits = GL_DEPTH_BUFFER_BIT;
333 if (hasStencil)
334 {
335 clearBits |= GL_STENCIL_BUFFER_BIT;
336 }
337
338 const GLfloat d00 = 0.2;
339 const GLfloat d01 = 0.4;
340 const GLfloat d10 = 0.6;
341 const GLfloat d11 = 0.8;
342 glEnable(GL_SCISSOR_TEST);
343 glScissor(0, 0, 1, 1);
344 glClearDepthf(d00);
345 glClearStencil(1);
346 glClear(clearBits);
347 glScissor(1, 0, 1, 1);
348 glClearDepthf(d10);
349 glClearStencil(2);
350 glClear(clearBits);
351 glScissor(0, 1, 1, 1);
352 glClearDepthf(d01);
353 glClearStencil(3);
354 glClear(clearBits);
355 glScissor(1, 1, 1, 1);
356 glClearDepthf(d11);
357 glClearStencil(4);
358 glClear(clearBits);
359 glDisable(GL_SCISSOR_TEST);
360
361 GLubyte actualPixels[destRes * destRes * 8];
362 glReadPixels(0, 0, destRes, destRes, GL_DEPTH_COMPONENT,
363 hasFloatDepth ? GL_FLOAT : GL_UNSIGNED_SHORT, actualPixels);
364 if (hasReadDepthSupport())
365 {
366 EXPECT_GL_NO_ERROR();
367 if (hasFloatDepth)
368 {
369 constexpr float kEpsilon = 0.002f;
370 const float *pixels = reinterpret_cast<const float *>(actualPixels);
371 ASSERT_NEAR(pixels[0], d00, kEpsilon);
372 ASSERT_NEAR(pixels[0 + destRes], d01, kEpsilon);
373 ASSERT_NEAR(pixels[1], d10, kEpsilon);
374 ASSERT_NEAR(pixels[1 + destRes], d11, kEpsilon);
375 }
376 else
377 {
378 constexpr unsigned short kEpsilon = 2;
379 const unsigned short *pixels = reinterpret_cast<const unsigned short *>(actualPixels);
380 ASSERT_NEAR(pixels[0], gl::unorm<16>(d00), kEpsilon);
381 ASSERT_NEAR(pixels[0 + destRes], gl::unorm<16>(d01), kEpsilon);
382 ASSERT_NEAR(pixels[1], gl::unorm<16>(d10), kEpsilon);
383 ASSERT_NEAR(pixels[1 + destRes], gl::unorm<16>(d11), kEpsilon);
384 }
385 }
386 else
387 {
388 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
389 }
390 if (hasStencil)
391 {
392 glReadPixels(0, 0, destRes, destRes, GL_STENCIL_INDEX_OES, GL_UNSIGNED_BYTE, actualPixels);
393 if (hasReadStencilSupport())
394 {
395 EXPECT_GL_NO_ERROR();
396 ASSERT_TRUE((actualPixels[0] == 1) && (actualPixels[1] == 2) &&
397 (actualPixels[0 + destRes] == 3) && (actualPixels[1 + destRes] == 4));
398 }
399 else
400 {
401 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
402 }
403
404 ASSERT(!hasFloatDepth);
405
406 glReadPixels(0, 0, destRes, destRes, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES,
407 actualPixels);
408 if (hasReadDepthStencilSupport())
409 {
410 EXPECT_GL_NO_ERROR();
411
412 struct Pixel
413 {
414 uint32_t x;
415
416 uint32_t d24() const { return x >> 8; }
417
418 uint8_t s8() const { return x & 0xff; }
419 };
420
421 constexpr unsigned short kEpsilon = 2;
422 const Pixel *pixels = reinterpret_cast<const Pixel *>(actualPixels);
423
424 ASSERT_NEAR(pixels[0].d24(), gl::unorm<24>(d00), kEpsilon);
425 ASSERT_NEAR(pixels[0 + destRes].d24(), gl::unorm<24>(d01), kEpsilon);
426 ASSERT_NEAR(pixels[1].d24(), gl::unorm<24>(d10), kEpsilon);
427 ASSERT_NEAR(pixels[1 + destRes].d24(), gl::unorm<24>(d11), kEpsilon);
428 ASSERT_TRUE((pixels[0].s8() == 1) && (pixels[1].s8() == 2) &&
429 (pixels[0 + destRes].s8() == 3) && (pixels[1 + destRes].s8() == 4));
430 }
431 else
432 {
433 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
434 }
435 }
436 }
437
438 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_UShort)439 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UShort)
440 {
441 GLuint fakeData[10] = {0};
442 ReadbackTestParam type = {
443 GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0};
444 depthStencilReadbackCase(type);
445 }
446
447 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_UInt)448 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UInt)
449 {
450 // http://anglebug.com/40644772
451 ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
452
453 GLuint fakeData[10] = {0};
454 ReadbackTestParam type = {
455 GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0};
456 depthStencilReadbackCase(type);
457 }
458
459 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_Float)460 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_Float)
461 {
462 // http://anglebug.com/40644772
463 ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
464
465 GLuint fakeData[10] = {0};
466 ReadbackTestParam type = {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_FLOAT, fakeData, 32, 0};
467 depthStencilReadbackCase(type);
468 }
469
470 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_DepthStencil)471 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_DepthStencil)
472 {
473 GLuint fakeData[10] = {0};
474 ReadbackTestParam type = {
475 GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8};
476 depthStencilReadbackCase(type);
477 }
478
479 // Verify that packed D/S readPixels with a D32_FLOAT_S8X24_UINT attachment
TEST_P(DepthStencilFormatsTestES3,DepthStencilReadback_DepthFloatStencil)480 TEST_P(DepthStencilFormatsTestES3, DepthStencilReadback_DepthFloatStencil)
481 {
482 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
483 !IsGLExtensionEnabled("GL_NV_depth_buffer_float2") ||
484 !IsGLExtensionEnabled("GL_NV_read_depth") ||
485 !IsGLExtensionEnabled("GL_NV_read_depth_stencil") ||
486 !IsGLExtensionEnabled("GL_NV_read_stencil"));
487
488 GLFramebuffer FBO;
489 glBindFramebuffer(GL_FRAMEBUFFER, FBO);
490 ASSERT_GL_NO_ERROR();
491
492 GLRenderbuffer RBO;
493 glBindRenderbuffer(GL_RENDERBUFFER, RBO);
494 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH32F_STENCIL8, getWindowWidth(),
495 getWindowHeight());
496 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO);
497 ASSERT_GL_NO_ERROR();
498
499 constexpr float kDepthClearValue = 0.123f;
500 constexpr uint8_t kStencilClearValue = 0x42;
501
502 glClearDepthf(kDepthClearValue);
503 glClearStencil(kStencilClearValue);
504 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
505 ASSERT_GL_NO_ERROR();
506
507 struct
508 {
509 float depth;
510 uint8_t stencil;
511 char unused[3];
512 } pixel = {};
513 glReadPixels(0, 0, 1, 1, GL_DEPTH_STENCIL_OES, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &pixel);
514 EXPECT_GL_NO_ERROR();
515
516 EXPECT_FLOAT_EQ(pixel.depth, kDepthClearValue);
517 EXPECT_EQ(pixel.stencil, kStencilClearValue);
518 }
519
520 // This test will initialize a depth texture and then render with it and verify
521 // pixel correctness.
522 // This is modeled after webgl-depth-texture.html
TEST_P(DepthStencilFormatsTest,DepthTextureRender)523 TEST_P(DepthStencilFormatsTest, DepthTextureRender)
524 {
525 constexpr char kVS[] = R"(attribute vec4 a_position;
526 void main()
527 {
528 gl_Position = a_position;
529 })";
530
531 constexpr char kFS[] = R"(precision mediump float;
532 uniform sampler2D u_texture;
533 uniform vec2 u_resolution;
534 void main()
535 {
536 vec2 texcoord = (gl_FragCoord.xy - vec2(0.5)) / (u_resolution - vec2(1.0));
537 gl_FragColor = texture2D(u_texture, texcoord);
538 })";
539
540 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture") &&
541 !IsGLExtensionEnabled("GL_ANGLE_depth_texture"));
542
543 bool depthTextureCubeSupport = IsGLExtensionEnabled("GL_OES_depth_texture_cube_map");
544 bool textureSrgbDecodeSupport = IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode");
545
546 // http://anglebug.com/42262117
547 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsD3D9());
548
549 const int res = 2;
550 const int destRes = 4;
551 GLint resolution;
552
553 ANGLE_GL_PROGRAM(program, kVS, kFS);
554
555 glUseProgram(program);
556 resolution = glGetUniformLocation(program, "u_resolution");
557 ASSERT_NE(-1, resolution);
558 glUniform2f(resolution, static_cast<float>(destRes), static_cast<float>(destRes));
559
560 GLuint buffer;
561 glGenBuffers(1, &buffer);
562 glBindBuffer(GL_ARRAY_BUFFER, buffer);
563 float verts[] = {
564 1, 1, 1, -1, 1, 0, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 0,
565 };
566 glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
567 glEnableVertexAttribArray(0);
568 glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
569
570 // OpenGL ES does not have a FLIPY PixelStore attribute
571 // glPixelStorei(GL_UNPACK_FLIP)
572
573 struct TypeInfo
574 {
575 GLuint attachment;
576 GLuint format;
577 GLuint type;
578 void *data;
579 int depthBits;
580 int stencilBits;
581 };
582
583 GLuint fakeData[10] = {0};
584
585 std::vector<TypeInfo> types = {
586 {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0},
587 {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0},
588 {GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8},
589 };
590
591 for (const TypeInfo &type : types)
592 {
593 GLTexture cubeTex;
594 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
595 ASSERT_GL_NO_ERROR();
596
597 std::vector<GLuint> targets{GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
598 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
599 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
600
601 for (const GLuint target : targets)
602 {
603 glTexImage2D(target, 0, type.format, 1, 1, 0, type.format, type.type, nullptr);
604 if (depthTextureCubeSupport)
605 {
606 ASSERT_GL_NO_ERROR();
607 }
608 else
609 {
610 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
611 }
612 }
613
614 std::vector<GLuint> filterModes = {GL_LINEAR, GL_NEAREST};
615
616 const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;
617
618 for (const GLuint filterMode : filterModes)
619 {
620 GLTexture tex;
621 glBindTexture(GL_TEXTURE_2D, tex);
622 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
623 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
624 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
625 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
626 if (textureSrgbDecodeSupport)
627 {
628 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
629 }
630
631 // test level > 0
632 glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
633 if (IsGLExtensionEnabled("GL_OES_depth_texture"))
634 {
635 EXPECT_GL_NO_ERROR();
636 }
637 else
638 {
639 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
640 }
641
642 // test with data
643 glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
644 if (IsGLExtensionEnabled("GL_OES_depth_texture"))
645 {
646 EXPECT_GL_NO_ERROR();
647 }
648 else
649 {
650 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
651 }
652
653 // test copyTexImage2D
654 glCopyTexImage2D(GL_TEXTURE_2D, 0, type.format, 0, 0, 1, 1, 0);
655 GLuint error = glGetError();
656 ASSERT_TRUE(error == GL_INVALID_ENUM || error == GL_INVALID_OPERATION);
657
658 // test real thing
659 glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type,
660 nullptr);
661 EXPECT_GL_NO_ERROR();
662
663 // test texSubImage2D
664 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
665 if (IsGLExtensionEnabled("GL_OES_depth_texture"))
666 {
667 EXPECT_GL_NO_ERROR();
668 }
669 else
670 {
671 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
672 }
673
674 // test copyTexSubImage2D
675 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
676 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
677
678 // test generateMipmap
679 glGenerateMipmap(GL_TEXTURE_2D);
680 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
681
682 GLuint fbo = 0;
683 glGenFramebuffers(1, &fbo);
684 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
685 if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
686 {
687 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
688 EXPECT_GL_NO_ERROR();
689 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex,
690 0);
691 EXPECT_GL_NO_ERROR();
692 }
693 else
694 {
695 glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
696 EXPECT_GL_NO_ERROR();
697 }
698
699 // Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
700 // UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
701 // UNSIGNED_INT_24_8_WEBGL.
702
703 GLint depthBits = 0;
704 glGetIntegerv(GL_DEPTH_BITS, &depthBits);
705 EXPECT_GE(depthBits, type.depthBits);
706
707 GLint stencilBits = 0;
708 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
709 EXPECT_GE(stencilBits, type.stencilBits);
710
711 // TODO: remove this check if the spec is updated to require these combinations to work.
712 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
713 {
714 // try adding a color buffer.
715 GLuint colorTex = 0;
716 glGenTextures(1, &colorTex);
717 glBindTexture(GL_TEXTURE_2D, colorTex);
718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
722 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE,
723 nullptr);
724 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
725 colorTex, 0);
726 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
727 }
728
729 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
730
731 // use the default texture to render with while we return to the depth texture.
732 glBindTexture(GL_TEXTURE_2D, 0);
733
734 /* Setup 2x2 depth texture:
735 * 1 0.6 0.8
736 * |
737 * 0 0.2 0.4
738 * 0---1
739 */
740 const GLfloat d00 = 0.2;
741 const GLfloat d01 = 0.4;
742 const GLfloat d10 = 0.6;
743 const GLfloat d11 = 0.8;
744 glEnable(GL_SCISSOR_TEST);
745 glScissor(0, 0, 1, 1);
746 glClearDepthf(d00);
747 glClear(GL_DEPTH_BUFFER_BIT);
748 glScissor(1, 0, 1, 1);
749 glClearDepthf(d10);
750 glClear(GL_DEPTH_BUFFER_BIT);
751 glScissor(0, 1, 1, 1);
752 glClearDepthf(d01);
753 glClear(GL_DEPTH_BUFFER_BIT);
754 glScissor(1, 1, 1, 1);
755 glClearDepthf(d11);
756 glClear(GL_DEPTH_BUFFER_BIT);
757 glDisable(GL_SCISSOR_TEST);
758
759 // render the depth texture.
760 glBindFramebuffer(GL_FRAMEBUFFER, 0);
761 glViewport(0, 0, destRes, destRes);
762 glBindTexture(GL_TEXTURE_2D, tex);
763 glDisable(GL_DITHER);
764 glEnable(GL_DEPTH_TEST);
765 glClearColor(1, 0, 0, 1);
766 glClearDepthf(1.0);
767 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
768 glDrawArrays(GL_TRIANGLES, 0, 6);
769
770 GLubyte actualPixels[destRes * destRes * 4];
771 glReadPixels(0, 0, destRes, destRes, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels);
772 const GLfloat eps = 0.002;
773 std::vector<GLfloat> expectedMin;
774 std::vector<GLfloat> expectedMax;
775 if (filterMode == GL_NEAREST)
776 {
777 GLfloat init[] = {d00, d00, d10, d10, d00, d00, d10, d10,
778 d01, d01, d11, d11, d01, d01, d11, d11};
779 expectedMin.insert(expectedMin.begin(), init, init + 16);
780 expectedMax.insert(expectedMax.begin(), init, init + 16);
781
782 for (int i = 0; i < 16; i++)
783 {
784 expectedMin[i] = expectedMin[i] - eps;
785 expectedMax[i] = expectedMax[i] + eps;
786 }
787 }
788 else
789 {
790 GLfloat initMin[] = {
791 d00 - eps, d00, d00, d10 - eps, d00, d00, d00, d10,
792 d00, d00, d00, d10, d01 - eps, d01, d01, d11 - eps,
793 };
794 GLfloat initMax[] = {
795 d00 + eps, d10, d10, d10 + eps, d01, d11, d11, d11,
796 d01, d11, d11, d11, d01 + eps, d11, d11, d11 + eps,
797 };
798 expectedMin.insert(expectedMin.begin(), initMin, initMin + 16);
799 expectedMax.insert(expectedMax.begin(), initMax, initMax + 16);
800 }
801 for (int yy = 0; yy < destRes; ++yy)
802 {
803 for (int xx = 0; xx < destRes; ++xx)
804 {
805 const int t = xx + destRes * yy;
806 const GLfloat was = (GLfloat)(actualPixels[4 * t] / 255.0); // 4bpp
807 const GLfloat eMin = expectedMin[t];
808 const GLfloat eMax = expectedMax[t];
809 EXPECT_TRUE(was >= eMin && was <= eMax)
810 << "At " << xx << ", " << yy << ", expected within [" << eMin << ", "
811 << eMax << "] was " << was;
812 }
813 }
814
815 // check limitations
816 // Note: What happens if current attachment type is GL_DEPTH_STENCIL_ATTACHMENT
817 // and you try to call glFramebufferTexture2D with GL_DEPTH_ATTACHMENT?
818 // The webGL test this code came from expected that to fail.
819 // I think due to this line in ES3 spec:
820 // GL_INVALID_OPERATION is generated if textarget and texture are not compatible
821 // However, that's not the behavior I'm seeing, nor does it seem that a depth_stencil
822 // buffer isn't compatible with a depth attachment (e.g. stencil is unused).
823 if (type.attachment == GL_DEPTH_ATTACHMENT)
824 {
825 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
826 glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, 0, 0);
827 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
828 tex, 0);
829 EXPECT_GLENUM_NE(GL_NO_ERROR, glGetError());
830 EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
831 glClear(GL_DEPTH_BUFFER_BIT);
832 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
833 glBindFramebuffer(GL_FRAMEBUFFER, 0);
834 EXPECT_GL_NO_ERROR();
835 }
836 }
837 }
838 }
839
840 // This test will initialize a frame buffer, attaching a color and 16-bit depth buffer,
841 // render to it with depth testing, and verify pixel correctness.
TEST_P(DepthStencilFormatsTest,DepthBuffer16)842 TEST_P(DepthStencilFormatsTest, DepthBuffer16)
843 {
844 verifyDepthRenderBuffer(GL_DEPTH_COMPONENT16);
845 }
846
847 // This test will initialize a frame buffer, attaching a color and 24-bit depth buffer,
848 // render to it with depth testing, and verify pixel correctness.
TEST_P(DepthStencilFormatsTest,DepthBuffer24)849 TEST_P(DepthStencilFormatsTest, DepthBuffer24)
850 {
851 bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_depth24");
852 EXPECT_EQ(shouldHaveRenderbufferSupport,
853 checkRenderbufferFormatSupport(GL_DEPTH_COMPONENT24_OES));
854
855 if (shouldHaveRenderbufferSupport)
856 {
857 verifyDepthRenderBuffer(GL_DEPTH_COMPONENT24_OES);
858 }
859 }
860
TEST_P(DepthStencilFormatsTestES3,DrawWithDepth16)861 TEST_P(DepthStencilFormatsTestES3, DrawWithDepth16)
862 {
863 GLushort data[16];
864 for (unsigned int i = 0; i < 16; i++)
865 {
866 data[i] = std::numeric_limits<GLushort>::max();
867 }
868 glBindTexture(GL_TEXTURE_2D, mTexture);
869 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4);
870 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
871
872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
873 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
874
875 glUseProgram(mProgram);
876 glUniform1i(mTextureUniformLocation, 0);
877
878 glClear(GL_COLOR_BUFFER_BIT);
879 drawQuad(mProgram, "position", 0.5f);
880
881 ASSERT_GL_NO_ERROR();
882
883 GLubyte pixel[4];
884 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
885
886 // Only require the red and alpha channels have the correct values, the depth texture extensions
887 // leave the green and blue channels undefined
888 ASSERT_NEAR(255, pixel[0], 2.0);
889 ASSERT_EQ(255, pixel[3]);
890 }
891
892 // This test reproduces a driver bug on Intel windows platforms on driver version
893 // from 4815 to 4901.
894 // When rendering with Stencil buffer enabled and depth buffer disabled, large
895 // viewport will lead to memory leak and driver crash. And the pixel result
896 // is a random value.
TEST_P(DepthStencilFormatsTestES3,DrawWithLargeViewport)897 TEST_P(DepthStencilFormatsTestES3, DrawWithLargeViewport)
898 {
899 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows());
900
901 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
902
903 glEnable(GL_STENCIL_TEST);
904 glDisable(GL_DEPTH_TEST);
905
906 // The iteration is to reproduce memory leak when rendering several times.
907 for (int i = 0; i < 10; ++i)
908 {
909 // Create offscreen fbo and its color attachment and depth stencil attachment.
910 GLTexture framebufferColorTexture;
911 glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
912 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
913 ASSERT_GL_NO_ERROR();
914
915 GLTexture framebufferStencilTexture;
916 glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
917 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
918 ASSERT_GL_NO_ERROR();
919
920 GLFramebuffer fb;
921 glBindFramebuffer(GL_FRAMEBUFFER, fb);
922 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
923 framebufferColorTexture, 0);
924 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
925 framebufferStencilTexture, 0);
926
927 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
928 ASSERT_GL_NO_ERROR();
929
930 GLint kStencilRef = 4;
931 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
932 glStencilFunc(GL_ALWAYS, kStencilRef, 0xFF);
933
934 float viewport[2];
935 glGetFloatv(GL_MAX_VIEWPORT_DIMS, viewport);
936
937 glViewport(0, 0, static_cast<GLsizei>(viewport[0]), static_cast<GLsizei>(viewport[1]));
938 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
939
940 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
941 ASSERT_GL_NO_ERROR();
942
943 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
944 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
945 ASSERT_GL_NO_ERROR();
946 }
947 }
948
949 // Verify that stencil component of depth texture is uploaded
TEST_P(DepthStencilFormatsTest,VerifyDepthStencilUploadData)950 TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)
951 {
952 // http://anglebug.com/42262342
953 // When bug is resolved we can remove this skip.
954 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
955
956 // http://anglebug.com/42262345
957 ANGLE_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsAMD());
958
959 bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_OES_packed_depth_stencil") &&
960 IsGLExtensionEnabled("GL_OES_depth_texture")) ||
961 (getClientMajorVersion() >= 3);
962
963 ANGLE_SKIP_TEST_IF(!shouldHaveTextureSupport ||
964 !checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
965
966 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
967
968 glEnable(GL_STENCIL_TEST);
969 glDisable(GL_DEPTH_TEST);
970 glDepthMask(GL_FALSE);
971
972 glViewport(0, 0, getWindowWidth(), getWindowHeight());
973 glClearColor(0, 0, 0, 1);
974
975 // Create offscreen fbo and its color attachment and depth stencil attachment.
976 GLTexture framebufferColorTexture;
977 glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
978 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
979 GL_UNSIGNED_BYTE, nullptr);
980 ASSERT_GL_NO_ERROR();
981
982 // drawQuad's depth range is -1.0 to 1.0, so a depth value of 0.5 (0x7fffff) matches a drawQuad
983 // depth of 0.0.
984 std::vector<GLuint> depthStencilData(getWindowWidth() * getWindowHeight(), 0x7fffffA9);
985 GLTexture framebufferStencilTexture;
986 glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
987 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, getWindowWidth(), getWindowHeight(), 0,
988 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, depthStencilData.data());
989 ASSERT_GL_NO_ERROR();
990
991 GLFramebuffer fb;
992 glBindFramebuffer(GL_FRAMEBUFFER, fb);
993 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
994 framebufferColorTexture, 0);
995
996 if (getClientMajorVersion() >= 3)
997 {
998 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
999 framebufferStencilTexture, 0);
1000 ASSERT_GL_NO_ERROR();
1001 }
1002 else
1003 {
1004 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
1005 framebufferStencilTexture, 0);
1006 ASSERT_GL_NO_ERROR();
1007 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
1008 framebufferStencilTexture, 0);
1009 ASSERT_GL_NO_ERROR();
1010 }
1011
1012 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1013
1014 GLint kStencilRef = 0xA9;
1015 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1016 glStencilFunc(GL_EQUAL, kStencilRef, 0xFF);
1017
1018 glBindFramebuffer(GL_FRAMEBUFFER, fb);
1019
1020 glClear(GL_COLOR_BUFFER_BIT);
1021
1022 drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);
1023 ASSERT_GL_NO_ERROR();
1024
1025 glBindFramebuffer(GL_FRAMEBUFFER, fb);
1026 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1027 ASSERT_GL_NO_ERROR();
1028
1029 // Check Z values
1030
1031 glClear(GL_COLOR_BUFFER_BIT);
1032 glDisable(GL_STENCIL_TEST);
1033 glEnable(GL_DEPTH_TEST);
1034 glDepthFunc(GL_LESS);
1035
1036 drawQuad(program, essl1_shaders::PositionAttrib(), -0.1f);
1037 ASSERT_GL_NO_ERROR();
1038
1039 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1040
1041 glClear(GL_COLOR_BUFFER_BIT);
1042
1043 drawQuad(program, essl1_shaders::PositionAttrib(), 0.1f);
1044 ASSERT_GL_NO_ERROR();
1045
1046 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::black);
1047 }
1048
1049 // Verify that depth texture's data can be uploaded correctly
TEST_P(DepthStencilFormatsTest,VerifyDepth32UploadData)1050 TEST_P(DepthStencilFormatsTest, VerifyDepth32UploadData)
1051 {
1052 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
1053
1054 GLTexture tex;
1055 glBindTexture(GL_TEXTURE_2D, tex);
1056 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1057 ASSERT_GL_NO_ERROR();
1058
1059 // normalized 0.99 = 0xfd70a3d6
1060 std::vector<GLuint> depthData(1, 0xfd70a3d6);
1061 GLTexture rbDepth;
1062 glBindTexture(GL_TEXTURE_2D, rbDepth);
1063 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
1064 depthData.data());
1065 ASSERT_GL_NO_ERROR();
1066
1067 GLFramebuffer fbo;
1068 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1069 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1070 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
1071
1072 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1073 ASSERT_GL_NO_ERROR();
1074
1075 ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1076 glEnable(GL_DEPTH_TEST);
1077 glDepthFunc(GL_GEQUAL);
1078 glClearColor(0, 1, 0, 1);
1079 glClear(GL_COLOR_BUFFER_BIT);
1080
1081 // Fail Depth Test and color buffer is unchanged
1082 float depthValue = 0.98f;
1083 drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1084 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1085
1086 // Pass Depth Test and draw red
1087 depthValue = 1.0f;
1088 drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1089 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1090
1091 ASSERT_GL_NO_ERROR();
1092
1093 // Change depth texture data
1094 glBindTexture(GL_TEXTURE_2D, rbDepth);
1095 depthData[0] = 0x7fffffff; // 0.5
1096 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
1097 depthData.data());
1098 ASSERT_GL_NO_ERROR();
1099
1100 ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1101
1102 // Fail Depth Test and color buffer is unchanged
1103 depthValue = 0.48f;
1104 drawQuad(programGreen, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1105 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1106
1107 ASSERT_GL_NO_ERROR();
1108
1109 ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1110 glClearDepthf(0.0f);
1111 glClear(GL_DEPTH_BUFFER_BIT);
1112
1113 // Pass Depth Test and draw blue
1114 depthValue = 0.01f;
1115 drawQuad(programBlue, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1116 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1117
1118 glDisable(GL_DEPTH_TEST);
1119 ASSERT_GL_NO_ERROR();
1120 }
1121
1122 // Verify that 16 bits depth texture's data can be uploaded correctly
TEST_P(DepthStencilFormatsTest,VerifyDepth16UploadData)1123 TEST_P(DepthStencilFormatsTest, VerifyDepth16UploadData)
1124 {
1125 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
1126
1127 GLTexture tex;
1128 glBindTexture(GL_TEXTURE_2D, tex);
1129 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1130 ASSERT_GL_NO_ERROR();
1131
1132 // normalized 0.99 = 0xfd6f
1133 std::vector<GLushort> depthData(1, 0xfd6f);
1134 GLTexture rbDepth;
1135 glBindTexture(GL_TEXTURE_2D, rbDepth);
1136 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT,
1137 GL_UNSIGNED_SHORT, depthData.data());
1138 ASSERT_GL_NO_ERROR();
1139
1140 GLFramebuffer fbo;
1141 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1142 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1143 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
1144
1145 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1146 ASSERT_GL_NO_ERROR();
1147
1148 ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1149 glEnable(GL_DEPTH_TEST);
1150 glDepthFunc(GL_GEQUAL);
1151 glClearColor(0, 1, 0, 1);
1152 glClear(GL_COLOR_BUFFER_BIT);
1153
1154 // Fail Depth Test and color buffer is unchanged
1155 float depthValue = 0.98f;
1156 drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1157 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1158
1159 // Pass Depth Test and draw red
1160 depthValue = 1.0f;
1161 drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1162 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1163
1164 ASSERT_GL_NO_ERROR();
1165
1166 // Change depth texture data
1167 glBindTexture(GL_TEXTURE_2D, rbDepth);
1168 depthData[0] = 0x7fff; // 0.5
1169 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
1170 depthData.data());
1171 ASSERT_GL_NO_ERROR();
1172
1173 ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1174
1175 // Fail Depth Test and color buffer is unchanged
1176 depthValue = 0.48f;
1177 drawQuad(programGreen, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1178 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1179
1180 ASSERT_GL_NO_ERROR();
1181
1182 ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1183 glClearDepthf(0.0f);
1184 glClear(GL_DEPTH_BUFFER_BIT);
1185
1186 // Pass Depth Test and draw blue
1187 depthValue = 0.01f;
1188 drawQuad(programBlue, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1189 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1190
1191 glDisable(GL_DEPTH_TEST);
1192 ASSERT_GL_NO_ERROR();
1193 }
1194
1195 class DepthStencilFormatsTestES31 : public DepthStencilFormatsTestBase
1196 {};
1197
1198 // Test depth24 texture sample from fragment shader and then read access from compute
TEST_P(DepthStencilFormatsTestES31,DrawReadDrawDispatch)1199 TEST_P(DepthStencilFormatsTestES31, DrawReadDrawDispatch)
1200 {
1201 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth24") ||
1202 !IsGLExtensionEnabled("GL_NV_read_depth"));
1203
1204 const char kVS[] = R"(#version 310 es
1205 layout (location = 0) in vec3 pos;
1206 void main(void) {
1207 gl_Position = vec4(pos, 1.0);
1208 })";
1209
1210 const char kFS[] = R"(#version 310 es
1211 precision highp float;
1212 uniform sampler2D tex;
1213 out vec4 fragColor;
1214 void main(void) {
1215 float d = texture(tex,vec2(0,0)).x;
1216 fragColor = vec4(d, 0, 0, 1);
1217 })";
1218
1219 // Create depth texture
1220 GLTexture depthTexture;
1221 glActiveTexture(GL_TEXTURE0);
1222 glBindTexture(GL_TEXTURE_2D, depthTexture);
1223 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1226 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, 1, 1);
1227
1228 // Clear depth texture to 0.51f
1229 GLFramebuffer framebuffer;
1230 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1231 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
1232 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1233 GLfloat depthValue = 0.51f;
1234 glClearDepthf(depthValue);
1235 glClear(GL_DEPTH_BUFFER_BIT);
1236 GLuint actualDepthValue;
1237 GLfloat depthErrorTolerance = 0.001f;
1238 glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &actualDepthValue);
1239 EXPECT_NEAR(depthValue, actualDepthValue / (float)UINT_MAX, depthErrorTolerance);
1240 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1241
1242 // Render to surface with texture sample from depth texture
1243 ANGLE_GL_PROGRAM(graphicsProgram, kVS, kFS);
1244 glUseProgram(graphicsProgram);
1245 const auto &quadVertices = GetQuadVertices();
1246 GLBuffer arrayBuffer;
1247 glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
1248 glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
1249 GL_STATIC_DRAW);
1250 GLint positionAttributeLocation = 0;
1251 glBindAttribLocation(graphicsProgram, positionAttributeLocation, "pos");
1252 glVertexAttribPointer(positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
1253 glEnableVertexAttribArray(positionAttributeLocation);
1254
1255 GLint uTextureLocation = glGetUniformLocation(graphicsProgram, "tex");
1256 ASSERT_NE(-1, uTextureLocation);
1257 glActiveTexture(GL_TEXTURE0);
1258 glBindTexture(GL_TEXTURE_2D, depthTexture);
1259 glUniform1i(uTextureLocation, 0);
1260 // Sample the depth texture from fragment shader and verify. This flushes out commands which
1261 // ensures there will be no layout transition in next renderPass.
1262 glDepthMask(false);
1263 glDisable(GL_DEPTH_TEST);
1264 glDrawArrays(GL_TRIANGLES, 0, 6);
1265 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor((GLubyte)(depthValue * 255), 0u, 0u, 255u));
1266
1267 // Sample the depth texture from fragment shader. No image layout transition expected here.
1268 glDrawArrays(GL_TRIANGLES, 0, 6);
1269
1270 // Sample it from compute shader while the renderPass also sample from the same texture
1271 constexpr char kCS[] = R"(#version 310 es
1272 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1273 layout(std140, binding=0) buffer buf {
1274 vec4 outData;
1275 };
1276 uniform sampler2D u_tex2D;
1277 void main()
1278 {
1279 outData = texture(u_tex2D, vec2(gl_LocalInvocationID.xy));
1280 })";
1281 ANGLE_GL_COMPUTE_PROGRAM(computeProgram, kCS);
1282 glUseProgram(computeProgram);
1283 GLBuffer ssbo;
1284 const std::vector<GLfloat> initialData(16, 0.0f);
1285 glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1286 glBufferData(GL_SHADER_STORAGE_BUFFER, 16, initialData.data(), GL_STATIC_DRAW);
1287 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
1288 glDispatchCompute(1, 1, 1);
1289 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1290 glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1291 const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
1292 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));
1293 EXPECT_NEAR(depthValue, ptr[0], depthErrorTolerance);
1294 EXPECT_GL_NO_ERROR();
1295 }
1296
1297 ANGLE_INSTANTIATE_TEST_ES2(DepthStencilFormatsTest);
1298
1299 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilFormatsTestES3);
1300 ANGLE_INSTANTIATE_TEST_ES3(DepthStencilFormatsTestES3);
1301
1302 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilFormatsTestES31);
1303 ANGLE_INSTANTIATE_TEST_ES31(DepthStencilFormatsTestES31);
1304
1305 class TinyDepthStencilWorkaroundTest : public ANGLETest<>
1306 {
1307 public:
TinyDepthStencilWorkaroundTest()1308 TinyDepthStencilWorkaroundTest()
1309 {
1310 setWindowWidth(512);
1311 setWindowHeight(512);
1312 setConfigRedBits(8);
1313 setConfigGreenBits(8);
1314 setConfigBlueBits(8);
1315 setConfigAlphaBits(8);
1316 }
1317 };
1318
1319 // Tests that the tiny depth stencil textures workaround does not "stick" depth textures.
1320 // http://anglebug.com/40644610
TEST_P(TinyDepthStencilWorkaroundTest,DepthTexturesStick)1321 TEST_P(TinyDepthStencilWorkaroundTest, DepthTexturesStick)
1322 {
1323 // http://anglebug.com/40096654
1324 ANGLE_SKIP_TEST_IF((IsAndroid() && IsOpenGLES()) || (IsLinux() && IsVulkan()));
1325
1326 constexpr char kDrawVS[] =
1327 "#version 100\n"
1328 "attribute vec3 vertex;\n"
1329 "void main () {\n"
1330 " gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);\n"
1331 "}\n";
1332
1333 ANGLE_GL_PROGRAM(drawProgram, kDrawVS, essl1_shaders::fs::Red());
1334
1335 constexpr char kBlitVS[] =
1336 "#version 100\n"
1337 "attribute vec2 vertex;\n"
1338 "varying vec2 position;\n"
1339 "void main () {\n"
1340 " position = vertex * .5 + .5;\n"
1341 " gl_Position = vec4(vertex, 0, 1);\n"
1342 "}\n";
1343
1344 constexpr char kBlitFS[] =
1345 "#version 100\n"
1346 "precision mediump float;\n"
1347 "uniform sampler2D texture;\n"
1348 "varying vec2 position;\n"
1349 "void main () {\n"
1350 " gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);\n"
1351 "}\n";
1352
1353 ANGLE_GL_PROGRAM(blitProgram, kBlitVS, kBlitFS);
1354
1355 GLint blitTextureLocation = glGetUniformLocation(blitProgram, "texture");
1356 ASSERT_NE(-1, blitTextureLocation);
1357
1358 GLTexture colorTex;
1359 glBindTexture(GL_TEXTURE_2D, colorTex);
1360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1364 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1365 GL_UNSIGNED_BYTE, nullptr);
1366 glBindTexture(GL_TEXTURE_2D, 0);
1367
1368 GLTexture depthTex;
1369 glBindTexture(GL_TEXTURE_2D, depthTex);
1370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1371 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1374 ASSERT_EQ(getWindowWidth(), getWindowHeight());
1375 int levels = gl::log2(getWindowWidth());
1376 for (int mipLevel = 0; mipLevel <= levels; ++mipLevel)
1377 {
1378 int size = getWindowWidth() >> mipLevel;
1379 glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_DEPTH_STENCIL, size, size, 0, GL_DEPTH_STENCIL,
1380 GL_UNSIGNED_INT_24_8_OES, nullptr);
1381 }
1382
1383 glBindTexture(GL_TEXTURE_2D, 0);
1384
1385 ASSERT_GL_NO_ERROR();
1386
1387 GLFramebuffer framebuffer;
1388 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1389
1390 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1391 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
1392
1393 ASSERT_GL_NO_ERROR();
1394
1395 glDepthRangef(0.0f, 1.0f);
1396 glViewport(0, 0, getWindowWidth(), getWindowHeight());
1397 glClearColor(0, 0, 0, 1);
1398
1399 // Draw loop.
1400 for (unsigned int frame = 0; frame < 3; ++frame)
1401 {
1402 // draw into FBO
1403 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1404 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1405
1406 glEnable(GL_DEPTH_TEST);
1407
1408 float depth = ((frame % 2 == 0) ? 0.0f : 1.0f);
1409 drawQuad(drawProgram, "vertex", depth);
1410
1411 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1412
1413 // blit FBO
1414 glDisable(GL_DEPTH_TEST);
1415
1416 glUseProgram(blitProgram);
1417 glUniform1i(blitTextureLocation, 0);
1418 glBindTexture(GL_TEXTURE_2D, depthTex);
1419
1420 drawQuad(blitProgram, "vertex", 0.5f);
1421
1422 Vector4 depthVec(depth, depth, depth, 1);
1423 GLColor depthColor(depthVec);
1424
1425 EXPECT_PIXEL_COLOR_NEAR(0, 0, depthColor, 1);
1426 ASSERT_GL_NO_ERROR();
1427 }
1428 }
1429
1430 // Initialize a depth texture by writing to it in a fragment shader then attempt to read it from a
1431 // compute shader. Regression test for D3D11 not unbinding the depth texture and the sampler binding
1432 // failing.
TEST_P(DepthStencilFormatsTestES31,ReadDepthStencilInComputeShader)1433 TEST_P(DepthStencilFormatsTestES31, ReadDepthStencilInComputeShader)
1434 {
1435 constexpr char kTestVertexShader[] = R"(#version 310 es
1436
1437 void main() {
1438 gl_PointSize = 1.0;
1439 vec2 pos[6] = vec2[6](vec2(-1.0f), vec2(1.0f, -1.0f), vec2(-1.0f, 1.0f), vec2(-1.0f, 1.0f), vec2(1.0f, -1.0f), vec2(1.0f));
1440 gl_Position = vec4(pos[uint(gl_VertexID)], 0.5f, 1.0f);
1441 return;
1442 }
1443 )";
1444
1445 constexpr char kTestFragmentShader[] = R"(#version 310 es
1446 precision highp float;
1447
1448 void main()
1449 {
1450 gl_FragDepth = 0.51f;
1451 return;
1452 }
1453 )";
1454
1455 constexpr char kTestComputeShader[] = R"(#version 310 es
1456
1457 layout(binding = 0, std430) buffer dst_buf_block_ssbo {
1458 float inner[];
1459 } dst_buf;
1460
1461 uniform highp sampler2D tex;
1462 void blit_depth_to_buffer(uvec3 id) {
1463 uvec2 coord = (id.xy);
1464 uint dstOffset = (id.x + (id.y * 1u));
1465 dst_buf.inner[dstOffset] = texelFetch(tex, ivec2(coord), 0).x;
1466 }
1467
1468 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
1469 void main() {
1470 blit_depth_to_buffer(gl_GlobalInvocationID);
1471 }
1472 )";
1473
1474 GLfloat depthValue = 0.51f;
1475 GLfloat depthErrorTolerance = 0.001f;
1476
1477 GLTexture depthTexture;
1478 glActiveTexture(GL_TEXTURE0);
1479 glBindTexture(GL_TEXTURE_2D, depthTexture);
1480 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1481 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1482 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1483 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1484
1485 // Clear depth texture to depthValue
1486 GLFramebuffer framebuffer;
1487 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1488 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
1489 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1490
1491 // 2. Draw and write to gl_FragDepth
1492 ANGLE_GL_PROGRAM(graphicsProgram, kTestVertexShader, kTestFragmentShader);
1493 glUseProgram(graphicsProgram);
1494 EXPECT_GL_NO_ERROR();
1495
1496 glDrawBuffers(0, nullptr);
1497 EXPECT_GL_NO_ERROR();
1498
1499 glClearDepthf(0.8);
1500 glEnable(GL_DEPTH_TEST);
1501 glDepthFunc(GL_ALWAYS);
1502 glDisable(GL_CULL_FACE);
1503 glDepthMask(true);
1504 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1505 glDrawArrays(GL_TRIANGLES, 0, 6);
1506 EXPECT_GL_NO_ERROR();
1507
1508 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1509
1510 ANGLE_GL_COMPUTE_PROGRAM(computeProgram, kTestComputeShader);
1511 glUseProgram(computeProgram);
1512
1513 GLint uTextureLocation = glGetUniformLocation(computeProgram, "tex");
1514 ASSERT_NE(-1, uTextureLocation);
1515 glActiveTexture(GL_TEXTURE0);
1516 glBindTexture(GL_TEXTURE_2D, depthTexture);
1517 glUniform1i(uTextureLocation, 0);
1518
1519 GLBuffer ssbo;
1520 std::array<GLfloat, 16> initialData{0};
1521 glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1522 glBufferData(GL_SHADER_STORAGE_BUFFER, 16, initialData.data(), GL_STATIC_DRAW);
1523 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
1524 glDispatchCompute(1, 1, 1);
1525 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1526 glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1527 const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
1528 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));
1529 EXPECT_NEAR(depthValue, ptr[0], depthErrorTolerance);
1530 EXPECT_GL_NO_ERROR();
1531 }
1532
1533 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TinyDepthStencilWorkaroundTest);
1534 ANGLE_INSTANTIATE_TEST_ES3_AND(TinyDepthStencilWorkaroundTest,
1535 ES3_D3D11().enable(Feature::EmulateTinyStencilTextures));
1536