Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/DepthStencilFormatsTest.cpp
1693 views
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/FeaturesD3D.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:
28
DepthStencilFormatsTestBase()
29
{
30
setWindowWidth(128);
31
setWindowHeight(128);
32
setConfigRedBits(8);
33
setConfigGreenBits(8);
34
setConfigBlueBits(8);
35
setConfigAlphaBits(8);
36
}
37
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
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
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
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.get(), 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.get(), 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.get(), 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
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
167
void testTearDown() override
168
{
169
glDeleteProgram(mProgram);
170
glDeleteTextures(1, &mTexture);
171
}
172
173
bool hasReadDepthSupport() const { return IsGLExtensionEnabled("GL_NV_read_depth"); }
174
175
bool hasReadStencilSupport() const { return IsGLExtensionEnabled("GL_NV_read_stencil"); }
176
177
bool hasFloatDepthSupport() const { return IsGLExtensionEnabled("GL_NV_depth_buffer_float2"); }
178
179
void depthStencilReadbackCase(const ReadbackTestParam &type);
180
181
GLuint mProgram;
182
GLuint mTexture;
183
GLint mTextureUniformLocation;
184
};
185
186
class DepthStencilFormatsTest : public DepthStencilFormatsTestBase
187
{};
188
189
class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase
190
{};
191
192
TEST_P(DepthStencilFormatsTest, DepthTexture)
193
{
194
bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_ANGLE_depth_texture") ||
195
IsGLExtensionEnabled("GL_OES_depth_texture"));
196
197
EXPECT_EQ(shouldHaveTextureSupport,
198
checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));
199
EXPECT_EQ(shouldHaveTextureSupport,
200
checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));
201
202
if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
203
{
204
EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));
205
EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));
206
}
207
}
208
209
TEST_P(DepthStencilFormatsTest, PackedDepthStencil)
210
{
211
// Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.
212
// Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not
213
// present.
214
215
bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil");
216
EXPECT_EQ(shouldHaveRenderbufferSupport,
217
checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));
218
219
bool shouldHaveTextureSupport = ((IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
220
IsGLExtensionEnabled("GL_OES_depth_texture_cube_map")) &&
221
IsGLExtensionEnabled("GL_OES_depth_texture")) ||
222
IsGLExtensionEnabled("GL_ANGLE_depth_texture");
223
EXPECT_EQ(shouldHaveTextureSupport,
224
checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
225
226
if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
227
{
228
bool shouldHaveTexStorageSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
229
IsGLExtensionEnabled("GL_ANGLE_depth_texture");
230
EXPECT_EQ(shouldHaveTexStorageSupport,
231
checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));
232
}
233
}
234
235
void DepthStencilFormatsTestBase::depthStencilReadbackCase(const ReadbackTestParam &type)
236
{
237
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
238
239
const bool hasFloatDepth = (type.type == GL_FLOAT);
240
ANGLE_SKIP_TEST_IF(hasFloatDepth && !hasFloatDepthSupport());
241
242
const bool hasStencil = (type.format != GL_DEPTH_COMPONENT);
243
244
const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;
245
246
const int res = 2;
247
const int destRes = 4;
248
249
GLTexture tex;
250
glBindTexture(GL_TEXTURE_2D, tex);
251
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
252
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
253
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
254
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
255
256
// test level > 0
257
glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
258
EXPECT_GL_NO_ERROR();
259
260
// test with data
261
glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
262
EXPECT_GL_NO_ERROR();
263
264
// test real thing
265
glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type, nullptr);
266
EXPECT_GL_NO_ERROR();
267
268
// test texSubImage2D
269
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
270
EXPECT_GL_NO_ERROR();
271
272
GLuint fbo = 0;
273
glGenFramebuffers(1, &fbo);
274
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
275
if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
276
{
277
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
278
EXPECT_GL_NO_ERROR();
279
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
280
EXPECT_GL_NO_ERROR();
281
}
282
else
283
{
284
glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
285
EXPECT_GL_NO_ERROR();
286
}
287
288
// Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
289
// UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
290
// UNSIGNED_INT_24_8_WEBGL.
291
292
GLint depthBits = 0;
293
glGetIntegerv(GL_DEPTH_BITS, &depthBits);
294
EXPECT_GE(depthBits, type.depthBits);
295
296
GLint stencilBits = 0;
297
glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
298
EXPECT_GE(stencilBits, type.stencilBits);
299
300
// TODO: remove this check if the spec is updated to require these combinations to work.
301
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
302
{
303
// try adding a color buffer.
304
GLuint colorTex = 0;
305
glGenTextures(1, &colorTex);
306
glBindTexture(GL_TEXTURE_2D, colorTex);
307
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
308
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
309
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
310
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
311
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
312
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
313
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
314
}
315
316
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
317
318
// use the default texture to render with while we return to the depth texture.
319
glBindTexture(GL_TEXTURE_2D, 0);
320
321
/* Setup 2x2 depth texture:
322
* 1 0.6 0.8
323
* |
324
* 0 0.2 0.4
325
* 0---1
326
*/
327
GLbitfield clearBits = GL_DEPTH_BUFFER_BIT;
328
if (hasStencil)
329
{
330
clearBits |= GL_STENCIL_BUFFER_BIT;
331
}
332
333
const GLfloat d00 = 0.2;
334
const GLfloat d01 = 0.4;
335
const GLfloat d10 = 0.6;
336
const GLfloat d11 = 0.8;
337
glEnable(GL_SCISSOR_TEST);
338
glScissor(0, 0, 1, 1);
339
glClearDepthf(d00);
340
glClearStencil(1);
341
glClear(clearBits);
342
glScissor(1, 0, 1, 1);
343
glClearDepthf(d10);
344
glClearStencil(2);
345
glClear(clearBits);
346
glScissor(0, 1, 1, 1);
347
glClearDepthf(d01);
348
glClearStencil(3);
349
glClear(clearBits);
350
glScissor(1, 1, 1, 1);
351
glClearDepthf(d11);
352
glClearStencil(4);
353
glClear(clearBits);
354
glDisable(GL_SCISSOR_TEST);
355
356
GLubyte actualPixels[destRes * destRes * 8];
357
glReadPixels(0, 0, destRes, destRes, GL_DEPTH_COMPONENT,
358
hasFloatDepth ? GL_FLOAT : GL_UNSIGNED_SHORT, actualPixels);
359
// NV_read_depth and NV_read_stencil do not support packed depth/stencil
360
if (hasReadDepthSupport() && type.format != GL_DEPTH_STENCIL)
361
{
362
EXPECT_GL_NO_ERROR();
363
if (hasFloatDepth)
364
{
365
constexpr float kEpsilon = 0.002f;
366
const float *pixels = reinterpret_cast<const float *>(actualPixels);
367
ASSERT_NEAR(pixels[0], d00, kEpsilon);
368
ASSERT_NEAR(pixels[0 + destRes], d01, kEpsilon);
369
ASSERT_NEAR(pixels[1], d10, kEpsilon);
370
ASSERT_NEAR(pixels[1 + destRes], d11, kEpsilon);
371
}
372
else
373
{
374
auto scale = [](float f) {
375
return static_cast<uint16_t>(
376
static_cast<float>(std::numeric_limits<uint16_t>::max()) * f);
377
};
378
379
constexpr unsigned short kEpsilon = 2;
380
const unsigned short *pixels = reinterpret_cast<const unsigned short *>(actualPixels);
381
ASSERT_NEAR(pixels[0], scale(d00), kEpsilon);
382
ASSERT_NEAR(pixels[0 + destRes], scale(d01), kEpsilon);
383
ASSERT_NEAR(pixels[1], scale(d10), kEpsilon);
384
ASSERT_NEAR(pixels[1 + destRes], scale(d11), kEpsilon);
385
}
386
}
387
else
388
{
389
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
390
}
391
if (hasStencil)
392
{
393
glReadPixels(0, 0, destRes, destRes, GL_STENCIL_INDEX_OES, GL_UNSIGNED_BYTE, actualPixels);
394
if (hasReadStencilSupport())
395
{
396
EXPECT_GL_NO_ERROR();
397
ASSERT_TRUE((actualPixels[0] == 1) && (actualPixels[1] == 2) &&
398
(actualPixels[0 + destRes] == 3) && (actualPixels[1 + destRes] = 4));
399
}
400
else
401
{
402
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
403
}
404
}
405
}
406
407
// This test will initialize a depth texture, clear it and read it back, if possible
408
TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UShort)
409
{
410
GLuint fakeData[10] = {0};
411
ReadbackTestParam type = {
412
GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0};
413
depthStencilReadbackCase(type);
414
}
415
416
// This test will initialize a depth texture, clear it and read it back, if possible
417
TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UInt)
418
{
419
// http://anglebug.com/5269
420
ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
421
422
GLuint fakeData[10] = {0};
423
ReadbackTestParam type = {
424
GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0};
425
depthStencilReadbackCase(type);
426
}
427
428
// This test will initialize a depth texture, clear it and read it back, if possible
429
TEST_P(DepthStencilFormatsTest, DepthStencilReadback_Float)
430
{
431
// http://anglebug.com/5269
432
ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
433
434
GLuint fakeData[10] = {0};
435
ReadbackTestParam type = {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_FLOAT, fakeData, 32, 0};
436
depthStencilReadbackCase(type);
437
}
438
439
// This test will initialize a depth texture, clear it and read it back, if possible
440
TEST_P(DepthStencilFormatsTest, DepthStencilReadback_DepthStencil)
441
{
442
GLuint fakeData[10] = {0};
443
ReadbackTestParam type = {
444
GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8};
445
depthStencilReadbackCase(type);
446
}
447
448
// This test will initialize a depth texture and then render with it and verify
449
// pixel correctness.
450
// This is modeled after webgl-depth-texture.html
451
TEST_P(DepthStencilFormatsTest, DepthTextureRender)
452
{
453
constexpr char kVS[] = R"(attribute vec4 a_position;
454
void main()
455
{
456
gl_Position = a_position;
457
})";
458
459
constexpr char kFS[] = R"(precision mediump float;
460
uniform sampler2D u_texture;
461
uniform vec2 u_resolution;
462
void main()
463
{
464
vec2 texcoord = (gl_FragCoord.xy - vec2(0.5)) / (u_resolution - vec2(1.0));
465
gl_FragColor = texture2D(u_texture, texcoord);
466
})";
467
468
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture") &&
469
!IsGLExtensionEnabled("GL_ANGLE_depth_texture"));
470
471
bool depthTextureCubeSupport = IsGLExtensionEnabled("GL_OES_depth_texture_cube_map");
472
473
// http://anglebug.com/3454
474
ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsD3D9());
475
476
const int res = 2;
477
const int destRes = 4;
478
GLint resolution;
479
480
ANGLE_GL_PROGRAM(program, kVS, kFS);
481
482
glUseProgram(program);
483
resolution = glGetUniformLocation(program, "u_resolution");
484
ASSERT_NE(-1, resolution);
485
glUniform2f(resolution, static_cast<float>(destRes), static_cast<float>(destRes));
486
487
GLuint buffer;
488
glGenBuffers(1, &buffer);
489
glBindBuffer(GL_ARRAY_BUFFER, buffer);
490
float verts[] = {
491
1, 1, 1, -1, 1, 0, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 0,
492
};
493
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
494
glEnableVertexAttribArray(0);
495
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
496
497
// OpenGL ES does not have a FLIPY PixelStore attribute
498
// glPixelStorei(GL_UNPACK_FLIP)
499
500
struct TypeInfo
501
{
502
GLuint attachment;
503
GLuint format;
504
GLuint type;
505
void *data;
506
int depthBits;
507
int stencilBits;
508
};
509
510
GLuint fakeData[10] = {0};
511
512
std::vector<TypeInfo> types = {
513
{GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0},
514
{GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0},
515
{GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8},
516
};
517
518
for (const TypeInfo &type : types)
519
{
520
GLTexture cubeTex;
521
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
522
ASSERT_GL_NO_ERROR();
523
524
std::vector<GLuint> targets{GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
525
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
526
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
527
528
for (const GLuint target : targets)
529
{
530
glTexImage2D(target, 0, type.format, 1, 1, 0, type.format, type.type, nullptr);
531
if (depthTextureCubeSupport)
532
{
533
ASSERT_GL_NO_ERROR();
534
}
535
else
536
{
537
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
538
}
539
}
540
541
std::vector<GLuint> filterModes = {GL_LINEAR, GL_NEAREST};
542
543
const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;
544
545
for (const GLuint filterMode : filterModes)
546
{
547
GLTexture tex;
548
glBindTexture(GL_TEXTURE_2D, tex);
549
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
550
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
551
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
552
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
553
554
// test level > 0
555
glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
556
if (IsGLExtensionEnabled("GL_OES_depth_texture"))
557
{
558
EXPECT_GL_NO_ERROR();
559
}
560
else
561
{
562
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
563
}
564
565
// test with data
566
glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
567
if (IsGLExtensionEnabled("GL_OES_depth_texture"))
568
{
569
EXPECT_GL_NO_ERROR();
570
}
571
else
572
{
573
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
574
}
575
576
// test copyTexImage2D
577
glCopyTexImage2D(GL_TEXTURE_2D, 0, type.format, 0, 0, 1, 1, 0);
578
GLuint error = glGetError();
579
ASSERT_TRUE(error == GL_INVALID_ENUM || error == GL_INVALID_OPERATION);
580
581
// test real thing
582
glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type,
583
nullptr);
584
EXPECT_GL_NO_ERROR();
585
586
// test texSubImage2D
587
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
588
if (IsGLExtensionEnabled("GL_OES_depth_texture"))
589
{
590
EXPECT_GL_NO_ERROR();
591
}
592
else
593
{
594
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
595
}
596
597
// test copyTexSubImage2D
598
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
599
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
600
601
// test generateMipmap
602
glGenerateMipmap(GL_TEXTURE_2D);
603
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
604
605
GLuint fbo = 0;
606
glGenFramebuffers(1, &fbo);
607
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
608
if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
609
{
610
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
611
EXPECT_GL_NO_ERROR();
612
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex,
613
0);
614
EXPECT_GL_NO_ERROR();
615
}
616
else
617
{
618
glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
619
EXPECT_GL_NO_ERROR();
620
}
621
622
// Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
623
// UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
624
// UNSIGNED_INT_24_8_WEBGL.
625
626
GLint depthBits = 0;
627
glGetIntegerv(GL_DEPTH_BITS, &depthBits);
628
EXPECT_GE(depthBits, type.depthBits);
629
630
GLint stencilBits = 0;
631
glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
632
EXPECT_GE(stencilBits, type.stencilBits);
633
634
// TODO: remove this check if the spec is updated to require these combinations to work.
635
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
636
{
637
// try adding a color buffer.
638
GLuint colorTex = 0;
639
glGenTextures(1, &colorTex);
640
glBindTexture(GL_TEXTURE_2D, colorTex);
641
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
642
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
643
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
644
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
645
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE,
646
nullptr);
647
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
648
colorTex, 0);
649
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
650
}
651
652
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
653
654
// use the default texture to render with while we return to the depth texture.
655
glBindTexture(GL_TEXTURE_2D, 0);
656
657
/* Setup 2x2 depth texture:
658
* 1 0.6 0.8
659
* |
660
* 0 0.2 0.4
661
* 0---1
662
*/
663
const GLfloat d00 = 0.2;
664
const GLfloat d01 = 0.4;
665
const GLfloat d10 = 0.6;
666
const GLfloat d11 = 0.8;
667
glEnable(GL_SCISSOR_TEST);
668
glScissor(0, 0, 1, 1);
669
glClearDepthf(d00);
670
glClear(GL_DEPTH_BUFFER_BIT);
671
glScissor(1, 0, 1, 1);
672
glClearDepthf(d10);
673
glClear(GL_DEPTH_BUFFER_BIT);
674
glScissor(0, 1, 1, 1);
675
glClearDepthf(d01);
676
glClear(GL_DEPTH_BUFFER_BIT);
677
glScissor(1, 1, 1, 1);
678
glClearDepthf(d11);
679
glClear(GL_DEPTH_BUFFER_BIT);
680
glDisable(GL_SCISSOR_TEST);
681
682
// render the depth texture.
683
glBindFramebuffer(GL_FRAMEBUFFER, 0);
684
glViewport(0, 0, destRes, destRes);
685
glBindTexture(GL_TEXTURE_2D, tex);
686
glDisable(GL_DITHER);
687
glEnable(GL_DEPTH_TEST);
688
glClearColor(1, 0, 0, 1);
689
glClearDepthf(1.0);
690
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
691
glDrawArrays(GL_TRIANGLES, 0, 6);
692
693
GLubyte actualPixels[destRes * destRes * 4];
694
glReadPixels(0, 0, destRes, destRes, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels);
695
const GLfloat eps = 0.002;
696
std::vector<GLfloat> expectedMin;
697
std::vector<GLfloat> expectedMax;
698
if (filterMode == GL_NEAREST)
699
{
700
GLfloat init[] = {d00, d00, d10, d10, d00, d00, d10, d10,
701
d01, d01, d11, d11, d01, d01, d11, d11};
702
expectedMin.insert(expectedMin.begin(), init, init + 16);
703
expectedMax.insert(expectedMax.begin(), init, init + 16);
704
705
for (int i = 0; i < 16; i++)
706
{
707
expectedMin[i] = expectedMin[i] - eps;
708
expectedMax[i] = expectedMax[i] + eps;
709
}
710
}
711
else
712
{
713
GLfloat initMin[] = {
714
d00 - eps, d00, d00, d10 - eps, d00, d00, d00, d10,
715
d00, d00, d00, d10, d01 - eps, d01, d01, d11 - eps,
716
};
717
GLfloat initMax[] = {
718
d00 + eps, d10, d10, d10 + eps, d01, d11, d11, d11,
719
d01, d11, d11, d11, d01 + eps, d11, d11, d11 + eps,
720
};
721
expectedMin.insert(expectedMin.begin(), initMin, initMin + 16);
722
expectedMax.insert(expectedMax.begin(), initMax, initMax + 16);
723
}
724
for (int yy = 0; yy < destRes; ++yy)
725
{
726
for (int xx = 0; xx < destRes; ++xx)
727
{
728
const int t = xx + destRes * yy;
729
const GLfloat was = (GLfloat)(actualPixels[4 * t] / 255.0); // 4bpp
730
const GLfloat eMin = expectedMin[t];
731
const GLfloat eMax = expectedMax[t];
732
EXPECT_TRUE(was >= eMin && was <= eMax)
733
<< "At " << xx << ", " << yy << ", expected within [" << eMin << ", "
734
<< eMax << "] was " << was;
735
}
736
}
737
738
// check limitations
739
// Note: What happens if current attachment type is GL_DEPTH_STENCIL_ATTACHMENT
740
// and you try to call glFramebufferTexture2D with GL_DEPTH_ATTACHMENT?
741
// The webGL test this code came from expected that to fail.
742
// I think due to this line in ES3 spec:
743
// GL_INVALID_OPERATION is generated if textarget and texture are not compatible
744
// However, that's not the behavior I'm seeing, nor does it seem that a depth_stencil
745
// buffer isn't compatible with a depth attachment (e.g. stencil is unused).
746
if (type.attachment == GL_DEPTH_ATTACHMENT)
747
{
748
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
749
glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, 0, 0);
750
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
751
tex, 0);
752
EXPECT_GLENUM_NE(GL_NO_ERROR, glGetError());
753
EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
754
glClear(GL_DEPTH_BUFFER_BIT);
755
EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
756
glBindFramebuffer(GL_FRAMEBUFFER, 0);
757
EXPECT_GL_NO_ERROR();
758
}
759
}
760
}
761
}
762
763
// This test will initialize a frame buffer, attaching a color and 16-bit depth buffer,
764
// render to it with depth testing, and verify pixel correctness.
765
TEST_P(DepthStencilFormatsTest, DepthBuffer16)
766
{
767
verifyDepthRenderBuffer(GL_DEPTH_COMPONENT16);
768
}
769
770
// This test will initialize a frame buffer, attaching a color and 24-bit depth buffer,
771
// render to it with depth testing, and verify pixel correctness.
772
TEST_P(DepthStencilFormatsTest, DepthBuffer24)
773
{
774
bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_depth24");
775
EXPECT_EQ(shouldHaveRenderbufferSupport,
776
checkRenderbufferFormatSupport(GL_DEPTH_COMPONENT24_OES));
777
778
if (shouldHaveRenderbufferSupport)
779
{
780
verifyDepthRenderBuffer(GL_DEPTH_COMPONENT24_OES);
781
}
782
}
783
784
TEST_P(DepthStencilFormatsTestES3, DrawWithDepth16)
785
{
786
GLushort data[16];
787
for (unsigned int i = 0; i < 16; i++)
788
{
789
data[i] = std::numeric_limits<GLushort>::max();
790
}
791
glBindTexture(GL_TEXTURE_2D, mTexture);
792
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4);
793
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
794
795
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
796
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
797
798
glUseProgram(mProgram);
799
glUniform1i(mTextureUniformLocation, 0);
800
801
glClear(GL_COLOR_BUFFER_BIT);
802
drawQuad(mProgram, "position", 0.5f);
803
804
ASSERT_GL_NO_ERROR();
805
806
GLubyte pixel[4];
807
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
808
809
// Only require the red and alpha channels have the correct values, the depth texture extensions
810
// leave the green and blue channels undefined
811
ASSERT_NEAR(255, pixel[0], 2.0);
812
ASSERT_EQ(255, pixel[3]);
813
}
814
815
// This test reproduces a driver bug on Intel windows platforms on driver version
816
// from 4815 to 4901.
817
// When rendering with Stencil buffer enabled and depth buffer disabled, large
818
// viewport will lead to memory leak and driver crash. And the pixel result
819
// is a random value.
820
TEST_P(DepthStencilFormatsTestES3, DrawWithLargeViewport)
821
{
822
ANGLE_SKIP_TEST_IF(IsIntel() && (IsOSX() || IsWindows()));
823
824
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
825
826
glEnable(GL_STENCIL_TEST);
827
glDisable(GL_DEPTH_TEST);
828
829
// The iteration is to reproduce memory leak when rendering several times.
830
for (int i = 0; i < 10; ++i)
831
{
832
// Create offscreen fbo and its color attachment and depth stencil attachment.
833
GLTexture framebufferColorTexture;
834
glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
835
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
836
ASSERT_GL_NO_ERROR();
837
838
GLTexture framebufferStencilTexture;
839
glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
840
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
841
ASSERT_GL_NO_ERROR();
842
843
GLFramebuffer fb;
844
glBindFramebuffer(GL_FRAMEBUFFER, fb);
845
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
846
framebufferColorTexture, 0);
847
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
848
framebufferStencilTexture, 0);
849
850
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
851
ASSERT_GL_NO_ERROR();
852
853
GLint kStencilRef = 4;
854
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
855
glStencilFunc(GL_ALWAYS, kStencilRef, 0xFF);
856
857
float viewport[2];
858
glGetFloatv(GL_MAX_VIEWPORT_DIMS, viewport);
859
860
glViewport(0, 0, static_cast<GLsizei>(viewport[0]), static_cast<GLsizei>(viewport[1]));
861
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
862
863
drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f);
864
ASSERT_GL_NO_ERROR();
865
866
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
867
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
868
ASSERT_GL_NO_ERROR();
869
}
870
}
871
872
// Verify that stencil component of depth texture is uploaded
873
TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)
874
{
875
// http://anglebug.com/3683
876
// When bug is resolved we can remove this skip.
877
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
878
879
// http://anglebug.com/3689
880
ANGLE_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsAMD());
881
882
// http://anglebug.com/4908
883
ANGLE_SKIP_TEST_IF(IsIntel() && IsMetal());
884
885
// Test failure introduced by Apple's changes (anglebug.com/5505)
886
ANGLE_SKIP_TEST_IF(IsMetal() && IsAMD());
887
888
// Test failure introduced by Apple's changes (anglebug.com/5505)
889
ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsMetal());
890
891
bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_OES_packed_depth_stencil") &&
892
IsGLExtensionEnabled("GL_OES_depth_texture")) ||
893
(getClientMajorVersion() >= 3);
894
895
ANGLE_SKIP_TEST_IF(!shouldHaveTextureSupport ||
896
!checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
897
898
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
899
900
glEnable(GL_STENCIL_TEST);
901
glDisable(GL_DEPTH_TEST);
902
glDepthMask(GL_FALSE);
903
904
glViewport(0, 0, getWindowWidth(), getWindowHeight());
905
glClearColor(0, 0, 0, 1);
906
907
// Create offscreen fbo and its color attachment and depth stencil attachment.
908
GLTexture framebufferColorTexture;
909
glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
910
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
911
GL_UNSIGNED_BYTE, nullptr);
912
ASSERT_GL_NO_ERROR();
913
914
// drawQuad's depth range is -1.0 to 1.0, so a depth value of 0.5 (0x7fffff) matches a drawQuad
915
// depth of 0.0.
916
std::vector<GLuint> depthStencilData(getWindowWidth() * getWindowHeight(), 0x7fffffA9);
917
GLTexture framebufferStencilTexture;
918
glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
919
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, getWindowWidth(), getWindowHeight(), 0,
920
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, depthStencilData.data());
921
ASSERT_GL_NO_ERROR();
922
923
GLFramebuffer fb;
924
glBindFramebuffer(GL_FRAMEBUFFER, fb);
925
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
926
framebufferColorTexture, 0);
927
928
if (getClientMajorVersion() >= 3)
929
{
930
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
931
framebufferStencilTexture, 0);
932
ASSERT_GL_NO_ERROR();
933
}
934
else
935
{
936
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
937
framebufferStencilTexture, 0);
938
ASSERT_GL_NO_ERROR();
939
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
940
framebufferStencilTexture, 0);
941
ASSERT_GL_NO_ERROR();
942
}
943
944
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
945
946
GLint kStencilRef = 0xA9;
947
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
948
glStencilFunc(GL_EQUAL, kStencilRef, 0xFF);
949
950
glBindFramebuffer(GL_FRAMEBUFFER, fb);
951
952
glClear(GL_COLOR_BUFFER_BIT);
953
954
drawQuad(program.get(), essl1_shaders::PositionAttrib(), 1.0f);
955
ASSERT_GL_NO_ERROR();
956
957
glBindFramebuffer(GL_FRAMEBUFFER, fb);
958
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
959
ASSERT_GL_NO_ERROR();
960
961
// Check Z values
962
963
glClear(GL_COLOR_BUFFER_BIT);
964
glDisable(GL_STENCIL_TEST);
965
glEnable(GL_DEPTH_TEST);
966
glDepthFunc(GL_LESS);
967
968
drawQuad(program.get(), essl1_shaders::PositionAttrib(), -0.1f);
969
ASSERT_GL_NO_ERROR();
970
971
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
972
973
glClear(GL_COLOR_BUFFER_BIT);
974
975
drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.1f);
976
ASSERT_GL_NO_ERROR();
977
978
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::black);
979
}
980
981
// Verify that depth texture's data can be uploaded correctly
982
TEST_P(DepthStencilFormatsTest, VerifyDepth32UploadData)
983
{
984
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
985
986
GLTexture tex;
987
glBindTexture(GL_TEXTURE_2D, tex);
988
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
989
ASSERT_GL_NO_ERROR();
990
991
// normalized 0.99 = 0xfd70a3d6
992
std::vector<GLuint> depthData(1, 0xfd70a3d6);
993
GLTexture rbDepth;
994
glBindTexture(GL_TEXTURE_2D, rbDepth);
995
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
996
depthData.data());
997
ASSERT_GL_NO_ERROR();
998
999
GLFramebuffer fbo;
1000
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1001
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1002
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
1003
1004
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1005
ASSERT_GL_NO_ERROR();
1006
1007
ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1008
glEnable(GL_DEPTH_TEST);
1009
glDepthFunc(GL_GEQUAL);
1010
glClearColor(0, 1, 0, 1);
1011
glClear(GL_COLOR_BUFFER_BIT);
1012
1013
// Fail Depth Test and color buffer is unchanged
1014
float depthValue = 0.98f;
1015
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1016
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1017
1018
// Pass Depth Test and draw red
1019
depthValue = 1.0f;
1020
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1021
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1022
1023
ASSERT_GL_NO_ERROR();
1024
1025
// Change depth texture data
1026
glBindTexture(GL_TEXTURE_2D, rbDepth);
1027
depthData[0] = 0x7fffffff; // 0.5
1028
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
1029
depthData.data());
1030
ASSERT_GL_NO_ERROR();
1031
1032
ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1033
1034
// Fail Depth Test and color buffer is unchanged
1035
depthValue = 0.48f;
1036
drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1037
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1038
1039
ASSERT_GL_NO_ERROR();
1040
1041
ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1042
glClearDepthf(0.0f);
1043
glClear(GL_DEPTH_BUFFER_BIT);
1044
1045
// Pass Depth Test and draw blue
1046
depthValue = 0.01f;
1047
drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1048
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1049
1050
glDisable(GL_DEPTH_TEST);
1051
ASSERT_GL_NO_ERROR();
1052
}
1053
1054
// Verify that 16 bits depth texture's data can be uploaded correctly
1055
TEST_P(DepthStencilFormatsTest, VerifyDepth16UploadData)
1056
{
1057
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
1058
1059
GLTexture tex;
1060
glBindTexture(GL_TEXTURE_2D, tex);
1061
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1062
ASSERT_GL_NO_ERROR();
1063
1064
// normalized 0.99 = 0xfd6f
1065
std::vector<GLushort> depthData(1, 0xfd6f);
1066
GLTexture rbDepth;
1067
glBindTexture(GL_TEXTURE_2D, rbDepth);
1068
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT,
1069
GL_UNSIGNED_SHORT, depthData.data());
1070
ASSERT_GL_NO_ERROR();
1071
1072
GLFramebuffer fbo;
1073
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1074
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1075
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
1076
1077
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1078
ASSERT_GL_NO_ERROR();
1079
1080
ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1081
glEnable(GL_DEPTH_TEST);
1082
glDepthFunc(GL_GEQUAL);
1083
glClearColor(0, 1, 0, 1);
1084
glClear(GL_COLOR_BUFFER_BIT);
1085
1086
// Fail Depth Test and color buffer is unchanged
1087
float depthValue = 0.98f;
1088
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1089
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1090
1091
// Pass Depth Test and draw red
1092
depthValue = 1.0f;
1093
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1094
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1095
1096
ASSERT_GL_NO_ERROR();
1097
1098
// Change depth texture data
1099
glBindTexture(GL_TEXTURE_2D, rbDepth);
1100
depthData[0] = 0x7fff; // 0.5
1101
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
1102
depthData.data());
1103
ASSERT_GL_NO_ERROR();
1104
1105
ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1106
1107
// Fail Depth Test and color buffer is unchanged
1108
depthValue = 0.48f;
1109
drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1110
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1111
1112
ASSERT_GL_NO_ERROR();
1113
1114
ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1115
glClearDepthf(0.0f);
1116
glClear(GL_DEPTH_BUFFER_BIT);
1117
1118
// Pass Depth Test and draw blue
1119
depthValue = 0.01f;
1120
drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1121
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1122
1123
glDisable(GL_DEPTH_TEST);
1124
ASSERT_GL_NO_ERROR();
1125
}
1126
1127
ANGLE_INSTANTIATE_TEST_ES2(DepthStencilFormatsTest);
1128
1129
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilFormatsTestES3);
1130
ANGLE_INSTANTIATE_TEST_ES3(DepthStencilFormatsTestES3);
1131
1132
class TinyDepthStencilWorkaroundTest : public ANGLETest
1133
{
1134
public:
1135
TinyDepthStencilWorkaroundTest()
1136
{
1137
setWindowWidth(512);
1138
setWindowHeight(512);
1139
setConfigRedBits(8);
1140
setConfigGreenBits(8);
1141
setConfigBlueBits(8);
1142
setConfigAlphaBits(8);
1143
}
1144
1145
// Override the features to enable "tiny" depth/stencil textures.
1146
void overrideWorkaroundsD3D(FeaturesD3D *features) override
1147
{
1148
features->overrideFeatures({"emulate_tiny_stencil_textures"}, true);
1149
}
1150
};
1151
1152
// Tests that the tiny depth stencil textures workaround does not "stick" depth textures.
1153
// http://anglebug.com/1664
1154
TEST_P(TinyDepthStencilWorkaroundTest, DepthTexturesStick)
1155
{
1156
// http://anglebug.com/4092
1157
ANGLE_SKIP_TEST_IF((IsAndroid() && IsOpenGLES()) || (IsLinux() && IsVulkan()));
1158
ANGLE_SKIP_TEST_IF(isSwiftshader());
1159
1160
// TODO(anglebug.com/5491)
1161
ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
1162
1163
constexpr char kDrawVS[] =
1164
"#version 100\n"
1165
"attribute vec3 vertex;\n"
1166
"void main () {\n"
1167
" gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);\n"
1168
"}\n";
1169
1170
ANGLE_GL_PROGRAM(drawProgram, kDrawVS, essl1_shaders::fs::Red());
1171
1172
constexpr char kBlitVS[] =
1173
"#version 100\n"
1174
"attribute vec2 vertex;\n"
1175
"varying vec2 position;\n"
1176
"void main () {\n"
1177
" position = vertex * .5 + .5;\n"
1178
" gl_Position = vec4(vertex, 0, 1);\n"
1179
"}\n";
1180
1181
constexpr char kBlitFS[] =
1182
"#version 100\n"
1183
"precision mediump float;\n"
1184
"uniform sampler2D texture;\n"
1185
"varying vec2 position;\n"
1186
"void main () {\n"
1187
" gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);\n"
1188
"}\n";
1189
1190
ANGLE_GL_PROGRAM(blitProgram, kBlitVS, kBlitFS);
1191
1192
GLint blitTextureLocation = glGetUniformLocation(blitProgram.get(), "texture");
1193
ASSERT_NE(-1, blitTextureLocation);
1194
1195
GLTexture colorTex;
1196
glBindTexture(GL_TEXTURE_2D, colorTex.get());
1197
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1198
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1199
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1200
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1201
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1202
GL_UNSIGNED_BYTE, nullptr);
1203
glBindTexture(GL_TEXTURE_2D, 0);
1204
1205
GLTexture depthTex;
1206
glBindTexture(GL_TEXTURE_2D, depthTex.get());
1207
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1208
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1209
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1210
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1211
ASSERT_EQ(getWindowWidth(), getWindowHeight());
1212
int levels = gl::log2(getWindowWidth());
1213
for (int mipLevel = 0; mipLevel <= levels; ++mipLevel)
1214
{
1215
int size = getWindowWidth() >> mipLevel;
1216
glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_DEPTH_STENCIL, size, size, 0, GL_DEPTH_STENCIL,
1217
GL_UNSIGNED_INT_24_8_OES, nullptr);
1218
}
1219
1220
glBindTexture(GL_TEXTURE_2D, 0);
1221
1222
ASSERT_GL_NO_ERROR();
1223
1224
GLFramebuffer framebuffer;
1225
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1226
1227
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex.get(), 0);
1228
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex.get(), 0);
1229
1230
ASSERT_GL_NO_ERROR();
1231
1232
glDepthRangef(0.0f, 1.0f);
1233
glViewport(0, 0, getWindowWidth(), getWindowHeight());
1234
glClearColor(0, 0, 0, 1);
1235
1236
// Draw loop.
1237
for (unsigned int frame = 0; frame < 3; ++frame)
1238
{
1239
// draw into FBO
1240
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1241
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1242
1243
glEnable(GL_DEPTH_TEST);
1244
1245
float depth = ((frame % 2 == 0) ? 0.0f : 1.0f);
1246
drawQuad(drawProgram.get(), "vertex", depth);
1247
1248
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1249
1250
// blit FBO
1251
glDisable(GL_DEPTH_TEST);
1252
1253
glUseProgram(blitProgram.get());
1254
glUniform1i(blitTextureLocation, 0);
1255
glBindTexture(GL_TEXTURE_2D, depthTex.get());
1256
1257
drawQuad(blitProgram.get(), "vertex", 0.5f);
1258
1259
Vector4 depthVec(depth, depth, depth, 1);
1260
GLColor depthColor(depthVec);
1261
1262
EXPECT_PIXEL_COLOR_NEAR(0, 0, depthColor, 1);
1263
ASSERT_GL_NO_ERROR();
1264
}
1265
}
1266
1267
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TinyDepthStencilWorkaroundTest);
1268
ANGLE_INSTANTIATE_TEST_ES3(TinyDepthStencilWorkaroundTest);
1269
1270