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 // SixteenBppTextureTest:
7 //   Basic tests using 16bpp texture formats (e.g. GL_RGB565).
8 
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11 
12 #include "image_util/imageformats.h"
13 
14 using namespace angle;
15 
16 namespace
17 {
18 
Convert565(const R5G6B5 & rgb565)19 GLColor Convert565(const R5G6B5 &rgb565)
20 {
21     gl::ColorF colorf;
22     R5G6B5::readColor(&colorf, &rgb565);
23     Vector4 vecColor(colorf.red, colorf.green, colorf.blue, colorf.alpha);
24     return GLColor(vecColor);
25 }
26 
Convert565(const GLColor & glColor)27 R5G6B5 Convert565(const GLColor &glColor)
28 {
29     const Vector4 &vecColor = glColor.toNormalizedVector();
30     gl::ColorF colorf(vecColor.x, vecColor.y, vecColor.z, vecColor.w);
31     R5G6B5 rgb565;
32     R5G6B5::writeColor(&rgb565, &colorf);
33     return rgb565;
34 }
35 
36 class SixteenBppTextureTest : public ANGLETest
37 {
38   protected:
SixteenBppTextureTest()39     SixteenBppTextureTest()
40     {
41         setWindowWidth(128);
42         setWindowHeight(128);
43         setConfigRedBits(8);
44         setConfigGreenBits(8);
45         setConfigBlueBits(8);
46         setConfigAlphaBits(8);
47     }
48 
SetUp()49     void SetUp() override
50     {
51         ANGLETest::SetUp();
52 
53         const std::string vertexShaderSource = SHADER_SOURCE
54         (
55             precision highp float;
56             attribute vec4 position;
57             varying vec2 texcoord;
58 
59             void main()
60             {
61                 gl_Position = vec4(position.xy, 0.0, 1.0);
62                 texcoord = (position.xy * 0.5) + 0.5;
63             }
64         );
65 
66         const std::string fragmentShaderSource2D = SHADER_SOURCE
67         (
68             precision highp float;
69             uniform sampler2D tex;
70             varying vec2 texcoord;
71 
72             void main()
73             {
74                 gl_FragColor = texture2D(tex, texcoord);
75             }
76         );
77 
78         m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D);
79         mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
80     }
81 
TearDown()82     void TearDown() override
83     {
84         glDeleteProgram(m2DProgram);
85 
86         ANGLETest::TearDown();
87     }
88 
simpleValidationBase(GLuint tex)89     void simpleValidationBase(GLuint tex)
90     {
91         // Draw a quad using the texture
92         glClear(GL_COLOR_BUFFER_BIT);
93         glUseProgram(m2DProgram);
94         glUniform1i(mTexture2DUniformLocation, 0);
95         drawQuad(m2DProgram, "position", 0.5f);
96         ASSERT_GL_NO_ERROR();
97 
98         int w = getWindowWidth() - 1;
99         int h = getWindowHeight() - 1;
100 
101         // Check that it drew as expected
102         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
103         EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
104         EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
105         EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
106 
107         // Generate mipmaps
108         glGenerateMipmap(GL_TEXTURE_2D);
109 
110         // Draw a quad using the texture
111         glClear(GL_COLOR_BUFFER_BIT);
112         glUseProgram(m2DProgram);
113         glUniform1i(mTexture2DUniformLocation, 0);
114         drawQuad(m2DProgram, "position", 0.5f);
115         ASSERT_GL_NO_ERROR();
116 
117         // Check that it drew as expected
118         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
119         EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
120         EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
121         EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
122 
123         // Bind the texture as a framebuffer, render to it, then check the results
124         GLFramebuffer fbo;
125         glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
126         glBindTexture(GL_TEXTURE_2D, 0);
127         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
128 
129         if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_UNSUPPORTED)
130         {
131             glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
132             glClear(GL_COLOR_BUFFER_BIT);
133             EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
134             EXPECT_PIXEL_EQ(1, 0, 255, 0, 0, 255);
135             EXPECT_PIXEL_EQ(1, 1, 255, 0, 0, 255);
136             EXPECT_PIXEL_EQ(0, 1, 255, 0, 0, 255);
137         }
138         else
139         {
140             std::cout << "Skipping rendering to an unsupported framebuffer format" << std::endl;
141         }
142     }
143 
144     GLuint m2DProgram;
145     GLint mTexture2DUniformLocation;
146 };
147 
148 class SixteenBppTextureTestES3 : public SixteenBppTextureTest
149 {
150 };
151 
152 // Simple validation test for GL_RGB565 textures.
153 // Samples from the texture, renders to it, generates mipmaps etc.
TEST_P(SixteenBppTextureTest,RGB565Validation)154 TEST_P(SixteenBppTextureTest, RGB565Validation)
155 {
156     // These tests fail on certain Intel machines running an un-updated version of Win7
157     // The tests pass after installing the latest updates from Windows Update.
158     // TODO: reenable these tests once the bots have been updated
159     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
160     {
161         std::cout << "Test skipped on Intel D3D11." << std::endl;
162         return;
163     }
164 
165     GLuint test;
166     memcpy(&test, &GLColor::black, 4);
167 
168     R5G6B5 pixels[4] = {Convert565(GLColor::red), Convert565(GLColor::green),
169                         Convert565(GLColor::blue), Convert565(GLColor::yellow)};
170 
171     glClearColor(0, 0, 0, 0);
172 
173     // Create a simple RGB565 texture
174     GLTexture tex;
175     glBindTexture(GL_TEXTURE_2D, tex.get());
176     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
177     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
178     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
179     EXPECT_GL_NO_ERROR();
180 
181     // Supply the data to it
182     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
183     EXPECT_GL_NO_ERROR();
184 
185     simpleValidationBase(tex.get());
186 }
187 
188 // Simple validation test for GL_RGBA5551 textures.
189 // Samples from the texture, renders to it, generates mipmaps etc.
TEST_P(SixteenBppTextureTest,RGBA5551Validation)190 TEST_P(SixteenBppTextureTest, RGBA5551Validation)
191 {
192     // These tests fail on certain Intel machines running an un-updated version of Win7
193     // The tests pass after installing the latest updates from Windows Update.
194     // TODO: reenable these tests once the bots have been updated
195     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
196     {
197         std::cout << "Test skipped on Intel D3D11." << std::endl;
198         return;
199     }
200 
201     GLushort pixels[4] =
202     {
203         0xF801, // Red
204         0x07C1, // Green
205         0x003F, // Blue
206         0xFFC1  // Red + Green
207     };
208 
209     // Create a simple 5551 texture
210     GLTexture tex;
211     glBindTexture(GL_TEXTURE_2D, tex.get());
212     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
213     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
214     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
215     EXPECT_GL_NO_ERROR();
216 
217     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels);
218     EXPECT_GL_NO_ERROR();
219 
220     simpleValidationBase(tex.get());
221 }
222 
223 // Test to ensure calling Clear() on an RGBA5551 texture does something reasonable
224 // Based on WebGL test conformance/textures/texture-attachment-formats.html
TEST_P(SixteenBppTextureTest,RGBA5551ClearAlpha)225 TEST_P(SixteenBppTextureTest, RGBA5551ClearAlpha)
226 {
227     // These tests fail on certain Intel machines running an un-updated version of Win7
228     // The tests pass after installing the latest updates from Windows Update.
229     // TODO: reenable these tests once the bots have been updated
230     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
231     {
232         std::cout << "Test skipped on Intel D3D11." << std::endl;
233         return;
234     }
235 
236     GLTexture tex;
237     GLFramebuffer fbo;
238 
239     // Create a simple 5551 texture
240     glBindTexture(GL_TEXTURE_2D, tex.get());
241     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
242     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
243     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
244     EXPECT_GL_NO_ERROR();
245 
246     // Bind the texture as a framebuffer, clear it, then check the results
247     glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
248     glBindTexture(GL_TEXTURE_2D, 0);
249     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.get(), 0);
250 
251     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_UNSUPPORTED)
252     {
253         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
254         glClear(GL_COLOR_BUFFER_BIT);
255         EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
256 
257         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
258         glClear(GL_COLOR_BUFFER_BIT);
259         EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255);
260     }
261     else
262     {
263         std::cout << "Skipping rendering to an unsupported framebuffer format" << std::endl;
264     }
265 }
266 
267 // Simple validation test for GL_RGBA4444 textures.
268 // Samples from the texture, renders to it, generates mipmaps etc.
TEST_P(SixteenBppTextureTest,RGBA4444Validation)269 TEST_P(SixteenBppTextureTest, RGBA4444Validation)
270 {
271     // These tests fail on certain Intel machines running an un-updated version of Win7
272     // The tests pass after installing the latest updates from Windows Update.
273     // TODO: reenable these tests once the bots have been updated
274     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
275     {
276         std::cout << "Test skipped on Intel D3D11." << std::endl;
277         return;
278     }
279 
280     GLushort pixels[4] =
281     {
282         0xF00F, // Red
283         0x0F0F, // Green
284         0x00FF, // Blue
285         0xFF0F  // Red + Green
286     };
287 
288     glClearColor(0, 0, 0, 0);
289 
290     // Generate a RGBA4444 texture, no mipmaps
291     GLTexture tex;
292     glBindTexture(GL_TEXTURE_2D, tex.get());
293     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, nullptr);
294     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
295     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
296     EXPECT_GL_NO_ERROR();
297 
298     // Provide some data for the texture
299     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels);
300     EXPECT_GL_NO_ERROR();
301 
302     simpleValidationBase(tex.get());
303 }
304 
305 // Test uploading RGBA8 data to RGBA4 textures.
TEST_P(SixteenBppTextureTestES3,RGBA4UploadRGBA8)306 TEST_P(SixteenBppTextureTestES3, RGBA4UploadRGBA8)
307 {
308     std::vector<GLColor> fourColors;
309     fourColors.push_back(GLColor::red);
310     fourColors.push_back(GLColor::green);
311     fourColors.push_back(GLColor::blue);
312     fourColors.push_back(GLColor::yellow);
313 
314     GLTexture tex;
315     glBindTexture(GL_TEXTURE_2D, tex.get());
316     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, fourColors.data());
317     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
318     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
319     ASSERT_GL_NO_ERROR();
320     simpleValidationBase(tex.get());
321 }
322 
323 // Test uploading RGB8 data to RGB565 textures.
TEST_P(SixteenBppTextureTestES3,RGB565UploadRGB8)324 TEST_P(SixteenBppTextureTestES3, RGB565UploadRGB8)
325 {
326     std::vector<GLColorRGB> fourColors;
327     fourColors.push_back(GLColorRGB::red);
328     fourColors.push_back(GLColorRGB::green);
329     fourColors.push_back(GLColorRGB::blue);
330     fourColors.push_back(GLColorRGB::yellow);
331 
332     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
333 
334     GLTexture tex;
335     glBindTexture(GL_TEXTURE_2D, tex.get());
336     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, fourColors.data());
337     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
338     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
339     ASSERT_GL_NO_ERROR();
340 
341     simpleValidationBase(tex.get());
342 }
343 
344 // Test uploading RGBA8 data to RGB5A41 textures.
TEST_P(SixteenBppTextureTestES3,RGB5A1UploadRGBA8)345 TEST_P(SixteenBppTextureTestES3, RGB5A1UploadRGBA8)
346 {
347     std::vector<GLColor> fourColors;
348     fourColors.push_back(GLColor::red);
349     fourColors.push_back(GLColor::green);
350     fourColors.push_back(GLColor::blue);
351     fourColors.push_back(GLColor::yellow);
352 
353     GLTexture tex;
354     glBindTexture(GL_TEXTURE_2D, tex.get());
355     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
356                  fourColors.data());
357     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
358     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
359     ASSERT_GL_NO_ERROR();
360     simpleValidationBase(tex.get());
361 }
362 
363 // Test uploading RGB10A2 data to RGB5A1 textures.
TEST_P(SixteenBppTextureTestES3,RGB5A1UploadRGB10A2)364 TEST_P(SixteenBppTextureTestES3, RGB5A1UploadRGB10A2)
365 {
366     struct RGB10A2
367     {
368         RGB10A2(uint32_t r, uint32_t g, uint32_t b, uint32_t a) : R(r), G(g), B(b), A(a) {}
369 
370         uint32_t R : 10;
371         uint32_t G : 10;
372         uint32_t B : 10;
373         uint32_t A : 2;
374     };
375 
376     uint32_t one10 = (1u << 10u) - 1u;
377 
378     RGB10A2 red(one10, 0u, 0u, 0x3u);
379     RGB10A2 green(0u, one10, 0u, 0x3u);
380     RGB10A2 blue(0u, 0u, one10, 0x3u);
381     RGB10A2 yellow(one10, one10, 0u, 0x3u);
382 
383     std::vector<RGB10A2> fourColors;
384     fourColors.push_back(red);
385     fourColors.push_back(green);
386     fourColors.push_back(blue);
387     fourColors.push_back(yellow);
388 
389     GLTexture tex;
390     glBindTexture(GL_TEXTURE_2D, tex.get());
391     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 2, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
392                  fourColors.data());
393     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
394     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
395     ASSERT_GL_NO_ERROR();
396     simpleValidationBase(tex.get());
397 }
398 
399 // Test reading from RGBA4 textures attached to FBO.
TEST_P(SixteenBppTextureTestES3,RGBA4FramebufferReadback)400 TEST_P(SixteenBppTextureTestES3, RGBA4FramebufferReadback)
401 {
402     // TODO(jmadill): Fix bug with GLES
403     if (IsOpenGLES())
404     {
405         std::cout << "Test skipped on GLES." << std::endl;
406         return;
407     }
408 
409     Vector4 rawColor(0.5f, 0.7f, 1.0f, 0.0f);
410     GLColor expectedColor(rawColor);
411 
412     GLFramebuffer fbo;
413     glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
414 
415     GLTexture tex;
416     glBindTexture(GL_TEXTURE_2D, tex.get());
417     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
418     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.get(), 0);
419 
420     glClearColor(rawColor.x, rawColor.y, rawColor.z, rawColor.w);
421     glClear(GL_COLOR_BUFFER_BIT);
422 
423     ASSERT_GL_NO_ERROR();
424 
425     GLenum colorReadFormat = GL_NONE;
426     GLenum colorReadType   = GL_NONE;
427     glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, reinterpret_cast<GLint *>(&colorReadFormat));
428     glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, reinterpret_cast<GLint *>(&colorReadType));
429 
430     if (colorReadFormat == GL_RGBA && colorReadType == GL_UNSIGNED_BYTE)
431     {
432         GLColor actualColor = GLColor::black;
433         glReadPixels(0, 0, 1, 1, colorReadFormat, colorReadType, &actualColor);
434         EXPECT_COLOR_NEAR(expectedColor, actualColor, 20);
435     }
436     else
437     {
438         ASSERT_GLENUM_EQ(GL_RGBA, colorReadFormat);
439         ASSERT_TRUE(colorReadType == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT ||
440                     colorReadType == GL_UNSIGNED_SHORT_4_4_4_4);
441 
442         uint16_t rgba = 0;
443         glReadPixels(0, 0, 1, 1, colorReadFormat, colorReadType, &rgba);
444 
445         GLubyte r8 = static_cast<GLubyte>((rgba & 0xF000) >> 12);
446         GLubyte g8 = static_cast<GLubyte>((rgba & 0x0F00) >> 8);
447         GLubyte b8 = static_cast<GLubyte>((rgba & 0x00F0) >> 4);
448         GLubyte a8 = static_cast<GLubyte>((rgba & 0x000F));
449 
450         GLColor actualColor(r8 << 4, g8 << 4, b8 << 4, a8 << 4);
451         EXPECT_COLOR_NEAR(expectedColor, actualColor, 20);
452     }
453 
454     ASSERT_GL_NO_ERROR();
455 }
456 
457 // Test reading from RGB565 textures attached to FBO.
TEST_P(SixteenBppTextureTestES3,RGB565FramebufferReadback)458 TEST_P(SixteenBppTextureTestES3, RGB565FramebufferReadback)
459 {
460     // TODO(jmadill): Fix bug with GLES
461     if (IsOpenGLES())
462     {
463         std::cout << "Test skipped on GLES." << std::endl;
464         return;
465     }
466 
467     GLFramebuffer fbo;
468     glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
469 
470     std::vector<GLColor> fourColors;
471     fourColors.push_back(GLColor::red);
472     fourColors.push_back(GLColor::green);
473     fourColors.push_back(GLColor::blue);
474     fourColors.push_back(GLColor::white);
475 
476     const std::string &vertexShader =
477         "#version 300 es\n"
478         "in vec4 color;\n"
479         "in vec2 position;\n"
480         "out vec4 fcolor;\n"
481         "void main() {\n"
482         "    fcolor = color;\n"
483         "    gl_Position = vec4(position, 0.5, 1.0);\n"
484         "}";
485     const std::string &fragmentShader =
486         "#version 300 es\n"
487         "in mediump vec4 fcolor;\n"
488         "out mediump vec4 color;\n"
489         "void main() {\n"
490         "    color = fcolor;\n"
491         "}";
492 
493     GLuint program = CompileProgram(vertexShader, fragmentShader);
494     glUseProgram(program);
495 
496     GLint colorLocation = glGetAttribLocation(program, "color");
497     ASSERT_NE(-1, colorLocation);
498     glEnableVertexAttribArray(colorLocation);
499     glVertexAttribPointer(colorLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, fourColors.data());
500 
501     int w = getWindowWidth();
502     int h = getWindowHeight();
503 
504     glViewport(0, 0, w, h);
505 
506     GLTexture tex;
507     glBindTexture(GL_TEXTURE_2D, tex.get());
508     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
509     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.get(), 0);
510 
511     drawIndexedQuad(program, "position", 0.5f);
512 
513     ASSERT_GL_NO_ERROR();
514 
515     int t = 12;
516     EXPECT_PIXEL_COLOR_NEAR(0, h - 1, GLColor::red, t);
517     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::green, t);
518     EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, GLColor::blue, t);
519     EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, GLColor::white, t);
520 
521     GLenum colorReadFormat = GL_NONE;
522     GLenum colorReadType   = GL_NONE;
523     glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, reinterpret_cast<GLint *>(&colorReadFormat));
524     glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, reinterpret_cast<GLint *>(&colorReadType));
525 
526     if (colorReadFormat == GL_RGB && colorReadType == GL_UNSIGNED_SHORT_5_6_5)
527     {
528         std::vector<R5G6B5> readColors(w * h);
529         glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, readColors.data());
530 
531         int hoffset = (h - 1) * w;
532         EXPECT_COLOR_NEAR(GLColor::red, Convert565(readColors[hoffset]), t);
533         EXPECT_COLOR_NEAR(GLColor::green, Convert565(readColors[0]), t);
534         EXPECT_COLOR_NEAR(GLColor::blue, Convert565(readColors[w - 1]), t);
535         EXPECT_COLOR_NEAR(GLColor::white, Convert565(readColors[w - 1 + hoffset]), t);
536     }
537 
538     glDeleteProgram(program);
539 }
540 
541 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
542 ANGLE_INSTANTIATE_TEST(SixteenBppTextureTest,
543                        ES2_D3D9(),
544                        ES2_D3D11(),
545                        ES2_D3D11_FL9_3(),
546                        ES2_OPENGL(),
547                        ES2_OPENGLES());
548 
549 ANGLE_INSTANTIATE_TEST(SixteenBppTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
550 
551 } // namespace
552