Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/CopyTexImageTest.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
namespace angle
11
{
12
13
class CopyTexImageTest : public ANGLETest
14
{
15
protected:
16
CopyTexImageTest()
17
{
18
setWindowWidth(32);
19
setWindowHeight(32);
20
setConfigRedBits(8);
21
setConfigGreenBits(8);
22
setConfigBlueBits(8);
23
setConfigAlphaBits(8);
24
}
25
26
void testSetUp() override
27
{
28
mTextureProgram =
29
CompileProgram(essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
30
if (mTextureProgram == 0)
31
{
32
FAIL() << "shader compilation failed.";
33
}
34
35
mTextureUniformLocation =
36
glGetUniformLocation(mTextureProgram, essl1_shaders::Texture2DUniform());
37
38
ASSERT_GL_NO_ERROR();
39
}
40
41
void testTearDown() override { glDeleteProgram(mTextureProgram); }
42
43
void initializeResources(GLenum format, GLenum type)
44
{
45
for (size_t i = 0; i < kFboCount; ++i)
46
{
47
glBindTexture(GL_TEXTURE_2D, mFboTextures[i]);
48
glTexImage2D(GL_TEXTURE_2D, 0, format, kFboSizes[i], kFboSizes[i], 0, format, type,
49
nullptr);
50
51
// Disable mipmapping
52
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
53
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
54
55
glBindFramebuffer(GL_FRAMEBUFFER, mFbos[i]);
56
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
57
mFboTextures[i], 0);
58
59
glClearColor(kFboColors[i][0], kFboColors[i][1], kFboColors[i][2], kFboColors[i][3]);
60
glClear(GL_COLOR_BUFFER_BIT);
61
}
62
63
ASSERT_GL_NO_ERROR();
64
}
65
66
void verifyResults(GLuint texture,
67
const GLubyte data[4],
68
GLint fboSize,
69
GLint xs,
70
GLint ys,
71
GLint xe,
72
GLint ye)
73
{
74
glViewport(0, 0, fboSize, fboSize);
75
76
glBindFramebuffer(GL_FRAMEBUFFER, 0);
77
78
// Draw a quad with the target texture
79
glUseProgram(mTextureProgram);
80
glBindTexture(GL_TEXTURE_2D, texture);
81
glUniform1i(mTextureUniformLocation, 0);
82
83
drawQuad(mTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);
84
85
// Expect that the rendered quad has the same color as the source texture
86
EXPECT_PIXEL_NEAR(xs, ys, data[0], data[1], data[2], data[3], 1.0);
87
EXPECT_PIXEL_NEAR(xs, ye - 1, data[0], data[1], data[2], data[3], 1.0);
88
EXPECT_PIXEL_NEAR(xe - 1, ys, data[0], data[1], data[2], data[3], 1.0);
89
EXPECT_PIXEL_NEAR(xe - 1, ye - 1, data[0], data[1], data[2], data[3], 1.0);
90
EXPECT_PIXEL_NEAR((xs + xe) / 2, (ys + ye) / 2, data[0], data[1], data[2], data[3], 1.0);
91
}
92
93
void runCopyTexImageTest(GLenum format, GLubyte expected[3][4])
94
{
95
GLTexture tex;
96
glBindTexture(GL_TEXTURE_2D, tex);
97
98
// Disable mipmapping
99
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
100
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
101
102
// Perform the copy multiple times.
103
//
104
// - The first time, a new texture is created
105
// - The second time, as the fbo size is the same as previous, the texture storage is not
106
// recreated.
107
// - The third time, the fbo size is different, so a new texture is created.
108
for (size_t i = 0; i < kFboCount; ++i)
109
{
110
glBindFramebuffer(GL_FRAMEBUFFER, mFbos[i]);
111
112
glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, kFboSizes[i], kFboSizes[i], 0);
113
ASSERT_GL_NO_ERROR();
114
115
verifyResults(tex, expected[i], kFboSizes[i], 0, 0, kFboSizes[i], kFboSizes[i]);
116
}
117
}
118
119
void runCopyTexSubImageTest(GLenum format, GLubyte expected[3][4])
120
{
121
GLTexture tex;
122
glBindTexture(GL_TEXTURE_2D, tex);
123
124
// Disable mipmapping
125
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
126
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
127
128
// Create the texture with copy of the first fbo.
129
glBindFramebuffer(GL_FRAMEBUFFER, mFbos[0]);
130
glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, kFboSizes[0], kFboSizes[0], 0);
131
ASSERT_GL_NO_ERROR();
132
133
verifyResults(tex, expected[0], kFboSizes[0], 0, 0, kFboSizes[0], kFboSizes[0]);
134
135
// Make sure out-of-bound writes to the texture return invalid value.
136
glBindFramebuffer(GL_FRAMEBUFFER, mFbos[1]);
137
138
// xoffset < 0 and yoffset < 0
139
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, -1, -1, 0, 0, kFboSizes[0], kFboSizes[0]);
140
ASSERT_GL_ERROR(GL_INVALID_VALUE);
141
142
// xoffset + width > w and yoffset + height > h
143
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 0, 0, kFboSizes[0], kFboSizes[0]);
144
ASSERT_GL_ERROR(GL_INVALID_VALUE);
145
146
// xoffset + width > w and yoffset + height > h, out of bounds
147
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, -1, -1, 1 + kFboSizes[0], 1 + kFboSizes[0]);
148
ASSERT_GL_ERROR(GL_INVALID_VALUE);
149
150
// Copy the second fbo over a portion of the image.
151
GLint offset = kFboSizes[0] / 2;
152
GLint extent = kFboSizes[0] - offset;
153
154
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, offset, offset, kFboSizes[1] / 2, kFboSizes[1] / 2,
155
extent, extent);
156
ASSERT_GL_NO_ERROR();
157
158
verifyResults(tex, expected[1], kFboSizes[0], offset, offset, kFboSizes[0], kFboSizes[0]);
159
160
// The rest of the image should be untouched
161
verifyResults(tex, expected[0], kFboSizes[0], 0, 0, offset, offset);
162
verifyResults(tex, expected[0], kFboSizes[0], offset, 0, kFboSizes[0], offset);
163
verifyResults(tex, expected[0], kFboSizes[0], 0, offset, offset, kFboSizes[0]);
164
165
// Copy the third fbo over another portion of the image.
166
glBindFramebuffer(GL_FRAMEBUFFER, mFbos[2]);
167
168
offset = kFboSizes[0] / 4;
169
extent = kFboSizes[0] - offset;
170
171
// While width and height are set as 3/4 of the size, the fbo offset is given such that
172
// after clipping, width and height are effectively 1/2 of the size.
173
GLint srcOffset = kFboSizes[2] - kFboSizes[0] / 2;
174
GLint effectiveExtent = kFboSizes[0] / 2;
175
176
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, offset, offset, srcOffset, srcOffset, extent, extent);
177
ASSERT_GL_NO_ERROR();
178
179
verifyResults(tex, expected[2], kFboSizes[0], offset, offset, effectiveExtent,
180
effectiveExtent);
181
182
// The rest of the image should be untouched
183
verifyResults(tex, expected[1], kFboSizes[0], offset + effectiveExtent, kFboSizes[0] / 2,
184
kFboSizes[0], kFboSizes[0]);
185
verifyResults(tex, expected[1], kFboSizes[0], kFboSizes[0] / 2, offset + effectiveExtent,
186
kFboSizes[0], kFboSizes[0]);
187
188
verifyResults(tex, expected[0], kFboSizes[0], 0, 0, kFboSizes[0], offset);
189
verifyResults(tex, expected[0], kFboSizes[0], 0, 0, offset, kFboSizes[0]);
190
verifyResults(tex, expected[0], kFboSizes[0], offset + effectiveExtent, 0, kFboSizes[0],
191
kFboSizes[0] / 2);
192
verifyResults(tex, expected[0], kFboSizes[0], 0, offset + effectiveExtent, kFboSizes[0] / 2,
193
kFboSizes[0]);
194
}
195
196
GLuint mTextureProgram;
197
GLint mTextureUniformLocation;
198
199
static constexpr uint32_t kFboCount = 3;
200
GLFramebuffer mFbos[kFboCount];
201
GLTexture mFboTextures[kFboCount];
202
203
static constexpr uint32_t kFboSizes[kFboCount] = {16, 16, 32};
204
static constexpr GLfloat kFboColors[kFboCount][4] = {{0.25f, 1.0f, 0.75f, 0.5f},
205
{1.0f, 0.75f, 0.5f, 0.25f},
206
{0.5f, 0.25f, 1.0f, 0.75f}};
207
};
208
209
// Until C++17, need to redundantly declare the constexpr members outside the class (only the
210
// arrays, because the others are already const-propagated and not needed by the linker).
211
constexpr uint32_t CopyTexImageTest::kFboSizes[];
212
constexpr GLfloat CopyTexImageTest::kFboColors[][4];
213
214
TEST_P(CopyTexImageTest, RGBAToRGB)
215
{
216
GLubyte expected[3][4] = {
217
{64, 255, 191, 255},
218
{255, 191, 127, 255},
219
{127, 64, 255, 255},
220
};
221
222
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
223
runCopyTexImageTest(GL_RGB, expected);
224
}
225
226
TEST_P(CopyTexImageTest, RGBAToL)
227
{
228
GLubyte expected[3][4] = {
229
{64, 64, 64, 255},
230
{255, 255, 255, 255},
231
{127, 127, 127, 255},
232
};
233
234
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
235
runCopyTexImageTest(GL_LUMINANCE, expected);
236
}
237
238
TEST_P(CopyTexImageTest, RGBToL)
239
{
240
GLubyte expected[3][4] = {
241
{64, 64, 64, 255},
242
{255, 255, 255, 255},
243
{127, 127, 127, 255},
244
};
245
246
initializeResources(GL_RGB, GL_UNSIGNED_BYTE);
247
runCopyTexImageTest(GL_LUMINANCE, expected);
248
}
249
250
TEST_P(CopyTexImageTest, RGBAToLA)
251
{
252
GLubyte expected[3][4] = {
253
{64, 64, 64, 127},
254
{255, 255, 255, 64},
255
{127, 127, 127, 191},
256
};
257
258
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
259
runCopyTexImageTest(GL_LUMINANCE_ALPHA, expected);
260
}
261
262
TEST_P(CopyTexImageTest, RGBAToA)
263
{
264
GLubyte expected[3][4] = {
265
{0, 0, 0, 127},
266
{0, 0, 0, 64},
267
{0, 0, 0, 191},
268
};
269
270
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
271
runCopyTexImageTest(GL_ALPHA, expected);
272
}
273
274
TEST_P(CopyTexImageTest, SubImageRGBAToRGB)
275
{
276
GLubyte expected[3][4] = {
277
{64, 255, 191, 255},
278
{255, 191, 127, 255},
279
{127, 64, 255, 255},
280
};
281
282
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
283
runCopyTexSubImageTest(GL_RGB, expected);
284
}
285
286
TEST_P(CopyTexImageTest, SubImageRGBAToL)
287
{
288
GLubyte expected[3][4] = {
289
{64, 64, 64, 255},
290
{255, 255, 255, 255},
291
{127, 127, 127, 255},
292
};
293
294
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
295
runCopyTexSubImageTest(GL_LUMINANCE, expected);
296
}
297
298
TEST_P(CopyTexImageTest, SubImageRGBAToLA)
299
{
300
GLubyte expected[3][4] = {
301
{64, 64, 64, 127},
302
{255, 255, 255, 64},
303
{127, 127, 127, 191},
304
};
305
306
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
307
runCopyTexSubImageTest(GL_LUMINANCE_ALPHA, expected);
308
}
309
310
TEST_P(CopyTexImageTest, SubImageRGBToL)
311
{
312
GLubyte expected[3][4] = {
313
{64, 64, 64, 255},
314
{255, 255, 255, 255},
315
{127, 127, 127, 255},
316
};
317
318
initializeResources(GL_RGB, GL_UNSIGNED_BYTE);
319
runCopyTexSubImageTest(GL_LUMINANCE, expected);
320
}
321
322
// Read default framebuffer with glCopyTexImage2D().
323
TEST_P(CopyTexImageTest, DefaultFramebuffer)
324
{
325
// Seems to be a bug in Mesa with the GLX back end: cannot read framebuffer until we draw to it.
326
// glCopyTexImage2D() below will fail without this clear.
327
glClear(GL_COLOR_BUFFER_BIT);
328
329
const GLint w = getWindowWidth(), h = getWindowHeight();
330
GLTexture tex;
331
glBindTexture(GL_TEXTURE_2D, tex);
332
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
333
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, w, h, 0);
334
EXPECT_GL_NO_ERROR();
335
}
336
337
// Read default framebuffer with glCopyTexSubImage2D().
338
TEST_P(CopyTexImageTest, SubDefaultFramebuffer)
339
{
340
// Seems to be a bug in Mesa with the GLX back end: cannot read framebuffer until we draw to it.
341
// glCopyTexSubImage2D() below will fail without this clear.
342
glClear(GL_COLOR_BUFFER_BIT);
343
344
const GLint w = getWindowWidth(), h = getWindowHeight();
345
GLTexture tex;
346
glBindTexture(GL_TEXTURE_2D, tex);
347
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
348
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
349
EXPECT_GL_NO_ERROR();
350
}
351
352
// Calling CopyTexSubImage from cubeMap texture.
353
TEST_P(CopyTexImageTest, CopyTexSubImageFromCubeMap)
354
{
355
constexpr GLsizei kCubeMapFaceCount = 6;
356
357
// The framebuffer will be a face of a cube map with a different colors for each face. Each
358
// glCopyTexSubImage2D will take one face of this image to copy over a pixel in a 1x6
359
// framebuffer.
360
GLColor fboPixels[kCubeMapFaceCount] = {GLColor::red, GLColor::yellow, GLColor::green,
361
GLColor::cyan, GLColor::blue, GLColor::magenta};
362
GLColor whitePixels[kCubeMapFaceCount] = {GLColor::white, GLColor::white, GLColor::white,
363
GLColor::white, GLColor::white, GLColor::white};
364
365
GLTexture fboTex;
366
glBindTexture(GL_TEXTURE_CUBE_MAP, fboTex);
367
for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
368
face++)
369
{
370
GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
371
372
glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &fboPixels[faceIndex]);
373
}
374
375
GLTexture dstTex;
376
glBindTexture(GL_TEXTURE_2D, dstTex);
377
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeMapFaceCount, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
378
whitePixels);
379
380
GLFramebuffer fbo;
381
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
382
383
for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
384
face++)
385
{
386
GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
387
388
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, fboTex, 0);
389
390
ASSERT_GL_NO_ERROR();
391
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
392
393
// Copy the fbo (a cube map face) into a pixel of the destination texture.
394
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, faceIndex, 0, 0, 0, 1, 1);
395
}
396
397
// Make sure all the copies are done correctly.
398
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0);
399
400
ASSERT_GL_NO_ERROR();
401
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
402
403
for (GLsizei faceIndex = 0; faceIndex < kCubeMapFaceCount; ++faceIndex)
404
{
405
EXPECT_PIXEL_COLOR_EQ(faceIndex, 0, fboPixels[faceIndex]);
406
}
407
}
408
409
// Calling CopyTexSubImage to a non-cube-complete texture.
410
TEST_P(CopyTexImageTest, CopyTexSubImageToNonCubeCompleteDestination)
411
{
412
// TODO(hqle): Find what wrong with NVIDIA GPU. http://anglebug.com/4137
413
ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsMetal());
414
415
constexpr GLsizei kCubeMapFaceCount = 6;
416
417
// The framebuffer will be a 1x6 image with 6 different colors. Each glCopyTexSubImage2D will
418
// take one pixel of this image to copy over each face of a cube map.
419
GLColor fboPixels[kCubeMapFaceCount] = {GLColor::red, GLColor::yellow, GLColor::green,
420
GLColor::cyan, GLColor::blue, GLColor::magenta};
421
GLColor whitePixel = GLColor::white;
422
423
GLTexture fboTex;
424
glBindTexture(GL_TEXTURE_2D, fboTex);
425
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeMapFaceCount, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
426
fboPixels);
427
428
GLFramebuffer fbo;
429
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
430
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
431
432
ASSERT_GL_NO_ERROR();
433
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
434
435
GLTexture cubeMap;
436
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMap);
437
438
for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
439
face++)
440
{
441
GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
442
443
// Initialize the face with a color not found in the fbo.
444
glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &whitePixel);
445
446
// Copy one pixel from the fbo into this face. The first 5 copies are done on a
447
// non-cube-complete texture.
448
glCopyTexSubImage2D(face, 0, 0, 0, faceIndex, 0, 1, 1);
449
}
450
451
// Make sure all the copies are done correctly.
452
for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
453
face++)
454
{
455
GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
456
457
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, cubeMap, 0);
458
459
ASSERT_GL_NO_ERROR();
460
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
461
462
EXPECT_PIXEL_COLOR_EQ(0, 0, fboPixels[faceIndex]);
463
}
464
}
465
466
// Deleting textures after copying to them. http://anglebug.com/4267
467
TEST_P(CopyTexImageTest, DeleteAfterCopyingToTextures)
468
{
469
// TODO(anglebug.com/5360): Failing on ARM-based Apple DTKs.
470
ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
471
472
GLTexture texture;
473
glBindTexture(GL_TEXTURE_2D, texture);
474
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
475
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
476
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
477
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
478
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
479
480
GLTexture texture2;
481
glBindTexture(GL_TEXTURE_2D, texture2);
482
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
483
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
484
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
485
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
486
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
487
488
GLFramebuffer framebuffer;
489
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
490
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
491
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
492
493
// Perform CopyTexImage2D
494
glBindTexture(GL_TEXTURE_2D, texture);
495
glCopyTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 0, 0, 2, 2, 0);
496
ASSERT_GL_NO_ERROR();
497
// Not necessary to do any CopyTexImage2D operations to texture2.
498
499
// Perform CopyTexSubImage2D
500
glBindTexture(GL_TEXTURE_2D, texture);
501
glCopyTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 0, 0, 1, 1);
502
ASSERT_GL_NO_ERROR();
503
glBindTexture(GL_TEXTURE_2D, texture2);
504
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
505
ASSERT_GL_NO_ERROR();
506
507
// Clean up - provokes crash on buggy drivers.
508
texture.reset();
509
// Crashes on Intel GPUs on macOS.
510
texture2.reset();
511
}
512
// Test if glCopyTexImage2D() implementation performs conversions well from GL_TEXTURE_3D to
513
// GL_TEXTURE_2D.
514
// This is similar to CopyTexImageTestES3.CopyTexSubImageFromTexture3D but for GL_OES_texture_3D
515
// extension.
516
TEST_P(CopyTexImageTest, CopyTexSubImageFrom3DTexureOES)
517
{
518
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_3D"));
519
// TODO(anglebug.com/3801)
520
// Seems to fail on D3D11 Windows.
521
ANGLE_SKIP_TEST_IF(IsD3D11() & IsWindows());
522
523
// http://anglebug.com/4927
524
ANGLE_SKIP_TEST_IF((IsPixel2() || IsNexus5X()) && IsOpenGLES());
525
526
constexpr GLsizei kDepth = 6;
527
528
// The framebuffer will be a slice of a 3d texture with a different colors for each slice. Each
529
// glCopyTexSubImage2D will take one face of this image to copy over a pixel in a 1x6
530
// framebuffer.
531
GLColor fboPixels[kDepth] = {GLColor::red, GLColor::yellow, GLColor::green,
532
GLColor::cyan, GLColor::blue, GLColor::magenta};
533
GLColor whitePixels[kDepth] = {GLColor::white, GLColor::white, GLColor::white,
534
GLColor::white, GLColor::white, GLColor::white};
535
536
GLTexture fboTex;
537
glBindTexture(GL_TEXTURE_3D, fboTex);
538
glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, kDepth, 0, GL_RGBA, GL_UNSIGNED_BYTE,
539
fboPixels);
540
541
GLTexture dstTex;
542
glBindTexture(GL_TEXTURE_2D, dstTex);
543
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kDepth, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, whitePixels);
544
545
GLFramebuffer fbo;
546
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
547
548
for (GLsizei slice = 0; slice < kDepth; ++slice)
549
{
550
glFramebufferTexture3DOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, fboTex, 0,
551
slice);
552
553
ASSERT_GL_NO_ERROR();
554
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
555
556
// Copy the fbo (a 3d slice) into a pixel of the destination texture.
557
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, slice, 0, 0, 0, 1, 1);
558
}
559
560
// Make sure all the copies are done correctly.
561
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0);
562
563
ASSERT_GL_NO_ERROR();
564
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
565
566
for (GLsizei slice = 0; slice < kDepth; ++slice)
567
{
568
EXPECT_PIXEL_COLOR_EQ(slice, 0, fboPixels[slice]);
569
}
570
}
571
572
// specialization of CopyTexImageTest is added so that some tests can be explicitly run with an ES3
573
// context
574
class CopyTexImageTestES3 : public CopyTexImageTest
575
{
576
protected:
577
void initialize3DTexture(GLTexture &texture,
578
const GLsizei imageWidth,
579
const GLsizei imageHeight,
580
const GLsizei imageDepth,
581
const GLColor *textureData);
582
void initialize2DTexture(GLTexture &texture,
583
const GLsizei imageWidth,
584
const GLsizei imageHeight,
585
const GLColor *textureData);
586
void initialize2DTextureUShort4444(GLTexture &texture,
587
const GLsizei imageWidth,
588
const GLsizei imageHeight,
589
const GLColor *textureData);
590
void fillTexture(std::vector<GLColor> &texture, const GLColor color);
591
void clearTexture(GLFramebuffer &fbo, GLTexture &texture, const GLColor color);
592
void copyTexSubImage3D(GLTexture &subTexture2D,
593
const GLint xOffset,
594
const GLint yOffset,
595
const GLsizei subImageWidth,
596
const GLsizei subImageHeight,
597
const GLsizei imageDepth);
598
void verifyCopyTexSubImage3D(GLTexture &texture3D,
599
const GLint xOffset,
600
const GLint yOffset,
601
const GLColor subImageColor);
602
603
// Constants
604
const GLColor kSubImageColor = GLColor::yellow;
605
// 3D image dimensions
606
const GLsizei kImageWidth = getWindowWidth();
607
const GLsizei kImageHeight = getWindowHeight();
608
const GLsizei kImageDepth = 4;
609
// 2D sub-image dimensions
610
const GLsizei kSubImageWidth = getWindowWidth() / 4;
611
const GLsizei kSubImageHeight = getWindowHeight() / 4;
612
// Sub-Image Offsets
613
const GLint kXOffset = getWindowWidth() - kSubImageWidth;
614
const GLint kYOffset = getWindowHeight() - kSubImageHeight;
615
};
616
617
// The test verifies that glCopyTexSubImage2D generates a GL_INVALID_OPERATION error
618
// when the read buffer is GL_NONE.
619
// Reference: GLES 3.0.4, Section 3.8.5 Alternate Texture Image Specification Commands
620
TEST_P(CopyTexImageTestES3, ReadBufferIsNone)
621
{
622
initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
623
624
GLTexture tex;
625
glBindTexture(GL_TEXTURE_2D, tex);
626
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
627
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
628
629
glBindFramebuffer(GL_FRAMEBUFFER, mFbos[0]);
630
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kFboSizes[0], kFboSizes[0], 0);
631
632
glReadBuffer(GL_NONE);
633
634
EXPECT_GL_NO_ERROR();
635
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
636
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
637
}
638
639
// Test CopyTexImage3D with some simple parameters with a 2D array texture.
640
TEST_P(CopyTexImageTestES3, 2DArraySubImage)
641
{
642
// Seems to fail on AMD OpenGL Windows.
643
ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() & IsWindows());
644
645
GLTexture tex;
646
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
647
648
constexpr GLsizei kTexSize = 4;
649
constexpr GLsizei kLayerOffset = 1;
650
constexpr GLsizei kLayers = 2;
651
652
// Clear screen to green.
653
glClearColor(0, 1, 0, 1);
654
glClear(GL_COLOR_BUFFER_BIT);
655
656
// Initialize a two-layer 2D array texture with red.
657
std::vector<GLColor> red(kTexSize * kTexSize * kLayers, GLColor::red);
658
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kTexSize, kTexSize, kLayers, 0, GL_RGBA,
659
GL_UNSIGNED_BYTE, red.data());
660
glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, kLayerOffset, 0, 0, kTexSize, kTexSize);
661
ASSERT_GL_NO_ERROR();
662
663
// Check level 0 (red from image data) and 1 (green from backbuffer clear).
664
GLFramebuffer fbo;
665
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
666
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
667
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
668
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
669
for (int x = 0; x < kTexSize; x++)
670
{
671
for (int y = 0; y < kTexSize; y++)
672
{
673
EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
674
}
675
}
676
ASSERT_GL_NO_ERROR();
677
}
678
679
// Test if glCopyTexImage2D() implementation performs conversions well from GL_TEXTURE_3D to
680
// GL_TEXTURE_2D.
681
TEST_P(CopyTexImageTestES3, CopyTexSubImageFromTexture3D)
682
{
683
// TODO(anglebug.com/3801)
684
// Seems to fail on D3D11 Windows.
685
ANGLE_SKIP_TEST_IF(IsD3D11() & IsWindows());
686
687
constexpr GLsizei kTexSize = 4;
688
constexpr GLsizei kLayers = 2;
689
std::vector<GLColor> red(kTexSize * kTexSize * kLayers, GLColor::red);
690
691
GLFramebuffer fbo;
692
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
693
glBindTexture(GL_TEXTURE_2D, 0);
694
695
// We will be reading from zeroth color attachment.
696
glReadBuffer(GL_COLOR_ATTACHMENT0);
697
698
GLTexture src_object_id;
699
glBindTexture(GL_TEXTURE_3D, src_object_id);
700
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kTexSize, kTexSize, kLayers, 0, GL_RGBA,
701
GL_UNSIGNED_BYTE, NULL);
702
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, kTexSize, kTexSize, 1, GL_RGBA, GL_UNSIGNED_BYTE,
703
red.data());
704
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, src_object_id, 0, 1);
705
ASSERT_GL_NO_ERROR();
706
707
GLTexture dst_object_id;
708
glBindTexture(GL_TEXTURE_2D, dst_object_id);
709
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, kTexSize, kTexSize, 0);
710
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_object_id,
711
0);
712
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
713
ASSERT_GL_NO_ERROR();
714
}
715
716
// Test that copying from a non-zero base texture works.
717
TEST_P(CopyTexImageTestES3, CopyTexSubImageFromNonZeroBase)
718
{
719
// http://anglebug.com/5000
720
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
721
722
constexpr GLsizei kTexSize = 4;
723
std::vector<GLColor> red(kTexSize * kTexSize, GLColor::red);
724
std::vector<GLColor> green(kTexSize * kTexSize, GLColor::green);
725
726
// Create a framebuffer attached to a non-zero base texture
727
GLTexture srcColor;
728
glBindTexture(GL_TEXTURE_2D, srcColor);
729
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
730
red.data());
731
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
732
green.data());
733
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
734
ASSERT_GL_NO_ERROR();
735
736
GLFramebuffer fbo;
737
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
738
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 1);
739
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
740
741
// Create a texture with an identical format
742
GLTexture dstColor;
743
glBindTexture(GL_TEXTURE_2D, dstColor);
744
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
745
nullptr);
746
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
747
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
748
ASSERT_GL_NO_ERROR();
749
750
// Copy into a part of this texture.
751
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTexSize / 2, kTexSize / 2);
752
ASSERT_GL_NO_ERROR();
753
754
// Verify it.
755
constexpr std::array<GLubyte, 4> kExpected = {0, 255, 0, 255};
756
verifyResults(dstColor, kExpected.data(), kTexSize, 0, 0, kTexSize / 2, kTexSize / 2);
757
758
// Copy into another part of the texture. The previous verification ensures that the texture's
759
// internal image is allocated, so this should be a direct copy.
760
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
761
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kTexSize / 2, kTexSize / 2, 0, 0, kTexSize / 2,
762
kTexSize / 2);
763
ASSERT_GL_NO_ERROR();
764
765
// Verify it.
766
verifyResults(dstColor, kExpected.data(), kTexSize, kTexSize / 2, kTexSize / 2, kTexSize,
767
kTexSize);
768
}
769
770
// Test that copying into a non-zero base texture works.
771
TEST_P(CopyTexImageTestES3, CopyTexSubImageToNonZeroBase)
772
{
773
// http://anglebug.com/5000
774
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
775
776
constexpr GLsizei kTexSize = 4;
777
std::vector<GLColor> green(kTexSize * kTexSize, GLColor::green);
778
779
// Create a framebuffer attached to a non-zero base texture
780
GLTexture srcColor;
781
glBindTexture(GL_TEXTURE_2D, srcColor);
782
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
783
green.data());
784
ASSERT_GL_NO_ERROR();
785
786
GLFramebuffer fbo;
787
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
788
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 0);
789
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
790
791
// Create a texture with an identical format
792
GLTexture dstColor;
793
glBindTexture(GL_TEXTURE_2D, dstColor);
794
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
795
nullptr);
796
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
797
nullptr);
798
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
799
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
800
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
801
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
802
ASSERT_GL_NO_ERROR();
803
804
// Copy into a part of this texture.
805
glCopyTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kTexSize / 2, kTexSize / 2);
806
ASSERT_GL_NO_ERROR();
807
808
// Verify it.
809
constexpr std::array<GLubyte, 4> kExpected = {0, 255, 0, 255};
810
verifyResults(dstColor, kExpected.data(), kTexSize, 0, 0, kTexSize / 2, kTexSize / 2);
811
812
// Copy into another part of the texture. The previous verification ensures that the texture's
813
// internal image is allocated, so this should be a direct copy.
814
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
815
glCopyTexSubImage2D(GL_TEXTURE_2D, 1, kTexSize / 2, kTexSize / 2, 0, 0, kTexSize / 2,
816
kTexSize / 2);
817
ASSERT_GL_NO_ERROR();
818
819
// Verify it.
820
verifyResults(dstColor, kExpected.data(), kTexSize, kTexSize / 2, kTexSize / 2, kTexSize,
821
kTexSize);
822
}
823
824
// Initialize the 3D texture we will copy the subImage data into
825
void CopyTexImageTestES3::initialize3DTexture(GLTexture &texture,
826
const GLsizei imageWidth,
827
const GLsizei imageHeight,
828
const GLsizei imageDepth,
829
const GLColor *textureData)
830
{
831
glBindTexture(GL_TEXTURE_3D, texture);
832
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, imageWidth, imageHeight, imageDepth, 0, GL_RGBA,
833
GL_UNSIGNED_BYTE, textureData);
834
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
835
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
836
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
837
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
838
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
839
}
840
841
void CopyTexImageTestES3::initialize2DTexture(GLTexture &texture,
842
const GLsizei imageWidth,
843
const GLsizei imageHeight,
844
const GLColor *textureData)
845
{
846
glBindTexture(GL_TEXTURE_2D, texture);
847
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
848
textureData);
849
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
850
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
851
}
852
853
void CopyTexImageTestES3::initialize2DTextureUShort4444(GLTexture &texture,
854
const GLsizei imageWidth,
855
const GLsizei imageHeight,
856
const GLColor *textureData)
857
{
858
glBindTexture(GL_TEXTURE_2D, texture);
859
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA,
860
GL_UNSIGNED_SHORT_4_4_4_4, textureData);
861
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
862
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
863
}
864
865
void CopyTexImageTestES3::fillTexture(std::vector<GLColor> &texture, const GLColor color)
866
{
867
for (auto &texel : texture)
868
{
869
texel = color;
870
}
871
}
872
873
void CopyTexImageTestES3::clearTexture(GLFramebuffer &fbo, GLTexture &texture, const GLColor color)
874
{
875
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
876
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
877
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
878
glClearColor(color.R, color.G, color.B, color.A);
879
glClear(GL_COLOR_BUFFER_BIT);
880
EXPECT_PIXEL_COLOR_EQ(0, 0, color);
881
}
882
883
void CopyTexImageTestES3::copyTexSubImage3D(GLTexture &subTexture2D,
884
const GLint xOffset,
885
const GLint yOffset,
886
const GLsizei subImageWidth,
887
const GLsizei subImageHeight,
888
const GLsizei imageDepth)
889
{
890
// Copy the 2D sub-image into the 3D texture
891
for (int currLayer = 0; currLayer < imageDepth; ++currLayer)
892
{
893
// Bind the 2D texture to GL_COLOR_ATTACHMENT0
894
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
895
subTexture2D, 0);
896
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
897
glCopyTexSubImage3D(GL_TEXTURE_3D, 0, xOffset, yOffset, currLayer, 0, 0, subImageWidth,
898
subImageHeight);
899
ASSERT_GL_NO_ERROR();
900
}
901
}
902
903
void CopyTexImageTestES3::verifyCopyTexSubImage3D(GLTexture &texture3D,
904
const GLint xOffset,
905
const GLint yOffset,
906
const GLColor subImageColor)
907
{
908
// Bind to an FBO to check the copy was successful
909
for (int currLayer = 0; currLayer < kImageDepth; ++currLayer)
910
{
911
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0, currLayer);
912
ASSERT_GL_NO_ERROR();
913
EXPECT_PIXEL_COLOR_EQ(xOffset, yOffset, subImageColor);
914
}
915
}
916
917
// Test glCopyTexSubImage3D with initialized texture data
918
TEST_P(CopyTexImageTestES3, 3DSubImageRawTextureData)
919
{
920
// Texture data
921
std::vector<GLColor> textureData(kImageWidth * kImageHeight * kImageDepth);
922
923
// Fill the textures with color
924
fillTexture(textureData, GLColor::red);
925
926
GLFramebuffer fbo;
927
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
928
929
GLTexture texture3D;
930
initialize3DTexture(texture3D, kImageWidth, kImageHeight, kImageDepth, textureData.data());
931
932
// The 2D texture that will be the sub-image copied into the destination texture
933
GLTexture subTexture2D;
934
initialize2DTexture(subTexture2D, kSubImageWidth, kSubImageHeight, nullptr);
935
clearTexture(fbo, subTexture2D, kSubImageColor);
936
937
// Copy the 2D subimage into the 3D texture
938
copyTexSubImage3D(subTexture2D, kXOffset, kYOffset, kSubImageWidth, kSubImageHeight,
939
kImageDepth);
940
941
// Verify the color wasn't overwritten
942
verifyCopyTexSubImage3D(texture3D, 0, 0, GLColor::red);
943
// Verify the copy succeeded
944
verifyCopyTexSubImage3D(texture3D, kXOffset, kYOffset, kSubImageColor);
945
946
glBindFramebuffer(GL_FRAMEBUFFER, 0);
947
glBindTexture(GL_TEXTURE_2D, 0);
948
glBindTexture(GL_TEXTURE_3D, 0);
949
}
950
951
// Test glCopyTexSubImage3D with initialized texture data that was drawn to
952
TEST_P(CopyTexImageTestES3, 3DSubImageDrawTextureData)
953
{
954
// TODO(anglebug.com/3801)
955
ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
956
957
GLFramebuffer fbo;
958
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
959
960
// The 3D texture we will copy the sub-image into
961
GLTexture texture3D;
962
initialize3DTexture(texture3D, kImageWidth, kImageHeight, kImageDepth, nullptr);
963
964
// Draw to each layer in the 3D texture
965
for (int currLayer = 0; currLayer < kImageDepth; ++currLayer)
966
{
967
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
968
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0,
969
currLayer);
970
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0,
971
currLayer);
972
ASSERT_GL_NO_ERROR();
973
glUseProgram(greenProgram);
974
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
975
ASSERT_GL_NO_ERROR();
976
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
977
}
978
979
// The 2D texture that will be the sub-image copied into the destination texture
980
GLTexture subTexture2D;
981
initialize2DTexture(subTexture2D, kSubImageWidth, kSubImageHeight, nullptr);
982
clearTexture(fbo, subTexture2D, kSubImageColor);
983
984
// Copy the 2D sub-image into the 3D texture
985
copyTexSubImage3D(subTexture2D, kXOffset, kYOffset, kSubImageWidth, kSubImageHeight,
986
kImageDepth);
987
988
// Verify the color wasn't overwritten
989
verifyCopyTexSubImage3D(texture3D, 0, 0, GLColor::green);
990
// Verify the copy succeeded
991
verifyCopyTexSubImage3D(texture3D, kXOffset, kYOffset, kSubImageColor);
992
993
glBindFramebuffer(GL_FRAMEBUFFER, 0);
994
glBindTexture(GL_TEXTURE_2D, 0);
995
glBindTexture(GL_TEXTURE_3D, 0);
996
}
997
998
// Test glCopyTexSubImage3D with mismatched texture formats
999
TEST_P(CopyTexImageTestES3, 3DSubImageDrawMismatchedTextureTypes)
1000
{
1001
// TODO(anglebug.com/3801)
1002
ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
1003
1004
// TODO(anglebug.com/5491)
1005
ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
1006
1007
GLFramebuffer fbo;
1008
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1009
1010
// The 3D texture we will copy the sub-image into
1011
GLTexture texture3D;
1012
initialize3DTexture(texture3D, kImageWidth, kImageHeight, kImageDepth, nullptr);
1013
1014
// Draw to each layer in the 3D texture
1015
for (int currLayer = 0; currLayer < kImageDepth; ++currLayer)
1016
{
1017
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1018
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0, currLayer);
1019
ASSERT_GL_NO_ERROR();
1020
glUseProgram(greenProgram);
1021
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1022
ASSERT_GL_NO_ERROR();
1023
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1024
}
1025
1026
// The 2D texture that will be the sub-image copied into the destination texture
1027
GLTexture subTexture2D;
1028
initialize2DTextureUShort4444(subTexture2D, kSubImageWidth, kSubImageHeight, nullptr);
1029
clearTexture(fbo, subTexture2D, kSubImageColor);
1030
1031
// Copy the 2D sub-image into the 3D texture
1032
copyTexSubImage3D(subTexture2D, kXOffset, kYOffset, kSubImageWidth, kSubImageHeight,
1033
kImageDepth);
1034
1035
// Verify the color wasn't overwritten
1036
verifyCopyTexSubImage3D(texture3D, 0, 0, GLColor::green);
1037
// Verify the copy succeeded
1038
verifyCopyTexSubImage3D(texture3D, kXOffset, kYOffset, kSubImageColor);
1039
1040
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1041
glBindTexture(GL_TEXTURE_2D, 0);
1042
glBindTexture(GL_TEXTURE_3D, 0);
1043
}
1044
1045
ANGLE_INSTANTIATE_TEST(CopyTexImageTest,
1046
ANGLE_ALL_TEST_PLATFORMS_ES2,
1047
ES2_D3D11_PRESENT_PATH_FAST(),
1048
ES3_VULKAN(),
1049
WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()),
1050
WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES()));
1051
1052
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyTexImageTestES3);
1053
ANGLE_INSTANTIATE_TEST(CopyTexImageTestES3,
1054
ANGLE_ALL_TEST_PLATFORMS_ES3,
1055
WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()),
1056
WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES()));
1057
} // namespace angle
1058
1059