1#include "ANGLETest.h" 2 3class MaxTextureSizeTest : public ANGLETest 4{ 5protected: 6 MaxTextureSizeTest() 7 { 8 setWindowWidth(512); 9 setWindowHeight(512); 10 setConfigRedBits(8); 11 setConfigGreenBits(8); 12 setConfigBlueBits(8); 13 setConfigAlphaBits(8); 14 } 15 16 virtual void SetUp() 17 { 18 ANGLETest::SetUp(); 19 20 const std::string vsSource = SHADER_SOURCE 21 ( 22 precision highp float; 23 attribute vec4 position; 24 varying vec2 texcoord; 25 26 void main() 27 { 28 gl_Position = position; 29 texcoord = (position.xy * 0.5) + 0.5; 30 } 31 ); 32 33 const std::string textureFSSource = SHADER_SOURCE 34 ( 35 precision highp float; 36 uniform sampler2D tex; 37 varying vec2 texcoord; 38 39 void main() 40 { 41 gl_FragColor = texture2D(tex, texcoord); 42 } 43 ); 44 45 const std::string blueFSSource = SHADER_SOURCE 46 ( 47 precision highp float; 48 49 void main() 50 { 51 gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); 52 } 53 ); 54 55 mTextureProgram = CompileProgram(vsSource, textureFSSource); 56 mBlueProgram = CompileProgram(vsSource, blueFSSource); 57 if (mTextureProgram == 0 || mBlueProgram == 0) 58 { 59 FAIL() << "shader compilation failed."; 60 } 61 62 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); 63 64 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTexture2DSize); 65 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxTextureCubeSize); 66 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize); 67 68 ASSERT_GL_NO_ERROR(); 69 } 70 71 virtual void TearDown() 72 { 73 glDeleteProgram(mTextureProgram); 74 glDeleteProgram(mBlueProgram); 75 76 ANGLETest::TearDown(); 77 } 78 79 GLuint mTextureProgram; 80 GLint mTextureUniformLocation; 81 82 GLuint mBlueProgram; 83 84 GLint mMaxTexture2DSize; 85 GLint mMaxTextureCubeSize; 86 GLint mMaxRenderbufferSize; 87}; 88 89TEST_F(MaxTextureSizeTest, SpecificationTexImage) 90{ 91 GLuint tex; 92 glGenTextures(1, &tex); 93 glBindTexture(GL_TEXTURE_2D, tex); 94 95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 99 100 GLsizei textureWidth = mMaxTexture2DSize; 101 GLsizei textureHeight = 64; 102 103 std::vector<GLubyte> data(textureWidth * textureHeight * 4); 104 for (int y = 0; y < textureHeight; y++) 105 { 106 for (int x = 0; x < textureWidth; x++) 107 { 108 GLubyte* pixel = data.data() + ((y * textureWidth + x) * 4); 109 110 // Draw a gradient, red in direction, green in y direction 111 pixel[0] = static_cast<GLubyte>((float(x) / textureWidth) * 255); 112 pixel[1] = static_cast<GLubyte>((float(y) / textureHeight) * 255); 113 pixel[2] = 0; 114 pixel[3] = 255; 115 } 116 } 117 118 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.data()); 119 EXPECT_GL_NO_ERROR(); 120 121 glUseProgram(mTextureProgram); 122 glUniform1i(mTextureUniformLocation, 0); 123 124 drawQuad(mTextureProgram, "position", 0.5f); 125 126 std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4); 127 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); 128 129 for (int y = 1; y < getWindowHeight(); y++) 130 { 131 for (int x = 1; x < getWindowWidth(); x++) 132 { 133 const GLubyte* prevPixel = pixels.data() + (((y - 1) * getWindowWidth() + (x - 1)) * 4); 134 const GLubyte* curPixel = pixels.data() + ((y * getWindowWidth() + x) * 4); 135 136 EXPECT_GE(curPixel[0], prevPixel[0]); 137 EXPECT_GE(curPixel[1], prevPixel[1]); 138 EXPECT_EQ(curPixel[2], prevPixel[2]); 139 EXPECT_EQ(curPixel[3], prevPixel[3]); 140 } 141 } 142} 143 144TEST_F(MaxTextureSizeTest, SpecificationTexStorage) 145{ 146 if (getClientVersion() < 3 && (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8"))) 147 { 148 return; 149 } 150 151 GLuint tex; 152 glGenTextures(1, &tex); 153 glBindTexture(GL_TEXTURE_2D, tex); 154 155 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 159 160 GLsizei textureWidth = 64; 161 GLsizei textureHeight = mMaxTexture2DSize; 162 163 std::vector<GLubyte> data(textureWidth * textureHeight * 4); 164 for (int y = 0; y < textureHeight; y++) 165 { 166 for (int x = 0; x < textureWidth; x++) 167 { 168 GLubyte* pixel = data.data() + ((y * textureWidth + x) * 4); 169 170 // Draw a gradient, red in direction, green in y direction 171 pixel[0] = static_cast<GLubyte>((float(x) / textureWidth) * 255); 172 pixel[1] = static_cast<GLubyte>((float(y) / textureHeight) * 255); 173 pixel[2] = 0; 174 pixel[3] = 255; 175 } 176 } 177 178 if (getClientVersion() < 3) 179 { 180 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, textureWidth, textureHeight); 181 } 182 else 183 { 184 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8_OES, textureWidth, textureHeight); 185 } 186 EXPECT_GL_NO_ERROR(); 187 188 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, data.data()); 189 EXPECT_GL_NO_ERROR(); 190 191 glUseProgram(mTextureProgram); 192 glUniform1i(mTextureUniformLocation, 0); 193 194 drawQuad(mTextureProgram, "position", 0.5f); 195 196 std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4); 197 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); 198 199 for (int y = 1; y < getWindowHeight(); y++) 200 { 201 for (int x = 1; x < getWindowWidth(); x++) 202 { 203 const GLubyte* prevPixel = pixels.data() + (((y - 1) * getWindowWidth() + (x - 1)) * 4); 204 const GLubyte* curPixel = pixels.data() + ((y * getWindowWidth() + x) * 4); 205 206 EXPECT_GE(curPixel[0], prevPixel[0]); 207 EXPECT_GE(curPixel[1], prevPixel[1]); 208 EXPECT_EQ(curPixel[2], prevPixel[2]); 209 EXPECT_EQ(curPixel[3], prevPixel[3]); 210 } 211 } 212} 213 214TEST_F(MaxTextureSizeTest, RenderToTexture) 215{ 216 GLuint fbo = 0; 217 GLuint textureId = 0; 218 // create a 1-level texture at maximum size 219 glGenTextures(1, &textureId); 220 glBindTexture(GL_TEXTURE_2D, textureId); 221 222 GLsizei textureWidth = 64; 223 GLsizei textureHeight = mMaxTexture2DSize; 224 225 // texture setup code 226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 230 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, textureHeight, textureWidth, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); 231 EXPECT_GL_NO_ERROR(); 232 233 // create an FBO and attach the texture 234 glGenFramebuffers(1, &fbo); 235 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 236 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); 237 238 EXPECT_GL_NO_ERROR(); 239 EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE); 240 241 const int frameCount = 64; 242 for (int i = 0; i < frameCount; i++) 243 { 244 // clear the screen 245 glBindFramebuffer(GL_FRAMEBUFFER, 0); 246 247 GLubyte clearRed = static_cast<GLubyte>((float(i) / frameCount) * 255); 248 GLubyte clearGreen = 255 - clearRed; 249 GLubyte clearBlue = 0; 250 251 glClearColor(clearRed / 255.0f, clearGreen / 255.0f, clearBlue / 255.0f, 1.0f); 252 glClear(GL_COLOR_BUFFER_BIT); 253 254 // render blue into the texture 255 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 256 drawQuad(mBlueProgram, "position", 0.5f); 257 258 // copy corner of texture to LL corner of window 259 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0); 260 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fbo); 261 glBlitFramebufferANGLE(0, 0, textureWidth - 1, getWindowHeight() - 1, 262 0, 0, textureWidth - 1, getWindowHeight() - 1, 263 GL_COLOR_BUFFER_BIT, GL_NEAREST); 264 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, 0); 265 EXPECT_GL_NO_ERROR(); 266 267 EXPECT_PIXEL_EQ(textureWidth / 2, getWindowHeight() / 2, 0, 0, 255, 255); 268 EXPECT_PIXEL_EQ(textureWidth + 10, getWindowHeight() / 2, clearRed, clearGreen, clearBlue, 255); 269 270 swapBuffers(); 271 } 272 273 glBindFramebuffer(GL_FRAMEBUFFER, 0); 274 glBindTexture(GL_TEXTURE_2D, 0); 275 276 glDeleteFramebuffers(1, &fbo); 277 glDeleteTextures(1, &textureId); 278} 279