blob: d2e08e0eb40aa7d66ab82ad7586f695103fbb9d6 [file] [log] [blame]
Jamie Madillf67115c2014-04-22 13:14:05 -04001#include "ANGLETest.h"
2
Austin Kinross18b931d2014-09-29 12:58:31 -07003// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang0d3683c2014-10-23 11:08:16 -04004ANGLE_TYPED_TEST_CASE(TextureTest, ES2_D3D9, ES2_D3D11);
Austin Kinross18b931d2014-09-29 12:58:31 -07005
6template<typename T>
Jamie Madillf67115c2014-04-22 13:14:05 -04007class TextureTest : public ANGLETest
8{
9protected:
Geoff Lang0d3683c2014-10-23 11:08:16 -040010 TextureTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
Jamie Madillf67115c2014-04-22 13:14:05 -040011 {
12 setWindowWidth(128);
13 setWindowHeight(128);
14 setConfigRedBits(8);
15 setConfigGreenBits(8);
16 setConfigBlueBits(8);
17 setConfigAlphaBits(8);
18 }
19
20 virtual void SetUp()
21 {
22 ANGLETest::SetUp();
Jamie Madilld4cfa572014-07-08 10:00:32 -040023 glGenTextures(1, &mTexture2D);
24 glGenTextures(1, &mTextureCube);
Jamie Madillf67115c2014-04-22 13:14:05 -040025
Jamie Madilld4cfa572014-07-08 10:00:32 -040026 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -040027 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
28 EXPECT_GL_NO_ERROR();
29
Jamie Madilld4cfa572014-07-08 10:00:32 -040030 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
31 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
32 EXPECT_GL_NO_ERROR();
33
Jamie Madillf67115c2014-04-22 13:14:05 -040034 ASSERT_GL_NO_ERROR();
Geoff Langc41e42d2014-04-28 10:58:16 -040035
36 const std::string vertexShaderSource = SHADER_SOURCE
37 (
38 precision highp float;
39 attribute vec4 position;
40 varying vec2 texcoord;
41
Jamie Madill9aca0592014-10-06 16:26:59 -040042 uniform vec2 textureScale;
43
Geoff Langc41e42d2014-04-28 10:58:16 -040044 void main()
45 {
Jamie Madill9aca0592014-10-06 16:26:59 -040046 gl_Position = vec4(position.xy * textureScale, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040047 texcoord = (position.xy * 0.5) + 0.5;
48 }
49 );
50
Jamie Madilld4cfa572014-07-08 10:00:32 -040051 const std::string fragmentShaderSource2D = SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040052 (
53 precision highp float;
54 uniform sampler2D tex;
55 varying vec2 texcoord;
56
57 void main()
58 {
59 gl_FragColor = texture2D(tex, texcoord);
60 }
61 );
62
Jamie Madilld4cfa572014-07-08 10:00:32 -040063 const std::string fragmentShaderSourceCube = SHADER_SOURCE
64 (
65 precision highp float;
66 uniform sampler2D tex2D;
67 uniform samplerCube texCube;
68 varying vec2 texcoord;
69
70 void main()
71 {
72 gl_FragColor = texture2D(tex2D, texcoord);
73 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
74 }
75 );
76
Jamie Madill5599c8f2014-08-26 13:16:39 -040077 m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D);
78 mCubeProgram = CompileProgram(vertexShaderSource, fragmentShaderSourceCube);
Jamie Madilld4cfa572014-07-08 10:00:32 -040079 if (m2DProgram == 0 || mCubeProgram == 0)
Geoff Langc41e42d2014-04-28 10:58:16 -040080 {
81 FAIL() << "shader compilation failed.";
82 }
83
Jamie Madilld4cfa572014-07-08 10:00:32 -040084 mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
Jamie Madill9aca0592014-10-06 16:26:59 -040085 ASSERT_NE(-1, mTexture2DUniformLocation);
86
87 mTextureScaleUniformLocation = glGetUniformLocation(m2DProgram, "textureScale");
88 ASSERT_NE(-1, mTextureScaleUniformLocation);
89
90 glUseProgram(m2DProgram);
91 glUniform2f(mTextureScaleUniformLocation, 1.0f, 1.0f);
92 glUseProgram(0);
93 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -040094 }
95
96 virtual void TearDown()
97 {
Jamie Madilld4cfa572014-07-08 10:00:32 -040098 glDeleteTextures(1, &mTexture2D);
99 glDeleteTextures(1, &mTextureCube);
100 glDeleteProgram(m2DProgram);
101 glDeleteProgram(mCubeProgram);
Jamie Madillf67115c2014-04-22 13:14:05 -0400102
103 ANGLETest::TearDown();
104 }
105
Jamie Madilld4cfa572014-07-08 10:00:32 -0400106 GLuint mTexture2D;
107 GLuint mTextureCube;
Geoff Langc41e42d2014-04-28 10:58:16 -0400108
Jamie Madilld4cfa572014-07-08 10:00:32 -0400109 GLuint m2DProgram;
110 GLuint mCubeProgram;
111 GLint mTexture2DUniformLocation;
Jamie Madill9aca0592014-10-06 16:26:59 -0400112 GLint mTextureScaleUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400113};
114
Jamie Madillf8fccb32014-11-12 15:05:26 -0500115ANGLE_TYPED_TEST_CASE(TextureTestES3, ES3_D3D11);
116
117template<typename T>
118class TextureTestES3 : public TextureTest<T>
119{
120 protected:
121 virtual void SetUp()
122 {
123 TextureTest::SetUp();
124
125 glGenTextures(1, &mTextureArray);
126 EXPECT_GL_NO_ERROR();
127
128 ASSERT_GL_NO_ERROR();
129
130 const std::string vertexShaderSource = SHADER_SOURCE
131 (
132 #version 300 es\n
133 precision highp float;
134 in vec4 position;
135 out vec2 texcoord;
136
137 uniform vec2 textureScale;
138
139 void main()
140 {
141 gl_Position = vec4(position.xy * textureScale, 0.0, 1.0);
142 texcoord = (position.xy * 0.5) + 0.5;
143 }
144 );
145
146 const std::string fragmentShaderSourceArray = SHADER_SOURCE
147 (
148 #version 300 es\n
149 precision highp float;
150 uniform sampler2DArray tex;
151 uniform int slice;
152 in vec2 texcoord;
153 out vec4 out_FragColor;
154
155 void main()
156 {
157 out_FragColor = texture(tex, vec3(texcoord, float(slice)));
158 }
159 );
160
161 mArrayProgram = CompileProgram(vertexShaderSource, fragmentShaderSourceArray);
162 if (mArrayProgram == 0)
163 {
164 FAIL() << "shader compilation failed.";
165 }
166
167 mTextureArrayUniformLocation = glGetUniformLocation(mArrayProgram, "tex");
168 ASSERT_NE(-1, mTextureArrayUniformLocation);
169
170 mTextureArrayScaleUniformLocation = glGetUniformLocation(mArrayProgram, "textureScale");
171 ASSERT_NE(-1, mTextureArrayScaleUniformLocation);
172
173 mTextureArraySliceUniformLocation = glGetUniformLocation(mArrayProgram, "slice");
174 ASSERT_NE(-1, mTextureArraySliceUniformLocation);
175
176 glUseProgram(mArrayProgram);
177 glUniform2f(mTextureArrayScaleUniformLocation, 1.0f, 1.0f);
178 glUseProgram(0);
179 ASSERT_GL_NO_ERROR();
180 }
181
182 virtual void TearDown()
183 {
184 glDeleteTextures(1, &mTextureArray);
185 glDeleteProgram(mArrayProgram);
186
187 TextureTest::TearDown();
188 }
189
190 GLuint mTextureArray;
191
192 GLuint mArrayProgram;
193 GLint mTextureArrayUniformLocation;
194 GLint mTextureArrayScaleUniformLocation;
195 GLint mTextureArraySliceUniformLocation;
196};
197
Austin Kinross18b931d2014-09-29 12:58:31 -0700198TYPED_TEST(TextureTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400199{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400200 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400201 EXPECT_GL_ERROR(GL_NO_ERROR);
202
203 const GLubyte *pixels[20] = { 0 };
204 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
205 EXPECT_GL_ERROR(GL_INVALID_VALUE);
206}
Geoff Langc41e42d2014-04-28 10:58:16 -0400207
Austin Kinross18b931d2014-09-29 12:58:31 -0700208TYPED_TEST(TextureTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400209{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400210 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400211 EXPECT_GL_ERROR(GL_NO_ERROR);
212
213 // Use the texture first to make sure it's in video memory
Jamie Madilld4cfa572014-07-08 10:00:32 -0400214 glUseProgram(m2DProgram);
215 glUniform1i(mTexture2DUniformLocation, 0);
216 drawQuad(m2DProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400217
218 const GLubyte *pixel[4] = { 0 };
219
220 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
221 EXPECT_GL_NO_ERROR();
222
223 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
224 EXPECT_GL_NO_ERROR();
225
226 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
227 EXPECT_GL_NO_ERROR();
228}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400229
230// Test drawing with two texture types, to trigger an ANGLE bug in validation
Austin Kinross18b931d2014-09-29 12:58:31 -0700231TYPED_TEST(TextureTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400232{
233 glActiveTexture(GL_TEXTURE0);
234 glBindTexture(GL_TEXTURE_2D, mTexture2D);
235 glActiveTexture(GL_TEXTURE1);
236 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
237 EXPECT_GL_ERROR(GL_NO_ERROR);
238
239 glUseProgram(mCubeProgram);
240 GLint tex2DUniformLocation = glGetUniformLocation(mCubeProgram, "tex2D");
241 GLint texCubeUniformLocation = glGetUniformLocation(mCubeProgram, "texCube");
242 EXPECT_NE(-1, tex2DUniformLocation);
243 EXPECT_NE(-1, texCubeUniformLocation);
244 glUniform1i(tex2DUniformLocation, 0);
245 glUniform1i(texCubeUniformLocation, 1);
246 drawQuad(mCubeProgram, "position", 0.5f);
247 EXPECT_GL_NO_ERROR();
248}
Jamie Madill9aca0592014-10-06 16:26:59 -0400249
250// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
251TYPED_TEST(TextureTest, MipmapsTwice)
252{
253 int px = getWindowWidth() / 2;
254 int py = getWindowHeight() / 2;
255
256 glActiveTexture(GL_TEXTURE0);
257 glBindTexture(GL_TEXTURE_2D, mTexture2D);
258
259 // Fill with red
260 std::vector<GLubyte> pixels(4 * 16 * 16);
261 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
262 {
263 pixels[pixelId * 4 + 0] = 255;
264 pixels[pixelId * 4 + 1] = 0;
265 pixels[pixelId * 4 + 2] = 0;
266 pixels[pixelId * 4 + 3] = 255;
267 }
268
269 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
272 glGenerateMipmap(GL_TEXTURE_2D);
273
274 glUseProgram(m2DProgram);
275 glUniform1i(mTexture2DUniformLocation, 0);
276 glUniform2f(mTextureScaleUniformLocation, 0.0625f, 0.0625f);
277 drawQuad(m2DProgram, "position", 0.5f);
278 EXPECT_GL_NO_ERROR();
279 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
280
281 // Fill with blue
282 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
283 {
284 pixels[pixelId * 4 + 0] = 0;
285 pixels[pixelId * 4 + 1] = 0;
286 pixels[pixelId * 4 + 2] = 255;
287 pixels[pixelId * 4 + 3] = 255;
288 }
289
290 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
291 glGenerateMipmap(GL_TEXTURE_2D);
292
293 // Fill with green
294 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
295 {
296 pixels[pixelId * 4 + 0] = 0;
297 pixels[pixelId * 4 + 1] = 255;
298 pixels[pixelId * 4 + 2] = 0;
299 pixels[pixelId * 4 + 3] = 255;
300 }
301
302 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
303 glGenerateMipmap(GL_TEXTURE_2D);
304
305 drawQuad(m2DProgram, "position", 0.5f);
306
307 EXPECT_GL_NO_ERROR();
308 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
309}
Jamie Madillf8fccb32014-11-12 15:05:26 -0500310
311// Creates a mipmapped 2D array texture with three layers, and calls ANGLE's GenerateMipmap.
312// Then tests if the mipmaps are rendered correctly for all three layers.
313TYPED_TEST(TextureTestES3, MipmapsForTextureArray)
314{
315 int px = getWindowWidth() / 2;
316 int py = getWindowHeight() / 2;
317
318 glActiveTexture(GL_TEXTURE0);
319 glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
320
321 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 5, GL_RGBA8, 16, 16, 3);
322
323 // Fill the first layer with red
324 std::vector<GLubyte> pixels(4 * 16 * 16);
325 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
326 {
327 pixels[pixelId * 4 + 0] = 255;
328 pixels[pixelId * 4 + 1] = 0;
329 pixels[pixelId * 4 + 2] = 0;
330 pixels[pixelId * 4 + 3] = 255;
331 }
332
333 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
334
335 // Fill the second layer with green
336 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
337 {
338 pixels[pixelId * 4 + 0] = 0;
339 pixels[pixelId * 4 + 1] = 255;
340 pixels[pixelId * 4 + 2] = 0;
341 pixels[pixelId * 4 + 3] = 255;
342 }
343
344 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
345
346 // Fill the third layer with blue
347 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
348 {
349 pixels[pixelId * 4 + 0] = 0;
350 pixels[pixelId * 4 + 1] = 0;
351 pixels[pixelId * 4 + 2] = 255;
352 pixels[pixelId * 4 + 3] = 255;
353 }
354
355 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
356
357 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
358 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
359
360 EXPECT_GL_NO_ERROR();
361
362 glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
363
364 EXPECT_GL_NO_ERROR();
365
366 glUseProgram(mArrayProgram);
367 glUniform1i(mTextureArrayUniformLocation, 0);
368 glUniform2f(mTextureScaleUniformLocation, 0.0625f, 0.0625f);
369
370 EXPECT_GL_NO_ERROR();
371
372 // Draw the first slice
373 glUseProgram(mArrayProgram);
374 glUniform1i(mTextureArraySliceUniformLocation, 0);
375 drawQuad(mArrayProgram, "position", 0.5f);
376 EXPECT_GL_NO_ERROR();
377 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
378
379 // Draw the second slice
380 glUseProgram(mArrayProgram);
381 glUniform1i(mTextureArraySliceUniformLocation, 1);
382 drawQuad(mArrayProgram, "position", 0.5f);
383 EXPECT_GL_NO_ERROR();
384 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
385
386 // Draw the third slice
387 glUseProgram(mArrayProgram);
388 glUniform1i(mTextureArraySliceUniformLocation, 2);
389 drawQuad(mArrayProgram, "position", 0.5f);
390 EXPECT_GL_NO_ERROR();
391 EXPECT_PIXEL_EQ(px, py, 0, 0, 255, 255);
392}