1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "test_utils/ANGLETest.h"
8
9 #include <vector>
10
11 using namespace angle;
12
13 class IncompleteTextureTest : public ANGLETest
14 {
15 protected:
IncompleteTextureTest()16 IncompleteTextureTest()
17 {
18 setWindowWidth(128);
19 setWindowHeight(128);
20 setConfigRedBits(8);
21 setConfigGreenBits(8);
22 setConfigBlueBits(8);
23 setConfigAlphaBits(8);
24 }
25
SetUp()26 virtual void SetUp()
27 {
28 ANGLETest::SetUp();
29
30 const std::string vertexShaderSource = SHADER_SOURCE
31 (
32 precision highp float;
33 attribute vec4 position;
34 varying vec2 texcoord;
35
36 void main()
37 {
38 gl_Position = position;
39 texcoord = (position.xy * 0.5) + 0.5;
40 }
41 );
42
43 const std::string fragmentShaderSource = SHADER_SOURCE
44 (
45 precision highp float;
46 uniform sampler2D tex;
47 varying vec2 texcoord;
48
49 void main()
50 {
51 gl_FragColor = texture2D(tex, texcoord);
52 }
53 );
54
55 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
56 if (mProgram == 0)
57 {
58 FAIL() << "shader compilation failed.";
59 }
60
61 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
62 }
63
TearDown()64 virtual void TearDown()
65 {
66 glDeleteProgram(mProgram);
67
68 ANGLETest::TearDown();
69 }
70
fillTextureData(std::vector<GLubyte> & buffer,GLubyte r,GLubyte g,GLubyte b,GLubyte a)71 void fillTextureData(std::vector<GLubyte> &buffer, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
72 {
73 size_t count = buffer.size() / 4;
74 for (size_t i = 0; i < count; i++)
75 {
76 buffer[i * 4 + 0] = r;
77 buffer[i * 4 + 1] = g;
78 buffer[i * 4 + 2] = b;
79 buffer[i * 4 + 3] = a;
80 }
81 }
82
83 GLuint mProgram;
84 GLint mTextureUniformLocation;
85 };
86
TEST_P(IncompleteTextureTest,IncompleteTexture2D)87 TEST_P(IncompleteTextureTest, IncompleteTexture2D)
88 {
89 GLuint tex;
90 glGenTextures(1, &tex);
91 glActiveTexture(GL_TEXTURE0);
92 glBindTexture(GL_TEXTURE_2D, tex);
93
94 glUseProgram(mProgram);
95 glUniform1i(mTextureUniformLocation, 0);
96
97 const GLsizei textureWidth = 2;
98 const GLsizei textureHeight = 2;
99 std::vector<GLubyte> textureData(textureWidth * textureHeight * 4);
100 fillTextureData(textureData, 255, 0, 0, 255);
101
102 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]);
103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
104
105 drawQuad(mProgram, "position", 0.5f);
106 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
107
108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
109
110 drawQuad(mProgram, "position", 0.5f);
111 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255);
112
113 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, textureWidth >> 1, textureHeight >> 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]);
114
115 drawQuad(mProgram, "position", 0.5f);
116 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
117
118 glDeleteTextures(1, &tex);
119 }
120
TEST_P(IncompleteTextureTest,UpdateTexture)121 TEST_P(IncompleteTextureTest, UpdateTexture)
122 {
123 GLuint tex;
124 glGenTextures(1, &tex);
125 glActiveTexture(GL_TEXTURE0);
126 glBindTexture(GL_TEXTURE_2D, tex);
127
128 glUseProgram(mProgram);
129 glUniform1i(mTextureUniformLocation, 0);
130
131 const GLsizei redTextureWidth = 64;
132 const GLsizei redTextureHeight = 64;
133 std::vector<GLubyte> redTextureData(redTextureWidth * redTextureHeight * 4);
134 fillTextureData(redTextureData, 255, 0, 0, 255);
135 for (size_t i = 0; i < 7; i++)
136 {
137 glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), GL_RGBA, redTextureWidth >> i,
138 redTextureHeight >> i, 0, GL_RGBA, GL_UNSIGNED_BYTE, &redTextureData[0]);
139 }
140
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
143
144 drawQuad(mProgram, "position", 0.5f);
145 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
146
147 const GLsizei greenTextureWidth = 32;
148 const GLsizei greenTextureHeight = 32;
149 std::vector<GLubyte> greenTextureData(greenTextureWidth * greenTextureHeight * 4);
150 fillTextureData(greenTextureData, 0, 255, 0, 255);
151
152 for (size_t i = 0; i < 6; i++)
153 {
154 glTexSubImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), greenTextureWidth >> i,
155 greenTextureHeight >> i, greenTextureWidth >> i, greenTextureHeight >> i,
156 GL_RGBA, GL_UNSIGNED_BYTE, &greenTextureData[0]);
157 }
158
159 drawQuad(mProgram, "position", 0.5f);
160 EXPECT_PIXEL_EQ(getWindowWidth() - greenTextureWidth, getWindowHeight() - greenTextureWidth, 0, 255, 0, 255);
161
162 glDeleteTextures(1, &tex);
163 }
164
165 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
166 ANGLE_INSTANTIATE_TEST(IncompleteTextureTest,
167 ES2_D3D9(),
168 ES2_D3D11(),
169 ES2_OPENGL(),
170 ES2_OPENGLES());
171