3 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
4 typedef ::testing::Types<TFT<Gles::Two, Rend::D3D11>, TFT<Gles::Two, Rend::D3D9>> TestFixtureTypes;
5 TYPED_TEST_CASE(MaxTextureSizeTest, TestFixtureTypes);
8 class MaxTextureSizeTest : public ANGLETest
11 MaxTextureSizeTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetRequestedRenderer())
16 setConfigGreenBits(8);
18 setConfigAlphaBits(8);
25 const std::string vsSource = SHADER_SOURCE
27 precision highp float;
28 attribute vec4 position;
29 varying vec2 texcoord;
33 gl_Position = position;
34 texcoord = (position.xy * 0.5) + 0.5;
38 const std::string textureFSSource = SHADER_SOURCE
40 precision highp float;
41 uniform sampler2D tex;
42 varying vec2 texcoord;
46 gl_FragColor = texture2D(tex, texcoord);
50 const std::string blueFSSource = SHADER_SOURCE
52 precision highp float;
56 gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
60 mTextureProgram = CompileProgram(vsSource, textureFSSource);
61 mBlueProgram = CompileProgram(vsSource, blueFSSource);
62 if (mTextureProgram == 0 || mBlueProgram == 0)
64 FAIL() << "shader compilation failed.";
67 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
69 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTexture2DSize);
70 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxTextureCubeSize);
71 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize);
76 virtual void TearDown()
78 glDeleteProgram(mTextureProgram);
79 glDeleteProgram(mBlueProgram);
81 ANGLETest::TearDown();
84 GLuint mTextureProgram;
85 GLint mTextureUniformLocation;
89 GLint mMaxTexture2DSize;
90 GLint mMaxTextureCubeSize;
91 GLint mMaxRenderbufferSize;
94 TYPED_TEST(MaxTextureSizeTest, SpecificationTexImage)
97 glGenTextures(1, &tex);
98 glBindTexture(GL_TEXTURE_2D, tex);
100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
105 GLsizei textureWidth = mMaxTexture2DSize;
106 GLsizei textureHeight = 64;
108 std::vector<GLubyte> data(textureWidth * textureHeight * 4);
109 for (int y = 0; y < textureHeight; y++)
111 for (int x = 0; x < textureWidth; x++)
113 GLubyte* pixel = &data[0] + ((y * textureWidth + x) * 4);
115 // Draw a gradient, red in direction, green in y direction
116 pixel[0] = static_cast<GLubyte>((float(x) / textureWidth) * 255);
117 pixel[1] = static_cast<GLubyte>((float(y) / textureHeight) * 255);
123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
124 EXPECT_GL_NO_ERROR();
126 glUseProgram(mTextureProgram);
127 glUniform1i(mTextureUniformLocation, 0);
129 drawQuad(mTextureProgram, "position", 0.5f);
131 std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
132 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
134 for (int y = 1; y < getWindowHeight(); y++)
136 for (int x = 1; x < getWindowWidth(); x++)
138 const GLubyte* prevPixel = &pixels[0] + (((y - 1) * getWindowWidth() + (x - 1)) * 4);
139 const GLubyte* curPixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);
141 EXPECT_GE(curPixel[0], prevPixel[0]);
142 EXPECT_GE(curPixel[1], prevPixel[1]);
143 EXPECT_EQ(curPixel[2], prevPixel[2]);
144 EXPECT_EQ(curPixel[3], prevPixel[3]);
149 TYPED_TEST(MaxTextureSizeTest, SpecificationTexStorage)
151 if (getClientVersion() < 3 && (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8")))
157 glGenTextures(1, &tex);
158 glBindTexture(GL_TEXTURE_2D, tex);
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
161 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
165 GLsizei textureWidth = 64;
166 GLsizei textureHeight = mMaxTexture2DSize;
168 std::vector<GLubyte> data(textureWidth * textureHeight * 4);
169 for (int y = 0; y < textureHeight; y++)
171 for (int x = 0; x < textureWidth; x++)
173 GLubyte* pixel = &data[0] + ((y * textureWidth + x) * 4);
175 // Draw a gradient, red in direction, green in y direction
176 pixel[0] = static_cast<GLubyte>((float(x) / textureWidth) * 255);
177 pixel[1] = static_cast<GLubyte>((float(y) / textureHeight) * 255);
183 if (getClientVersion() < 3)
185 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, textureWidth, textureHeight);
189 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8_OES, textureWidth, textureHeight);
191 EXPECT_GL_NO_ERROR();
193 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
194 EXPECT_GL_NO_ERROR();
196 glUseProgram(mTextureProgram);
197 glUniform1i(mTextureUniformLocation, 0);
199 drawQuad(mTextureProgram, "position", 0.5f);
201 std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
202 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
204 for (int y = 1; y < getWindowHeight(); y++)
206 for (int x = 1; x < getWindowWidth(); x++)
208 const GLubyte* prevPixel = &pixels[0] + (((y - 1) * getWindowWidth() + (x - 1)) * 4);
209 const GLubyte* curPixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);
211 EXPECT_GE(curPixel[0], prevPixel[0]);
212 EXPECT_GE(curPixel[1], prevPixel[1]);
213 EXPECT_EQ(curPixel[2], prevPixel[2]);
214 EXPECT_EQ(curPixel[3], prevPixel[3]);
219 TYPED_TEST(MaxTextureSizeTest, RenderToTexture)
222 GLuint textureId = 0;
223 // create a 1-level texture at maximum size
224 glGenTextures(1, &textureId);
225 glBindTexture(GL_TEXTURE_2D, textureId);
227 GLsizei textureWidth = 64;
228 GLsizei textureHeight = mMaxTexture2DSize;
230 // texture setup code
231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
235 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, textureWidth, textureHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
236 EXPECT_GL_NO_ERROR();
238 // create an FBO and attach the texture
239 glGenFramebuffers(1, &fbo);
240 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
241 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
243 EXPECT_GL_NO_ERROR();
244 EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
246 const int frameCount = 64;
247 for (int i = 0; i < frameCount; i++)
250 glBindFramebuffer(GL_FRAMEBUFFER, 0);
252 GLubyte clearRed = static_cast<GLubyte>((float(i) / frameCount) * 255);
253 GLubyte clearGreen = 255 - clearRed;
254 GLubyte clearBlue = 0;
256 glClearColor(clearRed / 255.0f, clearGreen / 255.0f, clearBlue / 255.0f, 1.0f);
257 glClear(GL_COLOR_BUFFER_BIT);
259 // render blue into the texture
260 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
261 drawQuad(mBlueProgram, "position", 0.5f);
263 // copy corner of texture to LL corner of window
264 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
265 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fbo);
266 glBlitFramebufferANGLE(0, 0, textureWidth - 1, getWindowHeight() - 1,
267 0, 0, textureWidth - 1, getWindowHeight() - 1,
268 GL_COLOR_BUFFER_BIT, GL_NEAREST);
269 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, 0);
270 EXPECT_GL_NO_ERROR();
272 EXPECT_PIXEL_EQ(textureWidth / 2, getWindowHeight() / 2, 0, 0, 255, 255);
273 EXPECT_PIXEL_EQ(textureWidth + 10, getWindowHeight() / 2, clearRed, clearGreen, clearBlue, 255);
278 glBindFramebuffer(GL_FRAMEBUFFER, 0);
279 glBindTexture(GL_TEXTURE_2D, 0);
281 glDeleteFramebuffers(1, &fbo);
282 glDeleteTextures(1, &textureId);