Home | History | Annotate | Download | only in angle_tests
      1 #include "ANGLETest.h"
      2 
      3 class MaxTextureSizeTest : public ANGLETest
      4 {
      5 protected:
      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 
     89 TEST_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 
    144 TEST_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 
    214 TEST_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