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
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker namespace
14*8975f5c5SAndroid Build Coastguard Worker {
15*8975f5c5SAndroid Build Coastguard Worker
TexImageCubeMapFaces(GLint level,GLenum internalformat,GLsizei width,GLenum format,GLenum type,void * pixels)16*8975f5c5SAndroid Build Coastguard Worker void TexImageCubeMapFaces(GLint level,
17*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
18*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
19*8975f5c5SAndroid Build Coastguard Worker GLenum format,
20*8975f5c5SAndroid Build Coastguard Worker GLenum type,
21*8975f5c5SAndroid Build Coastguard Worker void *pixels)
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internalformat, width, width, 0, format,
24*8975f5c5SAndroid Build Coastguard Worker type, pixels);
25*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalformat, width, width, 0, format,
26*8975f5c5SAndroid Build Coastguard Worker type, pixels);
27*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalformat, width, width, 0, format,
28*8975f5c5SAndroid Build Coastguard Worker type, pixels);
29*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalformat, width, width, 0, format,
30*8975f5c5SAndroid Build Coastguard Worker type, pixels);
31*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalformat, width, width, 0, format,
32*8975f5c5SAndroid Build Coastguard Worker type, pixels);
33*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalformat, width, width, 0, format,
34*8975f5c5SAndroid Build Coastguard Worker type, pixels);
35*8975f5c5SAndroid Build Coastguard Worker }
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker class BaseMipmapTest : public ANGLETest<>
38*8975f5c5SAndroid Build Coastguard Worker {
39*8975f5c5SAndroid Build Coastguard Worker protected:
clearAndDrawQuad(GLuint program,GLsizei viewportWidth,GLsizei viewportHeight)40*8975f5c5SAndroid Build Coastguard Worker void clearAndDrawQuad(GLuint program, GLsizei viewportWidth, GLsizei viewportHeight)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
43*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
44*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, viewportWidth, viewportHeight);
45*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, "position", 0.0f);
48*8975f5c5SAndroid Build Coastguard Worker }
49*8975f5c5SAndroid Build Coastguard Worker };
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker } // namespace
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker class MipmapTest : public BaseMipmapTest
54*8975f5c5SAndroid Build Coastguard Worker {
55*8975f5c5SAndroid Build Coastguard Worker protected:
MipmapTest()56*8975f5c5SAndroid Build Coastguard Worker MipmapTest()
57*8975f5c5SAndroid Build Coastguard Worker : m2DProgram(0),
58*8975f5c5SAndroid Build Coastguard Worker mCubeProgram(0),
59*8975f5c5SAndroid Build Coastguard Worker mTexture2D(0),
60*8975f5c5SAndroid Build Coastguard Worker mTextureCube(0),
61*8975f5c5SAndroid Build Coastguard Worker m3DProgram(0),
62*8975f5c5SAndroid Build Coastguard Worker mLevelZeroBlueInitData(),
63*8975f5c5SAndroid Build Coastguard Worker mLevelZeroWhiteInitData(),
64*8975f5c5SAndroid Build Coastguard Worker mLevelOneGreenInitData(),
65*8975f5c5SAndroid Build Coastguard Worker mLevelTwoRedInitData(),
66*8975f5c5SAndroid Build Coastguard Worker mOffscreenFramebuffer(0)
67*8975f5c5SAndroid Build Coastguard Worker {
68*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(128);
69*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(128);
70*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
71*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
72*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
73*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
74*8975f5c5SAndroid Build Coastguard Worker }
75*8975f5c5SAndroid Build Coastguard Worker
setUp2DProgram()76*8975f5c5SAndroid Build Coastguard Worker void setUp2DProgram()
77*8975f5c5SAndroid Build Coastguard Worker {
78*8975f5c5SAndroid Build Coastguard Worker // Vertex Shader source
79*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(attribute vec4 position;
80*8975f5c5SAndroid Build Coastguard Worker varying vec2 vTexCoord;
81*8975f5c5SAndroid Build Coastguard Worker
82*8975f5c5SAndroid Build Coastguard Worker void main()
83*8975f5c5SAndroid Build Coastguard Worker {
84*8975f5c5SAndroid Build Coastguard Worker gl_Position = position;
85*8975f5c5SAndroid Build Coastguard Worker vTexCoord = (position.xy * 0.5) + 0.5;
86*8975f5c5SAndroid Build Coastguard Worker })";
87*8975f5c5SAndroid Build Coastguard Worker
88*8975f5c5SAndroid Build Coastguard Worker // Fragment Shader source
89*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(precision mediump float;
90*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D uTexture;
91*8975f5c5SAndroid Build Coastguard Worker varying vec2 vTexCoord;
92*8975f5c5SAndroid Build Coastguard Worker
93*8975f5c5SAndroid Build Coastguard Worker void main()
94*8975f5c5SAndroid Build Coastguard Worker {
95*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = texture2D(uTexture, vTexCoord);
96*8975f5c5SAndroid Build Coastguard Worker })";
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker m2DProgram = CompileProgram(kVS, kFS);
99*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, m2DProgram);
100*8975f5c5SAndroid Build Coastguard Worker }
101*8975f5c5SAndroid Build Coastguard Worker
setUpCubeProgram()102*8975f5c5SAndroid Build Coastguard Worker void setUpCubeProgram()
103*8975f5c5SAndroid Build Coastguard Worker {
104*8975f5c5SAndroid Build Coastguard Worker // A simple vertex shader for the texture cube
105*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(attribute vec4 position;
106*8975f5c5SAndroid Build Coastguard Worker varying vec4 vPosition;
107*8975f5c5SAndroid Build Coastguard Worker void main()
108*8975f5c5SAndroid Build Coastguard Worker {
109*8975f5c5SAndroid Build Coastguard Worker gl_Position = position;
110*8975f5c5SAndroid Build Coastguard Worker vPosition = position;
111*8975f5c5SAndroid Build Coastguard Worker })";
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker // A very simple fragment shader to sample from the negative-Y face of a texture cube.
114*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(precision mediump float;
115*8975f5c5SAndroid Build Coastguard Worker uniform samplerCube uTexture;
116*8975f5c5SAndroid Build Coastguard Worker varying vec4 vPosition;
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker void main()
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = textureCube(uTexture, vec3(vPosition.x, -1, vPosition.y));
121*8975f5c5SAndroid Build Coastguard Worker })";
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker mCubeProgram = CompileProgram(kVS, kFS);
124*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mCubeProgram);
125*8975f5c5SAndroid Build Coastguard Worker }
126*8975f5c5SAndroid Build Coastguard Worker
setUp3DProgram()127*8975f5c5SAndroid Build Coastguard Worker void setUp3DProgram()
128*8975f5c5SAndroid Build Coastguard Worker {
129*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_3D"));
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42263501
132*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF((IsPixel2() || IsNexus5X()) && IsOpenGLES());
133*8975f5c5SAndroid Build Coastguard Worker
134*8975f5c5SAndroid Build Coastguard Worker // Vertex Shader source
135*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(attribute vec4 position;
136*8975f5c5SAndroid Build Coastguard Worker varying vec2 vTexCoord;
137*8975f5c5SAndroid Build Coastguard Worker
138*8975f5c5SAndroid Build Coastguard Worker void main()
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker gl_Position = position;
141*8975f5c5SAndroid Build Coastguard Worker vTexCoord = (position.xy * 0.5) + 0.5;
142*8975f5c5SAndroid Build Coastguard Worker })";
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 100
145*8975f5c5SAndroid Build Coastguard Worker #extension GL_OES_texture_3D : enable
146*8975f5c5SAndroid Build Coastguard Worker precision highp float;
147*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler3D tex;
148*8975f5c5SAndroid Build Coastguard Worker uniform float slice;
149*8975f5c5SAndroid Build Coastguard Worker uniform float lod;
150*8975f5c5SAndroid Build Coastguard Worker varying vec2 vTexCoord;
151*8975f5c5SAndroid Build Coastguard Worker
152*8975f5c5SAndroid Build Coastguard Worker void main()
153*8975f5c5SAndroid Build Coastguard Worker {
154*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = texture3DLod(tex, vec3(vTexCoord, slice), lod);
155*8975f5c5SAndroid Build Coastguard Worker })";
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker m3DProgram = CompileProgram(kVS, kFS);
158*8975f5c5SAndroid Build Coastguard Worker if (m3DProgram == 0)
159*8975f5c5SAndroid Build Coastguard Worker {
160*8975f5c5SAndroid Build Coastguard Worker FAIL() << "shader compilation failed.";
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Worker mTexture3DSliceUniformLocation = glGetUniformLocation(m3DProgram, "slice");
164*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, mTexture3DSliceUniformLocation);
165*8975f5c5SAndroid Build Coastguard Worker
166*8975f5c5SAndroid Build Coastguard Worker mTexture3DLODUniformLocation = glGetUniformLocation(m3DProgram, "lod");
167*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, mTexture3DLODUniformLocation);
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m3DProgram);
170*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 0);
171*8975f5c5SAndroid Build Coastguard Worker glUseProgram(0);
172*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
173*8975f5c5SAndroid Build Coastguard Worker }
174*8975f5c5SAndroid Build Coastguard Worker
testSetUp()175*8975f5c5SAndroid Build Coastguard Worker void testSetUp() override
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
178*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
179*8975f5c5SAndroid Build Coastguard Worker
180*8975f5c5SAndroid Build Coastguard Worker setUp2DProgram();
181*8975f5c5SAndroid Build Coastguard Worker
182*8975f5c5SAndroid Build Coastguard Worker setUpCubeProgram();
183*8975f5c5SAndroid Build Coastguard Worker
184*8975f5c5SAndroid Build Coastguard Worker setUp3DProgram();
185*8975f5c5SAndroid Build Coastguard Worker
186*8975f5c5SAndroid Build Coastguard Worker mLevelZeroBlueInitData =
187*8975f5c5SAndroid Build Coastguard Worker createRGBInitData(getWindowWidth(), getWindowHeight(), 0, 0, 255); // Blue
188*8975f5c5SAndroid Build Coastguard Worker mLevelZeroWhiteInitData =
189*8975f5c5SAndroid Build Coastguard Worker createRGBInitData(getWindowWidth(), getWindowHeight(), 255, 255, 255); // White
190*8975f5c5SAndroid Build Coastguard Worker mLevelOneGreenInitData =
191*8975f5c5SAndroid Build Coastguard Worker createRGBInitData((getWindowWidth() / 2), (getWindowHeight() / 2), 0, 255, 0); // Green
192*8975f5c5SAndroid Build Coastguard Worker mLevelTwoRedInitData =
193*8975f5c5SAndroid Build Coastguard Worker createRGBInitData((getWindowWidth() / 4), (getWindowHeight() / 4), 255, 0, 0); // Red
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker glGenFramebuffers(1, &mOffscreenFramebuffer);
196*8975f5c5SAndroid Build Coastguard Worker glGenTextures(1, &mTexture2D);
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker // Initialize the texture2D to be empty, and don't use mips.
199*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
200*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
201*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, nullptr);
202*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
203*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
204*8975f5c5SAndroid Build Coastguard Worker
205*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(getWindowWidth(), getWindowHeight());
206*8975f5c5SAndroid Build Coastguard Worker
207*8975f5c5SAndroid Build Coastguard Worker // Create a non-mipped texture cube. Set the negative-Y face to be blue.
208*8975f5c5SAndroid Build Coastguard Worker // The other sides of the cube map have been set to white.
209*8975f5c5SAndroid Build Coastguard Worker glGenTextures(1, &mTextureCube);
210*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
211*8975f5c5SAndroid Build Coastguard Worker TexImageCubeMapFaces(0, GL_RGB, getWindowWidth(), GL_RGB, GL_UNSIGNED_BYTE, nullptr);
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, getWindowWidth(), getWindowWidth(),
214*8975f5c5SAndroid Build Coastguard Worker 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroWhiteInitData.data());
215*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, getWindowWidth(), getWindowWidth(),
216*8975f5c5SAndroid Build Coastguard Worker 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroWhiteInitData.data());
217*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, getWindowWidth(), getWindowWidth(),
218*8975f5c5SAndroid Build Coastguard Worker 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroWhiteInitData.data());
219*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, getWindowWidth(), getWindowWidth(),
220*8975f5c5SAndroid Build Coastguard Worker 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroBlueInitData.data());
221*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, getWindowWidth(), getWindowWidth(),
222*8975f5c5SAndroid Build Coastguard Worker 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroWhiteInitData.data());
223*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, getWindowWidth(), getWindowWidth(),
224*8975f5c5SAndroid Build Coastguard Worker 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroWhiteInitData.data());
225*8975f5c5SAndroid Build Coastguard Worker
226*8975f5c5SAndroid Build Coastguard Worker // Complete the texture cube without mipmaps to start with.
227*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
228*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
229*8975f5c5SAndroid Build Coastguard Worker
230*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
231*8975f5c5SAndroid Build Coastguard Worker }
232*8975f5c5SAndroid Build Coastguard Worker
testTearDown()233*8975f5c5SAndroid Build Coastguard Worker void testTearDown() override
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(m2DProgram);
236*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mCubeProgram);
237*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(m3DProgram);
238*8975f5c5SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &mOffscreenFramebuffer);
239*8975f5c5SAndroid Build Coastguard Worker glDeleteTextures(1, &mTexture2D);
240*8975f5c5SAndroid Build Coastguard Worker glDeleteTextures(1, &mTextureCube);
241*8975f5c5SAndroid Build Coastguard Worker }
242*8975f5c5SAndroid Build Coastguard Worker
createRGBInitData(GLint width,GLint height,GLint r,GLint g,GLint b)243*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> createRGBInitData(GLint width, GLint height, GLint r, GLint g, GLint b)
244*8975f5c5SAndroid Build Coastguard Worker {
245*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> data(3 * width * height);
246*8975f5c5SAndroid Build Coastguard Worker
247*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < width * height; i += 1)
248*8975f5c5SAndroid Build Coastguard Worker {
249*8975f5c5SAndroid Build Coastguard Worker data[3 * i + 0] = static_cast<GLubyte>(r);
250*8975f5c5SAndroid Build Coastguard Worker data[3 * i + 1] = static_cast<GLubyte>(g);
251*8975f5c5SAndroid Build Coastguard Worker data[3 * i + 2] = static_cast<GLubyte>(b);
252*8975f5c5SAndroid Build Coastguard Worker }
253*8975f5c5SAndroid Build Coastguard Worker
254*8975f5c5SAndroid Build Coastguard Worker return data;
255*8975f5c5SAndroid Build Coastguard Worker }
256*8975f5c5SAndroid Build Coastguard Worker
clearTextureLevel0(GLenum textarget,GLuint texture,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)257*8975f5c5SAndroid Build Coastguard Worker void clearTextureLevel0(GLenum textarget,
258*8975f5c5SAndroid Build Coastguard Worker GLuint texture,
259*8975f5c5SAndroid Build Coastguard Worker GLfloat red,
260*8975f5c5SAndroid Build Coastguard Worker GLfloat green,
261*8975f5c5SAndroid Build Coastguard Worker GLfloat blue,
262*8975f5c5SAndroid Build Coastguard Worker GLfloat alpha)
263*8975f5c5SAndroid Build Coastguard Worker {
264*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, mOffscreenFramebuffer);
265*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textarget, texture, 0);
266*8975f5c5SAndroid Build Coastguard Worker ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
267*8975f5c5SAndroid Build Coastguard Worker glClearColor(red, green, blue, alpha);
268*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
269*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, 0);
270*8975f5c5SAndroid Build Coastguard Worker }
271*8975f5c5SAndroid Build Coastguard Worker
272*8975f5c5SAndroid Build Coastguard Worker GLuint m2DProgram;
273*8975f5c5SAndroid Build Coastguard Worker GLuint mCubeProgram;
274*8975f5c5SAndroid Build Coastguard Worker GLuint mTexture2D;
275*8975f5c5SAndroid Build Coastguard Worker GLuint mTextureCube;
276*8975f5c5SAndroid Build Coastguard Worker
277*8975f5c5SAndroid Build Coastguard Worker GLuint m3DProgram = 0;
278*8975f5c5SAndroid Build Coastguard Worker GLint mTexture3DSliceUniformLocation;
279*8975f5c5SAndroid Build Coastguard Worker GLint mTexture3DLODUniformLocation;
280*8975f5c5SAndroid Build Coastguard Worker
281*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> mLevelZeroBlueInitData;
282*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> mLevelZeroWhiteInitData;
283*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> mLevelOneGreenInitData;
284*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> mLevelTwoRedInitData;
285*8975f5c5SAndroid Build Coastguard Worker
286*8975f5c5SAndroid Build Coastguard Worker private:
287*8975f5c5SAndroid Build Coastguard Worker GLuint mOffscreenFramebuffer;
288*8975f5c5SAndroid Build Coastguard Worker };
289*8975f5c5SAndroid Build Coastguard Worker
290*8975f5c5SAndroid Build Coastguard Worker class MipmapTestES3 : public BaseMipmapTest
291*8975f5c5SAndroid Build Coastguard Worker {
292*8975f5c5SAndroid Build Coastguard Worker protected:
MipmapTestES3()293*8975f5c5SAndroid Build Coastguard Worker MipmapTestES3()
294*8975f5c5SAndroid Build Coastguard Worker : mTexture(0),
295*8975f5c5SAndroid Build Coastguard Worker mArrayProgram(0),
296*8975f5c5SAndroid Build Coastguard Worker mTextureArraySliceUniformLocation(-1),
297*8975f5c5SAndroid Build Coastguard Worker m3DProgram(0),
298*8975f5c5SAndroid Build Coastguard Worker mTexture3DSliceUniformLocation(-1),
299*8975f5c5SAndroid Build Coastguard Worker mTexture3DLODUniformLocation(-1),
300*8975f5c5SAndroid Build Coastguard Worker m2DProgram(0)
301*8975f5c5SAndroid Build Coastguard Worker
302*8975f5c5SAndroid Build Coastguard Worker {
303*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(128);
304*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(128);
305*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
306*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
307*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
308*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
309*8975f5c5SAndroid Build Coastguard Worker }
310*8975f5c5SAndroid Build Coastguard Worker
vertexShaderSource()311*8975f5c5SAndroid Build Coastguard Worker const char *vertexShaderSource()
312*8975f5c5SAndroid Build Coastguard Worker {
313*8975f5c5SAndroid Build Coastguard Worker // Don't put "#version ..." on its own line. See [cpp]p1:
314*8975f5c5SAndroid Build Coastguard Worker // "If there are sequences of preprocessing tokens within the list of arguments that
315*8975f5c5SAndroid Build Coastguard Worker // would otherwise act as preprocessing directives, the behavior is undefined"
316*8975f5c5SAndroid Build Coastguard Worker return
317*8975f5c5SAndroid Build Coastguard Worker R"(#version 300 es
318*8975f5c5SAndroid Build Coastguard Worker precision highp float;
319*8975f5c5SAndroid Build Coastguard Worker in vec4 position;
320*8975f5c5SAndroid Build Coastguard Worker out vec2 texcoord;
321*8975f5c5SAndroid Build Coastguard Worker
322*8975f5c5SAndroid Build Coastguard Worker void main()
323*8975f5c5SAndroid Build Coastguard Worker {
324*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(position.xy, 0.0, 1.0);
325*8975f5c5SAndroid Build Coastguard Worker texcoord = (position.xy * 0.5) + 0.5;
326*8975f5c5SAndroid Build Coastguard Worker })";
327*8975f5c5SAndroid Build Coastguard Worker }
328*8975f5c5SAndroid Build Coastguard Worker
setUpArrayProgram()329*8975f5c5SAndroid Build Coastguard Worker void setUpArrayProgram()
330*8975f5c5SAndroid Build Coastguard Worker {
331*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 300 es
332*8975f5c5SAndroid Build Coastguard Worker precision highp float;
333*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler2DArray tex;
334*8975f5c5SAndroid Build Coastguard Worker uniform int slice;
335*8975f5c5SAndroid Build Coastguard Worker in vec2 texcoord;
336*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
337*8975f5c5SAndroid Build Coastguard Worker
338*8975f5c5SAndroid Build Coastguard Worker void main()
339*8975f5c5SAndroid Build Coastguard Worker {
340*8975f5c5SAndroid Build Coastguard Worker out_FragColor = texture(tex, vec3(texcoord, float(slice)));
341*8975f5c5SAndroid Build Coastguard Worker })";
342*8975f5c5SAndroid Build Coastguard Worker
343*8975f5c5SAndroid Build Coastguard Worker mArrayProgram = CompileProgram(vertexShaderSource(), kFS);
344*8975f5c5SAndroid Build Coastguard Worker if (mArrayProgram == 0)
345*8975f5c5SAndroid Build Coastguard Worker {
346*8975f5c5SAndroid Build Coastguard Worker FAIL() << "shader compilation failed.";
347*8975f5c5SAndroid Build Coastguard Worker }
348*8975f5c5SAndroid Build Coastguard Worker
349*8975f5c5SAndroid Build Coastguard Worker mTextureArraySliceUniformLocation = glGetUniformLocation(mArrayProgram, "slice");
350*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, mTextureArraySliceUniformLocation);
351*8975f5c5SAndroid Build Coastguard Worker
352*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mArrayProgram);
353*8975f5c5SAndroid Build Coastguard Worker glUseProgram(0);
354*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
355*8975f5c5SAndroid Build Coastguard Worker }
356*8975f5c5SAndroid Build Coastguard Worker
setUp3DProgram()357*8975f5c5SAndroid Build Coastguard Worker void setUp3DProgram()
358*8975f5c5SAndroid Build Coastguard Worker {
359*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 300 es
360*8975f5c5SAndroid Build Coastguard Worker precision highp float;
361*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler3D tex;
362*8975f5c5SAndroid Build Coastguard Worker uniform float slice;
363*8975f5c5SAndroid Build Coastguard Worker uniform float lod;
364*8975f5c5SAndroid Build Coastguard Worker in vec2 texcoord;
365*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
366*8975f5c5SAndroid Build Coastguard Worker
367*8975f5c5SAndroid Build Coastguard Worker void main()
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker out_FragColor = textureLod(tex, vec3(texcoord, slice), lod);
370*8975f5c5SAndroid Build Coastguard Worker })";
371*8975f5c5SAndroid Build Coastguard Worker
372*8975f5c5SAndroid Build Coastguard Worker m3DProgram = CompileProgram(vertexShaderSource(), kFS);
373*8975f5c5SAndroid Build Coastguard Worker if (m3DProgram == 0)
374*8975f5c5SAndroid Build Coastguard Worker {
375*8975f5c5SAndroid Build Coastguard Worker FAIL() << "shader compilation failed.";
376*8975f5c5SAndroid Build Coastguard Worker }
377*8975f5c5SAndroid Build Coastguard Worker
378*8975f5c5SAndroid Build Coastguard Worker mTexture3DSliceUniformLocation = glGetUniformLocation(m3DProgram, "slice");
379*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, mTexture3DSliceUniformLocation);
380*8975f5c5SAndroid Build Coastguard Worker
381*8975f5c5SAndroid Build Coastguard Worker mTexture3DLODUniformLocation = glGetUniformLocation(m3DProgram, "lod");
382*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, mTexture3DLODUniformLocation);
383*8975f5c5SAndroid Build Coastguard Worker
384*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m3DProgram);
385*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 0);
386*8975f5c5SAndroid Build Coastguard Worker glUseProgram(0);
387*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
388*8975f5c5SAndroid Build Coastguard Worker }
389*8975f5c5SAndroid Build Coastguard Worker
setUp2DProgram()390*8975f5c5SAndroid Build Coastguard Worker void setUp2DProgram()
391*8975f5c5SAndroid Build Coastguard Worker {
392*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 300 es
393*8975f5c5SAndroid Build Coastguard Worker precision highp float;
394*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler2D tex;
395*8975f5c5SAndroid Build Coastguard Worker in vec2 texcoord;
396*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
397*8975f5c5SAndroid Build Coastguard Worker
398*8975f5c5SAndroid Build Coastguard Worker void main()
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker out_FragColor = texture(tex, texcoord);
401*8975f5c5SAndroid Build Coastguard Worker })";
402*8975f5c5SAndroid Build Coastguard Worker
403*8975f5c5SAndroid Build Coastguard Worker m2DProgram = CompileProgram(vertexShaderSource(), kFS);
404*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, m2DProgram);
405*8975f5c5SAndroid Build Coastguard Worker
406*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
407*8975f5c5SAndroid Build Coastguard Worker }
408*8975f5c5SAndroid Build Coastguard Worker
setUpCubeProgram()409*8975f5c5SAndroid Build Coastguard Worker void setUpCubeProgram()
410*8975f5c5SAndroid Build Coastguard Worker {
411*8975f5c5SAndroid Build Coastguard Worker // A very simple fragment shader to sample from the negative-Y face of a texture cube.
412*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 300 es
413*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
414*8975f5c5SAndroid Build Coastguard Worker uniform samplerCube uTexture;
415*8975f5c5SAndroid Build Coastguard Worker in vec2 texcoord;
416*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
417*8975f5c5SAndroid Build Coastguard Worker
418*8975f5c5SAndroid Build Coastguard Worker void main()
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker out_FragColor = texture(uTexture, vec3(texcoord.x, -1, texcoord.y));
421*8975f5c5SAndroid Build Coastguard Worker })";
422*8975f5c5SAndroid Build Coastguard Worker
423*8975f5c5SAndroid Build Coastguard Worker mCubeProgram = CompileProgram(vertexShaderSource(), kFS);
424*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mCubeProgram);
425*8975f5c5SAndroid Build Coastguard Worker
426*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
427*8975f5c5SAndroid Build Coastguard Worker }
428*8975f5c5SAndroid Build Coastguard Worker
testSetUp()429*8975f5c5SAndroid Build Coastguard Worker void testSetUp() override
430*8975f5c5SAndroid Build Coastguard Worker {
431*8975f5c5SAndroid Build Coastguard Worker glGenTextures(1, &mTexture);
432*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
433*8975f5c5SAndroid Build Coastguard Worker
434*8975f5c5SAndroid Build Coastguard Worker setUpArrayProgram();
435*8975f5c5SAndroid Build Coastguard Worker setUp3DProgram();
436*8975f5c5SAndroid Build Coastguard Worker setUp2DProgram();
437*8975f5c5SAndroid Build Coastguard Worker setUpCubeProgram();
438*8975f5c5SAndroid Build Coastguard Worker }
439*8975f5c5SAndroid Build Coastguard Worker
testTearDown()440*8975f5c5SAndroid Build Coastguard Worker void testTearDown() override
441*8975f5c5SAndroid Build Coastguard Worker {
442*8975f5c5SAndroid Build Coastguard Worker glDeleteTextures(1, &mTexture);
443*8975f5c5SAndroid Build Coastguard Worker
444*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mArrayProgram);
445*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(m3DProgram);
446*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(m2DProgram);
447*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mCubeProgram);
448*8975f5c5SAndroid Build Coastguard Worker }
449*8975f5c5SAndroid Build Coastguard Worker
verifyAllMips(const uint32_t textureWidth,const uint32_t textureHeight,const GLColor & color)450*8975f5c5SAndroid Build Coastguard Worker void verifyAllMips(const uint32_t textureWidth,
451*8975f5c5SAndroid Build Coastguard Worker const uint32_t textureHeight,
452*8975f5c5SAndroid Build Coastguard Worker const GLColor &color)
453*8975f5c5SAndroid Build Coastguard Worker {
454*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(),
455*8975f5c5SAndroid Build Coastguard Worker essl3_shaders::fs::Texture2DLod());
456*8975f5c5SAndroid Build Coastguard Worker glUseProgram(program);
457*8975f5c5SAndroid Build Coastguard Worker const GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
458*8975f5c5SAndroid Build Coastguard Worker const GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
459*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, textureLoc);
460*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, lodLoc);
461*8975f5c5SAndroid Build Coastguard Worker glUniform1i(textureLoc, 0);
462*8975f5c5SAndroid Build Coastguard Worker
463*8975f5c5SAndroid Build Coastguard Worker // Verify that every mip is correct.
464*8975f5c5SAndroid Build Coastguard Worker const int w = getWindowWidth() - 1;
465*8975f5c5SAndroid Build Coastguard Worker const int h = getWindowHeight() - 1;
466*8975f5c5SAndroid Build Coastguard Worker for (uint32_t mip = 0; textureWidth >> mip >= 1 || textureHeight >> mip >= 1; ++mip)
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker glUniform1f(lodLoc, mip);
469*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
470*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
471*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
472*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
473*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, color) << "Failed on mip " << mip;
474*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(w, 0, color) << "Failed on mip " << mip;
475*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, h, color) << "Failed on mip " << mip;
476*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(w, h, color) << "Failed on mip " << mip;
477*8975f5c5SAndroid Build Coastguard Worker }
478*8975f5c5SAndroid Build Coastguard Worker }
479*8975f5c5SAndroid Build Coastguard Worker
480*8975f5c5SAndroid Build Coastguard Worker GLuint mTexture;
481*8975f5c5SAndroid Build Coastguard Worker
482*8975f5c5SAndroid Build Coastguard Worker GLuint mArrayProgram;
483*8975f5c5SAndroid Build Coastguard Worker GLint mTextureArraySliceUniformLocation;
484*8975f5c5SAndroid Build Coastguard Worker
485*8975f5c5SAndroid Build Coastguard Worker GLuint m3DProgram;
486*8975f5c5SAndroid Build Coastguard Worker GLint mTexture3DSliceUniformLocation;
487*8975f5c5SAndroid Build Coastguard Worker GLint mTexture3DLODUniformLocation;
488*8975f5c5SAndroid Build Coastguard Worker
489*8975f5c5SAndroid Build Coastguard Worker GLuint m2DProgram;
490*8975f5c5SAndroid Build Coastguard Worker
491*8975f5c5SAndroid Build Coastguard Worker GLuint mCubeProgram;
492*8975f5c5SAndroid Build Coastguard Worker };
493*8975f5c5SAndroid Build Coastguard Worker
494*8975f5c5SAndroid Build Coastguard Worker class MipmapTestES31 : public BaseMipmapTest
495*8975f5c5SAndroid Build Coastguard Worker {
496*8975f5c5SAndroid Build Coastguard Worker protected:
MipmapTestES31()497*8975f5c5SAndroid Build Coastguard Worker MipmapTestES31()
498*8975f5c5SAndroid Build Coastguard Worker
499*8975f5c5SAndroid Build Coastguard Worker {
500*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(128);
501*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(128);
502*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
503*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
504*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
505*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
506*8975f5c5SAndroid Build Coastguard Worker }
507*8975f5c5SAndroid Build Coastguard Worker };
508*8975f5c5SAndroid Build Coastguard Worker
509*8975f5c5SAndroid Build Coastguard Worker // Test generating mipmaps with base level and max level set. Ported from part of the
510*8975f5c5SAndroid Build Coastguard Worker // conformance2/textures/misc/tex-mipmap-levels WebGL2 test.
TEST_P(MipmapTestES3,GenerateMipmapPartialLevels)511*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapPartialLevels)
512*8975f5c5SAndroid Build Coastguard Worker {
513*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
514*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
515*8975f5c5SAndroid Build Coastguard Worker
516*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kRedData(64, GLColor::red);
517*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kGreenData(16, GLColor::green);
518*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kBlueData(4, GLColor::blue);
519*8975f5c5SAndroid Build Coastguard Worker
520*8975f5c5SAndroid Build Coastguard Worker // Initialize mips 2 to 4
521*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
522*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, texture);
523*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, kRedData.data());
524*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kGreenData.data());
525*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kBlueData.data());
526*8975f5c5SAndroid Build Coastguard Worker
527*8975f5c5SAndroid Build Coastguard Worker // Set base and max levels
528*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
529*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
530*8975f5c5SAndroid Build Coastguard Worker
531*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
532*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
533*8975f5c5SAndroid Build Coastguard Worker
534*8975f5c5SAndroid Build Coastguard Worker // Verify the data
535*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, 2, 2);
536*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
537*8975f5c5SAndroid Build Coastguard Worker
538*8975f5c5SAndroid Build Coastguard Worker // Test that generateMipmap works with partial levels.
539*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
540*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, 2, 2);
541*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
542*8975f5c5SAndroid Build Coastguard Worker }
543*8975f5c5SAndroid Build Coastguard Worker
544*8975f5c5SAndroid Build Coastguard Worker // This test generates mipmaps for a 1x1 texture, which should be a no-op.
TEST_P(MipmapTestES3,GenerateMipmap1x1Texture)545*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmap1x1Texture)
546*8975f5c5SAndroid Build Coastguard Worker {
547*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kTextureSize = 1;
548*8975f5c5SAndroid Build Coastguard Worker
549*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kInitialColor(kTextureSize * kTextureSize,
550*8975f5c5SAndroid Build Coastguard Worker GLColor(35, 81, 184, 211));
551*8975f5c5SAndroid Build Coastguard Worker
552*8975f5c5SAndroid Build Coastguard Worker // Create the texture.
553*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
554*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
555*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kInitialColor.data());
556*8975f5c5SAndroid Build Coastguard Worker
557*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
558*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
559*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
560*8975f5c5SAndroid Build Coastguard Worker
561*8975f5c5SAndroid Build Coastguard Worker // Verify that every mip is correct.
562*8975f5c5SAndroid Build Coastguard Worker verifyAllMips(kTextureSize, kTextureSize, kInitialColor[0]);
563*8975f5c5SAndroid Build Coastguard Worker }
564*8975f5c5SAndroid Build Coastguard Worker
565*8975f5c5SAndroid Build Coastguard Worker // This test generates mipmaps for a large texture and ensures all mips are generated.
TEST_P(MipmapTestES3,GenerateMipmapLargeTexture)566*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapLargeTexture)
567*8975f5c5SAndroid Build Coastguard Worker {
568*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kTextureSize = 4096;
569*8975f5c5SAndroid Build Coastguard Worker
570*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kInitialColor(kTextureSize * kTextureSize,
571*8975f5c5SAndroid Build Coastguard Worker GLColor(35, 81, 184, 211));
572*8975f5c5SAndroid Build Coastguard Worker
573*8975f5c5SAndroid Build Coastguard Worker // Create the texture.
574*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
575*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
576*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kInitialColor.data());
577*8975f5c5SAndroid Build Coastguard Worker
578*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
579*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
580*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
581*8975f5c5SAndroid Build Coastguard Worker
582*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
583*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
584*8975f5c5SAndroid Build Coastguard Worker
585*8975f5c5SAndroid Build Coastguard Worker // Verify that every mip is correct.
586*8975f5c5SAndroid Build Coastguard Worker verifyAllMips(kTextureSize, kTextureSize, kInitialColor[0]);
587*8975f5c5SAndroid Build Coastguard Worker }
588*8975f5c5SAndroid Build Coastguard Worker
589*8975f5c5SAndroid Build Coastguard Worker // This test generates mipmaps for a large npot texture and ensures all mips are generated.
TEST_P(MipmapTestES3,GenerateMipmapLargeNPOTTexture)590*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapLargeNPOTTexture)
591*8975f5c5SAndroid Build Coastguard Worker {
592*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kTextureWidth = 3840;
593*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kTextureHeight = 2160;
594*8975f5c5SAndroid Build Coastguard Worker
595*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kInitialColor(kTextureWidth * kTextureHeight,
596*8975f5c5SAndroid Build Coastguard Worker GLColor(35, 81, 184, 211));
597*8975f5c5SAndroid Build Coastguard Worker
598*8975f5c5SAndroid Build Coastguard Worker // Create the texture.
599*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
600*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureWidth, kTextureHeight, 0, GL_RGBA,
601*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kInitialColor.data());
602*8975f5c5SAndroid Build Coastguard Worker
603*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
604*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
605*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
606*8975f5c5SAndroid Build Coastguard Worker
607*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
608*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
609*8975f5c5SAndroid Build Coastguard Worker
610*8975f5c5SAndroid Build Coastguard Worker // Verify that every mip is correct.
611*8975f5c5SAndroid Build Coastguard Worker verifyAllMips(kTextureWidth, kTextureHeight, kInitialColor[0]);
612*8975f5c5SAndroid Build Coastguard Worker }
613*8975f5c5SAndroid Build Coastguard Worker
614*8975f5c5SAndroid Build Coastguard Worker // This test generates mipmaps for an elongated npot texture with the maximum number of mips and
615*8975f5c5SAndroid Build Coastguard Worker // ensures all mips are generated.
TEST_P(MipmapTestES3,GenerateMipmapLongNPOTTexture)616*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapLongNPOTTexture)
617*8975f5c5SAndroid Build Coastguard Worker {
618*8975f5c5SAndroid Build Coastguard Worker // Imprecisions in the result. http://anglebug.com/42263409
619*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL());
620*8975f5c5SAndroid Build Coastguard Worker
621*8975f5c5SAndroid Build Coastguard Worker GLint maxTextureWidth = 32767;
622*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureWidth);
623*8975f5c5SAndroid Build Coastguard Worker
624*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kTextureHeight = 43;
625*8975f5c5SAndroid Build Coastguard Worker const uint32_t kTextureWidth = maxTextureWidth - 1; // -1 to make the width NPOT
626*8975f5c5SAndroid Build Coastguard Worker
627*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kInitialColor(kTextureWidth * kTextureHeight,
628*8975f5c5SAndroid Build Coastguard Worker GLColor(35, 81, 184, 211));
629*8975f5c5SAndroid Build Coastguard Worker
630*8975f5c5SAndroid Build Coastguard Worker // Create the texture.
631*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
632*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureWidth, kTextureHeight, 0, GL_RGBA,
633*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kInitialColor.data());
634*8975f5c5SAndroid Build Coastguard Worker
635*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
636*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
637*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
638*8975f5c5SAndroid Build Coastguard Worker
639*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
640*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
641*8975f5c5SAndroid Build Coastguard Worker
642*8975f5c5SAndroid Build Coastguard Worker // Verify that every mip is correct.
643*8975f5c5SAndroid Build Coastguard Worker verifyAllMips(kTextureWidth, kTextureHeight, kInitialColor[0]);
644*8975f5c5SAndroid Build Coastguard Worker }
645*8975f5c5SAndroid Build Coastguard Worker
646*8975f5c5SAndroid Build Coastguard Worker // This test generates (and uses) mipmaps on a texture using init data. D3D11 will use a
647*8975f5c5SAndroid Build Coastguard Worker // non-renderable TextureStorage for this. The test then disables mips, renders to level zero of the
648*8975f5c5SAndroid Build Coastguard Worker // texture, and reenables mips before using the texture again. To do this, D3D11 has to convert the
649*8975f5c5SAndroid Build Coastguard Worker // TextureStorage into a renderable one. This test ensures that the conversion works correctly. In
650*8975f5c5SAndroid Build Coastguard Worker // particular, on D3D11 Feature Level 9_3 it ensures that both the zero LOD workaround texture AND
651*8975f5c5SAndroid Build Coastguard Worker // the 'normal' texture are copied during conversion.
TEST_P(MipmapTest,GenerateMipmapFromInitDataThenRender)652*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, GenerateMipmapFromInitDataThenRender)
653*8975f5c5SAndroid Build Coastguard Worker {
654*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
655*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
656*8975f5c5SAndroid Build Coastguard Worker
657*8975f5c5SAndroid Build Coastguard Worker // Pass in initial data so the texture is blue.
658*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
659*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
660*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, mLevelZeroBlueInitData.data());
661*8975f5c5SAndroid Build Coastguard Worker
662*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
663*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
664*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
665*8975f5c5SAndroid Build Coastguard Worker
666*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
667*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
668*8975f5c5SAndroid Build Coastguard Worker
669*8975f5c5SAndroid Build Coastguard Worker // Now draw the texture to various different sized areas.
670*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
671*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
672*8975f5c5SAndroid Build Coastguard Worker
673*8975f5c5SAndroid Build Coastguard Worker // Use mip level 1
674*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
675*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
676*8975f5c5SAndroid Build Coastguard Worker
677*8975f5c5SAndroid Build Coastguard Worker // Use mip level 2
678*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
679*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue);
680*8975f5c5SAndroid Build Coastguard Worker
681*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
682*8975f5c5SAndroid Build Coastguard Worker
683*8975f5c5SAndroid Build Coastguard Worker // Disable mips. Render a quad using the texture and ensure it's blue.
684*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
685*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
686*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
687*8975f5c5SAndroid Build Coastguard Worker
688*8975f5c5SAndroid Build Coastguard Worker // Clear level 0 of the texture to red.
689*8975f5c5SAndroid Build Coastguard Worker clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 1.0f, 0.0f, 0.0f, 1.0f);
690*8975f5c5SAndroid Build Coastguard Worker
691*8975f5c5SAndroid Build Coastguard Worker // Reenable mips, and try rendering different-sized quads.
692*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
693*8975f5c5SAndroid Build Coastguard Worker
694*8975f5c5SAndroid Build Coastguard Worker // Level 0 is now red, so this should render red.
695*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
696*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
697*8975f5c5SAndroid Build Coastguard Worker
698*8975f5c5SAndroid Build Coastguard Worker // Use mip level 1, blue.
699*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
700*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
701*8975f5c5SAndroid Build Coastguard Worker
702*8975f5c5SAndroid Build Coastguard Worker // Use mip level 2, blue.
703*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
704*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue);
705*8975f5c5SAndroid Build Coastguard Worker }
706*8975f5c5SAndroid Build Coastguard Worker
707*8975f5c5SAndroid Build Coastguard Worker // Test that generating mipmap after the image is already created for a single level works.
TEST_P(MipmapTest,GenerateMipmapAfterSingleLevelDraw)708*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, GenerateMipmapAfterSingleLevelDraw)
709*8975f5c5SAndroid Build Coastguard Worker {
710*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
711*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
712*8975f5c5SAndroid Build Coastguard Worker
713*8975f5c5SAndroid Build Coastguard Worker uint32_t width = getWindowWidth();
714*8975f5c5SAndroid Build Coastguard Worker uint32_t height = getWindowHeight();
715*8975f5c5SAndroid Build Coastguard Worker
716*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kInitData(width * height, GLColor::blue);
717*8975f5c5SAndroid Build Coastguard Worker
718*8975f5c5SAndroid Build Coastguard Worker // Pass in initial data so the texture is blue.
719*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
720*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
721*8975f5c5SAndroid Build Coastguard Worker kInitData.data());
722*8975f5c5SAndroid Build Coastguard Worker
723*8975f5c5SAndroid Build Coastguard Worker // Make sure the texture image is created.
724*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
725*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, kInitData[0]);
726*8975f5c5SAndroid Build Coastguard Worker
727*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
728*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
729*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
730*8975f5c5SAndroid Build Coastguard Worker
731*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
732*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
733*8975f5c5SAndroid Build Coastguard Worker
734*8975f5c5SAndroid Build Coastguard Worker // Draw and make sure the second mip is blue.
735*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
736*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, kInitData[0]);
737*8975f5c5SAndroid Build Coastguard Worker }
738*8975f5c5SAndroid Build Coastguard Worker
739*8975f5c5SAndroid Build Coastguard Worker // Test that generating mipmaps, then modifying the base level and generating mipmaps again works.
TEST_P(MipmapTest,GenerateMipmapAfterModifyingBaseLevel)740*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, GenerateMipmapAfterModifyingBaseLevel)
741*8975f5c5SAndroid Build Coastguard Worker {
742*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
743*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
744*8975f5c5SAndroid Build Coastguard Worker
745*8975f5c5SAndroid Build Coastguard Worker uint32_t width = getWindowWidth();
746*8975f5c5SAndroid Build Coastguard Worker uint32_t height = getWindowHeight();
747*8975f5c5SAndroid Build Coastguard Worker
748*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kInitData(width * height, GLColor::blue);
749*8975f5c5SAndroid Build Coastguard Worker
750*8975f5c5SAndroid Build Coastguard Worker // Pass in initial data so the texture is blue.
751*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
752*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
753*8975f5c5SAndroid Build Coastguard Worker kInitData.data());
754*8975f5c5SAndroid Build Coastguard Worker
755*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips.
756*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
757*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
758*8975f5c5SAndroid Build Coastguard Worker
759*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
760*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
761*8975f5c5SAndroid Build Coastguard Worker
762*8975f5c5SAndroid Build Coastguard Worker // Draw and make sure the second mip is blue. This is to make sure the texture image is
763*8975f5c5SAndroid Build Coastguard Worker // allocated.
764*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
765*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, kInitData[0]);
766*8975f5c5SAndroid Build Coastguard Worker
767*8975f5c5SAndroid Build Coastguard Worker // Modify mip 0 without redefining it.
768*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kModifyData(width * height, GLColor::green);
769*8975f5c5SAndroid Build Coastguard Worker glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
770*8975f5c5SAndroid Build Coastguard Worker kModifyData.data());
771*8975f5c5SAndroid Build Coastguard Worker
772*8975f5c5SAndroid Build Coastguard Worker // Generate the mips again, which should update all levels to the new (green) color.
773*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
774*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
775*8975f5c5SAndroid Build Coastguard Worker
776*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
777*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, kModifyData[0]);
778*8975f5c5SAndroid Build Coastguard Worker }
779*8975f5c5SAndroid Build Coastguard Worker
780*8975f5c5SAndroid Build Coastguard Worker // This test ensures that mips are correctly generated from a rendered image.
781*8975f5c5SAndroid Build Coastguard Worker // In particular, on D3D11 Feature Level 9_3, the clear call will be performed on the zero-level
782*8975f5c5SAndroid Build Coastguard Worker // texture, rather than the mipped one. The test ensures that the zero-level texture is correctly
783*8975f5c5SAndroid Build Coastguard Worker // copied into the mipped texture before the mipmaps are generated.
TEST_P(MipmapTest,GenerateMipmapFromRenderedImage)784*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, GenerateMipmapFromRenderedImage)
785*8975f5c5SAndroid Build Coastguard Worker {
786*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
787*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
788*8975f5c5SAndroid Build Coastguard Worker
789*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
790*8975f5c5SAndroid Build Coastguard Worker // Clear the texture to blue.
791*8975f5c5SAndroid Build Coastguard Worker clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 0.0f, 0.0f, 1.0f, 1.0f);
792*8975f5c5SAndroid Build Coastguard Worker
793*8975f5c5SAndroid Build Coastguard Worker // Then generate the mips
794*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
795*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
796*8975f5c5SAndroid Build Coastguard Worker
797*8975f5c5SAndroid Build Coastguard Worker // Enable mips.
798*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
799*8975f5c5SAndroid Build Coastguard Worker
800*8975f5c5SAndroid Build Coastguard Worker // Now draw the texture to various different sized areas.
801*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
802*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
803*8975f5c5SAndroid Build Coastguard Worker
804*8975f5c5SAndroid Build Coastguard Worker // Use mip level 1
805*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
806*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
807*8975f5c5SAndroid Build Coastguard Worker
808*8975f5c5SAndroid Build Coastguard Worker // Use mip level 2
809*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
810*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue);
811*8975f5c5SAndroid Build Coastguard Worker }
812*8975f5c5SAndroid Build Coastguard Worker
813*8975f5c5SAndroid Build Coastguard Worker // Test to ensure that rendering to a mipmapped texture works, regardless of whether mipmaps are
814*8975f5c5SAndroid Build Coastguard Worker // enabled or not.
815*8975f5c5SAndroid Build Coastguard Worker // TODO: This test hits a texture rebind bug in the D3D11 renderer. Fix this.
TEST_P(MipmapTest,RenderOntoLevelZeroAfterGenerateMipmap)816*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, RenderOntoLevelZeroAfterGenerateMipmap)
817*8975f5c5SAndroid Build Coastguard Worker {
818*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Figure out why this is broken on AMD OpenGL
819*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
820*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
821*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
822*8975f5c5SAndroid Build Coastguard Worker
823*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
824*8975f5c5SAndroid Build Coastguard Worker
825*8975f5c5SAndroid Build Coastguard Worker // Clear the texture to blue.
826*8975f5c5SAndroid Build Coastguard Worker clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 0.0f, 0.0f, 1.0f, 1.0f);
827*8975f5c5SAndroid Build Coastguard Worker
828*8975f5c5SAndroid Build Coastguard Worker // Now, draw the texture to a quad that's the same size as the texture. This draws to the
829*8975f5c5SAndroid Build Coastguard Worker // default framebuffer. The quad should be blue.
830*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
831*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
832*8975f5c5SAndroid Build Coastguard Worker
833*8975f5c5SAndroid Build Coastguard Worker // Now go back to the texture, and generate mips on it.
834*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
835*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
836*8975f5c5SAndroid Build Coastguard Worker
837*8975f5c5SAndroid Build Coastguard Worker // Now try rendering the textured quad again. Note: we've not told GL to use the generated mips.
838*8975f5c5SAndroid Build Coastguard Worker // The quad should be blue.
839*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
840*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
841*8975f5c5SAndroid Build Coastguard Worker
842*8975f5c5SAndroid Build Coastguard Worker // Now tell GL to use the generated mips.
843*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
844*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
845*8975f5c5SAndroid Build Coastguard Worker
846*8975f5c5SAndroid Build Coastguard Worker // Now render the textured quad again. It should be still be blue.
847*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
848*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
849*8975f5c5SAndroid Build Coastguard Worker
850*8975f5c5SAndroid Build Coastguard Worker // Now render the textured quad to an area smaller than the texture (i.e. to force
851*8975f5c5SAndroid Build Coastguard Worker // minification). This should be blue.
852*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
853*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue);
854*8975f5c5SAndroid Build Coastguard Worker
855*8975f5c5SAndroid Build Coastguard Worker // Now clear the texture to green. This just clears the top level. The lower mips should remain
856*8975f5c5SAndroid Build Coastguard Worker // blue.
857*8975f5c5SAndroid Build Coastguard Worker clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 0.0f, 1.0f, 0.0f, 1.0f);
858*8975f5c5SAndroid Build Coastguard Worker
859*8975f5c5SAndroid Build Coastguard Worker // Render a textured quad equal in size to the texture. This should be green, since we just
860*8975f5c5SAndroid Build Coastguard Worker // cleared level 0.
861*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
862*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
863*8975f5c5SAndroid Build Coastguard Worker
864*8975f5c5SAndroid Build Coastguard Worker // Render a small textured quad. This forces minification, so should render blue (the color of
865*8975f5c5SAndroid Build Coastguard Worker // levels 1+).
866*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
867*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue);
868*8975f5c5SAndroid Build Coastguard Worker
869*8975f5c5SAndroid Build Coastguard Worker // Disable mipmaps again
870*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
871*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
872*8975f5c5SAndroid Build Coastguard Worker
873*8975f5c5SAndroid Build Coastguard Worker // Render a textured quad equal in size to the texture. This should be green, the color of level
874*8975f5c5SAndroid Build Coastguard Worker // 0 in the texture.
875*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
876*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
877*8975f5c5SAndroid Build Coastguard Worker
878*8975f5c5SAndroid Build Coastguard Worker // Render a small textured quad. This would force minification if mips were enabled, but they're
879*8975f5c5SAndroid Build Coastguard Worker // not. Therefore, this should be green.
880*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
881*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green);
882*8975f5c5SAndroid Build Coastguard Worker }
883*8975f5c5SAndroid Build Coastguard Worker
884*8975f5c5SAndroid Build Coastguard Worker // This test defines a valid mipchain manually, with an extra level that's unused on the first few
885*8975f5c5SAndroid Build Coastguard Worker // draws. Later on, it redefines the whole mipchain but this time, uses the last mip that was
886*8975f5c5SAndroid Build Coastguard Worker // already uploaded before. The test expects that mip to be usable.
TEST_P(MipmapTest,DefineValidExtraLevelAndUseItLater)887*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, DefineValidExtraLevelAndUseItLater)
888*8975f5c5SAndroid Build Coastguard Worker {
889*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
890*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
891*8975f5c5SAndroid Build Coastguard Worker
892*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture2D);
893*8975f5c5SAndroid Build Coastguard Worker
894*8975f5c5SAndroid Build Coastguard Worker GLubyte *levels[] = {mLevelZeroBlueInitData.data(), mLevelOneGreenInitData.data(),
895*8975f5c5SAndroid Build Coastguard Worker mLevelTwoRedInitData.data()};
896*8975f5c5SAndroid Build Coastguard Worker
897*8975f5c5SAndroid Build Coastguard Worker int maxLevel = 1 + static_cast<int>(floor(log2(std::max(getWindowWidth(), getWindowHeight()))));
898*8975f5c5SAndroid Build Coastguard Worker
899*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < maxLevel; i++)
900*8975f5c5SAndroid Build Coastguard Worker {
901*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, i, GL_RGB, getWindowWidth() >> i, getWindowHeight() >> i, 0,
902*8975f5c5SAndroid Build Coastguard Worker GL_RGB, GL_UNSIGNED_BYTE, levels[i % 3]);
903*8975f5c5SAndroid Build Coastguard Worker }
904*8975f5c5SAndroid Build Coastguard Worker
905*8975f5c5SAndroid Build Coastguard Worker // Define an extra level that won't be used for now
906*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> magentaExtraLevelData =
907*8975f5c5SAndroid Build Coastguard Worker createRGBInitData(getWindowWidth() * 2, getWindowHeight() * 2, 255, 0, 255);
908*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, maxLevel, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE,
909*8975f5c5SAndroid Build Coastguard Worker magentaExtraLevelData.data());
910*8975f5c5SAndroid Build Coastguard Worker
911*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
912*8975f5c5SAndroid Build Coastguard Worker
913*8975f5c5SAndroid Build Coastguard Worker // Enable mipmaps.
914*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
915*8975f5c5SAndroid Build Coastguard Worker
916*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using mip 0, and check it's blue.
917*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
918*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
919*8975f5c5SAndroid Build Coastguard Worker
920*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using mip 1, and check it's green.
921*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
922*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
923*8975f5c5SAndroid Build Coastguard Worker
924*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using mip 2, and check it's red.
925*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
926*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red);
927*8975f5c5SAndroid Build Coastguard Worker
928*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using the last mip, and check it's green.
929*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, 1, 1);
930*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
931*8975f5c5SAndroid Build Coastguard Worker
932*8975f5c5SAndroid Build Coastguard Worker // Now redefine everything above level 8 to be a mipcomplete chain again.
933*8975f5c5SAndroid Build Coastguard Worker std::vector<GLubyte> levelDoubleSizeYellowInitData =
934*8975f5c5SAndroid Build Coastguard Worker createRGBInitData(getWindowWidth() * 2, getWindowHeight() * 2, 255, 255, 0);
935*8975f5c5SAndroid Build Coastguard Worker
936*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth() * 2, getWindowHeight() * 2, 0, GL_RGB,
937*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, levelDoubleSizeYellowInitData.data()); // 256
938*8975f5c5SAndroid Build Coastguard Worker
939*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < maxLevel - 1; i++)
940*8975f5c5SAndroid Build Coastguard Worker {
941*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, i + 1, GL_RGB, getWindowWidth() >> i, getWindowHeight() >> i, 0,
942*8975f5c5SAndroid Build Coastguard Worker GL_RGB, GL_UNSIGNED_BYTE, levels[i % 3]);
943*8975f5c5SAndroid Build Coastguard Worker }
944*8975f5c5SAndroid Build Coastguard Worker
945*8975f5c5SAndroid Build Coastguard Worker // At this point we have a valid mip chain, the last level being magenta if we draw 1x1 pixel.
946*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, 1, 1);
947*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
948*8975f5c5SAndroid Build Coastguard Worker
949*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using mip 0, and check it's yellow.
950*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() * 2, getWindowHeight() * 2);
951*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::yellow);
952*8975f5c5SAndroid Build Coastguard Worker
953*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using mip 1, and check it's blue.
954*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
955*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
956*8975f5c5SAndroid Build Coastguard Worker
957*8975f5c5SAndroid Build Coastguard Worker // Draw a full-sized quad using mip 2, and check it's green.
958*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
959*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green);
960*8975f5c5SAndroid Build Coastguard Worker }
961*8975f5c5SAndroid Build Coastguard Worker
962*8975f5c5SAndroid Build Coastguard Worker // Regression test for a bug that cause mipmaps to only generate using the top left corner as input.
TEST_P(MipmapTest,MipMapGenerationD3D9Bug)963*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, MipMapGenerationD3D9Bug)
964*8975f5c5SAndroid Build Coastguard Worker {
965*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
966*8975f5c5SAndroid Build Coastguard Worker !IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
967*8975f5c5SAndroid Build Coastguard Worker !IsGLExtensionEnabled("GL_ANGLE_texture_usage"));
968*8975f5c5SAndroid Build Coastguard Worker
969*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
970*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
971*8975f5c5SAndroid Build Coastguard Worker
972*8975f5c5SAndroid Build Coastguard Worker const GLColor mip0Color[4] = {
973*8975f5c5SAndroid Build Coastguard Worker GLColor::red,
974*8975f5c5SAndroid Build Coastguard Worker GLColor::green,
975*8975f5c5SAndroid Build Coastguard Worker GLColor::red,
976*8975f5c5SAndroid Build Coastguard Worker GLColor::green,
977*8975f5c5SAndroid Build Coastguard Worker };
978*8975f5c5SAndroid Build Coastguard Worker const GLColor mip1Color = GLColor(127, 127, 0, 255);
979*8975f5c5SAndroid Build Coastguard Worker
980*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
981*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, texture);
982*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
983*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
984*8975f5c5SAndroid Build Coastguard Worker glTexStorage2DEXT(GL_TEXTURE_2D, 2, GL_RGBA8_OES, 2, 2);
985*8975f5c5SAndroid Build Coastguard Worker glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color);
986*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
987*8975f5c5SAndroid Build Coastguard Worker
988*8975f5c5SAndroid Build Coastguard Worker // Only draw to a 1 pixel viewport so the lower mip is used
989*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, 1, 1);
990*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_NEAR(0, 0, mip1Color, 1.0);
991*8975f5c5SAndroid Build Coastguard Worker }
992*8975f5c5SAndroid Build Coastguard Worker
993*8975f5c5SAndroid Build Coastguard Worker // This test ensures that the level-zero workaround for TextureCubes (on D3D11 Feature Level 9_3)
994*8975f5c5SAndroid Build Coastguard Worker // works as expected. It tests enabling/disabling mipmaps, generating mipmaps, and rendering to
995*8975f5c5SAndroid Build Coastguard Worker // level zero.
TEST_P(MipmapTest,TextureCubeGeneralLevelZero)996*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, TextureCubeGeneralLevelZero)
997*8975f5c5SAndroid Build Coastguard Worker {
998*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42261821
999*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1000*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42261524
1001*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1002*8975f5c5SAndroid Build Coastguard Worker // http://issuetracker.google.com/159666631
1003*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(isSwiftshader());
1004*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
1005*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
1006*8975f5c5SAndroid Build Coastguard Worker
1007*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1008*8975f5c5SAndroid Build Coastguard Worker
1009*8975f5c5SAndroid Build Coastguard Worker // Draw. Since the negative-Y face's is blue, this should be blue.
1010*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight());
1011*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1012*8975f5c5SAndroid Build Coastguard Worker
1013*8975f5c5SAndroid Build Coastguard Worker // Generate mipmaps, and render. This should be blue.
1014*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
1015*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1016*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight());
1017*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1018*8975f5c5SAndroid Build Coastguard Worker
1019*8975f5c5SAndroid Build Coastguard Worker // Draw using a smaller viewport (to force a lower LOD of the texture). This should still be
1020*8975f5c5SAndroid Build Coastguard Worker // blue.
1021*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1022*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1023*8975f5c5SAndroid Build Coastguard Worker
1024*8975f5c5SAndroid Build Coastguard Worker // Now clear the negative-Y face of the cube to red.
1025*8975f5c5SAndroid Build Coastguard Worker clearTextureLevel0(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mTextureCube, 1.0f, 0.0f, 0.0f, 1.0f);
1026*8975f5c5SAndroid Build Coastguard Worker
1027*8975f5c5SAndroid Build Coastguard Worker // Draw using a full-size viewport. This should be red.
1028*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight());
1029*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1030*8975f5c5SAndroid Build Coastguard Worker
1031*8975f5c5SAndroid Build Coastguard Worker // Draw using a quarter-size viewport, to force a lower LOD. This should be *BLUE*, since we
1032*8975f5c5SAndroid Build Coastguard Worker // only cleared level zero of the negative-Y face to red, and left its mipmaps blue.
1033*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1034*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1035*8975f5c5SAndroid Build Coastguard Worker
1036*8975f5c5SAndroid Build Coastguard Worker // Disable mipmaps again, and draw a to a quarter-size viewport.
1037*8975f5c5SAndroid Build Coastguard Worker // Since this should use level zero of the texture, this should be *RED*.
1038*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1039*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1040*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1041*8975f5c5SAndroid Build Coastguard Worker }
1042*8975f5c5SAndroid Build Coastguard Worker
1043*8975f5c5SAndroid Build Coastguard Worker // This test ensures that rendering to level-zero of a TextureCube works as expected.
TEST_P(MipmapTest,TextureCubeRenderToLevelZero)1044*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, TextureCubeRenderToLevelZero)
1045*8975f5c5SAndroid Build Coastguard Worker {
1046*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42261821
1047*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1048*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42261524
1049*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1050*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
1051*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
1052*8975f5c5SAndroid Build Coastguard Worker
1053*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1054*8975f5c5SAndroid Build Coastguard Worker
1055*8975f5c5SAndroid Build Coastguard Worker // Draw. Since the negative-Y face's is blue, this should be blue.
1056*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight());
1057*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1058*8975f5c5SAndroid Build Coastguard Worker
1059*8975f5c5SAndroid Build Coastguard Worker // Now clear the negative-Y face of the cube to red.
1060*8975f5c5SAndroid Build Coastguard Worker clearTextureLevel0(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mTextureCube, 1.0f, 0.0f, 0.0f, 1.0f);
1061*8975f5c5SAndroid Build Coastguard Worker
1062*8975f5c5SAndroid Build Coastguard Worker // Draw using a full-size viewport. This should be red.
1063*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight());
1064*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1065*8975f5c5SAndroid Build Coastguard Worker
1066*8975f5c5SAndroid Build Coastguard Worker // Draw a to a quarter-size viewport. This should also be red.
1067*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1068*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1069*8975f5c5SAndroid Build Coastguard Worker }
1070*8975f5c5SAndroid Build Coastguard Worker
1071*8975f5c5SAndroid Build Coastguard Worker // Creates a mipmapped 3D texture with two layers, and calls ANGLE's GenerateMipmap.
1072*8975f5c5SAndroid Build Coastguard Worker // Then tests if the mipmaps are rendered correctly for all two layers.
1073*8975f5c5SAndroid Build Coastguard Worker // This is the same as MipmapTestES3.MipmapsForTexture3D but for GL_OES_texture_3D extension on
1074*8975f5c5SAndroid Build Coastguard Worker // GLES 2.0 instead.
TEST_P(MipmapTest,MipmapsForTexture3DOES)1075*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTest, MipmapsForTexture3DOES)
1076*8975f5c5SAndroid Build Coastguard Worker {
1077*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_3D"));
1078*8975f5c5SAndroid Build Coastguard Worker
1079*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42263501
1080*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF((IsPixel2() || IsNexus5X()) && IsOpenGLES());
1081*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264262
1082*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOzone());
1083*8975f5c5SAndroid Build Coastguard Worker
1084*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1085*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1086*8975f5c5SAndroid Build Coastguard Worker
1087*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
1088*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_3D, texture);
1089*8975f5c5SAndroid Build Coastguard Worker
1090*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1091*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1092*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1093*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 3, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1094*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 4, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1095*8975f5c5SAndroid Build Coastguard Worker
1096*8975f5c5SAndroid Build Coastguard Worker // Fill the first layer with red
1097*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(16 * 16, GLColor::red);
1098*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1099*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1100*8975f5c5SAndroid Build Coastguard Worker
1101*8975f5c5SAndroid Build Coastguard Worker // Fill the second layer with green
1102*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(16 * 16, GLColor::green);
1103*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1104*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1105*8975f5c5SAndroid Build Coastguard Worker
1106*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1107*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1108*8975f5c5SAndroid Build Coastguard Worker
1109*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1110*8975f5c5SAndroid Build Coastguard Worker
1111*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
1112*8975f5c5SAndroid Build Coastguard Worker
1113*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1114*8975f5c5SAndroid Build Coastguard Worker
1115*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m3DProgram);
1116*8975f5c5SAndroid Build Coastguard Worker
1117*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1118*8975f5c5SAndroid Build Coastguard Worker
1119*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 0
1120*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1121*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 0.);
1122*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.25f);
1123*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1124*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1125*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1126*8975f5c5SAndroid Build Coastguard Worker
1127*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1128*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.75f);
1129*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1130*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1131*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1132*8975f5c5SAndroid Build Coastguard Worker
1133*8975f5c5SAndroid Build Coastguard Worker // Regenerate mipmap of same color texture
1134*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1135*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1136*8975f5c5SAndroid Build Coastguard Worker
1137*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
1138*8975f5c5SAndroid Build Coastguard Worker
1139*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1140*8975f5c5SAndroid Build Coastguard Worker
1141*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 1 8*8*1
1142*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 1.);
1143*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1144*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1145*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1146*8975f5c5SAndroid Build Coastguard Worker
1147*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 2 4*4*1
1148*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 2.);
1149*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1150*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1151*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1152*8975f5c5SAndroid Build Coastguard Worker
1153*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 3 2*2*1
1154*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 3.);
1155*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1156*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1157*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1158*8975f5c5SAndroid Build Coastguard Worker
1159*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 4 1*1*1
1160*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 4.);
1161*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1162*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1163*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1164*8975f5c5SAndroid Build Coastguard Worker }
1165*8975f5c5SAndroid Build Coastguard Worker
1166*8975f5c5SAndroid Build Coastguard Worker // This test verifies 3D texture mipmap generation uses box filter on Metal back-end.
1167*8975f5c5SAndroid Build Coastguard Worker class Mipmap3DBoxFilterTest : public MipmapTest
1168*8975f5c5SAndroid Build Coastguard Worker {};
1169*8975f5c5SAndroid Build Coastguard Worker
TEST_P(Mipmap3DBoxFilterTest,GenMipmapsForTexture3DOES)1170*8975f5c5SAndroid Build Coastguard Worker TEST_P(Mipmap3DBoxFilterTest, GenMipmapsForTexture3DOES)
1171*8975f5c5SAndroid Build Coastguard Worker {
1172*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1173*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1174*8975f5c5SAndroid Build Coastguard Worker
1175*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
1176*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_3D, texture);
1177*8975f5c5SAndroid Build Coastguard Worker
1178*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1179*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 16, 16, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1180*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1181*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1182*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 4, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1183*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 5, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1184*8975f5c5SAndroid Build Coastguard Worker
1185*8975f5c5SAndroid Build Coastguard Worker // Fill the first layer with red
1186*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(32 * 32, GLColor::red);
1187*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 0, 32, 32, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1188*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1189*8975f5c5SAndroid Build Coastguard Worker
1190*8975f5c5SAndroid Build Coastguard Worker // Fill the second layer with green
1191*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(32 * 32, GLColor::green);
1192*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 1, 32, 32, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1193*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1194*8975f5c5SAndroid Build Coastguard Worker
1195*8975f5c5SAndroid Build Coastguard Worker // Fill the 3rd layer with blue
1196*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(32 * 32, GLColor::blue);
1197*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 2, 32, 32, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1198*8975f5c5SAndroid Build Coastguard Worker pixelsBlue.data());
1199*8975f5c5SAndroid Build Coastguard Worker
1200*8975f5c5SAndroid Build Coastguard Worker // Fill the 4th layer with yellow
1201*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsYellow(32 * 32, GLColor::yellow);
1202*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 3, 32, 32, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1203*8975f5c5SAndroid Build Coastguard Worker pixelsYellow.data());
1204*8975f5c5SAndroid Build Coastguard Worker
1205*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1206*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1207*8975f5c5SAndroid Build Coastguard Worker
1208*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1209*8975f5c5SAndroid Build Coastguard Worker
1210*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
1211*8975f5c5SAndroid Build Coastguard Worker
1212*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1213*8975f5c5SAndroid Build Coastguard Worker
1214*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m3DProgram);
1215*8975f5c5SAndroid Build Coastguard Worker
1216*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1217*8975f5c5SAndroid Build Coastguard Worker
1218*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 0
1219*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1220*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 0.);
1221*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.125f);
1222*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1223*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1224*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1225*8975f5c5SAndroid Build Coastguard Worker
1226*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1227*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.375f);
1228*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1229*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1230*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1231*8975f5c5SAndroid Build Coastguard Worker
1232*8975f5c5SAndroid Build Coastguard Worker // Draw the 3rd slice
1233*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.625f);
1234*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1235*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1236*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::blue);
1237*8975f5c5SAndroid Build Coastguard Worker
1238*8975f5c5SAndroid Build Coastguard Worker // Draw the 4th slice
1239*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.875f);
1240*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1241*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1242*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::yellow);
1243*8975f5c5SAndroid Build Coastguard Worker
1244*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 1
1245*8975f5c5SAndroid Build Coastguard Worker // The second mipmap should have two slice.
1246*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 1.);
1247*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.25f);
1248*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1249*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1250*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 0, 255, 1.0);
1251*8975f5c5SAndroid Build Coastguard Worker
1252*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.75f);
1253*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1254*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1255*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 127, 255, 1.0);
1256*8975f5c5SAndroid Build Coastguard Worker
1257*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 2
1258*8975f5c5SAndroid Build Coastguard Worker // The 3rd mipmap should only have one slice.
1259*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 2.);
1260*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.25f);
1261*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1262*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1263*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1264*8975f5c5SAndroid Build Coastguard Worker
1265*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.75f);
1266*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1267*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1268*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1269*8975f5c5SAndroid Build Coastguard Worker
1270*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 3
1271*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 3.);
1272*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1273*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1274*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1275*8975f5c5SAndroid Build Coastguard Worker
1276*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 4
1277*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 4.);
1278*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1279*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1280*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1281*8975f5c5SAndroid Build Coastguard Worker
1282*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 5
1283*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 5.);
1284*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1285*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1286*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1287*8975f5c5SAndroid Build Coastguard Worker }
1288*8975f5c5SAndroid Build Coastguard Worker
1289*8975f5c5SAndroid Build Coastguard Worker // Test that non-power of two texture also has mipmap generated using box filter
TEST_P(Mipmap3DBoxFilterTest,GenMipmapsForTexture3DOESNpot)1290*8975f5c5SAndroid Build Coastguard Worker TEST_P(Mipmap3DBoxFilterTest, GenMipmapsForTexture3DOESNpot)
1291*8975f5c5SAndroid Build Coastguard Worker {
1292*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1293*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1294*8975f5c5SAndroid Build Coastguard Worker
1295*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
1296*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_3D, texture);
1297*8975f5c5SAndroid Build Coastguard Worker
1298*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 30, 30, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1299*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 15, 15, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1300*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 7, 7, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1301*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 3, GL_RGBA, 3, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1302*8975f5c5SAndroid Build Coastguard Worker glTexImage3DOES(GL_TEXTURE_3D, 4, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1303*8975f5c5SAndroid Build Coastguard Worker
1304*8975f5c5SAndroid Build Coastguard Worker // Fill the first layer with red
1305*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(30 * 30, GLColor::red);
1306*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 0, 30, 30, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1307*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1308*8975f5c5SAndroid Build Coastguard Worker
1309*8975f5c5SAndroid Build Coastguard Worker // Fill the second layer with green
1310*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(30 * 30, GLColor::green);
1311*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 1, 30, 30, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1312*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1313*8975f5c5SAndroid Build Coastguard Worker
1314*8975f5c5SAndroid Build Coastguard Worker // Fill the 3rd layer with blue
1315*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(30 * 30, GLColor::blue);
1316*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 2, 30, 30, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1317*8975f5c5SAndroid Build Coastguard Worker pixelsBlue.data());
1318*8975f5c5SAndroid Build Coastguard Worker
1319*8975f5c5SAndroid Build Coastguard Worker // Fill the 4th layer with yellow
1320*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsYellow(30 * 30, GLColor::yellow);
1321*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3DOES(GL_TEXTURE_3D, 0, 0, 0, 3, 30, 30, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1322*8975f5c5SAndroid Build Coastguard Worker pixelsYellow.data());
1323*8975f5c5SAndroid Build Coastguard Worker
1324*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1325*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1326*8975f5c5SAndroid Build Coastguard Worker
1327*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1328*8975f5c5SAndroid Build Coastguard Worker
1329*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
1330*8975f5c5SAndroid Build Coastguard Worker
1331*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1332*8975f5c5SAndroid Build Coastguard Worker
1333*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m3DProgram);
1334*8975f5c5SAndroid Build Coastguard Worker
1335*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1336*8975f5c5SAndroid Build Coastguard Worker
1337*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 0
1338*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1339*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 0.);
1340*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.125f);
1341*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1342*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1343*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1344*8975f5c5SAndroid Build Coastguard Worker
1345*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1346*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.375f);
1347*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1348*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1349*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1350*8975f5c5SAndroid Build Coastguard Worker
1351*8975f5c5SAndroid Build Coastguard Worker // Draw the 3rd slice
1352*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.625f);
1353*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1354*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1355*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::blue);
1356*8975f5c5SAndroid Build Coastguard Worker
1357*8975f5c5SAndroid Build Coastguard Worker // Draw the 4th slice
1358*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.875f);
1359*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1360*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1361*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::yellow);
1362*8975f5c5SAndroid Build Coastguard Worker
1363*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 1
1364*8975f5c5SAndroid Build Coastguard Worker // The second mipmap should have two slice.
1365*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 1.);
1366*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.25f);
1367*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1368*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1369*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 0, 255, 1.0);
1370*8975f5c5SAndroid Build Coastguard Worker
1371*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.75f);
1372*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1373*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1374*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 127, 255, 1.0);
1375*8975f5c5SAndroid Build Coastguard Worker
1376*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 2
1377*8975f5c5SAndroid Build Coastguard Worker // The 3rd mipmap should only have one slice.
1378*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 2.);
1379*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.25f);
1380*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1381*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1382*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1383*8975f5c5SAndroid Build Coastguard Worker
1384*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.75f);
1385*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1386*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1387*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1388*8975f5c5SAndroid Build Coastguard Worker
1389*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 3
1390*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 3.);
1391*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1392*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1393*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1394*8975f5c5SAndroid Build Coastguard Worker
1395*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 4
1396*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 4.);
1397*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1398*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1399*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1400*8975f5c5SAndroid Build Coastguard Worker
1401*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 5
1402*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 5.);
1403*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1404*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1405*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(px, py, 127, 127, 64, 255, 1.0);
1406*8975f5c5SAndroid Build Coastguard Worker }
1407*8975f5c5SAndroid Build Coastguard Worker
1408*8975f5c5SAndroid Build Coastguard Worker // Creates a mipmapped 2D array texture with three layers, and calls ANGLE's GenerateMipmap.
1409*8975f5c5SAndroid Build Coastguard Worker // Then tests if the mipmaps are rendered correctly for all three layers.
TEST_P(MipmapTestES3,MipmapsForTextureArray)1410*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, MipmapsForTextureArray)
1411*8975f5c5SAndroid Build Coastguard Worker {
1412*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1413*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1414*8975f5c5SAndroid Build Coastguard Worker
1415*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
1416*8975f5c5SAndroid Build Coastguard Worker
1417*8975f5c5SAndroid Build Coastguard Worker glTexStorage3D(GL_TEXTURE_2D_ARRAY, 5, GL_RGBA8, 16, 16, 3);
1418*8975f5c5SAndroid Build Coastguard Worker
1419*8975f5c5SAndroid Build Coastguard Worker // Fill the first layer with red
1420*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(16 * 16, GLColor::red);
1421*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1422*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1423*8975f5c5SAndroid Build Coastguard Worker
1424*8975f5c5SAndroid Build Coastguard Worker // Fill the second layer with green
1425*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(16 * 16, GLColor::green);
1426*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1427*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1428*8975f5c5SAndroid Build Coastguard Worker
1429*8975f5c5SAndroid Build Coastguard Worker // Fill the third layer with blue
1430*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(16 * 16, GLColor::blue);
1431*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1432*8975f5c5SAndroid Build Coastguard Worker pixelsBlue.data());
1433*8975f5c5SAndroid Build Coastguard Worker
1434*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1435*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1436*8975f5c5SAndroid Build Coastguard Worker
1437*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1438*8975f5c5SAndroid Build Coastguard Worker
1439*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
1440*8975f5c5SAndroid Build Coastguard Worker
1441*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1442*8975f5c5SAndroid Build Coastguard Worker
1443*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mArrayProgram);
1444*8975f5c5SAndroid Build Coastguard Worker
1445*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1446*8975f5c5SAndroid Build Coastguard Worker
1447*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1448*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 0);
1449*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1450*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1451*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1452*8975f5c5SAndroid Build Coastguard Worker
1453*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1454*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 1);
1455*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1456*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1457*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1458*8975f5c5SAndroid Build Coastguard Worker
1459*8975f5c5SAndroid Build Coastguard Worker // Draw the third slice
1460*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 2);
1461*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1462*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1463*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::blue);
1464*8975f5c5SAndroid Build Coastguard Worker }
1465*8975f5c5SAndroid Build Coastguard Worker
1466*8975f5c5SAndroid Build Coastguard Worker // Create a mipmapped 2D array texture with more layers than width / height, and call
1467*8975f5c5SAndroid Build Coastguard Worker // GenerateMipmap.
TEST_P(MipmapTestES3,MipmapForDeepTextureArray)1468*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, MipmapForDeepTextureArray)
1469*8975f5c5SAndroid Build Coastguard Worker {
1470*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1471*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1472*8975f5c5SAndroid Build Coastguard Worker
1473*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
1474*8975f5c5SAndroid Build Coastguard Worker
1475*8975f5c5SAndroid Build Coastguard Worker // Fill the whole texture with red.
1476*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
1477*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1478*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1479*8975f5c5SAndroid Build Coastguard Worker
1480*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1481*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1482*8975f5c5SAndroid Build Coastguard Worker
1483*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1484*8975f5c5SAndroid Build Coastguard Worker
1485*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
1486*8975f5c5SAndroid Build Coastguard Worker
1487*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1488*8975f5c5SAndroid Build Coastguard Worker
1489*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mArrayProgram);
1490*8975f5c5SAndroid Build Coastguard Worker
1491*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1492*8975f5c5SAndroid Build Coastguard Worker
1493*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1494*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 0);
1495*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1496*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1497*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1498*8975f5c5SAndroid Build Coastguard Worker
1499*8975f5c5SAndroid Build Coastguard Worker // Draw the fourth slice
1500*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 3);
1501*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1502*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1503*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1504*8975f5c5SAndroid Build Coastguard Worker }
1505*8975f5c5SAndroid Build Coastguard Worker
1506*8975f5c5SAndroid Build Coastguard Worker // Creates a mipmapped 3D texture with two layers, and calls ANGLE's GenerateMipmap.
1507*8975f5c5SAndroid Build Coastguard Worker // Then tests if the mipmaps are rendered correctly for all two layers.
TEST_P(MipmapTestES3,MipmapsForTexture3D)1508*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, MipmapsForTexture3D)
1509*8975f5c5SAndroid Build Coastguard Worker {
1510*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1511*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1512*8975f5c5SAndroid Build Coastguard Worker
1513*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_3D, mTexture);
1514*8975f5c5SAndroid Build Coastguard Worker
1515*8975f5c5SAndroid Build Coastguard Worker glTexStorage3D(GL_TEXTURE_3D, 5, GL_RGBA8, 16, 16, 2);
1516*8975f5c5SAndroid Build Coastguard Worker
1517*8975f5c5SAndroid Build Coastguard Worker // Fill the first layer with red
1518*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(16 * 16, GLColor::red);
1519*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1520*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1521*8975f5c5SAndroid Build Coastguard Worker
1522*8975f5c5SAndroid Build Coastguard Worker // Fill the second layer with green
1523*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(16 * 16, GLColor::green);
1524*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1525*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1526*8975f5c5SAndroid Build Coastguard Worker
1527*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1528*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1529*8975f5c5SAndroid Build Coastguard Worker
1530*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1531*8975f5c5SAndroid Build Coastguard Worker
1532*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
1533*8975f5c5SAndroid Build Coastguard Worker
1534*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1535*8975f5c5SAndroid Build Coastguard Worker
1536*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m3DProgram);
1537*8975f5c5SAndroid Build Coastguard Worker
1538*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1539*8975f5c5SAndroid Build Coastguard Worker
1540*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 0
1541*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1542*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 0.);
1543*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.25f);
1544*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1545*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1546*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1547*8975f5c5SAndroid Build Coastguard Worker
1548*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1549*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DSliceUniformLocation, 0.75f);
1550*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1551*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1552*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1553*8975f5c5SAndroid Build Coastguard Worker
1554*8975f5c5SAndroid Build Coastguard Worker // Regenerate mipmap of same color texture
1555*8975f5c5SAndroid Build Coastguard Worker glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1556*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1557*8975f5c5SAndroid Build Coastguard Worker
1558*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
1559*8975f5c5SAndroid Build Coastguard Worker
1560*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1561*8975f5c5SAndroid Build Coastguard Worker
1562*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 1 8*8*1
1563*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 1.);
1564*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1565*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1566*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1567*8975f5c5SAndroid Build Coastguard Worker
1568*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 2 4*4*1
1569*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 2.);
1570*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1571*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1572*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1573*8975f5c5SAndroid Build Coastguard Worker
1574*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 3 2*2*1
1575*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 3.);
1576*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1577*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1578*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1579*8975f5c5SAndroid Build Coastguard Worker
1580*8975f5c5SAndroid Build Coastguard Worker // Mipmap level 4 1*1*1
1581*8975f5c5SAndroid Build Coastguard Worker glUniform1f(mTexture3DLODUniformLocation, 4.);
1582*8975f5c5SAndroid Build Coastguard Worker drawQuad(m3DProgram, "position", 0.5f);
1583*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1584*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1585*8975f5c5SAndroid Build Coastguard Worker }
1586*8975f5c5SAndroid Build Coastguard Worker
1587*8975f5c5SAndroid Build Coastguard Worker // Create a 2D array, then immediately redefine it to have fewer layers. Regression test for a bug
1588*8975f5c5SAndroid Build Coastguard Worker // in the Vulkan backend where the old higher-layer-count data upload was not removed.
TEST_P(MipmapTestES3,TextureArrayRedefineThenGenerateMipmap)1589*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, TextureArrayRedefineThenGenerateMipmap)
1590*8975f5c5SAndroid Build Coastguard Worker {
1591*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1592*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1593*8975f5c5SAndroid Build Coastguard Worker
1594*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
1595*8975f5c5SAndroid Build Coastguard Worker
1596*8975f5c5SAndroid Build Coastguard Worker // Fill the whole texture with red, then redefine it and fill with green
1597*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
1598*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
1599*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1600*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1601*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1602*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1603*8975f5c5SAndroid Build Coastguard Worker
1604*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1605*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1606*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1607*8975f5c5SAndroid Build Coastguard Worker
1608*8975f5c5SAndroid Build Coastguard Worker // Generate mipmaps
1609*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
1610*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1611*8975f5c5SAndroid Build Coastguard Worker
1612*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mArrayProgram);
1613*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1614*8975f5c5SAndroid Build Coastguard Worker
1615*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1616*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 0);
1617*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1618*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1619*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1620*8975f5c5SAndroid Build Coastguard Worker
1621*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1622*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 1);
1623*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1624*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1625*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1626*8975f5c5SAndroid Build Coastguard Worker }
1627*8975f5c5SAndroid Build Coastguard Worker
1628*8975f5c5SAndroid Build Coastguard Worker // Create a 2D array, use it, then redefine it to have fewer layers. Regression test for a bug in
1629*8975f5c5SAndroid Build Coastguard Worker // the Vulkan backend where the old higher-layer-count data upload was not removed.
TEST_P(MipmapTestES3,TextureArrayUseThenRedefineThenGenerateMipmap)1630*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, TextureArrayUseThenRedefineThenGenerateMipmap)
1631*8975f5c5SAndroid Build Coastguard Worker {
1632*8975f5c5SAndroid Build Coastguard Worker int px = getWindowWidth() / 2;
1633*8975f5c5SAndroid Build Coastguard Worker int py = getWindowHeight() / 2;
1634*8975f5c5SAndroid Build Coastguard Worker
1635*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
1636*8975f5c5SAndroid Build Coastguard Worker
1637*8975f5c5SAndroid Build Coastguard Worker // Fill the whole texture with red.
1638*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
1639*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1640*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1641*8975f5c5SAndroid Build Coastguard Worker
1642*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1643*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1644*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1645*8975f5c5SAndroid Build Coastguard Worker
1646*8975f5c5SAndroid Build Coastguard Worker // Generate mipmap
1647*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
1648*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1649*8975f5c5SAndroid Build Coastguard Worker
1650*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mArrayProgram);
1651*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1652*8975f5c5SAndroid Build Coastguard Worker
1653*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1654*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 0);
1655*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1656*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1657*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1658*8975f5c5SAndroid Build Coastguard Worker
1659*8975f5c5SAndroid Build Coastguard Worker // Draw the fourth slice
1660*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 3);
1661*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1662*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1663*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1664*8975f5c5SAndroid Build Coastguard Worker
1665*8975f5c5SAndroid Build Coastguard Worker // Redefine the image and fill with green
1666*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
1667*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1668*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1669*8975f5c5SAndroid Build Coastguard Worker
1670*8975f5c5SAndroid Build Coastguard Worker // Generate mipmap
1671*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
1672*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1673*8975f5c5SAndroid Build Coastguard Worker
1674*8975f5c5SAndroid Build Coastguard Worker // Draw the first slice
1675*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 0);
1676*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1677*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1678*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1679*8975f5c5SAndroid Build Coastguard Worker
1680*8975f5c5SAndroid Build Coastguard Worker // Draw the second slice
1681*8975f5c5SAndroid Build Coastguard Worker glUniform1i(mTextureArraySliceUniformLocation, 1);
1682*8975f5c5SAndroid Build Coastguard Worker drawQuad(mArrayProgram, "position", 0.5f);
1683*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1684*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1685*8975f5c5SAndroid Build Coastguard Worker }
1686*8975f5c5SAndroid Build Coastguard Worker
1687*8975f5c5SAndroid Build Coastguard Worker // Create a 2D texture with levels 0-2, call GenerateMipmap with base level 1 so that level 0 stays
1688*8975f5c5SAndroid Build Coastguard Worker // the same, and then sample levels 0 and 2.
1689*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10:
1690*8975f5c5SAndroid Build Coastguard Worker // "Mipmap generation replaces texel array levels levelbase + 1 through q with arrays derived from
1691*8975f5c5SAndroid Build Coastguard Worker // the levelbase array, regardless of their previous contents. All other mipmap arrays, including
1692*8975f5c5SAndroid Build Coastguard Worker // the levelbase array, are left unchanged by this computation."
TEST_P(MipmapTestES3,GenerateMipmapBaseLevel)1693*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapBaseLevel)
1694*8975f5c5SAndroid Build Coastguard Worker {
1695*8975f5c5SAndroid Build Coastguard Worker // Observed incorrect rendering on AMD, sampling level 2 returns black.
1696*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
1697*8975f5c5SAndroid Build Coastguard Worker
1698*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
1699*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
1700*8975f5c5SAndroid Build Coastguard Worker
1701*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
1702*8975f5c5SAndroid Build Coastguard Worker
1703*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(getWindowWidth(), getWindowHeight());
1704*8975f5c5SAndroid Build Coastguard Worker
1705*8975f5c5SAndroid Build Coastguard Worker // Fill level 0 with blue
1706*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowHeight(), GLColor::blue);
1707*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1708*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, pixelsBlue.data());
1709*8975f5c5SAndroid Build Coastguard Worker
1710*8975f5c5SAndroid Build Coastguard Worker // Fill level 1 with red
1711*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowHeight() / 4, GLColor::red);
1712*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
1713*8975f5c5SAndroid Build Coastguard Worker GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
1714*8975f5c5SAndroid Build Coastguard Worker
1715*8975f5c5SAndroid Build Coastguard Worker // Fill level 2 with green
1716*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowHeight() / 16, GLColor::green);
1717*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, getWindowWidth() / 4, getWindowHeight() / 4, 0,
1718*8975f5c5SAndroid Build Coastguard Worker GL_RGBA, GL_UNSIGNED_BYTE, pixelsGreen.data());
1719*8975f5c5SAndroid Build Coastguard Worker
1720*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1721*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1722*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1723*8975f5c5SAndroid Build Coastguard Worker
1724*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1725*8975f5c5SAndroid Build Coastguard Worker
1726*8975f5c5SAndroid Build Coastguard Worker // The blue level 0 should be untouched by this since base level is 1.
1727*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
1728*8975f5c5SAndroid Build Coastguard Worker
1729*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1730*8975f5c5SAndroid Build Coastguard Worker
1731*8975f5c5SAndroid Build Coastguard Worker // Draw using level 2. It should be set to red by GenerateMipmap.
1732*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1733*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red);
1734*8975f5c5SAndroid Build Coastguard Worker
1735*8975f5c5SAndroid Build Coastguard Worker // Draw using level 0. It should still be blue.
1736*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1737*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
1738*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
1739*8975f5c5SAndroid Build Coastguard Worker }
1740*8975f5c5SAndroid Build Coastguard Worker
1741*8975f5c5SAndroid Build Coastguard Worker // Test that generating mipmaps doesn't discard updates staged to out-of-range mips.
TEST_P(MipmapTestES3,GenerateMipmapPreservesOutOfRangeMips)1742*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapPreservesOutOfRangeMips)
1743*8975f5c5SAndroid Build Coastguard Worker {
1744*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42263372
1745*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOpenGL() && IsWindows() && (IsAMD() || IsIntel()));
1746*8975f5c5SAndroid Build Coastguard Worker
1747*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42263374
1748*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOpenGL() && IsLinux() && IsIntel());
1749*8975f5c5SAndroid Build Coastguard Worker
1750*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/40096708
1751*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsNVIDIAShield());
1752*8975f5c5SAndroid Build Coastguard Worker
1753*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
1754*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
1755*8975f5c5SAndroid Build Coastguard Worker
1756*8975f5c5SAndroid Build Coastguard Worker constexpr GLint kTextureSize = 16;
1757*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kLevel0Data(kTextureSize * kTextureSize, GLColor::red);
1758*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kLevel1Data(kTextureSize * kTextureSize, GLColor::green);
1759*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLColor> kLevel6Data(kTextureSize * kTextureSize, GLColor::blue);
1760*8975f5c5SAndroid Build Coastguard Worker
1761*8975f5c5SAndroid Build Coastguard Worker // Initialize a 16x16 RGBA8 texture with red, green and blue for levels 0, 1 and 6 respectively.
1762*8975f5c5SAndroid Build Coastguard Worker GLTexture tex;
1763*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, tex);
1764*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
1765*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kLevel0Data.data());
1766*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
1767*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kLevel1Data.data());
1768*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
1769*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, kLevel6Data.data());
1770*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1771*8975f5c5SAndroid Build Coastguard Worker
1772*8975f5c5SAndroid Build Coastguard Worker // Set base level to 1, and generate mipmaps. Levels 1 through 5 will be green.
1773*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1774*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1775*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1776*8975f5c5SAndroid Build Coastguard Worker
1777*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
1778*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, kLevel1Data[0]);
1779*8975f5c5SAndroid Build Coastguard Worker
1780*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
1781*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1782*8975f5c5SAndroid Build Coastguard Worker
1783*8975f5c5SAndroid Build Coastguard Worker // Verify that the mips are all green.
1784*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1785*8975f5c5SAndroid Build Coastguard Worker for (int mip = 0; mip < 5; ++mip)
1786*8975f5c5SAndroid Build Coastguard Worker {
1787*8975f5c5SAndroid Build Coastguard Worker int scale = 1 << mip;
1788*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / scale, getWindowHeight() / scale);
1789*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / scale / 2, getWindowHeight() / scale / 2,
1790*8975f5c5SAndroid Build Coastguard Worker kLevel1Data[0]);
1791*8975f5c5SAndroid Build Coastguard Worker }
1792*8975f5c5SAndroid Build Coastguard Worker
1793*8975f5c5SAndroid Build Coastguard Worker // Verify that level 0 is red. TODO: setting MAX_LEVEL should be unnecessary, but is needed to
1794*8975f5c5SAndroid Build Coastguard Worker // work around a bug in the Vulkan backend. http://anglebug.com/40096706
1795*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1796*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
1797*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1798*8975f5c5SAndroid Build Coastguard Worker
1799*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
1800*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, kLevel0Data[0]);
1801*8975f5c5SAndroid Build Coastguard Worker
1802*8975f5c5SAndroid Build Coastguard Worker // Verify that level 6 is blue.
1803*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 6);
1804*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
1805*8975f5c5SAndroid Build Coastguard Worker
1806*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
1807*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, kLevel6Data[0]);
1808*8975f5c5SAndroid Build Coastguard Worker }
1809*8975f5c5SAndroid Build Coastguard Worker
1810*8975f5c5SAndroid Build Coastguard Worker // Create a cube map with levels 0-2, call GenerateMipmap with base level 1 so that level 0 stays
1811*8975f5c5SAndroid Build Coastguard Worker // the same, and then sample levels 0 and 2.
1812*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10:
1813*8975f5c5SAndroid Build Coastguard Worker // "Mipmap generation replaces texel array levels levelbase + 1 through q with arrays derived from
1814*8975f5c5SAndroid Build Coastguard Worker // the levelbase array, regardless of their previous contents. All other mipmap arrays, including
1815*8975f5c5SAndroid Build Coastguard Worker // the levelbase array, are left unchanged by this computation."
TEST_P(MipmapTestES3,GenerateMipmapCubeBaseLevel)1816*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapCubeBaseLevel)
1817*8975f5c5SAndroid Build Coastguard Worker {
1818*8975f5c5SAndroid Build Coastguard Worker // Observed incorrect rendering on AMD, sampling level 2 returns black.
1819*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
1820*8975f5c5SAndroid Build Coastguard Worker
1821*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
1822*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
1823*8975f5c5SAndroid Build Coastguard Worker
1824*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(getWindowWidth(), getWindowHeight());
1825*8975f5c5SAndroid Build Coastguard Worker
1826*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
1827*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowWidth(), GLColor::blue);
1828*8975f5c5SAndroid Build Coastguard Worker TexImageCubeMapFaces(0, GL_RGBA8, getWindowWidth(), GL_RGBA, GL_UNSIGNED_BYTE,
1829*8975f5c5SAndroid Build Coastguard Worker pixelsBlue.data());
1830*8975f5c5SAndroid Build Coastguard Worker
1831*8975f5c5SAndroid Build Coastguard Worker // Fill level 1 with red
1832*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowWidth() / 4, GLColor::red);
1833*8975f5c5SAndroid Build Coastguard Worker TexImageCubeMapFaces(1, GL_RGBA8, getWindowWidth() / 2, GL_RGBA, GL_UNSIGNED_BYTE,
1834*8975f5c5SAndroid Build Coastguard Worker pixelsRed.data());
1835*8975f5c5SAndroid Build Coastguard Worker
1836*8975f5c5SAndroid Build Coastguard Worker // Fill level 2 with green
1837*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowWidth() / 16, GLColor::green);
1838*8975f5c5SAndroid Build Coastguard Worker TexImageCubeMapFaces(2, GL_RGBA8, getWindowWidth() / 4, GL_RGBA, GL_UNSIGNED_BYTE,
1839*8975f5c5SAndroid Build Coastguard Worker pixelsGreen.data());
1840*8975f5c5SAndroid Build Coastguard Worker
1841*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1842*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1843*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
1844*8975f5c5SAndroid Build Coastguard Worker
1845*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1846*8975f5c5SAndroid Build Coastguard Worker
1847*8975f5c5SAndroid Build Coastguard Worker // The blue level 0 should be untouched by this since base level is 1.
1848*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
1849*8975f5c5SAndroid Build Coastguard Worker
1850*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1851*8975f5c5SAndroid Build Coastguard Worker
1852*8975f5c5SAndroid Build Coastguard Worker // Draw using level 2. It should be set to red by GenerateMipmap.
1853*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1854*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red);
1855*8975f5c5SAndroid Build Coastguard Worker
1856*8975f5c5SAndroid Build Coastguard Worker // Observed incorrect rendering on NVIDIA, level zero seems to be incorrectly affected by
1857*8975f5c5SAndroid Build Coastguard Worker // GenerateMipmap.
1858*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42262495
1859*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL());
1860*8975f5c5SAndroid Build Coastguard Worker
1861*8975f5c5SAndroid Build Coastguard Worker // Draw using level 0. It should still be blue.
1862*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
1863*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight());
1864*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
1865*8975f5c5SAndroid Build Coastguard Worker }
1866*8975f5c5SAndroid Build Coastguard Worker
1867*8975f5c5SAndroid Build Coastguard Worker // Create a texture with levels 0-2, call GenerateMipmap with max level 1 so that level 2 stays the
1868*8975f5c5SAndroid Build Coastguard Worker // same, and then sample levels 1 and 2.
1869*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10:
1870*8975f5c5SAndroid Build Coastguard Worker // "Mipmap generation replaces texel array levels levelbase + 1 through q with arrays derived from
1871*8975f5c5SAndroid Build Coastguard Worker // the levelbase array, regardless of their previous contents. All other mipmap arrays, including
1872*8975f5c5SAndroid Build Coastguard Worker // the levelbase array, are left unchanged by this computation."
TEST_P(MipmapTestES3,GenerateMipmapMaxLevel)1873*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapMaxLevel)
1874*8975f5c5SAndroid Build Coastguard Worker {
1875*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
1876*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
1877*8975f5c5SAndroid Build Coastguard Worker
1878*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
1879*8975f5c5SAndroid Build Coastguard Worker
1880*8975f5c5SAndroid Build Coastguard Worker // Fill level 0 with blue
1881*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowHeight(), GLColor::blue);
1882*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1883*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, pixelsBlue.data());
1884*8975f5c5SAndroid Build Coastguard Worker
1885*8975f5c5SAndroid Build Coastguard Worker // Fill level 1 with red
1886*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowHeight() / 4, GLColor::red);
1887*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
1888*8975f5c5SAndroid Build Coastguard Worker GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
1889*8975f5c5SAndroid Build Coastguard Worker
1890*8975f5c5SAndroid Build Coastguard Worker // Fill level 2 with green
1891*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowHeight() / 16, GLColor::green);
1892*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, getWindowWidth() / 4, getWindowHeight() / 4, 0,
1893*8975f5c5SAndroid Build Coastguard Worker GL_RGBA, GL_UNSIGNED_BYTE, pixelsGreen.data());
1894*8975f5c5SAndroid Build Coastguard Worker
1895*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1896*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1897*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1898*8975f5c5SAndroid Build Coastguard Worker
1899*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1900*8975f5c5SAndroid Build Coastguard Worker
1901*8975f5c5SAndroid Build Coastguard Worker // The green level 2 should be untouched by this since max level is 1.
1902*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
1903*8975f5c5SAndroid Build Coastguard Worker
1904*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1905*8975f5c5SAndroid Build Coastguard Worker
1906*8975f5c5SAndroid Build Coastguard Worker // Draw using level 1. It should be set to blue by GenerateMipmap.
1907*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2);
1908*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
1909*8975f5c5SAndroid Build Coastguard Worker
1910*8975f5c5SAndroid Build Coastguard Worker // Draw using level 2. It should still be green.
1911*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1912*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
1913*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green);
1914*8975f5c5SAndroid Build Coastguard Worker }
1915*8975f5c5SAndroid Build Coastguard Worker
1916*8975f5c5SAndroid Build Coastguard Worker // Call GenerateMipmap with out-of-range base level. The spec is interpreted so that an out-of-range
1917*8975f5c5SAndroid Build Coastguard Worker // base level does not have a color-renderable/texture-filterable internal format, so the
1918*8975f5c5SAndroid Build Coastguard Worker // GenerateMipmap call generates INVALID_OPERATION. GLES 3.0.4 section 3.8.10:
1919*8975f5c5SAndroid Build Coastguard Worker // "If the levelbase array was not specified with an unsized internal format from table 3.3 or a
1920*8975f5c5SAndroid Build Coastguard Worker // sized internal format that is both color-renderable and texture-filterable according to table
1921*8975f5c5SAndroid Build Coastguard Worker // 3.13, an INVALID_OPERATION error is generated."
TEST_P(MipmapTestES3,GenerateMipmapBaseLevelOutOfRange)1922*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRange)
1923*8975f5c5SAndroid Build Coastguard Worker {
1924*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
1925*8975f5c5SAndroid Build Coastguard Worker
1926*8975f5c5SAndroid Build Coastguard Worker // Fill level 0 with blue
1927*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowHeight(), GLColor::blue);
1928*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1929*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, pixelsBlue.data());
1930*8975f5c5SAndroid Build Coastguard Worker
1931*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1000);
1932*8975f5c5SAndroid Build Coastguard Worker
1933*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1934*8975f5c5SAndroid Build Coastguard Worker
1935*8975f5c5SAndroid Build Coastguard Worker // Expecting the out-of-range base level to be treated as not color-renderable and
1936*8975f5c5SAndroid Build Coastguard Worker // texture-filterable.
1937*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
1938*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1939*8975f5c5SAndroid Build Coastguard Worker
1940*8975f5c5SAndroid Build Coastguard Worker // Draw using level 0. It should still be blue.
1941*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1942*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1943*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1944*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
1945*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
1946*8975f5c5SAndroid Build Coastguard Worker }
1947*8975f5c5SAndroid Build Coastguard Worker
1948*8975f5c5SAndroid Build Coastguard Worker // Call GenerateMipmap with out-of-range base level on an immutable texture. The base level should
1949*8975f5c5SAndroid Build Coastguard Worker // be clamped, so the call doesn't generate an error.
TEST_P(MipmapTestES3,GenerateMipmapBaseLevelOutOfRangeImmutableTexture)1950*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRangeImmutableTexture)
1951*8975f5c5SAndroid Build Coastguard Worker {
1952*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
1953*8975f5c5SAndroid Build Coastguard Worker
1954*8975f5c5SAndroid Build Coastguard Worker glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
1955*8975f5c5SAndroid Build Coastguard Worker glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
1956*8975f5c5SAndroid Build Coastguard Worker
1957*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1000);
1958*8975f5c5SAndroid Build Coastguard Worker
1959*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1960*8975f5c5SAndroid Build Coastguard Worker
1961*8975f5c5SAndroid Build Coastguard Worker // This is essentially a no-op, since the texture only has one level.
1962*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
1963*8975f5c5SAndroid Build Coastguard Worker
1964*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1965*8975f5c5SAndroid Build Coastguard Worker
1966*8975f5c5SAndroid Build Coastguard Worker // The only level of the texture should still be green.
1967*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1968*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1969*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
1970*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
1971*8975f5c5SAndroid Build Coastguard Worker }
1972*8975f5c5SAndroid Build Coastguard Worker
1973*8975f5c5SAndroid Build Coastguard Worker // A native version of the WebGL2 test tex-base-level-bug.html
TEST_P(MipmapTestES3,BaseLevelTextureBug)1974*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, BaseLevelTextureBug)
1975*8975f5c5SAndroid Build Coastguard Worker {
1976*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsOpenGL() && IsAMD());
1977*8975f5c5SAndroid Build Coastguard Worker
1978*8975f5c5SAndroid Build Coastguard Worker // Regression in 10.12.4 needing workaround -- crbug.com/705865.
1979*8975f5c5SAndroid Build Coastguard Worker // Seems to be passing on AMD GPUs. Definitely not NVIDIA.
1980*8975f5c5SAndroid Build Coastguard Worker // Probably not Intel.
1981*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA());
1982*8975f5c5SAndroid Build Coastguard Worker
1983*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
1984*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
1985*8975f5c5SAndroid Build Coastguard Worker
1986*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> texDataRed(2u * 2u, GLColor::red);
1987*8975f5c5SAndroid Build Coastguard Worker
1988*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mTexture);
1989*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1990*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
1991*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1992*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1993*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1994*8975f5c5SAndroid Build Coastguard Worker
1995*8975f5c5SAndroid Build Coastguard Worker drawQuad(m2DProgram, "position", 0.5f);
1996*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1997*8975f5c5SAndroid Build Coastguard Worker
1998*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1999*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2000*8975f5c5SAndroid Build Coastguard Worker
2001*8975f5c5SAndroid Build Coastguard Worker drawQuad(m2DProgram, "position", 0.5f);
2002*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2003*8975f5c5SAndroid Build Coastguard Worker }
2004*8975f5c5SAndroid Build Coastguard Worker
TEST_P(MipmapTestES31,MipmapWithMemoryBarrier)2005*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES31, MipmapWithMemoryBarrier)
2006*8975f5c5SAndroid Build Coastguard Worker {
2007*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowHeight(), GLColor::red);
2008*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowHeight() / 4, GLColor::green);
2009*8975f5c5SAndroid Build Coastguard Worker
2010*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(#version 300 es
2011*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2012*8975f5c5SAndroid Build Coastguard Worker in vec4 position;
2013*8975f5c5SAndroid Build Coastguard Worker out vec2 texcoord;
2014*8975f5c5SAndroid Build Coastguard Worker
2015*8975f5c5SAndroid Build Coastguard Worker void main()
2016*8975f5c5SAndroid Build Coastguard Worker {
2017*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(position.xy, 0.0, 1.0);
2018*8975f5c5SAndroid Build Coastguard Worker texcoord = (position.xy * 0.5) + 0.5;
2019*8975f5c5SAndroid Build Coastguard Worker })";
2020*8975f5c5SAndroid Build Coastguard Worker
2021*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 300 es
2022*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2023*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler2D tex;
2024*8975f5c5SAndroid Build Coastguard Worker in vec2 texcoord;
2025*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
2026*8975f5c5SAndroid Build Coastguard Worker
2027*8975f5c5SAndroid Build Coastguard Worker void main()
2028*8975f5c5SAndroid Build Coastguard Worker {
2029*8975f5c5SAndroid Build Coastguard Worker out_FragColor = texture(tex, texcoord);
2030*8975f5c5SAndroid Build Coastguard Worker })";
2031*8975f5c5SAndroid Build Coastguard Worker
2032*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(m2DProgram, kVS, kFS);
2033*8975f5c5SAndroid Build Coastguard Worker glUseProgram(m2DProgram);
2034*8975f5c5SAndroid Build Coastguard Worker
2035*8975f5c5SAndroid Build Coastguard Worker // Create a texture with red and enable the mipmap
2036*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
2037*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, texture);
2038*8975f5c5SAndroid Build Coastguard Worker // Fill level 0 with red
2039*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
2040*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, pixelsRed.data());
2041*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2042*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2043*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2044*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
2045*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2046*8975f5c5SAndroid Build Coastguard Worker // level 2 is red
2047*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
2048*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red);
2049*8975f5c5SAndroid Build Coastguard Worker
2050*8975f5c5SAndroid Build Coastguard Worker // Clear the level 1 to green
2051*8975f5c5SAndroid Build Coastguard Worker glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
2052*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_BYTE, pixelsGreen.data());
2053*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2054*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2055*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
2056*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2057*8975f5c5SAndroid Build Coastguard Worker // Insert a memory barrier, then it will break the graph node submission order.
2058*8975f5c5SAndroid Build Coastguard Worker glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
2059*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2060*8975f5c5SAndroid Build Coastguard Worker // level 0 is red
2061*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
2062*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
2063*8975f5c5SAndroid Build Coastguard Worker // Draw using level 2. It should be set to green by GenerateMipmap.
2064*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4);
2065*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green);
2066*8975f5c5SAndroid Build Coastguard Worker }
2067*8975f5c5SAndroid Build Coastguard Worker
2068*8975f5c5SAndroid Build Coastguard Worker // Tests respecifying 3D mipmaps.
TEST_P(MipmapTestES3,Generate3DMipmapRespecification)2069*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, Generate3DMipmapRespecification)
2070*8975f5c5SAndroid Build Coastguard Worker {
2071*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixels(256 * 256 * 100, GLColor::black);
2072*8975f5c5SAndroid Build Coastguard Worker
2073*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
2074*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_3D, texture);
2075*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 256, 256, 100, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2076*8975f5c5SAndroid Build Coastguard Worker pixels.data());
2077*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, 128, 128, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2078*8975f5c5SAndroid Build Coastguard Worker pixels.data());
2079*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
2080*8975f5c5SAndroid Build Coastguard Worker
2081*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2082*8975f5c5SAndroid Build Coastguard Worker }
2083*8975f5c5SAndroid Build Coastguard Worker
2084*8975f5c5SAndroid Build Coastguard Worker // Test the calling glGenerateMipmap on a texture with a zero dimension doesn't crash.
TEST_P(MipmapTestES3,GenerateMipmapZeroSize)2085*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapZeroSize)
2086*8975f5c5SAndroid Build Coastguard Worker {
2087*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
2088*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, texture);
2089*8975f5c5SAndroid Build Coastguard Worker
2090*8975f5c5SAndroid Build Coastguard Worker // Create a texture with at least one dimension that's zero.
2091*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2092*8975f5c5SAndroid Build Coastguard Worker
2093*8975f5c5SAndroid Build Coastguard Worker // Attempt to generate mipmap. This shouldn't crash.
2094*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
2095*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2096*8975f5c5SAndroid Build Coastguard Worker
2097*8975f5c5SAndroid Build Coastguard Worker // Try the same with a 3D texture where depth is 0.
2098*8975f5c5SAndroid Build Coastguard Worker GLTexture texture2;
2099*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_3D, texture2);
2100*8975f5c5SAndroid Build Coastguard Worker glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2101*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_3D);
2102*8975f5c5SAndroid Build Coastguard Worker }
2103*8975f5c5SAndroid Build Coastguard Worker
2104*8975f5c5SAndroid Build Coastguard Worker // Test that reducing the size of the mipchain by resizing the base image then deleting it doesn't
2105*8975f5c5SAndroid Build Coastguard Worker // cause a crash. Issue found by fuzzer.
TEST_P(MipmapTestES3,ResizeBaseMipTo1x1ThenDelete)2106*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, ResizeBaseMipTo1x1ThenDelete)
2107*8975f5c5SAndroid Build Coastguard Worker {
2108*8975f5c5SAndroid Build Coastguard Worker GLTexture tex;
2109*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, tex);
2110*8975f5c5SAndroid Build Coastguard Worker
2111*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> data(2, GLColor::blue);
2112*8975f5c5SAndroid Build Coastguard Worker
2113*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
2114*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
2115*8975f5c5SAndroid Build Coastguard Worker
2116*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
2117*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2118*8975f5c5SAndroid Build Coastguard Worker
2119*8975f5c5SAndroid Build Coastguard Worker data[0] = GLColor::green;
2120*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
2121*8975f5c5SAndroid Build Coastguard Worker
2122*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
2123*8975f5c5SAndroid Build Coastguard Worker
2124*8975f5c5SAndroid Build Coastguard Worker tex.reset();
2125*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2126*8975f5c5SAndroid Build Coastguard Worker }
2127*8975f5c5SAndroid Build Coastguard Worker
2128*8975f5c5SAndroid Build Coastguard Worker // Test the calling generateMipmap with redefining texture and modifying baselevel.
TEST_P(MipmapTestES3,GenerateMipmapWithRedefineLevelAndTexture)2129*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES3, GenerateMipmapWithRedefineLevelAndTexture)
2130*8975f5c5SAndroid Build Coastguard Worker {
2131*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> pixels(1000000, GLColor::black);
2132*8975f5c5SAndroid Build Coastguard Worker
2133*8975f5c5SAndroid Build Coastguard Worker GLTexture texture;
2134*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, texture);
2135*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
2136*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
2137*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
2138*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2139*8975f5c5SAndroid Build Coastguard Worker glGenerateMipmap(GL_TEXTURE_2D);
2140*8975f5c5SAndroid Build Coastguard Worker
2141*8975f5c5SAndroid Build Coastguard Worker clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight());
2142*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::black);
2143*8975f5c5SAndroid Build Coastguard Worker }
2144*8975f5c5SAndroid Build Coastguard Worker
2145*8975f5c5SAndroid Build Coastguard Worker // Test that manually generating mipmaps using draw calls is functional
TEST_P(MipmapTestES31,GenerateMipmapWithDraw)2146*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES31, GenerateMipmapWithDraw)
2147*8975f5c5SAndroid Build Coastguard Worker {
2148*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(#version 310 es
2149*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2150*8975f5c5SAndroid Build Coastguard Worker
2151*8975f5c5SAndroid Build Coastguard Worker in vec4 position;
2152*8975f5c5SAndroid Build Coastguard Worker out vec2 texcoord;
2153*8975f5c5SAndroid Build Coastguard Worker
2154*8975f5c5SAndroid Build Coastguard Worker void main()
2155*8975f5c5SAndroid Build Coastguard Worker {
2156*8975f5c5SAndroid Build Coastguard Worker gl_Position = position;
2157*8975f5c5SAndroid Build Coastguard Worker texcoord = (position.xy * 0.5) + 0.5;
2158*8975f5c5SAndroid Build Coastguard Worker })";
2159*8975f5c5SAndroid Build Coastguard Worker
2160*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(#version 310 es
2161*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2162*8975f5c5SAndroid Build Coastguard Worker
2163*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler2D tex;
2164*8975f5c5SAndroid Build Coastguard Worker
2165*8975f5c5SAndroid Build Coastguard Worker in vec2 texcoord;
2166*8975f5c5SAndroid Build Coastguard Worker out vec4 frag_color;
2167*8975f5c5SAndroid Build Coastguard Worker
2168*8975f5c5SAndroid Build Coastguard Worker void main()
2169*8975f5c5SAndroid Build Coastguard Worker {
2170*8975f5c5SAndroid Build Coastguard Worker highp vec4 samples = textureGatherOffset(tex, texcoord, ivec2(0, 0), 0);
2171*8975f5c5SAndroid Build Coastguard Worker highp float max_r = max(max(samples.x, samples.y), max(samples.z, samples.w));
2172*8975f5c5SAndroid Build Coastguard Worker
2173*8975f5c5SAndroid Build Coastguard Worker frag_color = vec4(max_r, 0.0, 0.0, 1.0);
2174*8975f5c5SAndroid Build Coastguard Worker }
2175*8975f5c5SAndroid Build Coastguard Worker )";
2176*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(program, kVS, kFS);
2177*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, program);
2178*8975f5c5SAndroid Build Coastguard Worker
2179*8975f5c5SAndroid Build Coastguard Worker GLTexture tex;
2180*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, tex);
2181*8975f5c5SAndroid Build Coastguard Worker glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
2182*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2183*8975f5c5SAndroid Build Coastguard Worker
2184*8975f5c5SAndroid Build Coastguard Worker // clang-format off
2185*8975f5c5SAndroid Build Coastguard Worker constexpr GLubyte kRedColor[16] = {
2186*8975f5c5SAndroid Build Coastguard Worker 0x0c, 0x08, 0x4c, 0x48,
2187*8975f5c5SAndroid Build Coastguard Worker 0x00, 0x04, 0x40, 0x44,
2188*8975f5c5SAndroid Build Coastguard Worker 0xcc, 0xc8, 0x8c, 0x88,
2189*8975f5c5SAndroid Build Coastguard Worker 0xc0, 0xc4, 0x80, 0x84,
2190*8975f5c5SAndroid Build Coastguard Worker };
2191*8975f5c5SAndroid Build Coastguard Worker
2192*8975f5c5SAndroid Build Coastguard Worker constexpr GLubyte kExpectedMip1Color[4] = {
2193*8975f5c5SAndroid Build Coastguard Worker 0x0c, 0x4c,
2194*8975f5c5SAndroid Build Coastguard Worker 0xcc, 0x8c,
2195*8975f5c5SAndroid Build Coastguard Worker };
2196*8975f5c5SAndroid Build Coastguard Worker
2197*8975f5c5SAndroid Build Coastguard Worker constexpr GLubyte kExpectedMip2Color[1] = {
2198*8975f5c5SAndroid Build Coastguard Worker 0xcc
2199*8975f5c5SAndroid Build Coastguard Worker };
2200*8975f5c5SAndroid Build Coastguard Worker // clang-format on
2201*8975f5c5SAndroid Build Coastguard Worker
2202*8975f5c5SAndroid Build Coastguard Worker GLubyte mip0Color[16 * 4];
2203*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 16; i++)
2204*8975f5c5SAndroid Build Coastguard Worker {
2205*8975f5c5SAndroid Build Coastguard Worker mip0Color[i * 4 + 0] = kRedColor[i];
2206*8975f5c5SAndroid Build Coastguard Worker mip0Color[i * 4 + 1] = 0;
2207*8975f5c5SAndroid Build Coastguard Worker mip0Color[i * 4 + 2] = 0;
2208*8975f5c5SAndroid Build Coastguard Worker mip0Color[i * 4 + 3] = 0xff;
2209*8975f5c5SAndroid Build Coastguard Worker }
2210*8975f5c5SAndroid Build Coastguard Worker
2211*8975f5c5SAndroid Build Coastguard Worker GLFramebuffer fb0, fb1, fb2;
2212*8975f5c5SAndroid Build Coastguard Worker
2213*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb0);
2214*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
2215*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2216*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb1);
2217*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 1);
2218*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2219*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb2);
2220*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 2);
2221*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2222*8975f5c5SAndroid Build Coastguard Worker
2223*8975f5c5SAndroid Build Coastguard Worker // initialize base mip
2224*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb0);
2225*8975f5c5SAndroid Build Coastguard Worker glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, &mip0Color[0]);
2226*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2227*8975f5c5SAndroid Build Coastguard Worker
2228*8975f5c5SAndroid Build Coastguard Worker // draw mip 1 with mip 0
2229*8975f5c5SAndroid Build Coastguard Worker glActiveTexture(GL_TEXTURE0);
2230*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, tex);
2231*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2232*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2233*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2234*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2235*8975f5c5SAndroid Build Coastguard Worker
2236*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, 2, 2);
2237*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb1);
2238*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2239*8975f5c5SAndroid Build Coastguard Worker
2240*8975f5c5SAndroid Build Coastguard Worker glUseProgram(program);
2241*8975f5c5SAndroid Build Coastguard Worker glUniform1i(glGetUniformLocation(program, "tex"), 0);
2242*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, "position", 0.5);
2243*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2244*8975f5c5SAndroid Build Coastguard Worker
2245*8975f5c5SAndroid Build Coastguard Worker // draw mip 2 with mip 1
2246*8975f5c5SAndroid Build Coastguard Worker glActiveTexture(GL_TEXTURE0);
2247*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, tex);
2248*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2249*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2250*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2251*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2252*8975f5c5SAndroid Build Coastguard Worker
2253*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, 1, 1);
2254*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb2);
2255*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2256*8975f5c5SAndroid Build Coastguard Worker
2257*8975f5c5SAndroid Build Coastguard Worker glUseProgram(program);
2258*8975f5c5SAndroid Build Coastguard Worker glUniform1i(glGetUniformLocation(program, "tex"), 0);
2259*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, "position", 0.5);
2260*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2261*8975f5c5SAndroid Build Coastguard Worker
2262*8975f5c5SAndroid Build Coastguard Worker // Read back rendered pixel values and compare
2263*8975f5c5SAndroid Build Coastguard Worker GLubyte resultColors[16];
2264*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb1);
2265*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, &resultColors[0]);
2266*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 4; i++)
2267*8975f5c5SAndroid Build Coastguard Worker {
2268*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(resultColors[i * 4], kExpectedMip1Color[i]);
2269*8975f5c5SAndroid Build Coastguard Worker }
2270*8975f5c5SAndroid Build Coastguard Worker
2271*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb2);
2272*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &resultColors[0]);
2273*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 1; i++)
2274*8975f5c5SAndroid Build Coastguard Worker {
2275*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(resultColors[i * 4], kExpectedMip2Color[i]);
2276*8975f5c5SAndroid Build Coastguard Worker }
2277*8975f5c5SAndroid Build Coastguard Worker }
2278*8975f5c5SAndroid Build Coastguard Worker
2279*8975f5c5SAndroid Build Coastguard Worker // Test that manually generating lower mipmaps using draw calls is functional
TEST_P(MipmapTestES31,GenerateLowerMipsWithDraw)2280*8975f5c5SAndroid Build Coastguard Worker TEST_P(MipmapTestES31, GenerateLowerMipsWithDraw)
2281*8975f5c5SAndroid Build Coastguard Worker {
2282*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
2283*8975f5c5SAndroid Build Coastguard Worker glUseProgram(program);
2284*8975f5c5SAndroid Build Coastguard Worker glUniform1i(glGetUniformLocation(program, essl1_shaders::Texture2DUniform()), 0);
2285*8975f5c5SAndroid Build Coastguard Worker
2286*8975f5c5SAndroid Build Coastguard Worker GLTexture tex;
2287*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, tex);
2288*8975f5c5SAndroid Build Coastguard Worker glTexStorage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 8, 8);
2289*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2290*8975f5c5SAndroid Build Coastguard Worker
2291*8975f5c5SAndroid Build Coastguard Worker glActiveTexture(GL_TEXTURE0);
2292*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2293*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2294*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2295*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2296*8975f5c5SAndroid Build Coastguard Worker
2297*8975f5c5SAndroid Build Coastguard Worker const std::array<GLColor, 4> kMip2Color = {
2298*8975f5c5SAndroid Build Coastguard Worker GLColor::red,
2299*8975f5c5SAndroid Build Coastguard Worker GLColor::green,
2300*8975f5c5SAndroid Build Coastguard Worker GLColor::blue,
2301*8975f5c5SAndroid Build Coastguard Worker GLColor::white,
2302*8975f5c5SAndroid Build Coastguard Worker };
2303*8975f5c5SAndroid Build Coastguard Worker
2304*8975f5c5SAndroid Build Coastguard Worker GLFramebuffer fb0, fb1, fb2;
2305*8975f5c5SAndroid Build Coastguard Worker
2306*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb0);
2307*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
2308*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2309*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb1);
2310*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 1);
2311*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2312*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb2);
2313*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 2);
2314*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2315*8975f5c5SAndroid Build Coastguard Worker
2316*8975f5c5SAndroid Build Coastguard Worker // initialize mip 2
2317*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb2);
2318*8975f5c5SAndroid Build Coastguard Worker glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, kMip2Color.data());
2319*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2320*8975f5c5SAndroid Build Coastguard Worker
2321*8975f5c5SAndroid Build Coastguard Worker // draw mip 1 with mip 2
2322*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2323*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2324*8975f5c5SAndroid Build Coastguard Worker
2325*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, 4, 4);
2326*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb1);
2327*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2328*8975f5c5SAndroid Build Coastguard Worker
2329*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
2330*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2331*8975f5c5SAndroid Build Coastguard Worker
2332*8975f5c5SAndroid Build Coastguard Worker // draw mip 0 with mip 1
2333*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2334*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2335*8975f5c5SAndroid Build Coastguard Worker
2336*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, 8, 8);
2337*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb0);
2338*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2339*8975f5c5SAndroid Build Coastguard Worker
2340*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
2341*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2342*8975f5c5SAndroid Build Coastguard Worker
2343*8975f5c5SAndroid Build Coastguard Worker // Read back rendered pixel values and compare
2344*8975f5c5SAndroid Build Coastguard Worker auto getCoeff = [](uint32_t x, uint32_t dimension) {
2345*8975f5c5SAndroid Build Coastguard Worker const uint32_t dimDiv2 = dimension / 2;
2346*8975f5c5SAndroid Build Coastguard Worker const uint32_t x2 = x > dimDiv2 ? (dimension - 1 - x) : x;
2347*8975f5c5SAndroid Build Coastguard Worker
2348*8975f5c5SAndroid Build Coastguard Worker const uint32_t denominator = dimension * dimension / 4;
2349*8975f5c5SAndroid Build Coastguard Worker uint32_t numerator = x2 * (x2 + 1) / 2;
2350*8975f5c5SAndroid Build Coastguard Worker if (x > dimDiv2)
2351*8975f5c5SAndroid Build Coastguard Worker {
2352*8975f5c5SAndroid Build Coastguard Worker numerator = denominator - numerator;
2353*8975f5c5SAndroid Build Coastguard Worker }
2354*8975f5c5SAndroid Build Coastguard Worker return static_cast<float>(numerator) / static_cast<float>(denominator);
2355*8975f5c5SAndroid Build Coastguard Worker };
2356*8975f5c5SAndroid Build Coastguard Worker auto upscale = [&](uint32_t index, uint32_t dimension) {
2357*8975f5c5SAndroid Build Coastguard Worker uint32_t x = index % dimension;
2358*8975f5c5SAndroid Build Coastguard Worker uint32_t y = index / dimension;
2359*8975f5c5SAndroid Build Coastguard Worker
2360*8975f5c5SAndroid Build Coastguard Worker const float xCoeff = getCoeff(x, dimension);
2361*8975f5c5SAndroid Build Coastguard Worker const float yCoeff = getCoeff(y, dimension);
2362*8975f5c5SAndroid Build Coastguard Worker
2363*8975f5c5SAndroid Build Coastguard Worker GLColor result;
2364*8975f5c5SAndroid Build Coastguard Worker for (uint32_t channel = 0; channel < 4; ++channel)
2365*8975f5c5SAndroid Build Coastguard Worker {
2366*8975f5c5SAndroid Build Coastguard Worker const float mixX0 =
2367*8975f5c5SAndroid Build Coastguard Worker kMip2Color[0][channel] * (1 - xCoeff) + kMip2Color[1][channel] * xCoeff;
2368*8975f5c5SAndroid Build Coastguard Worker const float mixX1 =
2369*8975f5c5SAndroid Build Coastguard Worker kMip2Color[2][channel] * (1 - xCoeff) + kMip2Color[3][channel] * xCoeff;
2370*8975f5c5SAndroid Build Coastguard Worker const float mix = mixX0 * (1 - yCoeff) + mixX1 * yCoeff;
2371*8975f5c5SAndroid Build Coastguard Worker
2372*8975f5c5SAndroid Build Coastguard Worker result[channel] = static_cast<GLubyte>(round(mix));
2373*8975f5c5SAndroid Build Coastguard Worker }
2374*8975f5c5SAndroid Build Coastguard Worker return result;
2375*8975f5c5SAndroid Build Coastguard Worker };
2376*8975f5c5SAndroid Build Coastguard Worker
2377*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb0);
2378*8975f5c5SAndroid Build Coastguard Worker for (uint32_t i = 0; i < 64; ++i)
2379*8975f5c5SAndroid Build Coastguard Worker {
2380*8975f5c5SAndroid Build Coastguard Worker const GLColor expect = upscale(i, 8);
2381*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_NEAR(i % 8, i / 8, expect, 1);
2382*8975f5c5SAndroid Build Coastguard Worker }
2383*8975f5c5SAndroid Build Coastguard Worker
2384*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb1);
2385*8975f5c5SAndroid Build Coastguard Worker for (uint32_t i = 0; i < 16; ++i)
2386*8975f5c5SAndroid Build Coastguard Worker {
2387*8975f5c5SAndroid Build Coastguard Worker const GLColor expect = upscale(i, 4);
2388*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_NEAR(i % 4, i / 4, expect, 1);
2389*8975f5c5SAndroid Build Coastguard Worker }
2390*8975f5c5SAndroid Build Coastguard Worker }
2391*8975f5c5SAndroid Build Coastguard Worker
2392*8975f5c5SAndroid Build Coastguard Worker // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2393*8975f5c5SAndroid Build Coastguard Worker // tests should be run against.
2394*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(MipmapTest);
2395*8975f5c5SAndroid Build Coastguard Worker
2396*8975f5c5SAndroid Build Coastguard Worker namespace extraPlatforms
2397*8975f5c5SAndroid Build Coastguard Worker {
2398*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MipmapTest,
2399*8975f5c5SAndroid Build Coastguard Worker ES2_METAL().disable(Feature::AllowGenMultipleMipsPerPass),
2400*8975f5c5SAndroid Build Coastguard Worker ES2_OPENGLES().enable(Feature::UseIntermediateTextureForGenerateMipmap));
2401*8975f5c5SAndroid Build Coastguard Worker
2402*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Mipmap3DBoxFilterTest);
2403*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(Mipmap3DBoxFilterTest,
2404*8975f5c5SAndroid Build Coastguard Worker ES2_METAL(),
2405*8975f5c5SAndroid Build Coastguard Worker ES2_METAL().disable(Feature::AllowGenMultipleMipsPerPass));
2406*8975f5c5SAndroid Build Coastguard Worker } // namespace extraPlatforms
2407*8975f5c5SAndroid Build Coastguard Worker
2408*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MipmapTestES3);
2409*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(MipmapTestES3);
2410*8975f5c5SAndroid Build Coastguard Worker
2411*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MipmapTestES31);
2412*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(MipmapTestES31);
2413