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 // Texture upload format tests:
7 // Test all texture unpack/upload formats for sampling correctness.
8 //
9
10 #include "common/mathutil.h"
11 #include "image_util/copyimage.h"
12 #include "test_utils/ANGLETest.h"
13 #include "test_utils/gl_raii.h"
14
15 using namespace angle;
16
17 namespace
18 {
19
20 class TextureUploadFormatTest : public ANGLETest
21 {};
22
23 struct TexFormat final
24 {
25 GLenum internalFormat;
26 GLenum unpackFormat;
27 GLenum unpackType;
28
29 TexFormat() = delete;
30
bytesPerPixel__anon05f1aacb0111::TexFormat31 uint8_t bytesPerPixel() const
32 {
33 uint8_t bytesPerChannel;
34 switch (unpackType)
35 {
36 case GL_UNSIGNED_SHORT_5_6_5:
37 case GL_UNSIGNED_SHORT_4_4_4_4:
38 case GL_UNSIGNED_SHORT_5_5_5_1:
39 return 2;
40
41 case GL_UNSIGNED_INT_2_10_10_10_REV:
42 case GL_UNSIGNED_INT_24_8:
43 case GL_UNSIGNED_INT_10F_11F_11F_REV:
44 case GL_UNSIGNED_INT_5_9_9_9_REV:
45 return 4;
46
47 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
48 return 8;
49
50 case GL_UNSIGNED_BYTE:
51 case GL_BYTE:
52 bytesPerChannel = 1;
53 break;
54
55 case GL_UNSIGNED_SHORT:
56 case GL_SHORT:
57 case GL_HALF_FLOAT:
58 case GL_HALF_FLOAT_OES:
59 bytesPerChannel = 2;
60 break;
61
62 case GL_UNSIGNED_INT:
63 case GL_INT:
64 case GL_FLOAT:
65 bytesPerChannel = 4;
66 break;
67
68 default:
69 assert(false);
70 return 0;
71 }
72
73 switch (unpackFormat)
74 {
75 case GL_RGBA:
76 case GL_RGBA_INTEGER:
77 return bytesPerChannel * 4;
78
79 case GL_RGB:
80 case GL_RGB_INTEGER:
81 return bytesPerChannel * 3;
82
83 case GL_RG:
84 case GL_RG_INTEGER:
85 case GL_LUMINANCE_ALPHA:
86 return bytesPerChannel * 2;
87
88 case GL_RED:
89 case GL_RED_INTEGER:
90 case GL_LUMINANCE:
91 case GL_ALPHA:
92 case GL_DEPTH_COMPONENT:
93 return bytesPerChannel * 1;
94
95 default:
96 assert(false);
97 return 0;
98 }
99 }
100 };
101
102 template <const uint8_t bits>
EncodeNormUint(const float val)103 constexpr uint32_t EncodeNormUint(const float val)
104 {
105 return static_cast<uint32_t>(val * static_cast<float>(UINT32_MAX >> (32 - bits)) +
106 0.5f); // round-half-up
107 }
108
109 } // anonymous namespace
110
111 namespace
112 {
113
114 template <typename DestT, typename SrcT, size_t SrcN>
ZeroAndCopy(DestT & dest,const SrcT (& src)[SrcN])115 void ZeroAndCopy(DestT &dest, const SrcT (&src)[SrcN])
116 {
117 dest.fill(0);
118 memcpy(dest.data(), src, sizeof(SrcT) * SrcN);
119 }
120
EnumStr(const GLenum v)121 std::string EnumStr(const GLenum v)
122 {
123 std::stringstream ret;
124 ret << "0x" << std::hex << v;
125 return ret.str();
126 }
127
128 template <typename ColorT, typename DestT>
EncodeThenZeroAndCopy(DestT & dest,const float srcVals[4])129 void EncodeThenZeroAndCopy(DestT &dest, const float srcVals[4])
130 {
131 ColorF srcValsF(srcVals[0], srcVals[1], srcVals[2], srcVals[3]);
132
133 ColorT encoded;
134 ColorT::writeColor(&encoded, &srcValsF);
135
136 dest.fill(0);
137 memcpy(dest.data(), &encoded, sizeof(ColorT));
138 }
139 } // anonymous namespace
140
141 // Upload (1,2,5,3) to integer formats, and (1,2,5,3)/8.0 to float formats.
142 // Draw a point into a 1x1 renderbuffer and readback the result for comparison with expectations.
143 // Test all internalFormat/unpackFormat/unpackType combinations from ES3.0.
TEST_P(TextureUploadFormatTest,All)144 TEST_P(TextureUploadFormatTest, All)
145 {
146 ANGLE_SKIP_TEST_IF(IsD3D9() || IsD3D11_FL93());
147
148 // Test failure introduced by Apple's changes (anglebug.com/5505)
149 ANGLE_SKIP_TEST_IF(IsMetal());
150
151 constexpr char kVertShaderES2[] = R"(
152 void main()
153 {
154 gl_PointSize = 1.0;
155 gl_Position = vec4(0, 0, 0, 1);
156 })";
157 constexpr char kFragShader_Floats[] = R"(
158 precision mediump float;
159 uniform sampler2D uTex;
160
161 void main()
162 {
163 gl_FragColor = texture2D(uTex, vec2(0,0));
164 })";
165 ANGLE_GL_PROGRAM(floatsProg, kVertShaderES2, kFragShader_Floats);
166
167 glDisable(GL_DITHER);
168
169 ASSERT_GL_NO_ERROR();
170
171 // Create the 1x1 framebuffer
172
173 GLRenderbuffer backbufferRB;
174 glBindRenderbuffer(GL_RENDERBUFFER, backbufferRB);
175 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
176 glBindRenderbuffer(GL_RENDERBUFFER, 0);
177
178 GLFramebuffer backbufferFB;
179 glBindFramebuffer(GL_FRAMEBUFFER, backbufferFB);
180 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, backbufferRB);
181 ASSERT_GL_NO_ERROR();
182 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
183
184 glViewport(0, 0, 1, 1);
185
186 // Create and bind our test texture
187
188 GLTexture testTex;
189 glBindTexture(GL_TEXTURE_2D, testTex);
190 // Must be nearest because some texture formats aren't filterable!
191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
193
194 ASSERT_GL_NO_ERROR();
195
196 // Initialize our test variables
197
198 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
199 const bool hasSubrectUploads = !glGetError();
200
201 constexpr uint8_t srcIntVals[4] = {1u, 2u, 5u, 3u};
202 constexpr float srcVals[4] = {srcIntVals[0] / 8.0f, srcIntVals[1] / 8.0f, srcIntVals[2] / 8.0f,
203 srcIntVals[3] / 8.0f};
204 constexpr uint8_t refVals[4] = {static_cast<uint8_t>(EncodeNormUint<8>(srcVals[0])),
205 static_cast<uint8_t>(EncodeNormUint<8>(srcVals[1])),
206 static_cast<uint8_t>(EncodeNormUint<8>(srcVals[2])),
207 static_cast<uint8_t>(EncodeNormUint<8>(srcVals[3]))};
208
209 // Test a format with the specified data
210
211 const auto fnTestData = [&](const TexFormat &format, const void *const data, const GLColor &err,
212 const char *const info) {
213 ASSERT_GL_NO_ERROR();
214 glTexImage2D(GL_TEXTURE_2D, 0, format.internalFormat, 1, 1, 0, format.unpackFormat,
215 format.unpackType, data);
216 const auto uploadErr = glGetError();
217 if (uploadErr) // Format might not be supported. (e.g. on ES2)
218 return;
219
220 glClearColor(1, 0, 1, 1);
221 glClear(GL_COLOR_BUFFER_BIT);
222 glDrawArrays(GL_POINTS, 0, 1);
223
224 const auto actual = ReadColor(0, 0);
225
226 GLColor expected;
227 switch (format.unpackFormat)
228 {
229 case GL_RGBA:
230 case GL_RGBA_INTEGER:
231 expected = {refVals[0], refVals[1], refVals[2], refVals[3]};
232 break;
233 case GL_RGB:
234 expected = {refVals[0], refVals[1], refVals[2], 255};
235 break;
236 case GL_RG:
237 expected = {refVals[0], refVals[1], 0, 255};
238 break;
239 case GL_DEPTH_COMPONENT:
240 case GL_DEPTH_STENCIL:
241 // Metal back-end requires swizzle feature to return (depth, 0, 0, 1) from sampling
242 // a depth texture.
243 // http://anglebug.com/5243
244 if (IsMetal() && !IsMetalTextureSwizzleAvailable())
245 {
246 // If texture swizzle is not supported, we should only compare the first
247 // component.
248 expected = {refVals[0], actual[1], actual[2], actual[3]};
249 }
250 else
251 {
252
253 expected = {refVals[0], 0, 0, 255};
254 }
255 break;
256 case GL_RED:
257 expected = {refVals[0], 0, 0, 255};
258 break;
259
260 case GL_RGB_INTEGER:
261 expected = {refVals[0], refVals[1], refVals[2], refVals[0]};
262 break;
263 case GL_RG_INTEGER:
264 expected = {refVals[0], refVals[1], 0, refVals[0]};
265 break;
266 case GL_RED_INTEGER:
267 expected = {refVals[0], 0, 0, refVals[0]};
268 break;
269
270 case GL_LUMINANCE_ALPHA:
271 expected = {refVals[0], refVals[0], refVals[0], refVals[1]};
272 break;
273 case GL_LUMINANCE:
274 expected = {refVals[0], refVals[0], refVals[0], 255};
275 break;
276 case GL_ALPHA:
277 expected = {0, 0, 0, refVals[0]};
278 break;
279
280 default:
281 assert(false);
282 }
283
284 ASSERT_GL_NO_ERROR();
285 auto result = actual.ExpectNear(expected, err);
286 if (!result)
287 {
288 result << " [" << EnumStr(format.internalFormat) << "/" << EnumStr(format.unpackFormat)
289 << "/" << EnumStr(format.unpackType) << " " << info << "]";
290 }
291 EXPECT_TRUE(result);
292 };
293
294 // Provide buffers for test data, and a func to run the test on both the data directly, and on
295 // a basic subrect selection to ensure pixel byte size is calculated correctly.
296 // Possible todo here is to add tests to ensure stride calculation.
297
298 std::array<uint8_t, sizeof(float) * 4> srcBuffer;
299
300 std::array<uint8_t, srcBuffer.size() * 2> subrectBuffer;
301 const auto fnTest = [&](const TexFormat &format, const GLColor &err) {
302 fnTestData(format, srcBuffer.data(), err, "simple");
303
304 if (!hasSubrectUploads)
305 return;
306
307 const auto bytesPerPixel = format.bytesPerPixel();
308
309 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
310
311 subrectBuffer.fill(0);
312 memcpy(subrectBuffer.data() + bytesPerPixel, srcBuffer.data(), bytesPerPixel);
313 fnTestData(format, subrectBuffer.data(), err, "subrect");
314
315 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
316 };
317
318 // Test All The Formats, organized by unpack format and type.
319 // (Combos from GLES 3.0.5 p111-112: Table 3.2: "Valid combinations of format, type, and sized
320 // internalformat.")
321
322 // Start with normalized ints
323 glUseProgram(floatsProg);
324
325 // RGBA+UNSIGNED_BYTE
326 {
327 constexpr uint8_t src[] = {static_cast<uint8_t>(EncodeNormUint<8>(srcVals[0])),
328 static_cast<uint8_t>(EncodeNormUint<8>(srcVals[1])),
329 static_cast<uint8_t>(EncodeNormUint<8>(srcVals[2])),
330 static_cast<uint8_t>(EncodeNormUint<8>(srcVals[3]))};
331 ZeroAndCopy(srcBuffer, src);
332
333 fnTest({GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
334 fnTest({GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE}, {8, 8, 8, 255});
335 fnTest({GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE}, {16, 16, 16, 16});
336
337 fnTest({GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE}, {1, 1, 1, 0});
338 fnTest({GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE}, {8, 4, 8, 0});
339
340 fnTest({GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, {1, 1, 0, 0});
341
342 fnTest({GL_R8, GL_RED, GL_UNSIGNED_BYTE}, {1, 0, 0, 0});
343
344 fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
345 fnTest({GL_RGB, GL_RGB, GL_UNSIGNED_BYTE}, {1, 1, 1, 0});
346 fnTest({GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
347 fnTest({GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE}, {1, 1, 1, 0});
348 fnTest({GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE}, {0, 0, 0, 1});
349 }
350
351 // RGBA+BYTE
352 {
353 constexpr uint8_t src[] = {static_cast<uint8_t>(EncodeNormUint<7>(srcVals[0])),
354 static_cast<uint8_t>(EncodeNormUint<7>(srcVals[1])),
355 static_cast<uint8_t>(EncodeNormUint<7>(srcVals[2])),
356 static_cast<uint8_t>(EncodeNormUint<7>(srcVals[3]))};
357 ZeroAndCopy(srcBuffer, src);
358
359 fnTest({GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, {2, 2, 2, 2});
360 fnTest({GL_RGB8_SNORM, GL_RGB, GL_BYTE}, {2, 2, 2, 0});
361 fnTest({GL_RG8_SNORM, GL_RG, GL_BYTE}, {2, 2, 0, 0});
362 fnTest({GL_R8_SNORM, GL_RED, GL_BYTE}, {2, 0, 0, 0});
363 }
364
365 // RGB+UNSIGNED_SHORT_5_6_5
366 {
367 constexpr uint16_t src[] = {static_cast<uint16_t>((EncodeNormUint<5>(srcVals[0]) << 11) |
368 (EncodeNormUint<6>(srcVals[1]) << 5) |
369 (EncodeNormUint<5>(srcVals[2]) << 0))};
370 ZeroAndCopy(srcBuffer, src);
371
372 fnTest({GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, {8, 4, 8, 0});
373 fnTest({GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, {8, 4, 8, 0});
374 }
375
376 // RGBA+UNSIGNED_SHORT_4_4_4_4
377 {
378 constexpr uint16_t src[] = {static_cast<uint16_t>(
379 (EncodeNormUint<4>(srcVals[0]) << 12) | (EncodeNormUint<4>(srcVals[1]) << 8) |
380 (EncodeNormUint<4>(srcVals[2]) << 4) | (EncodeNormUint<4>(srcVals[3]) << 0))};
381 ZeroAndCopy(srcBuffer, src);
382
383 fnTest({GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, {16, 16, 16, 16});
384 fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, {16, 16, 16, 16});
385 }
386
387 // RGBA+UNSIGNED_SHORT_5_5_5_1
388 {
389 constexpr uint16_t src[] = {static_cast<uint16_t>(
390 (EncodeNormUint<5>(srcVals[0]) << 11) | (EncodeNormUint<5>(srcVals[1]) << 6) |
391 (EncodeNormUint<5>(srcVals[2]) << 1) | (EncodeNormUint<1>(srcVals[3]) << 0))};
392 ZeroAndCopy(srcBuffer, src);
393
394 fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, {8, 8, 8, 255});
395 }
396
397 // RGBA+UNSIGNED_INT_2_10_10_10_REV
398 {
399 constexpr uint32_t src[] = {
400 (EncodeNormUint<10>(srcVals[0]) << 0) | (EncodeNormUint<10>(srcVals[1]) << 10) |
401 (EncodeNormUint<10>(srcVals[2]) << 20) | (EncodeNormUint<2>(srcVals[3]) << 30)};
402 ZeroAndCopy(srcBuffer, src);
403
404 fnTest({GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, {1, 1, 1, 128});
405 fnTest({GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, {8, 8, 8, 255});
406 fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, {1, 1, 1, 128});
407 }
408
409 // RGB+UNSIGNED_INT_2_10_10_10_REV
410 {
411 constexpr uint32_t src[] = {
412 (EncodeNormUint<10>(srcVals[0]) << 0) | (EncodeNormUint<10>(srcVals[1]) << 10) |
413 (EncodeNormUint<10>(srcVals[2]) << 20) | (EncodeNormUint<2>(srcVals[3]) << 30)};
414 ZeroAndCopy(srcBuffer, src);
415
416 fnTest({GL_RGB, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV}, {1, 1, 1, 0});
417 }
418
419 // DEPTH_COMPONENT+UNSIGNED_SHORT
420 {
421 const uint16_t src[] = {static_cast<uint16_t>(EncodeNormUint<16>(srcVals[0]))};
422 ZeroAndCopy(srcBuffer, src);
423
424 fnTest({GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, {1, 0, 0, 0});
425 }
426
427 // DEPTH_COMPONENT+UNSIGNED_INT
428 {
429 constexpr uint32_t src[] = {EncodeNormUint<32>(srcVals[0])};
430 ZeroAndCopy(srcBuffer, src);
431
432 fnTest({GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, {1, 0, 0, 0});
433 fnTest({GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, {1, 0, 0, 0});
434 }
435
436 // DEPTH_STENCIL+UNSIGNED_INT_24_8
437 {
438 // Drop stencil.
439 constexpr uint32_t src[] = {EncodeNormUint<24>(srcVals[0]) << 8};
440 ZeroAndCopy(srcBuffer, src);
441
442 fnTest({GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, {1, 0, 0, 0});
443 }
444
445 if (getClientMajorVersion() < 3)
446 return;
447
448 constexpr char kVertShaderES3[] = R"(#version 300 es
449 void main()
450 {
451 gl_PointSize = 1.0;
452 gl_Position = vec4(0, 0, 0, 1);
453 })";
454 constexpr char kFragShader_Ints[] = R"(#version 300 es
455 precision mediump float;
456 uniform highp isampler2D uTex;
457 out vec4 oFragColor;
458
459 void main()
460 {
461 oFragColor = vec4(texture(uTex, vec2(0,0))) / 8.0;
462 })";
463 constexpr char kFragShader_Uints[] = R"(#version 300 es
464 precision mediump float;
465 uniform highp usampler2D uTex;
466 out vec4 oFragColor;
467
468 void main()
469 {
470 oFragColor = vec4(texture(uTex, vec2(0,0))) / 8.0;
471 })";
472 ANGLE_GL_PROGRAM(intsProg, kVertShaderES3, kFragShader_Ints);
473 ANGLE_GL_PROGRAM(uintsProg, kVertShaderES3, kFragShader_Uints);
474
475 // Non-normalized ints
476 glUseProgram(intsProg);
477
478 // RGBA_INTEGER+UNSIGNED_BYTE
479 {
480 constexpr uint8_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
481 ZeroAndCopy(srcBuffer, src);
482
483 fnTest({GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE}, {1, 1, 1, 1});
484 fnTest({GL_RGB8I, GL_RGB_INTEGER, GL_BYTE}, {1, 1, 1, 1});
485 fnTest({GL_RG8I, GL_RG_INTEGER, GL_BYTE}, {1, 1, 1, 1});
486 fnTest({GL_R8I, GL_RED_INTEGER, GL_BYTE}, {1, 1, 1, 1});
487 }
488
489 // RGBA_INTEGER+UNSIGNED_SHORT
490 {
491 constexpr uint16_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
492 ZeroAndCopy(srcBuffer, src);
493
494 fnTest({GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT}, {1, 1, 1, 1});
495 fnTest({GL_RGB16I, GL_RGB_INTEGER, GL_SHORT}, {1, 1, 1, 1});
496 fnTest({GL_RG16I, GL_RG_INTEGER, GL_SHORT}, {1, 1, 1, 1});
497 fnTest({GL_R16I, GL_RED_INTEGER, GL_SHORT}, {1, 1, 1, 1});
498 }
499
500 // RGBA_INTEGER+UNSIGNED_INT
501 {
502 constexpr uint32_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
503 ZeroAndCopy(srcBuffer, src);
504
505 fnTest({GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, {1, 1, 1, 1});
506 fnTest({GL_RGB32I, GL_RGB_INTEGER, GL_INT}, {1, 1, 1, 1});
507 fnTest({GL_RG32I, GL_RG_INTEGER, GL_INT}, {1, 1, 1, 1});
508 fnTest({GL_R32I, GL_RED_INTEGER, GL_INT}, {1, 1, 1, 1});
509 }
510
511 // Non-normalized uints
512 glUseProgram(uintsProg);
513
514 // RGBA_INTEGER+UNSIGNED_BYTE
515 {
516 constexpr uint8_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
517 ZeroAndCopy(srcBuffer, src);
518
519 fnTest({GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
520 fnTest({GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
521 fnTest({GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
522 fnTest({GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
523 }
524
525 // RGBA_INTEGER+UNSIGNED_SHORT
526 {
527 constexpr uint16_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
528 ZeroAndCopy(srcBuffer, src);
529
530 fnTest({GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
531 fnTest({GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
532 fnTest({GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
533 fnTest({GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
534 }
535
536 // RGBA_INTEGER+UNSIGNED_INT
537 {
538 constexpr uint32_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
539 ZeroAndCopy(srcBuffer, src);
540
541 fnTest({GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
542 fnTest({GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
543 fnTest({GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
544 fnTest({GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
545 }
546
547 // RGBA_INTEGER+UNSIGNED_INT_2_10_10_10_REV
548 {
549 constexpr uint32_t src[] = {static_cast<uint32_t>(srcIntVals[0] << 0) |
550 static_cast<uint32_t>(srcIntVals[1] << 10) |
551 static_cast<uint32_t>(srcIntVals[2] << 20) |
552 static_cast<uint32_t>(srcIntVals[3] << 30)};
553 ZeroAndCopy(srcBuffer, src);
554
555 fnTest({GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV}, {1, 1, 1, 1});
556 }
557
558 // True floats
559 glUseProgram(floatsProg);
560
561 // RGBA+HALF_FLOAT
562 {
563 EncodeThenZeroAndCopy<R16G16B16A16F>(srcBuffer, srcVals);
564
565 fnTest({GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, {1, 1, 1, 1});
566
567 fnTest({GL_RGB16F, GL_RGB, GL_HALF_FLOAT}, {1, 1, 1, 0});
568 fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT}, {1, 1, 1, 0});
569 fnTest({GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT}, {1, 1, 1, 0});
570
571 fnTest({GL_RG16F, GL_RG, GL_HALF_FLOAT}, {1, 1, 0, 0});
572
573 fnTest({GL_R16F, GL_RED, GL_HALF_FLOAT}, {1, 0, 0, 0});
574
575 fnTest({GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES}, {1, 1, 1, 1});
576 fnTest({GL_RGB, GL_RGB, GL_HALF_FLOAT_OES}, {1, 1, 1, 0});
577 fnTest({GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES}, {1, 1, 1, 1});
578 fnTest({GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES}, {1, 1, 1, 0});
579 fnTest({GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES}, {0, 0, 0, 1});
580 }
581
582 // RGBA+FLOAT
583 {
584 ZeroAndCopy(srcBuffer, srcVals);
585
586 fnTest({GL_RGBA32F, GL_RGBA, GL_FLOAT}, {1, 1, 1, 1});
587 fnTest({GL_RGBA16F, GL_RGBA, GL_FLOAT}, {1, 1, 1, 1});
588
589 fnTest({GL_RGB32F, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
590 fnTest({GL_RGB16F, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
591 fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
592 fnTest({GL_RGB9_E5, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
593
594 fnTest({GL_RG32F, GL_RG, GL_FLOAT}, {1, 1, 0, 0});
595 fnTest({GL_RG16F, GL_RG, GL_FLOAT}, {1, 1, 0, 0});
596
597 fnTest({GL_R32F, GL_RED, GL_FLOAT}, {1, 0, 0, 0});
598 fnTest({GL_R16F, GL_RED, GL_FLOAT}, {1, 0, 0, 0});
599 }
600
601 // UNSIGNED_INT_10F_11F_11F_REV
602 {
603 EncodeThenZeroAndCopy<R11G11B10F>(srcBuffer, srcVals);
604
605 fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, {1, 1, 1, 0});
606 }
607
608 // UNSIGNED_INT_5_9_9_9_REV
609 {
610 EncodeThenZeroAndCopy<R9G9B9E5>(srcBuffer, srcVals);
611
612 fnTest({GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, {1, 1, 1, 0});
613 }
614
615 // DEPTH_COMPONENT+FLOAT
616 {
617 // Skip stencil.
618 constexpr float src[] = {srcVals[0], 0};
619 ZeroAndCopy(srcBuffer, src);
620
621 fnTest({GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, {1, 0, 0, 0});
622 fnTest({GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV},
623 {1, 0, 0, 0});
624 }
625
626 EXPECT_GL_NO_ERROR();
627 }
628
629 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(TextureUploadFormatTest);
630