xref: /aosp_15_r20/external/angle/src/tests/gl_tests/CopyTexImageTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker namespace angle
11*8975f5c5SAndroid Build Coastguard Worker {
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker class CopyTexImageTest : public ANGLETest<>
14*8975f5c5SAndroid Build Coastguard Worker {
15*8975f5c5SAndroid Build Coastguard Worker   protected:
CopyTexImageTest()16*8975f5c5SAndroid Build Coastguard Worker     CopyTexImageTest()
17*8975f5c5SAndroid Build Coastguard Worker     {
18*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(32);
19*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(32);
20*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
21*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
22*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
23*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
24*8975f5c5SAndroid Build Coastguard Worker     }
25*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()26*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
27*8975f5c5SAndroid Build Coastguard Worker     {
28*8975f5c5SAndroid Build Coastguard Worker         mTextureProgram =
29*8975f5c5SAndroid Build Coastguard Worker             CompileProgram(essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
30*8975f5c5SAndroid Build Coastguard Worker         if (mTextureProgram == 0)
31*8975f5c5SAndroid Build Coastguard Worker         {
32*8975f5c5SAndroid Build Coastguard Worker             FAIL() << "shader compilation failed.";
33*8975f5c5SAndroid Build Coastguard Worker         }
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker         mTextureUniformLocation =
36*8975f5c5SAndroid Build Coastguard Worker             glGetUniformLocation(mTextureProgram, essl1_shaders::Texture2DUniform());
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
39*8975f5c5SAndroid Build Coastguard Worker     }
40*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()41*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override { glDeleteProgram(mTextureProgram); }
42*8975f5c5SAndroid Build Coastguard Worker 
initializeResources(GLenum internalFormat,GLenum format,GLenum type,bool solidColor)43*8975f5c5SAndroid Build Coastguard Worker     void initializeResources(GLenum internalFormat, GLenum format, GLenum type, bool solidColor)
44*8975f5c5SAndroid Build Coastguard Worker     {
45*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < kFboCount; ++i)
46*8975f5c5SAndroid Build Coastguard Worker         {
47*8975f5c5SAndroid Build Coastguard Worker             glBindTexture(GL_TEXTURE_2D, mFboTextures[i]);
48*8975f5c5SAndroid Build Coastguard Worker             glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, kFboSizes[i], kFboSizes[i], 0, format,
49*8975f5c5SAndroid Build Coastguard Worker                          type, nullptr);
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker             // Disable mipmapping
52*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
53*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
54*8975f5c5SAndroid Build Coastguard Worker 
55*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, mFbos[i]);
56*8975f5c5SAndroid Build Coastguard Worker             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
57*8975f5c5SAndroid Build Coastguard Worker                                    mFboTextures[i], 0);
58*8975f5c5SAndroid Build Coastguard Worker 
59*8975f5c5SAndroid Build Coastguard Worker             if (solidColor)
60*8975f5c5SAndroid Build Coastguard Worker             {
61*8975f5c5SAndroid Build Coastguard Worker                 glClearColor(kSolidColors[i][0], kSolidColors[i][1], kSolidColors[i][2],
62*8975f5c5SAndroid Build Coastguard Worker                              kSolidColors[i][3]);
63*8975f5c5SAndroid Build Coastguard Worker             }
64*8975f5c5SAndroid Build Coastguard Worker             else
65*8975f5c5SAndroid Build Coastguard Worker             {
66*8975f5c5SAndroid Build Coastguard Worker                 glClearColor(kFboColors[i][0], kFboColors[i][1], kFboColors[i][2],
67*8975f5c5SAndroid Build Coastguard Worker                              kFboColors[i][3]);
68*8975f5c5SAndroid Build Coastguard Worker             }
69*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
70*8975f5c5SAndroid Build Coastguard Worker         }
71*8975f5c5SAndroid Build Coastguard Worker 
72*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
73*8975f5c5SAndroid Build Coastguard Worker     }
74*8975f5c5SAndroid Build Coastguard Worker 
initializeResources(GLenum format,GLenum type)75*8975f5c5SAndroid Build Coastguard Worker     void initializeResources(GLenum format, GLenum type)
76*8975f5c5SAndroid Build Coastguard Worker     {
77*8975f5c5SAndroid Build Coastguard Worker         initializeResources(format, format, type, false);
78*8975f5c5SAndroid Build Coastguard Worker     }
79*8975f5c5SAndroid Build Coastguard Worker 
verifyResults(GLuint texture,const GLubyte data[4],GLint fboSize,GLint xs,GLint ys,GLint xe,GLint ye,double errorBounds)80*8975f5c5SAndroid Build Coastguard Worker     void verifyResults(GLuint texture,
81*8975f5c5SAndroid Build Coastguard Worker                        const GLubyte data[4],
82*8975f5c5SAndroid Build Coastguard Worker                        GLint fboSize,
83*8975f5c5SAndroid Build Coastguard Worker                        GLint xs,
84*8975f5c5SAndroid Build Coastguard Worker                        GLint ys,
85*8975f5c5SAndroid Build Coastguard Worker                        GLint xe,
86*8975f5c5SAndroid Build Coastguard Worker                        GLint ye,
87*8975f5c5SAndroid Build Coastguard Worker                        double errorBounds)
88*8975f5c5SAndroid Build Coastguard Worker     {
89*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, fboSize, fboSize);
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker         // Draw a quad with the target texture
94*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mTextureProgram);
95*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
96*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(mTextureUniformLocation, 0);
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker         // Expect that the rendered quad has the same color as the source texture
101*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_NEAR(xs, ys, data[0], data[1], data[2], data[3], errorBounds);
102*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_NEAR(xs, ye - 1, data[0], data[1], data[2], data[3], errorBounds);
103*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_NEAR(xe - 1, ys, data[0], data[1], data[2], data[3], errorBounds);
104*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_NEAR(xe - 1, ye - 1, data[0], data[1], data[2], data[3], errorBounds);
105*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_NEAR((xs + xe) / 2, (ys + ye) / 2, data[0], data[1], data[2], data[3],
106*8975f5c5SAndroid Build Coastguard Worker                           errorBounds);
107*8975f5c5SAndroid Build Coastguard Worker     }
108*8975f5c5SAndroid Build Coastguard Worker 
verifyCheckeredResults(GLuint texture,const GLubyte data0[4],const GLubyte data1[4],const GLubyte data2[4],const GLubyte data3[4],GLint fboWidth,GLint fboHeight)109*8975f5c5SAndroid Build Coastguard Worker     void verifyCheckeredResults(GLuint texture,
110*8975f5c5SAndroid Build Coastguard Worker                                 const GLubyte data0[4],
111*8975f5c5SAndroid Build Coastguard Worker                                 const GLubyte data1[4],
112*8975f5c5SAndroid Build Coastguard Worker                                 const GLubyte data2[4],
113*8975f5c5SAndroid Build Coastguard Worker                                 const GLubyte data3[4],
114*8975f5c5SAndroid Build Coastguard Worker                                 GLint fboWidth,
115*8975f5c5SAndroid Build Coastguard Worker                                 GLint fboHeight)
116*8975f5c5SAndroid Build Coastguard Worker     {
117*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, fboWidth, fboHeight);
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker         // Draw a quad with the target texture
122*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mTextureProgram);
123*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
124*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(mTextureUniformLocation, 0);
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker         // Expect that the rendered quad has the same color as the source texture
129*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_EQ(fboWidth / 4, fboHeight / 4, data0[0], data0[1], data0[2], data0[3]);
130*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_EQ(fboWidth / 4, 3 * fboHeight / 4, data1[0], data1[1], data1[2], data1[3]);
131*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_EQ(3 * fboWidth / 4, fboHeight / 4, data2[0], data2[1], data2[2], data2[3]);
132*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_EQ(3 * fboWidth / 4, 3 * fboHeight / 4, data3[0], data3[1], data3[2],
133*8975f5c5SAndroid Build Coastguard Worker                         data3[3]);
134*8975f5c5SAndroid Build Coastguard Worker     }
135*8975f5c5SAndroid Build Coastguard Worker 
runCopyTexImageTest(GLenum format,GLubyte expected[3][4],double errorBounds=1.0)136*8975f5c5SAndroid Build Coastguard Worker     void runCopyTexImageTest(GLenum format, GLubyte expected[3][4], double errorBounds = 1.0)
137*8975f5c5SAndroid Build Coastguard Worker     {
138*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex;
139*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, tex);
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker         // Disable mipmapping
142*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
143*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker         // Perform the copy multiple times.
146*8975f5c5SAndroid Build Coastguard Worker         //
147*8975f5c5SAndroid Build Coastguard Worker         // - The first time, a new texture is created
148*8975f5c5SAndroid Build Coastguard Worker         // - The second time, as the fbo size is the same as previous, the texture storage is not
149*8975f5c5SAndroid Build Coastguard Worker         //   recreated.
150*8975f5c5SAndroid Build Coastguard Worker         // - The third time, the fbo size is different, so a new texture is created.
151*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < kFboCount; ++i)
152*8975f5c5SAndroid Build Coastguard Worker         {
153*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, mFbos[i]);
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker             glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, kFboSizes[i], kFboSizes[i], 0);
156*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker             verifyResults(tex, expected[i], kFboSizes[i], 0, 0, kFboSizes[i], kFboSizes[i],
159*8975f5c5SAndroid Build Coastguard Worker                           errorBounds);
160*8975f5c5SAndroid Build Coastguard Worker         }
161*8975f5c5SAndroid Build Coastguard Worker     }
162*8975f5c5SAndroid Build Coastguard Worker 
163*8975f5c5SAndroid Build Coastguard Worker     // x, y, width, height specify the portion of fbo to be copied into tex.
164*8975f5c5SAndroid Build Coastguard Worker     // flip_y specifies if the glCopyTextImage must be done from y-flipped fbo.
runCopyTexImageTestCheckered(GLenum format,const uint32_t x[3],const uint32_t y[3],const uint32_t width[3],const uint32_t height[3],const GLubyte expectedData0[4],const GLubyte expectedData1[4],const GLubyte expectedData2[4],const GLubyte expectedData3[4],bool mesaFlipY)165*8975f5c5SAndroid Build Coastguard Worker     void runCopyTexImageTestCheckered(GLenum format,
166*8975f5c5SAndroid Build Coastguard Worker                                       const uint32_t x[3],
167*8975f5c5SAndroid Build Coastguard Worker                                       const uint32_t y[3],
168*8975f5c5SAndroid Build Coastguard Worker                                       const uint32_t width[3],
169*8975f5c5SAndroid Build Coastguard Worker                                       const uint32_t height[3],
170*8975f5c5SAndroid Build Coastguard Worker                                       const GLubyte expectedData0[4],
171*8975f5c5SAndroid Build Coastguard Worker                                       const GLubyte expectedData1[4],
172*8975f5c5SAndroid Build Coastguard Worker                                       const GLubyte expectedData2[4],
173*8975f5c5SAndroid Build Coastguard Worker                                       const GLubyte expectedData3[4],
174*8975f5c5SAndroid Build Coastguard Worker                                       bool mesaFlipY)
175*8975f5c5SAndroid Build Coastguard Worker     {
176*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex;
177*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, tex);
178*8975f5c5SAndroid Build Coastguard Worker 
179*8975f5c5SAndroid Build Coastguard Worker         // Disable mipmapping
180*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
181*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
182*8975f5c5SAndroid Build Coastguard Worker 
183*8975f5c5SAndroid Build Coastguard Worker         // Perform the copy multiple times.
184*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < kFboCount; ++i)
185*8975f5c5SAndroid Build Coastguard Worker         {
186*8975f5c5SAndroid Build Coastguard Worker             glViewport(0, 0, kFboSizes[i], kFboSizes[i]);
187*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, mFbos[i]);
188*8975f5c5SAndroid Build Coastguard Worker 
189*8975f5c5SAndroid Build Coastguard Worker             ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
190*8975f5c5SAndroid Build Coastguard Worker                              essl1_shaders::fs::Checkered());
191*8975f5c5SAndroid Build Coastguard Worker             drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
192*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_NO_ERROR();
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker             if (mesaFlipY)
195*8975f5c5SAndroid Build Coastguard Worker                 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
196*8975f5c5SAndroid Build Coastguard Worker             glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x[i], y[i], width[i], height[i], 0);
197*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker             verifyCheckeredResults(tex, expectedData0, expectedData1, expectedData2, expectedData3,
200*8975f5c5SAndroid Build Coastguard Worker                                    kFboSizes[i], kFboSizes[i]);
201*8975f5c5SAndroid Build Coastguard Worker         }
202*8975f5c5SAndroid Build Coastguard Worker     }
203*8975f5c5SAndroid Build Coastguard Worker 
runCopyTexSubImageTest(GLenum format,GLubyte expected[3][4],double errorBounds=1.0)204*8975f5c5SAndroid Build Coastguard Worker     void runCopyTexSubImageTest(GLenum format, GLubyte expected[3][4], double errorBounds = 1.0)
205*8975f5c5SAndroid Build Coastguard Worker     {
206*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex;
207*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, tex);
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker         // Disable mipmapping
210*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
211*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker         // Create the texture with copy of the first fbo.
214*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mFbos[0]);
215*8975f5c5SAndroid Build Coastguard Worker         glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, kFboSizes[0], kFboSizes[0], 0);
216*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], 0, 0, kFboSizes[0], kFboSizes[0],
219*8975f5c5SAndroid Build Coastguard Worker                       errorBounds);
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker         // Make sure out-of-bound writes to the texture return invalid value.
222*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mFbos[1]);
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker         // xoffset < 0 and yoffset < 0
225*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, -1, -1, 0, 0, kFboSizes[0], kFboSizes[0]);
226*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_ERROR(GL_INVALID_VALUE);
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker         // xoffset + width > w and yoffset + height > h
229*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 0, 0, kFboSizes[0], kFboSizes[0]);
230*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_ERROR(GL_INVALID_VALUE);
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker         // xoffset + width > w and yoffset + height > h, out of bounds
233*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, -1, -1, 1 + kFboSizes[0], 1 + kFboSizes[0]);
234*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_ERROR(GL_INVALID_VALUE);
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker         // Copy the second fbo over a portion of the image.
237*8975f5c5SAndroid Build Coastguard Worker         GLint offset = kFboSizes[0] / 2;
238*8975f5c5SAndroid Build Coastguard Worker         GLint extent = kFboSizes[0] - offset;
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, offset, offset, kFboSizes[1] / 2, kFboSizes[1] / 2,
241*8975f5c5SAndroid Build Coastguard Worker                             extent, extent);
242*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[1], kFboSizes[0], offset, offset, kFboSizes[0], kFboSizes[0],
245*8975f5c5SAndroid Build Coastguard Worker                       errorBounds);
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker         // The rest of the image should be untouched
248*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], 0, 0, offset, offset, errorBounds);
249*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], offset, 0, kFboSizes[0], offset, errorBounds);
250*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], 0, offset, offset, kFboSizes[0], errorBounds);
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker         // Copy the third fbo over another portion of the image.
253*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mFbos[2]);
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker         offset = kFboSizes[0] / 4;
256*8975f5c5SAndroid Build Coastguard Worker         extent = kFboSizes[0] - offset;
257*8975f5c5SAndroid Build Coastguard Worker 
258*8975f5c5SAndroid Build Coastguard Worker         // While width and height are set as 3/4 of the size, the fbo offset is given such that
259*8975f5c5SAndroid Build Coastguard Worker         // after clipping, width and height are effectively 1/2 of the size.
260*8975f5c5SAndroid Build Coastguard Worker         GLint srcOffset       = kFboSizes[2] - kFboSizes[0] / 2;
261*8975f5c5SAndroid Build Coastguard Worker         GLint effectiveExtent = kFboSizes[0] / 2;
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, offset, offset, srcOffset, srcOffset, extent, extent);
264*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[2], kFboSizes[0], offset, offset, effectiveExtent,
267*8975f5c5SAndroid Build Coastguard Worker                       effectiveExtent, errorBounds);
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker         // The rest of the image should be untouched
270*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[1], kFboSizes[0], offset + effectiveExtent, kFboSizes[0] / 2,
271*8975f5c5SAndroid Build Coastguard Worker                       kFboSizes[0], kFboSizes[0], errorBounds);
272*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[1], kFboSizes[0], kFboSizes[0] / 2, offset + effectiveExtent,
273*8975f5c5SAndroid Build Coastguard Worker                       kFboSizes[0], kFboSizes[0], errorBounds);
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], 0, 0, kFboSizes[0], offset, errorBounds);
276*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], 0, 0, offset, kFboSizes[0], errorBounds);
277*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], offset + effectiveExtent, 0, kFboSizes[0],
278*8975f5c5SAndroid Build Coastguard Worker                       kFboSizes[0] / 2, errorBounds);
279*8975f5c5SAndroid Build Coastguard Worker         verifyResults(tex, expected[0], kFboSizes[0], 0, offset + effectiveExtent, kFboSizes[0] / 2,
280*8975f5c5SAndroid Build Coastguard Worker                       kFboSizes[0], errorBounds);
281*8975f5c5SAndroid Build Coastguard Worker     }
282*8975f5c5SAndroid Build Coastguard Worker 
testBGRAToRGBAConversion()283*8975f5c5SAndroid Build Coastguard Worker     void testBGRAToRGBAConversion()
284*8975f5c5SAndroid Build Coastguard Worker     {
285*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer framebuffer;
286*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
287*8975f5c5SAndroid Build Coastguard Worker 
288*8975f5c5SAndroid Build Coastguard Worker         GLColor bgraInputData(128, 64, 255, 255);
289*8975f5c5SAndroid Build Coastguard Worker         GLColor bgraExpectedData(255, 64, 128, 255);
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker         GLTexture bgraTexture;
292*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, bgraTexture);
293*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
294*8975f5c5SAndroid Build Coastguard Worker                      &bgraInputData);
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bgraTexture, 0);
297*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, bgraExpectedData);
298*8975f5c5SAndroid Build Coastguard Worker 
299*8975f5c5SAndroid Build Coastguard Worker         // Copy BGRA framebuffer -> RGBA texture
300*8975f5c5SAndroid Build Coastguard Worker         GLTexture rgbaTexture;
301*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, rgbaTexture);
302*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
303*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
304*8975f5c5SAndroid Build Coastguard Worker 
305*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgbaTexture, 0);
306*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, bgraExpectedData);
307*8975f5c5SAndroid Build Coastguard Worker     }
308*8975f5c5SAndroid Build Coastguard Worker 
testRGBAToBGRAConversion()309*8975f5c5SAndroid Build Coastguard Worker     void testRGBAToBGRAConversion()
310*8975f5c5SAndroid Build Coastguard Worker     {
311*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer framebuffer;
312*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
313*8975f5c5SAndroid Build Coastguard Worker 
314*8975f5c5SAndroid Build Coastguard Worker         GLColor rgbaData(255, 128, 64, 255);
315*8975f5c5SAndroid Build Coastguard Worker 
316*8975f5c5SAndroid Build Coastguard Worker         GLTexture rgbaTexture;
317*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, rgbaTexture);
318*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rgbaData);
319*8975f5c5SAndroid Build Coastguard Worker 
320*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgbaTexture, 0);
321*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, rgbaData);
322*8975f5c5SAndroid Build Coastguard Worker 
323*8975f5c5SAndroid Build Coastguard Worker         // Copy RGBA framebuffer -> BGRA Texture
324*8975f5c5SAndroid Build Coastguard Worker         GLTexture bgraTexture;
325*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, bgraTexture);
326*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
327*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
328*8975f5c5SAndroid Build Coastguard Worker 
329*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
330*8975f5c5SAndroid Build Coastguard Worker 
331*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bgraTexture, 0);
332*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, rgbaData);
333*8975f5c5SAndroid Build Coastguard Worker     }
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker     GLuint mTextureProgram;
336*8975f5c5SAndroid Build Coastguard Worker     GLint mTextureUniformLocation;
337*8975f5c5SAndroid Build Coastguard Worker 
338*8975f5c5SAndroid Build Coastguard Worker     static constexpr uint32_t kFboCount = 3;
339*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer mFbos[kFboCount];
340*8975f5c5SAndroid Build Coastguard Worker     GLTexture mFboTextures[kFboCount];
341*8975f5c5SAndroid Build Coastguard Worker 
342*8975f5c5SAndroid Build Coastguard Worker     static constexpr uint32_t kFboSizes[kFboCount]    = {16, 16, 32};
343*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLfloat kFboColors[kFboCount][4] = {{0.25f, 1.0f, 0.75f, 0.5f},
344*8975f5c5SAndroid Build Coastguard Worker                                                          {1.0f, 0.75f, 0.5f, 0.25f},
345*8975f5c5SAndroid Build Coastguard Worker                                                          {0.5f, 0.25f, 1.0f, 0.75f}};
346*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLfloat kSolidColors[kFboCount][4] = {{1.0f, 0.0f, 0.0f, 1.0f},
347*8975f5c5SAndroid Build Coastguard Worker                                                            {0.0f, 1.0f, 0.0f, 1.0f},
348*8975f5c5SAndroid Build Coastguard Worker                                                            {0.0f, 0.0f, 1.0f, 1.0f}};
349*8975f5c5SAndroid Build Coastguard Worker };
350*8975f5c5SAndroid Build Coastguard Worker 
351*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_RGB8
TEST_P(CopyTexImageTest,RGBAToRGB8)352*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToRGB8)
353*8975f5c5SAndroid Build Coastguard Worker {
354*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
355*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
356*8975f5c5SAndroid Build Coastguard Worker         {64, 255, 191, 255},
357*8975f5c5SAndroid Build Coastguard Worker         {255, 191, 127, 255},
358*8975f5c5SAndroid Build Coastguard Worker         {127, 64, 255, 255},
359*8975f5c5SAndroid Build Coastguard Worker     };
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
362*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_RGB8, expected);
363*8975f5c5SAndroid Build Coastguard Worker }
364*8975f5c5SAndroid Build Coastguard Worker 
365*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_RGBA
TEST_P(CopyTexImageTest,RGBAToRGBA)366*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToRGBA)
367*8975f5c5SAndroid Build Coastguard Worker {
368*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
369*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
370*8975f5c5SAndroid Build Coastguard Worker         {64, 255, 191, 128},
371*8975f5c5SAndroid Build Coastguard Worker         {255, 191, 127, 64},
372*8975f5c5SAndroid Build Coastguard Worker         {127, 64, 255, 192},
373*8975f5c5SAndroid Build Coastguard Worker     };
374*8975f5c5SAndroid Build Coastguard Worker 
375*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
376*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_RGBA, expected);
377*8975f5c5SAndroid Build Coastguard Worker }
378*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,RGBAToL)379*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToL)
380*8975f5c5SAndroid Build Coastguard Worker {
381*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
382*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 255},
383*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 255},
384*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 255},
385*8975f5c5SAndroid Build Coastguard Worker     };
386*8975f5c5SAndroid Build Coastguard Worker 
387*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
388*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE, expected);
389*8975f5c5SAndroid Build Coastguard Worker }
390*8975f5c5SAndroid Build Coastguard Worker 
391*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_LUMINANCE8_OES
TEST_P(CopyTexImageTest,RGBAToL8)392*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToL8)
393*8975f5c5SAndroid Build Coastguard Worker {
394*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
395*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
396*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 255},
397*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 255},
398*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 255},
399*8975f5c5SAndroid Build Coastguard Worker     };
400*8975f5c5SAndroid Build Coastguard Worker 
401*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
402*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE8_OES, expected);
403*8975f5c5SAndroid Build Coastguard Worker }
404*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,RGBAToLA)405*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToLA)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
408*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 127},
409*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 64},
410*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 191},
411*8975f5c5SAndroid Build Coastguard Worker     };
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
414*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE_ALPHA, expected);
415*8975f5c5SAndroid Build Coastguard Worker }
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_LUMINANCE8_ALPHA8_OES
TEST_P(CopyTexImageTest,RGBAToL8A8)418*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToL8A8)
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
421*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
422*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 127},
423*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 64},
424*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 191},
425*8975f5c5SAndroid Build Coastguard Worker     };
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
428*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE8_ALPHA8_OES, expected);
429*8975f5c5SAndroid Build Coastguard Worker }
430*8975f5c5SAndroid Build Coastguard Worker 
431*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_LUMINANCE4_ALPHA4_OES
TEST_P(CopyTexImageTest,RGBAToL4A4)432*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToL4A4)
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
435*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
436*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 127},
437*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 64},
438*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 191},
439*8975f5c5SAndroid Build Coastguard Worker     };
440*8975f5c5SAndroid Build Coastguard Worker 
441*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
442*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE4_ALPHA4_OES, expected, 9.0);
443*8975f5c5SAndroid Build Coastguard Worker }
444*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,RGBAToA)445*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToA)
446*8975f5c5SAndroid Build Coastguard Worker {
447*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
448*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 0, 127},
449*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 0, 64},
450*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 0, 191},
451*8975f5c5SAndroid Build Coastguard Worker     };
452*8975f5c5SAndroid Build Coastguard Worker 
453*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
454*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_ALPHA, expected);
455*8975f5c5SAndroid Build Coastguard Worker }
456*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_ALPHA8_OES
TEST_P(CopyTexImageTest,RGBAToA8)457*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToA8)
458*8975f5c5SAndroid Build Coastguard Worker {
459*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
460*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
461*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 0, 127},
462*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 0, 64},
463*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 0, 191},
464*8975f5c5SAndroid Build Coastguard Worker     };
465*8975f5c5SAndroid Build Coastguard Worker 
466*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
467*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_ALPHA8_OES, expected);
468*8975f5c5SAndroid Build Coastguard Worker }
469*8975f5c5SAndroid Build Coastguard Worker 
470*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_RGBA4
TEST_P(CopyTexImageTest,RGBAToRGBA4)471*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToRGBA4)
472*8975f5c5SAndroid Build Coastguard Worker {
473*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
474*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
475*8975f5c5SAndroid Build Coastguard Worker         {255, 0, 0, 255},
476*8975f5c5SAndroid Build Coastguard Worker         {0, 255, 0, 255},
477*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 255, 255},
478*8975f5c5SAndroid Build Coastguard Worker     };
479*8975f5c5SAndroid Build Coastguard Worker 
480*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE, true);
481*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_RGBA4, expected);
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker 
484*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGB to GL_RGB565
TEST_P(CopyTexImageTest,RGBToRGB565)485*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBToRGB565)
486*8975f5c5SAndroid Build Coastguard Worker {
487*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
488*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
489*8975f5c5SAndroid Build Coastguard Worker         {255, 0, 0, 255},
490*8975f5c5SAndroid Build Coastguard Worker         {0, 255, 0, 255},
491*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 255, 255},
492*8975f5c5SAndroid Build Coastguard Worker     };
493*8975f5c5SAndroid Build Coastguard Worker 
494*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE, true);
495*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_RGB565, expected);
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker 
498*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGBA to GL_RGB5_A1
TEST_P(CopyTexImageTest,RGBAToRGB5A1)499*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBAToRGB5A1)
500*8975f5c5SAndroid Build Coastguard Worker {
501*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
502*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
503*8975f5c5SAndroid Build Coastguard Worker         {255, 0, 0, 255},
504*8975f5c5SAndroid Build Coastguard Worker         {0, 255, 0, 255},
505*8975f5c5SAndroid Build Coastguard Worker         {0, 0, 255, 255},
506*8975f5c5SAndroid Build Coastguard Worker     };
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE, true);
509*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_RGB5_A1, expected);
510*8975f5c5SAndroid Build Coastguard Worker }
511*8975f5c5SAndroid Build Coastguard Worker 
512*8975f5c5SAndroid Build Coastguard Worker // CopyTexImage from GL_RGB to GL_LUMINANCE
TEST_P(CopyTexImageTest,RGBToL)513*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBToL)
514*8975f5c5SAndroid Build Coastguard Worker {
515*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_required_internalformat"));
516*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
517*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 255},
518*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 255},
519*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 255},
520*8975f5c5SAndroid Build Coastguard Worker     };
521*8975f5c5SAndroid Build Coastguard Worker 
522*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGB, GL_UNSIGNED_BYTE);
523*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE, expected);
524*8975f5c5SAndroid Build Coastguard Worker }
TEST_P(CopyTexImageTest,SubImageRGBAToRGB)525*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, SubImageRGBAToRGB)
526*8975f5c5SAndroid Build Coastguard Worker {
527*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
528*8975f5c5SAndroid Build Coastguard Worker         {64, 255, 191, 255},
529*8975f5c5SAndroid Build Coastguard Worker         {255, 191, 127, 255},
530*8975f5c5SAndroid Build Coastguard Worker         {127, 64, 255, 255},
531*8975f5c5SAndroid Build Coastguard Worker     };
532*8975f5c5SAndroid Build Coastguard Worker 
533*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
534*8975f5c5SAndroid Build Coastguard Worker     runCopyTexSubImageTest(GL_RGB, expected);
535*8975f5c5SAndroid Build Coastguard Worker }
536*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,SubImageRGBAToL)537*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, SubImageRGBAToL)
538*8975f5c5SAndroid Build Coastguard Worker {
539*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
540*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 255},
541*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 255},
542*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 255},
543*8975f5c5SAndroid Build Coastguard Worker     };
544*8975f5c5SAndroid Build Coastguard Worker 
545*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
546*8975f5c5SAndroid Build Coastguard Worker     runCopyTexSubImageTest(GL_LUMINANCE, expected);
547*8975f5c5SAndroid Build Coastguard Worker }
548*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,SubImageRGBAToLA)549*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, SubImageRGBAToLA)
550*8975f5c5SAndroid Build Coastguard Worker {
551*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
552*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 127},
553*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 64},
554*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 191},
555*8975f5c5SAndroid Build Coastguard Worker     };
556*8975f5c5SAndroid Build Coastguard Worker 
557*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
558*8975f5c5SAndroid Build Coastguard Worker     runCopyTexSubImageTest(GL_LUMINANCE_ALPHA, expected);
559*8975f5c5SAndroid Build Coastguard Worker }
560*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,SubImageRGBToL)561*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, SubImageRGBToL)
562*8975f5c5SAndroid Build Coastguard Worker {
563*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
564*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 255},
565*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 255},
566*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 255},
567*8975f5c5SAndroid Build Coastguard Worker     };
568*8975f5c5SAndroid Build Coastguard Worker 
569*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGB, GL_UNSIGNED_BYTE);
570*8975f5c5SAndroid Build Coastguard Worker     runCopyTexSubImageTest(GL_LUMINANCE, expected);
571*8975f5c5SAndroid Build Coastguard Worker }
572*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CopyTexImageTest,RGBXToL)573*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, RGBXToL)
574*8975f5c5SAndroid Build Coastguard Worker {
575*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
576*8975f5c5SAndroid Build Coastguard Worker 
577*8975f5c5SAndroid Build Coastguard Worker     GLubyte expected[3][4] = {
578*8975f5c5SAndroid Build Coastguard Worker         {64, 64, 64, 255},
579*8975f5c5SAndroid Build Coastguard Worker         {255, 255, 255, 255},
580*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 255},
581*8975f5c5SAndroid Build Coastguard Worker     };
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBX8_ANGLE, GL_RGB, GL_UNSIGNED_BYTE, false);
584*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTest(GL_LUMINANCE, expected);
585*8975f5c5SAndroid Build Coastguard Worker }
586*8975f5c5SAndroid Build Coastguard Worker 
587*8975f5c5SAndroid Build Coastguard Worker // Read default framebuffer with glCopyTexImage2D().
TEST_P(CopyTexImageTest,DefaultFramebuffer)588*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, DefaultFramebuffer)
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker     // Seems to be a bug in Mesa with the GLX back end: cannot read framebuffer until we draw to it.
591*8975f5c5SAndroid Build Coastguard Worker     // glCopyTexImage2D() below will fail without this clear.
592*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
593*8975f5c5SAndroid Build Coastguard Worker 
594*8975f5c5SAndroid Build Coastguard Worker     const GLint w = getWindowWidth(), h = getWindowHeight();
595*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
596*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
597*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
598*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, w, h, 0);
599*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
600*8975f5c5SAndroid Build Coastguard Worker }
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker // Read default framebuffer with glCopyTexSubImage2D().
TEST_P(CopyTexImageTest,SubDefaultFramebuffer)603*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, SubDefaultFramebuffer)
604*8975f5c5SAndroid Build Coastguard Worker {
605*8975f5c5SAndroid Build Coastguard Worker     // Seems to be a bug in Mesa with the GLX back end: cannot read framebuffer until we draw to it.
606*8975f5c5SAndroid Build Coastguard Worker     // glCopyTexSubImage2D() below will fail without this clear.
607*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
608*8975f5c5SAndroid Build Coastguard Worker 
609*8975f5c5SAndroid Build Coastguard Worker     const GLint w = getWindowWidth(), h = getWindowHeight();
610*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
611*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
612*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
613*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
614*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
615*8975f5c5SAndroid Build Coastguard Worker }
616*8975f5c5SAndroid Build Coastguard Worker 
617*8975f5c5SAndroid Build Coastguard Worker // Calling CopyTexSubImage from cubeMap texture.
TEST_P(CopyTexImageTest,CopyTexSubImageFromCubeMap)618*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, CopyTexSubImageFromCubeMap)
619*8975f5c5SAndroid Build Coastguard Worker {
620*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kCubeMapFaceCount = 6;
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker     // The framebuffer will be a face of a cube map with a different colors for each face.  Each
623*8975f5c5SAndroid Build Coastguard Worker     // glCopyTexSubImage2D will take one face of this image to copy over a pixel in a 1x6
624*8975f5c5SAndroid Build Coastguard Worker     // framebuffer.
625*8975f5c5SAndroid Build Coastguard Worker     GLColor fboPixels[kCubeMapFaceCount]   = {GLColor::red,  GLColor::yellow, GLColor::green,
626*8975f5c5SAndroid Build Coastguard Worker                                               GLColor::cyan, GLColor::blue,   GLColor::magenta};
627*8975f5c5SAndroid Build Coastguard Worker     GLColor whitePixels[kCubeMapFaceCount] = {GLColor::white, GLColor::white, GLColor::white,
628*8975f5c5SAndroid Build Coastguard Worker                                               GLColor::white, GLColor::white, GLColor::white};
629*8975f5c5SAndroid Build Coastguard Worker 
630*8975f5c5SAndroid Build Coastguard Worker     GLTexture fboTex;
631*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, fboTex);
632*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
633*8975f5c5SAndroid Build Coastguard Worker          face++)
634*8975f5c5SAndroid Build Coastguard Worker     {
635*8975f5c5SAndroid Build Coastguard Worker         GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
636*8975f5c5SAndroid Build Coastguard Worker 
637*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &fboPixels[faceIndex]);
638*8975f5c5SAndroid Build Coastguard Worker     }
639*8975f5c5SAndroid Build Coastguard Worker 
640*8975f5c5SAndroid Build Coastguard Worker     GLTexture dstTex;
641*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, dstTex);
642*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeMapFaceCount, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
643*8975f5c5SAndroid Build Coastguard Worker                  whitePixels);
644*8975f5c5SAndroid Build Coastguard Worker 
645*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
646*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
647*8975f5c5SAndroid Build Coastguard Worker 
648*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
649*8975f5c5SAndroid Build Coastguard Worker          face++)
650*8975f5c5SAndroid Build Coastguard Worker     {
651*8975f5c5SAndroid Build Coastguard Worker         GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
652*8975f5c5SAndroid Build Coastguard Worker 
653*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, fboTex, 0);
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
656*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
657*8975f5c5SAndroid Build Coastguard Worker 
658*8975f5c5SAndroid Build Coastguard Worker         // Copy the fbo (a cube map face) into a pixel of the destination texture.
659*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, faceIndex, 0, 0, 0, 1, 1);
660*8975f5c5SAndroid Build Coastguard Worker     }
661*8975f5c5SAndroid Build Coastguard Worker 
662*8975f5c5SAndroid Build Coastguard Worker     // Make sure all the copies are done correctly.
663*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0);
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
666*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
667*8975f5c5SAndroid Build Coastguard Worker 
668*8975f5c5SAndroid Build Coastguard Worker     for (GLsizei faceIndex = 0; faceIndex < kCubeMapFaceCount; ++faceIndex)
669*8975f5c5SAndroid Build Coastguard Worker     {
670*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(faceIndex, 0, fboPixels[faceIndex]);
671*8975f5c5SAndroid Build Coastguard Worker     }
672*8975f5c5SAndroid Build Coastguard Worker }
673*8975f5c5SAndroid Build Coastguard Worker 
674*8975f5c5SAndroid Build Coastguard Worker // Calling CopyTexSubImage to a non-cube-complete texture.
TEST_P(CopyTexImageTest,CopyTexSubImageToNonCubeCompleteDestination)675*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, CopyTexSubImageToNonCubeCompleteDestination)
676*8975f5c5SAndroid Build Coastguard Worker {
677*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kCubeMapFaceCount = 6;
678*8975f5c5SAndroid Build Coastguard Worker 
679*8975f5c5SAndroid Build Coastguard Worker     // The framebuffer will be a 1x6 image with 6 different colors.  Each glCopyTexSubImage2D will
680*8975f5c5SAndroid Build Coastguard Worker     // take one pixel of this image to copy over each face of a cube map.
681*8975f5c5SAndroid Build Coastguard Worker     GLColor fboPixels[kCubeMapFaceCount] = {GLColor::red,  GLColor::yellow, GLColor::green,
682*8975f5c5SAndroid Build Coastguard Worker                                             GLColor::cyan, GLColor::blue,   GLColor::magenta};
683*8975f5c5SAndroid Build Coastguard Worker     GLColor whitePixel                   = GLColor::white;
684*8975f5c5SAndroid Build Coastguard Worker 
685*8975f5c5SAndroid Build Coastguard Worker     GLTexture fboTex;
686*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, fboTex);
687*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeMapFaceCount, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
688*8975f5c5SAndroid Build Coastguard Worker                  fboPixels);
689*8975f5c5SAndroid Build Coastguard Worker 
690*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
691*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
692*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
693*8975f5c5SAndroid Build Coastguard Worker 
694*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
695*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
696*8975f5c5SAndroid Build Coastguard Worker 
697*8975f5c5SAndroid Build Coastguard Worker     GLTexture cubeMap;
698*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMap);
699*8975f5c5SAndroid Build Coastguard Worker 
700*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
701*8975f5c5SAndroid Build Coastguard Worker          face++)
702*8975f5c5SAndroid Build Coastguard Worker     {
703*8975f5c5SAndroid Build Coastguard Worker         GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
704*8975f5c5SAndroid Build Coastguard Worker 
705*8975f5c5SAndroid Build Coastguard Worker         // Initialize the face with a color not found in the fbo.
706*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &whitePixel);
707*8975f5c5SAndroid Build Coastguard Worker 
708*8975f5c5SAndroid Build Coastguard Worker         // Copy one pixel from the fbo into this face.  The first 5 copies are done on a
709*8975f5c5SAndroid Build Coastguard Worker         // non-cube-complete texture.
710*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(face, 0, 0, 0, faceIndex, 0, 1, 1);
711*8975f5c5SAndroid Build Coastguard Worker     }
712*8975f5c5SAndroid Build Coastguard Worker 
713*8975f5c5SAndroid Build Coastguard Worker     // Make sure all the copies are done correctly.
714*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
715*8975f5c5SAndroid Build Coastguard Worker          face++)
716*8975f5c5SAndroid Build Coastguard Worker     {
717*8975f5c5SAndroid Build Coastguard Worker         GLsizei faceIndex = face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
718*8975f5c5SAndroid Build Coastguard Worker 
719*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, cubeMap, 0);
720*8975f5c5SAndroid Build Coastguard Worker 
721*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
722*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
723*8975f5c5SAndroid Build Coastguard Worker 
724*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, fboPixels[faceIndex]);
725*8975f5c5SAndroid Build Coastguard Worker     }
726*8975f5c5SAndroid Build Coastguard Worker }
727*8975f5c5SAndroid Build Coastguard Worker 
728*8975f5c5SAndroid Build Coastguard Worker // Deleting textures after copying to them. http://anglebug.com/40644715
TEST_P(CopyTexImageTest,DeleteAfterCopyingToTextures)729*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, DeleteAfterCopyingToTextures)
730*8975f5c5SAndroid Build Coastguard Worker {
731*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
732*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
733*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
734*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
735*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
736*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
737*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
738*8975f5c5SAndroid Build Coastguard Worker 
739*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture2;
740*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture2);
741*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
742*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
743*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
744*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
745*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
746*8975f5c5SAndroid Build Coastguard Worker 
747*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
748*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
749*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
750*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
751*8975f5c5SAndroid Build Coastguard Worker 
752*8975f5c5SAndroid Build Coastguard Worker     // Perform CopyTexImage2D
753*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
754*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 0, 0, 2, 2, 0);
755*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
756*8975f5c5SAndroid Build Coastguard Worker     // Not necessary to do any CopyTexImage2D operations to texture2.
757*8975f5c5SAndroid Build Coastguard Worker 
758*8975f5c5SAndroid Build Coastguard Worker     // Perform CopyTexSubImage2D
759*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
760*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 0, 0, 1, 1);
761*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
762*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture2);
763*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
764*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
765*8975f5c5SAndroid Build Coastguard Worker 
766*8975f5c5SAndroid Build Coastguard Worker     // Clean up - provokes crash on buggy drivers.
767*8975f5c5SAndroid Build Coastguard Worker     texture.reset();
768*8975f5c5SAndroid Build Coastguard Worker     // Crashes on Intel GPUs on macOS.
769*8975f5c5SAndroid Build Coastguard Worker     texture2.reset();
770*8975f5c5SAndroid Build Coastguard Worker }
771*8975f5c5SAndroid Build Coastguard Worker 
772*8975f5c5SAndroid Build Coastguard Worker // Test if glCopyTexImage2D() implementation performs conversions well from GL_TEXTURE_3D to
773*8975f5c5SAndroid Build Coastguard Worker // GL_TEXTURE_2D.
774*8975f5c5SAndroid Build Coastguard Worker // This is similar to CopyTexImageTestES3.CopyTexSubImageFromTexture3D but for GL_OES_texture_3D
775*8975f5c5SAndroid Build Coastguard Worker // extension.
TEST_P(CopyTexImageTest,CopyTexSubImageFrom3DTexureOES)776*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, CopyTexSubImageFrom3DTexureOES)
777*8975f5c5SAndroid Build Coastguard Worker {
778*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_3D"));
779*8975f5c5SAndroid Build Coastguard Worker     // TODO(anglebug.com/42262446)
780*8975f5c5SAndroid Build Coastguard Worker     // Seems to fail on D3D11 Windows.
781*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11() && IsWindows());
782*8975f5c5SAndroid Build Coastguard Worker 
783*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263501
784*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF((IsPixel2() || IsNexus5X()) && IsOpenGLES());
785*8975f5c5SAndroid Build Coastguard Worker 
786*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kDepth = 6;
787*8975f5c5SAndroid Build Coastguard Worker 
788*8975f5c5SAndroid Build Coastguard Worker     // The framebuffer will be a slice of a 3d texture with a different colors for each slice.  Each
789*8975f5c5SAndroid Build Coastguard Worker     // glCopyTexSubImage2D will take one face of this image to copy over a pixel in a 1x6
790*8975f5c5SAndroid Build Coastguard Worker     // framebuffer.
791*8975f5c5SAndroid Build Coastguard Worker     GLColor fboPixels[kDepth]   = {GLColor::red,  GLColor::yellow, GLColor::green,
792*8975f5c5SAndroid Build Coastguard Worker                                    GLColor::cyan, GLColor::blue,   GLColor::magenta};
793*8975f5c5SAndroid Build Coastguard Worker     GLColor whitePixels[kDepth] = {GLColor::white, GLColor::white, GLColor::white,
794*8975f5c5SAndroid Build Coastguard Worker                                    GLColor::white, GLColor::white, GLColor::white};
795*8975f5c5SAndroid Build Coastguard Worker 
796*8975f5c5SAndroid Build Coastguard Worker     GLTexture fboTex;
797*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, fboTex);
798*8975f5c5SAndroid Build Coastguard Worker     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, kDepth, 0, GL_RGBA, GL_UNSIGNED_BYTE,
799*8975f5c5SAndroid Build Coastguard Worker                     fboPixels);
800*8975f5c5SAndroid Build Coastguard Worker 
801*8975f5c5SAndroid Build Coastguard Worker     GLTexture dstTex;
802*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, dstTex);
803*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kDepth, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, whitePixels);
804*8975f5c5SAndroid Build Coastguard Worker 
805*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
806*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
807*8975f5c5SAndroid Build Coastguard Worker 
808*8975f5c5SAndroid Build Coastguard Worker     for (GLsizei slice = 0; slice < kDepth; ++slice)
809*8975f5c5SAndroid Build Coastguard Worker     {
810*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture3DOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, fboTex, 0,
811*8975f5c5SAndroid Build Coastguard Worker                                   slice);
812*8975f5c5SAndroid Build Coastguard Worker 
813*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
814*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
815*8975f5c5SAndroid Build Coastguard Worker 
816*8975f5c5SAndroid Build Coastguard Worker         // Copy the fbo (a 3d slice) into a pixel of the destination texture.
817*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, slice, 0, 0, 0, 1, 1);
818*8975f5c5SAndroid Build Coastguard Worker     }
819*8975f5c5SAndroid Build Coastguard Worker 
820*8975f5c5SAndroid Build Coastguard Worker     // Make sure all the copies are done correctly.
821*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0);
822*8975f5c5SAndroid Build Coastguard Worker 
823*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
824*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
825*8975f5c5SAndroid Build Coastguard Worker 
826*8975f5c5SAndroid Build Coastguard Worker     for (GLsizei slice = 0; slice < kDepth; ++slice)
827*8975f5c5SAndroid Build Coastguard Worker     {
828*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(slice, 0, fboPixels[slice]);
829*8975f5c5SAndroid Build Coastguard Worker     }
830*8975f5c5SAndroid Build Coastguard Worker }
831*8975f5c5SAndroid Build Coastguard Worker 
832*8975f5c5SAndroid Build Coastguard Worker // Tests image copy from y-flipped fbo works.
TEST_P(CopyTexImageTest,CopyTexImageMesaYFlip)833*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, CopyTexImageMesaYFlip)
834*8975f5c5SAndroid Build Coastguard Worker {
835*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
836*8975f5c5SAndroid Build Coastguard Worker 
837*8975f5c5SAndroid Build Coastguard Worker     std::array<uint32_t, 3> copyOrigin{0};
838*8975f5c5SAndroid Build Coastguard Worker     std::array<uint32_t, 3> copySize;
839*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < kFboCount; i++)
840*8975f5c5SAndroid Build Coastguard Worker         copySize[i] = kFboSizes[i];
841*8975f5c5SAndroid Build Coastguard Worker 
842*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
843*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTestCheckered(GL_RGBA, copyOrigin.data(), copyOrigin.data(), copySize.data(),
844*8975f5c5SAndroid Build Coastguard Worker                                  copySize.data(), GLColor::green.data(), GLColor::red.data(),
845*8975f5c5SAndroid Build Coastguard Worker                                  GLColor::yellow.data(), GLColor::blue.data(),
846*8975f5c5SAndroid Build Coastguard Worker                                  true /* mesaFlipY */);
847*8975f5c5SAndroid Build Coastguard Worker }
848*8975f5c5SAndroid Build Coastguard Worker 
849*8975f5c5SAndroid Build Coastguard Worker // Tests image partial copy from y-flipped fbo works.
TEST_P(CopyTexImageTest,CopyTexImageMesaYFlipPartial)850*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, CopyTexImageMesaYFlipPartial)
851*8975f5c5SAndroid Build Coastguard Worker {
852*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
853*8975f5c5SAndroid Build Coastguard Worker 
854*8975f5c5SAndroid Build Coastguard Worker     std::array<uint32_t, kFboCount> copyX;
855*8975f5c5SAndroid Build Coastguard Worker     std::array<uint32_t, kFboCount> copyY{0};
856*8975f5c5SAndroid Build Coastguard Worker     std::array<uint32_t, kFboCount> copyWidth;
857*8975f5c5SAndroid Build Coastguard Worker     std::array<uint32_t, kFboCount> copyHeight;
858*8975f5c5SAndroid Build Coastguard Worker 
859*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < kFboCount; i++)
860*8975f5c5SAndroid Build Coastguard Worker     {
861*8975f5c5SAndroid Build Coastguard Worker         copyX[i]      = kFboSizes[i] / 2;
862*8975f5c5SAndroid Build Coastguard Worker         copyHeight[i] = kFboSizes[i];
863*8975f5c5SAndroid Build Coastguard Worker     }
864*8975f5c5SAndroid Build Coastguard Worker     copyWidth = copyX;
865*8975f5c5SAndroid Build Coastguard Worker 
866*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
867*8975f5c5SAndroid Build Coastguard Worker     runCopyTexImageTestCheckered(GL_RGBA, copyX.data(), copyY.data(), copyWidth.data(),
868*8975f5c5SAndroid Build Coastguard Worker                                  copyHeight.data(), GLColor::yellow.data(), GLColor::blue.data(),
869*8975f5c5SAndroid Build Coastguard Worker                                  GLColor::yellow.data(), GLColor::blue.data(),
870*8975f5c5SAndroid Build Coastguard Worker                                  true /* mesaFlipY */);
871*8975f5c5SAndroid Build Coastguard Worker }
872*8975f5c5SAndroid Build Coastguard Worker 
873*8975f5c5SAndroid Build Coastguard Worker // Tests subimage copy from y-flipped fbo works.
TEST_P(CopyTexImageTest,CopyTexSubImageMesaYFlip)874*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, CopyTexSubImageMesaYFlip)
875*8975f5c5SAndroid Build Coastguard Worker {
876*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
877*8975f5c5SAndroid Build Coastguard Worker 
878*8975f5c5SAndroid Build Coastguard Worker     GLuint format = GL_RGBA;
879*8975f5c5SAndroid Build Coastguard Worker     initializeResources(format, GL_UNSIGNED_BYTE);
880*8975f5c5SAndroid Build Coastguard Worker 
881*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, kFboSizes[0], kFboSizes[0]);
882*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, mFbos[0]);
883*8975f5c5SAndroid Build Coastguard Worker 
884*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
885*8975f5c5SAndroid Build Coastguard Worker                      essl1_shaders::fs::Checkered());
886*8975f5c5SAndroid Build Coastguard Worker     drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
887*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
888*8975f5c5SAndroid Build Coastguard Worker 
889*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
890*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
891*8975f5c5SAndroid Build Coastguard Worker 
892*8975f5c5SAndroid Build Coastguard Worker     // Disable mipmapping
893*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
894*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
895*8975f5c5SAndroid Build Coastguard Worker 
896*8975f5c5SAndroid Build Coastguard Worker     // Create the texture with copy of the first fbo.
897*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, mFbos[0]);
898*8975f5c5SAndroid Build Coastguard Worker     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
899*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, kFboSizes[0], kFboSizes[0], 0);
900*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
901*8975f5c5SAndroid Build Coastguard Worker 
902*8975f5c5SAndroid Build Coastguard Worker     // Make sure out-of-bound writes to the texture return invalid value.
903*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, mFbos[1]);
904*8975f5c5SAndroid Build Coastguard Worker     drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
905*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
906*8975f5c5SAndroid Build Coastguard Worker 
907*8975f5c5SAndroid Build Coastguard Worker     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
908*8975f5c5SAndroid Build Coastguard Worker 
909*8975f5c5SAndroid Build Coastguard Worker     // xoffset < 0 and yoffset < 0
910*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, -1, -1, 0, 0, kFboSizes[0], kFboSizes[0]);
911*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_ERROR(GL_INVALID_VALUE);
912*8975f5c5SAndroid Build Coastguard Worker 
913*8975f5c5SAndroid Build Coastguard Worker     // xoffset + width > w and yoffset + height > h
914*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 0, 0, kFboSizes[0], kFboSizes[0]);
915*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_ERROR(GL_INVALID_VALUE);
916*8975f5c5SAndroid Build Coastguard Worker 
917*8975f5c5SAndroid Build Coastguard Worker     // xoffset + width > w and yoffset + height > h, out of bounds
918*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, -1, -1, 1 + kFboSizes[0], 1 + kFboSizes[0]);
919*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_ERROR(GL_INVALID_VALUE);
920*8975f5c5SAndroid Build Coastguard Worker 
921*8975f5c5SAndroid Build Coastguard Worker     // Copy the second fbo over a portion of the image.
922*8975f5c5SAndroid Build Coastguard Worker     GLint offset = kFboSizes[0] / 2;
923*8975f5c5SAndroid Build Coastguard Worker     GLint extent = kFboSizes[0] - offset;
924*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, offset, offset, kFboSizes[1] / 2, kFboSizes[1] / 2,
925*8975f5c5SAndroid Build Coastguard Worker                         extent, extent);
926*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
927*8975f5c5SAndroid Build Coastguard Worker 
928*8975f5c5SAndroid Build Coastguard Worker     // Only part of the image is changed.
929*8975f5c5SAndroid Build Coastguard Worker     verifyCheckeredResults(tex, GLColor::green.data(), GLColor::red.data(), GLColor::yellow.data(),
930*8975f5c5SAndroid Build Coastguard Worker                            GLColor::blue.data(), kFboSizes[0], kFboSizes[0]);
931*8975f5c5SAndroid Build Coastguard Worker }
932*8975f5c5SAndroid Build Coastguard Worker 
933*8975f5c5SAndroid Build Coastguard Worker // Tests that set RobustResourceInit to true, so that code path with
934*8975f5c5SAndroid Build Coastguard Worker // RobustResourceInit == true can be checked
935*8975f5c5SAndroid Build Coastguard Worker class CopyTexImageTestRobustResourceInit : public CopyTexImageTest
936*8975f5c5SAndroid Build Coastguard Worker {
937*8975f5c5SAndroid Build Coastguard Worker   protected:
CopyTexImageTestRobustResourceInit()938*8975f5c5SAndroid Build Coastguard Worker     CopyTexImageTestRobustResourceInit() : CopyTexImageTest() { setRobustResourceInit(true); }
939*8975f5c5SAndroid Build Coastguard Worker };
940*8975f5c5SAndroid Build Coastguard Worker 
941*8975f5c5SAndroid Build Coastguard Worker // Adapted from the fuzz test with invalid input
TEST_P(CopyTexImageTestRobustResourceInit,InvalidInputParam)942*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestRobustResourceInit, InvalidInputParam)
943*8975f5c5SAndroid Build Coastguard Worker {
944*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
945*8975f5c5SAndroid Build Coastguard Worker 
946*8975f5c5SAndroid Build Coastguard Worker     const GLint w = getWindowWidth(), h = getWindowHeight();
947*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
948*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
949*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
950*8975f5c5SAndroid Build Coastguard Worker 
951*8975f5c5SAndroid Build Coastguard Worker     // pass y that is greater than max2DTextureSize
952*8975f5c5SAndroid Build Coastguard Worker     GLenum target         = GL_TEXTURE_2D;
953*8975f5c5SAndroid Build Coastguard Worker     GLint level           = 0;
954*8975f5c5SAndroid Build Coastguard Worker     GLenum internalFormat = GL_LUMINANCE_ALPHA;
955*8975f5c5SAndroid Build Coastguard Worker     GLint x               = 0;
956*8975f5c5SAndroid Build Coastguard Worker     GLint y               = 13434880;
957*8975f5c5SAndroid Build Coastguard Worker     GLsizei width         = 0;
958*8975f5c5SAndroid Build Coastguard Worker     GLsizei height        = 65830;
959*8975f5c5SAndroid Build Coastguard Worker     GLint border          = 0;
960*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
961*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_VALUE);
962*8975f5c5SAndroid Build Coastguard Worker 
963*8975f5c5SAndroid Build Coastguard Worker     // pass x and width that will result in integer overflow when we apply x+width
964*8975f5c5SAndroid Build Coastguard Worker     target         = GL_TEXTURE_2D;
965*8975f5c5SAndroid Build Coastguard Worker     level          = 0;
966*8975f5c5SAndroid Build Coastguard Worker     internalFormat = GL_LUMINANCE_ALPHA;
967*8975f5c5SAndroid Build Coastguard Worker     x              = std::numeric_limits<GLint>::max();
968*8975f5c5SAndroid Build Coastguard Worker     y              = 0;
969*8975f5c5SAndroid Build Coastguard Worker     width          = 253;
970*8975f5c5SAndroid Build Coastguard Worker     height         = 1;
971*8975f5c5SAndroid Build Coastguard Worker     border         = 0;
972*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
973*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_VALUE);
974*8975f5c5SAndroid Build Coastguard Worker }
975*8975f5c5SAndroid Build Coastguard Worker 
976*8975f5c5SAndroid Build Coastguard Worker // specialization of CopyTexImageTest is added so that some tests can be explicitly run with an ES3
977*8975f5c5SAndroid Build Coastguard Worker // context
978*8975f5c5SAndroid Build Coastguard Worker class CopyTexImageTestES3 : public CopyTexImageTest
979*8975f5c5SAndroid Build Coastguard Worker {
980*8975f5c5SAndroid Build Coastguard Worker   protected:
981*8975f5c5SAndroid Build Coastguard Worker     void initialize3DTexture(GLTexture &texture,
982*8975f5c5SAndroid Build Coastguard Worker                              const GLsizei imageWidth,
983*8975f5c5SAndroid Build Coastguard Worker                              const GLsizei imageHeight,
984*8975f5c5SAndroid Build Coastguard Worker                              const GLsizei imageDepth,
985*8975f5c5SAndroid Build Coastguard Worker                              const GLColor *textureData);
986*8975f5c5SAndroid Build Coastguard Worker     void initialize2DTexture(GLTexture &texture,
987*8975f5c5SAndroid Build Coastguard Worker                              const GLsizei imageWidth,
988*8975f5c5SAndroid Build Coastguard Worker                              const GLsizei imageHeight,
989*8975f5c5SAndroid Build Coastguard Worker                              const GLColor *textureData);
990*8975f5c5SAndroid Build Coastguard Worker     void initialize2DTextureUShort4444(GLTexture &texture,
991*8975f5c5SAndroid Build Coastguard Worker                                        const GLsizei imageWidth,
992*8975f5c5SAndroid Build Coastguard Worker                                        const GLsizei imageHeight,
993*8975f5c5SAndroid Build Coastguard Worker                                        const GLColor *textureData);
994*8975f5c5SAndroid Build Coastguard Worker     void fillTexture(std::vector<GLColor> &texture, const GLColor color);
995*8975f5c5SAndroid Build Coastguard Worker     void clearTexture(GLFramebuffer &fbo, GLTexture &texture, const GLColor color);
996*8975f5c5SAndroid Build Coastguard Worker     void copyTexSubImage3D(GLTexture &subTexture2D,
997*8975f5c5SAndroid Build Coastguard Worker                            const GLint xOffset,
998*8975f5c5SAndroid Build Coastguard Worker                            const GLint yOffset,
999*8975f5c5SAndroid Build Coastguard Worker                            const GLsizei subImageWidth,
1000*8975f5c5SAndroid Build Coastguard Worker                            const GLsizei subImageHeight,
1001*8975f5c5SAndroid Build Coastguard Worker                            const GLsizei imageDepth);
1002*8975f5c5SAndroid Build Coastguard Worker     void verifyCopyTexSubImage3D(GLTexture &texture3D,
1003*8975f5c5SAndroid Build Coastguard Worker                                  const GLint xOffset,
1004*8975f5c5SAndroid Build Coastguard Worker                                  const GLint yOffset,
1005*8975f5c5SAndroid Build Coastguard Worker                                  const GLColor subImageColor);
1006*8975f5c5SAndroid Build Coastguard Worker 
1007*8975f5c5SAndroid Build Coastguard Worker     // Constants
1008*8975f5c5SAndroid Build Coastguard Worker     const GLColor kSubImageColor = GLColor::yellow;
1009*8975f5c5SAndroid Build Coastguard Worker     // 3D image dimensions
1010*8975f5c5SAndroid Build Coastguard Worker     const GLsizei kImageWidth  = getWindowWidth();
1011*8975f5c5SAndroid Build Coastguard Worker     const GLsizei kImageHeight = getWindowHeight();
1012*8975f5c5SAndroid Build Coastguard Worker     const GLsizei kImageDepth  = 4;
1013*8975f5c5SAndroid Build Coastguard Worker     // 2D sub-image dimensions
1014*8975f5c5SAndroid Build Coastguard Worker     const GLsizei kSubImageWidth  = getWindowWidth() / 4;
1015*8975f5c5SAndroid Build Coastguard Worker     const GLsizei kSubImageHeight = getWindowHeight() / 4;
1016*8975f5c5SAndroid Build Coastguard Worker     // Sub-Image Offsets
1017*8975f5c5SAndroid Build Coastguard Worker     const GLint kXOffset = getWindowWidth() - kSubImageWidth;
1018*8975f5c5SAndroid Build Coastguard Worker     const GLint kYOffset = getWindowHeight() - kSubImageHeight;
1019*8975f5c5SAndroid Build Coastguard Worker };
1020*8975f5c5SAndroid Build Coastguard Worker 
1021*8975f5c5SAndroid Build Coastguard Worker //  The test verifies that glCopyTexSubImage2D generates a GL_INVALID_OPERATION error
1022*8975f5c5SAndroid Build Coastguard Worker //  when the read buffer is GL_NONE.
1023*8975f5c5SAndroid Build Coastguard Worker //  Reference: GLES 3.0.4, Section 3.8.5 Alternate Texture Image Specification Commands
TEST_P(CopyTexImageTestES3,ReadBufferIsNone)1024*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, ReadBufferIsNone)
1025*8975f5c5SAndroid Build Coastguard Worker {
1026*8975f5c5SAndroid Build Coastguard Worker     initializeResources(GL_RGBA, GL_UNSIGNED_BYTE);
1027*8975f5c5SAndroid Build Coastguard Worker 
1028*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
1029*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
1030*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1031*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1032*8975f5c5SAndroid Build Coastguard Worker 
1033*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, mFbos[0]);
1034*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kFboSizes[0], kFboSizes[0], 0);
1035*8975f5c5SAndroid Build Coastguard Worker 
1036*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_NONE);
1037*8975f5c5SAndroid Build Coastguard Worker 
1038*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1039*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
1040*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1041*8975f5c5SAndroid Build Coastguard Worker }
1042*8975f5c5SAndroid Build Coastguard Worker 
1043*8975f5c5SAndroid Build Coastguard Worker // Test CopyTexImage3D with some simple parameters with a 2D array texture.
1044*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, 2DArraySubImage)
1045*8975f5c5SAndroid Build Coastguard Worker {
1046*8975f5c5SAndroid Build Coastguard Worker     // Seems to fail on AMD OpenGL Windows.
1047*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() && IsWindows());
1048*8975f5c5SAndroid Build Coastguard Worker 
1049*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
1050*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1051*8975f5c5SAndroid Build Coastguard Worker 
1052*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kTexSize     = 4;
1053*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kLayerOffset = 1;
1054*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kLayers      = 2;
1055*8975f5c5SAndroid Build Coastguard Worker 
1056*8975f5c5SAndroid Build Coastguard Worker     // Clear screen to green.
1057*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0, 1, 0, 1);
1058*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1059*8975f5c5SAndroid Build Coastguard Worker 
1060*8975f5c5SAndroid Build Coastguard Worker     // Initialize a two-layer 2D array texture with red.
1061*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> red(kTexSize * kTexSize * kLayers, GLColor::red);
1062*8975f5c5SAndroid Build Coastguard Worker     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kTexSize, kTexSize, kLayers, 0, GL_RGBA,
1063*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, red.data());
1064*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, kLayerOffset, 0, 0, kTexSize, kTexSize);
1065*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1066*8975f5c5SAndroid Build Coastguard Worker 
1067*8975f5c5SAndroid Build Coastguard Worker     // Check level 0 (red from image data) and 1 (green from backbuffer clear).
1068*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1069*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1070*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
1071*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1072*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
1073*8975f5c5SAndroid Build Coastguard Worker     for (int x = 0; x < kTexSize; x++)
1074*8975f5c5SAndroid Build Coastguard Worker     {
1075*8975f5c5SAndroid Build Coastguard Worker         for (int y = 0; y < kTexSize; y++)
1076*8975f5c5SAndroid Build Coastguard Worker         {
1077*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
1078*8975f5c5SAndroid Build Coastguard Worker         }
1079*8975f5c5SAndroid Build Coastguard Worker     }
1080*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1081*8975f5c5SAndroid Build Coastguard Worker }
1082*8975f5c5SAndroid Build Coastguard Worker 
1083*8975f5c5SAndroid Build Coastguard Worker // Test if glCopyTexImage2D() implementation performs conversions well from GL_TEXTURE_3D to
1084*8975f5c5SAndroid Build Coastguard Worker // GL_TEXTURE_2D.
TEST_P(CopyTexImageTestES3,CopyTexSubImageFromTexture3D)1085*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, CopyTexSubImageFromTexture3D)
1086*8975f5c5SAndroid Build Coastguard Worker {
1087*8975f5c5SAndroid Build Coastguard Worker     // TODO(anglebug.com/42262446)
1088*8975f5c5SAndroid Build Coastguard Worker     // Seems to fail on D3D11 Windows.
1089*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11() && IsWindows());
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kTexSize = 4;
1092*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kLayers  = 2;
1093*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> red(kTexSize * kTexSize * kLayers, GLColor::red);
1094*8975f5c5SAndroid Build Coastguard Worker 
1095*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1096*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1097*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1098*8975f5c5SAndroid Build Coastguard Worker 
1099*8975f5c5SAndroid Build Coastguard Worker     // We will be reading from zeroth color attachment.
1100*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1101*8975f5c5SAndroid Build Coastguard Worker 
1102*8975f5c5SAndroid Build Coastguard Worker     GLTexture src_object_id;
1103*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, src_object_id);
1104*8975f5c5SAndroid Build Coastguard Worker     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kTexSize, kTexSize, kLayers, 0, GL_RGBA,
1105*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, NULL);
1106*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, kTexSize, kTexSize, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1107*8975f5c5SAndroid Build Coastguard Worker                     red.data());
1108*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, src_object_id, 0, 1);
1109*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1110*8975f5c5SAndroid Build Coastguard Worker 
1111*8975f5c5SAndroid Build Coastguard Worker     GLTexture dst_object_id;
1112*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, dst_object_id);
1113*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, kTexSize, kTexSize, 0);
1114*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_object_id,
1115*8975f5c5SAndroid Build Coastguard Worker                            0);
1116*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1117*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1118*8975f5c5SAndroid Build Coastguard Worker }
1119*8975f5c5SAndroid Build Coastguard Worker 
1120*8975f5c5SAndroid Build Coastguard Worker // Test that copying a 3D texture slice into another 3D texture slice via framebuffer works
TEST_P(CopyTexImageTestES3,CopyTexSubImage3DFromTexture3D)1121*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, CopyTexSubImage3DFromTexture3D)
1122*8975f5c5SAndroid Build Coastguard Worker {
1123*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kTexSize = 4;
1124*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kLayers  = 2;
1125*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> red(kTexSize * kTexSize, GLColor::red);
1126*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> green(kTexSize * kTexSize, GLColor::green);
1127*8975f5c5SAndroid Build Coastguard Worker 
1128*8975f5c5SAndroid Build Coastguard Worker     GLTexture srcTex;
1129*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, srcTex);
1130*8975f5c5SAndroid Build Coastguard Worker     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kTexSize, kTexSize, kLayers, 0, GL_RGBA,
1131*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
1132*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kTexSize, kTexSize, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1133*8975f5c5SAndroid Build Coastguard Worker                     red.data());
1134*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, kTexSize, kTexSize, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1135*8975f5c5SAndroid Build Coastguard Worker                     green.data());
1136*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1137*8975f5c5SAndroid Build Coastguard Worker 
1138*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1139*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1140*8975f5c5SAndroid Build Coastguard Worker 
1141*8975f5c5SAndroid Build Coastguard Worker     GLTexture dstTex;
1142*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, dstTex);
1143*8975f5c5SAndroid Build Coastguard Worker     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kTexSize, kTexSize, kLayers, 0, GL_RGBA,
1144*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
1145*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1146*8975f5c5SAndroid Build Coastguard Worker 
1147*8975f5c5SAndroid Build Coastguard Worker     // Copy while swapping the layers
1148*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTex, 0, 0);
1149*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, 0, 0, kTexSize, kTexSize);
1150*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTex, 0, 1);
1151*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, kTexSize, kTexSize);
1152*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1153*8975f5c5SAndroid Build Coastguard Worker 
1154*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTex, 0, 0);
1155*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1156*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTex, 0, 1);
1157*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1158*8975f5c5SAndroid Build Coastguard Worker }
1159*8975f5c5SAndroid Build Coastguard Worker 
1160*8975f5c5SAndroid Build Coastguard Worker // Test that copying from a non-zero base texture works.
TEST_P(CopyTexImageTestES3,CopyTexSubImageFromNonZeroBase)1161*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, CopyTexSubImageFromNonZeroBase)
1162*8975f5c5SAndroid Build Coastguard Worker {
1163*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40644750
1164*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
1165*8975f5c5SAndroid Build Coastguard Worker 
1166*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kTexSize = 4;
1167*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> red(kTexSize * kTexSize, GLColor::red);
1168*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> green(kTexSize * kTexSize, GLColor::green);
1169*8975f5c5SAndroid Build Coastguard Worker 
1170*8975f5c5SAndroid Build Coastguard Worker     // Create a framebuffer attached to a non-zero base texture
1171*8975f5c5SAndroid Build Coastguard Worker     GLTexture srcColor;
1172*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, srcColor);
1173*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1174*8975f5c5SAndroid Build Coastguard Worker                  red.data());
1175*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1176*8975f5c5SAndroid Build Coastguard Worker                  green.data());
1177*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1178*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1179*8975f5c5SAndroid Build Coastguard Worker 
1180*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1181*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1182*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 1);
1183*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1184*8975f5c5SAndroid Build Coastguard Worker 
1185*8975f5c5SAndroid Build Coastguard Worker     // Create a texture with an identical format
1186*8975f5c5SAndroid Build Coastguard Worker     GLTexture dstColor;
1187*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, dstColor);
1188*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1189*8975f5c5SAndroid Build Coastguard Worker                  nullptr);
1190*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1191*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1192*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1193*8975f5c5SAndroid Build Coastguard Worker 
1194*8975f5c5SAndroid Build Coastguard Worker     // Copy into a part of this texture.
1195*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTexSize / 2, kTexSize / 2);
1196*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1197*8975f5c5SAndroid Build Coastguard Worker 
1198*8975f5c5SAndroid Build Coastguard Worker     // Verify it.
1199*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLubyte, 4> kExpected = {0, 255, 0, 255};
1200*8975f5c5SAndroid Build Coastguard Worker     verifyResults(dstColor, kExpected.data(), kTexSize, 0, 0, kTexSize / 2, kTexSize / 2, 1.0);
1201*8975f5c5SAndroid Build Coastguard Worker 
1202*8975f5c5SAndroid Build Coastguard Worker     // Copy into another part of the texture.  The previous verification ensures that the texture's
1203*8975f5c5SAndroid Build Coastguard Worker     // internal image is allocated, so this should be a direct copy.
1204*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1205*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kTexSize / 2, kTexSize / 2, 0, 0, kTexSize / 2,
1206*8975f5c5SAndroid Build Coastguard Worker                         kTexSize / 2);
1207*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1208*8975f5c5SAndroid Build Coastguard Worker 
1209*8975f5c5SAndroid Build Coastguard Worker     // Verify it.
1210*8975f5c5SAndroid Build Coastguard Worker     verifyResults(dstColor, kExpected.data(), kTexSize, kTexSize / 2, kTexSize / 2, kTexSize,
1211*8975f5c5SAndroid Build Coastguard Worker                   kTexSize, 1.0);
1212*8975f5c5SAndroid Build Coastguard Worker }
1213*8975f5c5SAndroid Build Coastguard Worker 
1214*8975f5c5SAndroid Build Coastguard Worker // Test that copying into a non-zero base texture works.
TEST_P(CopyTexImageTestES3,CopyTexSubImageToNonZeroBase)1215*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, CopyTexSubImageToNonZeroBase)
1216*8975f5c5SAndroid Build Coastguard Worker {
1217*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40644750
1218*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
1219*8975f5c5SAndroid Build Coastguard Worker 
1220*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kTexSize = 4;
1221*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> green(kTexSize * kTexSize, GLColor::green);
1222*8975f5c5SAndroid Build Coastguard Worker 
1223*8975f5c5SAndroid Build Coastguard Worker     // Create a framebuffer attached to a non-zero base texture
1224*8975f5c5SAndroid Build Coastguard Worker     GLTexture srcColor;
1225*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, srcColor);
1226*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1227*8975f5c5SAndroid Build Coastguard Worker                  green.data());
1228*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1229*8975f5c5SAndroid Build Coastguard Worker 
1230*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1231*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1232*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 0);
1233*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1234*8975f5c5SAndroid Build Coastguard Worker 
1235*8975f5c5SAndroid Build Coastguard Worker     // Create a texture with an identical format
1236*8975f5c5SAndroid Build Coastguard Worker     GLTexture dstColor;
1237*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, dstColor);
1238*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1239*8975f5c5SAndroid Build Coastguard Worker                  nullptr);
1240*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1241*8975f5c5SAndroid Build Coastguard Worker                  nullptr);
1242*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1243*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1244*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1245*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1246*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1247*8975f5c5SAndroid Build Coastguard Worker 
1248*8975f5c5SAndroid Build Coastguard Worker     // Copy into a part of this texture.
1249*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kTexSize / 2, kTexSize / 2);
1250*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1251*8975f5c5SAndroid Build Coastguard Worker 
1252*8975f5c5SAndroid Build Coastguard Worker     // Verify it.
1253*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLubyte, 4> kExpected = {0, 255, 0, 255};
1254*8975f5c5SAndroid Build Coastguard Worker     verifyResults(dstColor, kExpected.data(), kTexSize, 0, 0, kTexSize / 2, kTexSize / 2, 1.0);
1255*8975f5c5SAndroid Build Coastguard Worker 
1256*8975f5c5SAndroid Build Coastguard Worker     // Copy into another part of the texture.  The previous verification ensures that the texture's
1257*8975f5c5SAndroid Build Coastguard Worker     // internal image is allocated, so this should be a direct copy.
1258*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1259*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 1, kTexSize / 2, kTexSize / 2, 0, 0, kTexSize / 2,
1260*8975f5c5SAndroid Build Coastguard Worker                         kTexSize / 2);
1261*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1262*8975f5c5SAndroid Build Coastguard Worker 
1263*8975f5c5SAndroid Build Coastguard Worker     // Verify it.
1264*8975f5c5SAndroid Build Coastguard Worker     verifyResults(dstColor, kExpected.data(), kTexSize, kTexSize / 2, kTexSize / 2, kTexSize,
1265*8975f5c5SAndroid Build Coastguard Worker                   kTexSize, 1.0);
1266*8975f5c5SAndroid Build Coastguard Worker }
1267*8975f5c5SAndroid Build Coastguard Worker 
1268*8975f5c5SAndroid Build Coastguard Worker // Initialize the 3D texture we will copy the subImage data into
initialize3DTexture(GLTexture & texture,const GLsizei imageWidth,const GLsizei imageHeight,const GLsizei imageDepth,const GLColor * textureData)1269*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::initialize3DTexture(GLTexture &texture,
1270*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei imageWidth,
1271*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei imageHeight,
1272*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei imageDepth,
1273*8975f5c5SAndroid Build Coastguard Worker                                               const GLColor *textureData)
1274*8975f5c5SAndroid Build Coastguard Worker {
1275*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, texture);
1276*8975f5c5SAndroid Build Coastguard Worker     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, imageWidth, imageHeight, imageDepth, 0, GL_RGBA,
1277*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, textureData);
1278*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1279*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1280*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
1281*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1282*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1283*8975f5c5SAndroid Build Coastguard Worker }
1284*8975f5c5SAndroid Build Coastguard Worker 
initialize2DTexture(GLTexture & texture,const GLsizei imageWidth,const GLsizei imageHeight,const GLColor * textureData)1285*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::initialize2DTexture(GLTexture &texture,
1286*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei imageWidth,
1287*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei imageHeight,
1288*8975f5c5SAndroid Build Coastguard Worker                                               const GLColor *textureData)
1289*8975f5c5SAndroid Build Coastguard Worker {
1290*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1291*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1292*8975f5c5SAndroid Build Coastguard Worker                  textureData);
1293*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1294*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1295*8975f5c5SAndroid Build Coastguard Worker }
1296*8975f5c5SAndroid Build Coastguard Worker 
initialize2DTextureUShort4444(GLTexture & texture,const GLsizei imageWidth,const GLsizei imageHeight,const GLColor * textureData)1297*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::initialize2DTextureUShort4444(GLTexture &texture,
1298*8975f5c5SAndroid Build Coastguard Worker                                                         const GLsizei imageWidth,
1299*8975f5c5SAndroid Build Coastguard Worker                                                         const GLsizei imageHeight,
1300*8975f5c5SAndroid Build Coastguard Worker                                                         const GLColor *textureData)
1301*8975f5c5SAndroid Build Coastguard Worker {
1302*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1303*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA,
1304*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_SHORT_4_4_4_4, textureData);
1305*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1306*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1307*8975f5c5SAndroid Build Coastguard Worker }
1308*8975f5c5SAndroid Build Coastguard Worker 
fillTexture(std::vector<GLColor> & texture,const GLColor color)1309*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::fillTexture(std::vector<GLColor> &texture, const GLColor color)
1310*8975f5c5SAndroid Build Coastguard Worker {
1311*8975f5c5SAndroid Build Coastguard Worker     for (auto &texel : texture)
1312*8975f5c5SAndroid Build Coastguard Worker     {
1313*8975f5c5SAndroid Build Coastguard Worker         texel = color;
1314*8975f5c5SAndroid Build Coastguard Worker     }
1315*8975f5c5SAndroid Build Coastguard Worker }
1316*8975f5c5SAndroid Build Coastguard Worker 
clearTexture(GLFramebuffer & fbo,GLTexture & texture,const GLColor color)1317*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::clearTexture(GLFramebuffer &fbo, GLTexture &texture, const GLColor color)
1318*8975f5c5SAndroid Build Coastguard Worker {
1319*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1320*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1321*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1322*8975f5c5SAndroid Build Coastguard Worker     glClearColor(color.R, color.G, color.B, color.A);
1323*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1324*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
1325*8975f5c5SAndroid Build Coastguard Worker }
1326*8975f5c5SAndroid Build Coastguard Worker 
copyTexSubImage3D(GLTexture & subTexture2D,const GLint xOffset,const GLint yOffset,const GLsizei subImageWidth,const GLsizei subImageHeight,const GLsizei imageDepth)1327*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::copyTexSubImage3D(GLTexture &subTexture2D,
1328*8975f5c5SAndroid Build Coastguard Worker                                             const GLint xOffset,
1329*8975f5c5SAndroid Build Coastguard Worker                                             const GLint yOffset,
1330*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei subImageWidth,
1331*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei subImageHeight,
1332*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei imageDepth)
1333*8975f5c5SAndroid Build Coastguard Worker {
1334*8975f5c5SAndroid Build Coastguard Worker     // Copy the 2D sub-image into the 3D texture
1335*8975f5c5SAndroid Build Coastguard Worker     for (int currLayer = 0; currLayer < imageDepth; ++currLayer)
1336*8975f5c5SAndroid Build Coastguard Worker     {
1337*8975f5c5SAndroid Build Coastguard Worker         // Bind the 2D texture to GL_COLOR_ATTACHMENT0
1338*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1339*8975f5c5SAndroid Build Coastguard Worker                                subTexture2D, 0);
1340*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1341*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage3D(GL_TEXTURE_3D, 0, xOffset, yOffset, currLayer, 0, 0, subImageWidth,
1342*8975f5c5SAndroid Build Coastguard Worker                             subImageHeight);
1343*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1344*8975f5c5SAndroid Build Coastguard Worker     }
1345*8975f5c5SAndroid Build Coastguard Worker }
1346*8975f5c5SAndroid Build Coastguard Worker 
verifyCopyTexSubImage3D(GLTexture & texture3D,const GLint xOffset,const GLint yOffset,const GLColor subImageColor)1347*8975f5c5SAndroid Build Coastguard Worker void CopyTexImageTestES3::verifyCopyTexSubImage3D(GLTexture &texture3D,
1348*8975f5c5SAndroid Build Coastguard Worker                                                   const GLint xOffset,
1349*8975f5c5SAndroid Build Coastguard Worker                                                   const GLint yOffset,
1350*8975f5c5SAndroid Build Coastguard Worker                                                   const GLColor subImageColor)
1351*8975f5c5SAndroid Build Coastguard Worker {
1352*8975f5c5SAndroid Build Coastguard Worker     // Bind to an FBO to check the copy was successful
1353*8975f5c5SAndroid Build Coastguard Worker     for (int currLayer = 0; currLayer < kImageDepth; ++currLayer)
1354*8975f5c5SAndroid Build Coastguard Worker     {
1355*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0, currLayer);
1356*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1357*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(xOffset, yOffset, subImageColor);
1358*8975f5c5SAndroid Build Coastguard Worker     }
1359*8975f5c5SAndroid Build Coastguard Worker }
1360*8975f5c5SAndroid Build Coastguard Worker 
1361*8975f5c5SAndroid Build Coastguard Worker // Test glCopyTexSubImage3D with initialized texture data
1362*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, 3DSubImageRawTextureData)
1363*8975f5c5SAndroid Build Coastguard Worker {
1364*8975f5c5SAndroid Build Coastguard Worker     // Texture data
1365*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> textureData(kImageWidth * kImageHeight * kImageDepth);
1366*8975f5c5SAndroid Build Coastguard Worker 
1367*8975f5c5SAndroid Build Coastguard Worker     // Fill the textures with color
1368*8975f5c5SAndroid Build Coastguard Worker     fillTexture(textureData, GLColor::red);
1369*8975f5c5SAndroid Build Coastguard Worker 
1370*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1371*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1372*8975f5c5SAndroid Build Coastguard Worker 
1373*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture3D;
1374*8975f5c5SAndroid Build Coastguard Worker     initialize3DTexture(texture3D, kImageWidth, kImageHeight, kImageDepth, textureData.data());
1375*8975f5c5SAndroid Build Coastguard Worker 
1376*8975f5c5SAndroid Build Coastguard Worker     // The 2D texture that will be the sub-image copied into the destination texture
1377*8975f5c5SAndroid Build Coastguard Worker     GLTexture subTexture2D;
1378*8975f5c5SAndroid Build Coastguard Worker     initialize2DTexture(subTexture2D, kSubImageWidth, kSubImageHeight, nullptr);
1379*8975f5c5SAndroid Build Coastguard Worker     clearTexture(fbo, subTexture2D, kSubImageColor);
1380*8975f5c5SAndroid Build Coastguard Worker 
1381*8975f5c5SAndroid Build Coastguard Worker     // Copy the 2D subimage into the 3D texture
1382*8975f5c5SAndroid Build Coastguard Worker     copyTexSubImage3D(subTexture2D, kXOffset, kYOffset, kSubImageWidth, kSubImageHeight,
1383*8975f5c5SAndroid Build Coastguard Worker                       kImageDepth);
1384*8975f5c5SAndroid Build Coastguard Worker 
1385*8975f5c5SAndroid Build Coastguard Worker     // Verify the color wasn't overwritten
1386*8975f5c5SAndroid Build Coastguard Worker     verifyCopyTexSubImage3D(texture3D, 0, 0, GLColor::red);
1387*8975f5c5SAndroid Build Coastguard Worker     // Verify the copy succeeded
1388*8975f5c5SAndroid Build Coastguard Worker     verifyCopyTexSubImage3D(texture3D, kXOffset, kYOffset, kSubImageColor);
1389*8975f5c5SAndroid Build Coastguard Worker 
1390*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1391*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1392*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, 0);
1393*8975f5c5SAndroid Build Coastguard Worker }
1394*8975f5c5SAndroid Build Coastguard Worker 
1395*8975f5c5SAndroid Build Coastguard Worker // Test glCopyTexSubImage3D with initialized texture data that was drawn to
1396*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, 3DSubImageDrawTextureData)
1397*8975f5c5SAndroid Build Coastguard Worker {
1398*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1399*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1400*8975f5c5SAndroid Build Coastguard Worker 
1401*8975f5c5SAndroid Build Coastguard Worker     // The 3D texture we will copy the sub-image into
1402*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture3D;
1403*8975f5c5SAndroid Build Coastguard Worker     initialize3DTexture(texture3D, kImageWidth, kImageHeight, kImageDepth, nullptr);
1404*8975f5c5SAndroid Build Coastguard Worker 
1405*8975f5c5SAndroid Build Coastguard Worker     // Draw to each layer in the 3D texture
1406*8975f5c5SAndroid Build Coastguard Worker     for (int currLayer = 0; currLayer < kImageDepth; ++currLayer)
1407*8975f5c5SAndroid Build Coastguard Worker     {
1408*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1409*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0,
1410*8975f5c5SAndroid Build Coastguard Worker                                   currLayer);
1411*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0,
1412*8975f5c5SAndroid Build Coastguard Worker                                   currLayer);
1413*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1414*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(greenProgram);
1415*8975f5c5SAndroid Build Coastguard Worker         drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
1416*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1417*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1418*8975f5c5SAndroid Build Coastguard Worker     }
1419*8975f5c5SAndroid Build Coastguard Worker 
1420*8975f5c5SAndroid Build Coastguard Worker     // The 2D texture that will be the sub-image copied into the destination texture
1421*8975f5c5SAndroid Build Coastguard Worker     GLTexture subTexture2D;
1422*8975f5c5SAndroid Build Coastguard Worker     initialize2DTexture(subTexture2D, kSubImageWidth, kSubImageHeight, nullptr);
1423*8975f5c5SAndroid Build Coastguard Worker     clearTexture(fbo, subTexture2D, kSubImageColor);
1424*8975f5c5SAndroid Build Coastguard Worker 
1425*8975f5c5SAndroid Build Coastguard Worker     // Copy the 2D sub-image into the 3D texture
1426*8975f5c5SAndroid Build Coastguard Worker     copyTexSubImage3D(subTexture2D, kXOffset, kYOffset, kSubImageWidth, kSubImageHeight,
1427*8975f5c5SAndroid Build Coastguard Worker                       kImageDepth);
1428*8975f5c5SAndroid Build Coastguard Worker 
1429*8975f5c5SAndroid Build Coastguard Worker     // Verify the color wasn't overwritten
1430*8975f5c5SAndroid Build Coastguard Worker     verifyCopyTexSubImage3D(texture3D, 0, 0, GLColor::green);
1431*8975f5c5SAndroid Build Coastguard Worker     // Verify the copy succeeded
1432*8975f5c5SAndroid Build Coastguard Worker     verifyCopyTexSubImage3D(texture3D, kXOffset, kYOffset, kSubImageColor);
1433*8975f5c5SAndroid Build Coastguard Worker 
1434*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1435*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1436*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, 0);
1437*8975f5c5SAndroid Build Coastguard Worker }
1438*8975f5c5SAndroid Build Coastguard Worker 
1439*8975f5c5SAndroid Build Coastguard Worker // Test glCopyTexSubImage3D with mismatched texture formats
1440*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, 3DSubImageDrawMismatchedTextureTypes)
1441*8975f5c5SAndroid Build Coastguard Worker {
1442*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1443*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1444*8975f5c5SAndroid Build Coastguard Worker 
1445*8975f5c5SAndroid Build Coastguard Worker     // The 3D texture we will copy the sub-image into
1446*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture3D;
1447*8975f5c5SAndroid Build Coastguard Worker     initialize3DTexture(texture3D, kImageWidth, kImageHeight, kImageDepth, nullptr);
1448*8975f5c5SAndroid Build Coastguard Worker 
1449*8975f5c5SAndroid Build Coastguard Worker     // Draw to each layer in the 3D texture
1450*8975f5c5SAndroid Build Coastguard Worker     for (int currLayer = 0; currLayer < kImageDepth; ++currLayer)
1451*8975f5c5SAndroid Build Coastguard Worker     {
1452*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1453*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0, currLayer);
1454*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1455*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(greenProgram);
1456*8975f5c5SAndroid Build Coastguard Worker         drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
1457*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1458*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1459*8975f5c5SAndroid Build Coastguard Worker     }
1460*8975f5c5SAndroid Build Coastguard Worker 
1461*8975f5c5SAndroid Build Coastguard Worker     // The 2D texture that will be the sub-image copied into the destination texture
1462*8975f5c5SAndroid Build Coastguard Worker     GLTexture subTexture2D;
1463*8975f5c5SAndroid Build Coastguard Worker     initialize2DTextureUShort4444(subTexture2D, kSubImageWidth, kSubImageHeight, nullptr);
1464*8975f5c5SAndroid Build Coastguard Worker     clearTexture(fbo, subTexture2D, kSubImageColor);
1465*8975f5c5SAndroid Build Coastguard Worker 
1466*8975f5c5SAndroid Build Coastguard Worker     // Copy the 2D sub-image into the 3D texture
1467*8975f5c5SAndroid Build Coastguard Worker     copyTexSubImage3D(subTexture2D, kXOffset, kYOffset, kSubImageWidth, kSubImageHeight,
1468*8975f5c5SAndroid Build Coastguard Worker                       kImageDepth);
1469*8975f5c5SAndroid Build Coastguard Worker 
1470*8975f5c5SAndroid Build Coastguard Worker     // Verify the color wasn't overwritten
1471*8975f5c5SAndroid Build Coastguard Worker     verifyCopyTexSubImage3D(texture3D, 0, 0, GLColor::green);
1472*8975f5c5SAndroid Build Coastguard Worker     // Verify the copy succeeded
1473*8975f5c5SAndroid Build Coastguard Worker     verifyCopyTexSubImage3D(texture3D, kXOffset, kYOffset, kSubImageColor);
1474*8975f5c5SAndroid Build Coastguard Worker 
1475*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1476*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1477*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, 0);
1478*8975f5c5SAndroid Build Coastguard Worker }
1479*8975f5c5SAndroid Build Coastguard Worker 
1480*8975f5c5SAndroid Build Coastguard Worker // Make sure a single-level texture can be redefined through glCopyTexImage2D from a framebuffer
1481*8975f5c5SAndroid Build Coastguard Worker // bound to the same texture.  Regression test for a bug in the Vulkan backend where the texture was
1482*8975f5c5SAndroid Build Coastguard Worker // released before the copy.
TEST_P(CopyTexImageTestES3,RedefineSameLevel)1483*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, RedefineSameLevel)
1484*8975f5c5SAndroid Build Coastguard Worker {
1485*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kSize     = 32;
1486*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kHalfSize = kSize / 2;
1487*8975f5c5SAndroid Build Coastguard Worker 
1488*8975f5c5SAndroid Build Coastguard Worker     // Create a single-level texture with four colors in different regions.
1489*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> initData(kSize * kSize);
1490*8975f5c5SAndroid Build Coastguard Worker     for (GLsizei y = 0; y < kSize; ++y)
1491*8975f5c5SAndroid Build Coastguard Worker     {
1492*8975f5c5SAndroid Build Coastguard Worker         const bool isTop = y < kHalfSize;
1493*8975f5c5SAndroid Build Coastguard Worker         for (GLsizei x = 0; x < kSize; ++x)
1494*8975f5c5SAndroid Build Coastguard Worker         {
1495*8975f5c5SAndroid Build Coastguard Worker             const bool isLeft = x < kHalfSize;
1496*8975f5c5SAndroid Build Coastguard Worker 
1497*8975f5c5SAndroid Build Coastguard Worker             GLColor color           = isLeft && isTop    ? GLColor::red
1498*8975f5c5SAndroid Build Coastguard Worker                                       : isLeft && !isTop ? GLColor::green
1499*8975f5c5SAndroid Build Coastguard Worker                                       : !isLeft && isTop ? GLColor::blue
1500*8975f5c5SAndroid Build Coastguard Worker                                                          : GLColor::yellow;
1501*8975f5c5SAndroid Build Coastguard Worker             color.A                 = 123;
1502*8975f5c5SAndroid Build Coastguard Worker             initData[y * kSize + x] = color;
1503*8975f5c5SAndroid Build Coastguard Worker         }
1504*8975f5c5SAndroid Build Coastguard Worker     }
1505*8975f5c5SAndroid Build Coastguard Worker 
1506*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
1507*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
1508*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1509*8975f5c5SAndroid Build Coastguard Worker                  initData.data());
1510*8975f5c5SAndroid Build Coastguard Worker 
1511*8975f5c5SAndroid Build Coastguard Worker     // Bind the framebuffer to the same texture
1512*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1513*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1514*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1515*8975f5c5SAndroid Build Coastguard Worker 
1516*8975f5c5SAndroid Build Coastguard Worker     // Redefine the texture
1517*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kHalfSize / 2, kHalfSize / 2, kHalfSize, kHalfSize,
1518*8975f5c5SAndroid Build Coastguard Worker                      0);
1519*8975f5c5SAndroid Build Coastguard Worker 
1520*8975f5c5SAndroid Build Coastguard Worker     // Verify copy is done correctly.
1521*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1522*8975f5c5SAndroid Build Coastguard Worker 
1523*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, kHalfSize / 2, kHalfSize / 2, GLColor::red);
1524*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(kHalfSize / 2, 0, kHalfSize / 2, kHalfSize / 2, GLColor::blue);
1525*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, kHalfSize / 2, kHalfSize / 2, kHalfSize / 2, GLColor::green);
1526*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(kHalfSize / 2, kHalfSize / 2, kHalfSize / 2, kHalfSize / 2,
1527*8975f5c5SAndroid Build Coastguard Worker                          GLColor::yellow);
1528*8975f5c5SAndroid Build Coastguard Worker }
1529*8975f5c5SAndroid Build Coastguard Worker 
1530*8975f5c5SAndroid Build Coastguard Worker class CopyTexImagePreRotationTest : public ANGLETest<>
1531*8975f5c5SAndroid Build Coastguard Worker {
1532*8975f5c5SAndroid Build Coastguard Worker   protected:
CopyTexImagePreRotationTest()1533*8975f5c5SAndroid Build Coastguard Worker     CopyTexImagePreRotationTest()
1534*8975f5c5SAndroid Build Coastguard Worker     {
1535*8975f5c5SAndroid Build Coastguard Worker         // Use a non-square window to catch width/height mismatch bugs
1536*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(54);
1537*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(32);
1538*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
1539*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
1540*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
1541*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
1542*8975f5c5SAndroid Build Coastguard Worker     }
1543*8975f5c5SAndroid Build Coastguard Worker };
1544*8975f5c5SAndroid Build Coastguard Worker 
1545*8975f5c5SAndroid Build Coastguard Worker // Basic copy test in the presence of pre-rotation
TEST_P(CopyTexImagePreRotationTest,Basic)1546*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImagePreRotationTest, Basic)
1547*8975f5c5SAndroid Build Coastguard Worker {
1548*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1, 0, 1, 1);
1549*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1550*8975f5c5SAndroid Build Coastguard Worker 
1551*8975f5c5SAndroid Build Coastguard Worker     const int w = getWindowWidth();
1552*8975f5c5SAndroid Build Coastguard Worker     const int h = getWindowHeight();
1553*8975f5c5SAndroid Build Coastguard Worker 
1554*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
1555*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1556*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, w, h);
1557*8975f5c5SAndroid Build Coastguard Worker 
1558*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
1559*8975f5c5SAndroid Build Coastguard Worker 
1560*8975f5c5SAndroid Build Coastguard Worker     // Verify results
1561*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1562*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1563*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1564*8975f5c5SAndroid Build Coastguard Worker 
1565*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::magenta);
1566*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1567*8975f5c5SAndroid Build Coastguard Worker }
1568*8975f5c5SAndroid Build Coastguard Worker 
1569*8975f5c5SAndroid Build Coastguard Worker // Copy test in the presence of pre-rotation with non-zero offsets and non-square sizes
TEST_P(CopyTexImagePreRotationTest,NonZeroNonSquare)1570*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImagePreRotationTest, NonZeroNonSquare)
1571*8975f5c5SAndroid Build Coastguard Worker {
1572*8975f5c5SAndroid Build Coastguard Worker     // Draw four colors in the framebuffer
1573*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
1574*8975f5c5SAndroid Build Coastguard Worker                      essl1_shaders::fs::Checkered());
1575*8975f5c5SAndroid Build Coastguard Worker     drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1576*8975f5c5SAndroid Build Coastguard Worker 
1577*8975f5c5SAndroid Build Coastguard Worker     const int w = getWindowWidth();
1578*8975f5c5SAndroid Build Coastguard Worker     const int h = getWindowHeight();
1579*8975f5c5SAndroid Build Coastguard Worker 
1580*8975f5c5SAndroid Build Coastguard Worker     const int texWidth  = (w + 6) * 2;
1581*8975f5c5SAndroid Build Coastguard Worker     const int texHeight = (h - 8) * 2;
1582*8975f5c5SAndroid Build Coastguard Worker 
1583*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
1584*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1585*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, texWidth * 2, texHeight * 2);
1586*8975f5c5SAndroid Build Coastguard Worker 
1587*8975f5c5SAndroid Build Coastguard Worker     // Copy with non-zero non-symmetric offsets to mips 0 and 1.
1588*8975f5c5SAndroid Build Coastguard Worker     //
1589*8975f5c5SAndroid Build Coastguard Worker     // The framebuffer is:
1590*8975f5c5SAndroid Build Coastguard Worker     //
1591*8975f5c5SAndroid Build Coastguard Worker     //                 54
1592*8975f5c5SAndroid Build Coastguard Worker     //      ____________^____________
1593*8975f5c5SAndroid Build Coastguard Worker     //     /                         \
1594*8975f5c5SAndroid Build Coastguard Worker     //     +------------+------------+\
1595*8975f5c5SAndroid Build Coastguard Worker     //     |            |            | |
1596*8975f5c5SAndroid Build Coastguard Worker     //     |    Red     |    Blue    | |
1597*8975f5c5SAndroid Build Coastguard Worker     //     |            |            | |
1598*8975f5c5SAndroid Build Coastguard Worker     //     |            |            | |
1599*8975f5c5SAndroid Build Coastguard Worker     //     +------------+------------+  > 32
1600*8975f5c5SAndroid Build Coastguard Worker     //     |            |            | |
1601*8975f5c5SAndroid Build Coastguard Worker     //     |   Green    |   Yellow   | |
1602*8975f5c5SAndroid Build Coastguard Worker     //     |            |            | |
1603*8975f5c5SAndroid Build Coastguard Worker     //     |            |            | |
1604*8975f5c5SAndroid Build Coastguard Worker     //     +------------+------------+/
1605*8975f5c5SAndroid Build Coastguard Worker     //
1606*8975f5c5SAndroid Build Coastguard Worker     // The texture's mip 0 is 120x48 and mip 1 is 60x24.
1607*8975f5c5SAndroid Build Coastguard Worker     //
1608*8975f5c5SAndroid Build Coastguard Worker     struct Copy
1609*8975f5c5SAndroid Build Coastguard Worker     {
1610*8975f5c5SAndroid Build Coastguard Worker         int mip;
1611*8975f5c5SAndroid Build Coastguard Worker         int texX, texY;
1612*8975f5c5SAndroid Build Coastguard Worker         int x, y;
1613*8975f5c5SAndroid Build Coastguard Worker         int width, height;
1614*8975f5c5SAndroid Build Coastguard Worker         GLColor expect;
1615*8975f5c5SAndroid Build Coastguard Worker     };
1616*8975f5c5SAndroid Build Coastguard Worker 
1617*8975f5c5SAndroid Build Coastguard Worker     // Make random copies with non-zero offsets, non-zero sizes and generally different numbers to
1618*8975f5c5SAndroid Build Coastguard Worker     // catch any mix up.
1619*8975f5c5SAndroid Build Coastguard Worker     const std::array<Copy, 4> kCopies = {{
1620*8975f5c5SAndroid Build Coastguard Worker         {1, 20, 13, 11, 2, 9, 13, GLColor::red},
1621*8975f5c5SAndroid Build Coastguard Worker         {1, 31, 17, 29, 27, 20, 5, GLColor::yellow},
1622*8975f5c5SAndroid Build Coastguard Worker         {0, 57, 1, 3, 22, 17, 9, GLColor::green},
1623*8975f5c5SAndroid Build Coastguard Worker         {0, 19, 38, 46, 4, 3, 11, GLColor::blue},
1624*8975f5c5SAndroid Build Coastguard Worker     }};
1625*8975f5c5SAndroid Build Coastguard Worker 
1626*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < kCopies.size(); ++i)
1627*8975f5c5SAndroid Build Coastguard Worker     {
1628*8975f5c5SAndroid Build Coastguard Worker         glCopyTexSubImage2D(GL_TEXTURE_2D, kCopies[i].mip, kCopies[i].texX, kCopies[i].texY,
1629*8975f5c5SAndroid Build Coastguard Worker                             kCopies[i].x, kCopies[i].y, kCopies[i].width, kCopies[i].height);
1630*8975f5c5SAndroid Build Coastguard Worker     }
1631*8975f5c5SAndroid Build Coastguard Worker 
1632*8975f5c5SAndroid Build Coastguard Worker     // Verify results
1633*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1634*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1635*8975f5c5SAndroid Build Coastguard Worker 
1636*8975f5c5SAndroid Build Coastguard Worker     for (int mip = 0; mip < 2; ++mip)
1637*8975f5c5SAndroid Build Coastguard Worker     {
1638*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, mip);
1639*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < kCopies.size(); ++i)
1640*8975f5c5SAndroid Build Coastguard Worker         {
1641*8975f5c5SAndroid Build Coastguard Worker             if (kCopies[i].mip == mip)
1642*8975f5c5SAndroid Build Coastguard Worker             {
1643*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_RECT_EQ(kCopies[i].texX, kCopies[i].texY, kCopies[i].width,
1644*8975f5c5SAndroid Build Coastguard Worker                                      kCopies[i].height, kCopies[i].expect);
1645*8975f5c5SAndroid Build Coastguard Worker             }
1646*8975f5c5SAndroid Build Coastguard Worker         }
1647*8975f5c5SAndroid Build Coastguard Worker     }
1648*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1649*8975f5c5SAndroid Build Coastguard Worker }
1650*8975f5c5SAndroid Build Coastguard Worker 
1651*8975f5c5SAndroid Build Coastguard Worker // ANGLE allows BGRA <-> RGBA copies. Test that these work and correctly swizzle the channels.
TEST_P(CopyTexImageTest,BGRAAndRGBAConversions)1652*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTest, BGRAAndRGBAConversions)
1653*8975f5c5SAndroid Build Coastguard Worker {
1654*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
1655*8975f5c5SAndroid Build Coastguard Worker     testBGRAToRGBAConversion();
1656*8975f5c5SAndroid Build Coastguard Worker     testRGBAToBGRAConversion();
1657*8975f5c5SAndroid Build Coastguard Worker }
1658*8975f5c5SAndroid Build Coastguard Worker 
1659*8975f5c5SAndroid Build Coastguard Worker // ANGLE allows BGRA <-> RGBA copies. Test that these work and correctly swizzle the channels.
1660*8975f5c5SAndroid Build Coastguard Worker // ES3 uses different validation code for glCopyTexImage.
TEST_P(CopyTexImageTestES3,BGRAAndRGBAConversions)1661*8975f5c5SAndroid Build Coastguard Worker TEST_P(CopyTexImageTestES3, BGRAAndRGBAConversions)
1662*8975f5c5SAndroid Build Coastguard Worker {
1663*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
1664*8975f5c5SAndroid Build Coastguard Worker     testBGRAToRGBAConversion();
1665*8975f5c5SAndroid Build Coastguard Worker     testRGBAToBGRAConversion();
1666*8975f5c5SAndroid Build Coastguard Worker }
1667*8975f5c5SAndroid Build Coastguard Worker 
1668*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND(
1669*8975f5c5SAndroid Build Coastguard Worker     CopyTexImageTest,
1670*8975f5c5SAndroid Build Coastguard Worker     ES2_D3D11_PRESENT_PATH_FAST(),
1671*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN(),
1672*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGL().enable(Feature::EmulateCopyTexImage2D),
1673*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2D),
1674*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers),
1675*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers));
1676*8975f5c5SAndroid Build Coastguard Worker 
1677*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyTexImageTestES3);
1678*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(
1679*8975f5c5SAndroid Build Coastguard Worker     CopyTexImageTestES3,
1680*8975f5c5SAndroid Build Coastguard Worker     ES3_OPENGL().enable(Feature::EmulateCopyTexImage2D),
1681*8975f5c5SAndroid Build Coastguard Worker     ES3_OPENGLES().enable(Feature::EmulateCopyTexImage2D),
1682*8975f5c5SAndroid Build Coastguard Worker     ES3_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers),
1683*8975f5c5SAndroid Build Coastguard Worker     ES3_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers));
1684*8975f5c5SAndroid Build Coastguard Worker 
1685*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND(
1686*8975f5c5SAndroid Build Coastguard Worker     CopyTexImageTestRobustResourceInit,
1687*8975f5c5SAndroid Build Coastguard Worker     ES2_D3D11_PRESENT_PATH_FAST(),
1688*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN(),
1689*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGL().enable(Feature::EmulateCopyTexImage2D),
1690*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2D),
1691*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers),
1692*8975f5c5SAndroid Build Coastguard Worker     ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers));
1693*8975f5c5SAndroid Build Coastguard Worker 
1694*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyTexImagePreRotationTest);
1695*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(CopyTexImagePreRotationTest,
1696*8975f5c5SAndroid Build Coastguard Worker                                ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
1697*8975f5c5SAndroid Build Coastguard Worker                                ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
1698*8975f5c5SAndroid Build Coastguard Worker                                ES3_VULKAN().enable(Feature::EmulatedPrerotation270));
1699*8975f5c5SAndroid Build Coastguard Worker 
1700*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
1701