blob: 398dcd66edb5ac1f00f3eed5d311aef3097f1e63 [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 Langfbfa47c2015-03-31 11:26:00 -04004ANGLE_TYPED_TEST_CASE(TextureTest, ES2_D3D9, ES2_D3D11, ES2_D3D11_FL9_3, ES2_OPENGL);
Austin Kinross18b931d2014-09-29 12:58:31 -07005
6template<typename T>
Jamie Madillf67115c2014-04-22 13:14:05 -04007class TextureTest : public ANGLETest
8{
Jamie Madillbc393df2015-01-29 13:46:07 -05009 protected:
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 Madillbc393df2015-01-29 13:46:07 -0500106 // Tests CopyTexSubImage with floating point textures of various formats.
107 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
108 {
Geoff Langfbfa47c2015-03-31 11:26:00 -0400109 if (getClientVersion() < 3)
110 {
111 if (!extensionEnabled("GL_OES_texture_float"))
112 {
113 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
114 return;
115 }
116
117 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
118 {
119 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
120 return;
121 }
122 }
123
Jamie Madillbc393df2015-01-29 13:46:07 -0500124 GLfloat sourceImageData[4][16] =
125 {
126 { // R
127 1.0f,
128 0.0f,
129 0.0f,
130 1.0f
131 },
132 { // RG
133 1.0f, 0.0f,
134 0.0f, 1.0f,
135 0.0f, 0.0f,
136 1.0f, 1.0f
137 },
138 { // RGB
139 1.0f, 0.0f, 0.0f,
140 0.0f, 1.0f, 0.0f,
141 0.0f, 0.0f, 1.0f,
142 1.0f, 1.0f, 0.0f
143 },
144 { // RGBA
145 1.0f, 0.0f, 0.0f, 1.0f,
146 0.0f, 1.0f, 0.0f, 1.0f,
147 0.0f, 0.0f, 1.0f, 1.0f,
148 1.0f, 1.0f, 0.0f, 1.0f
149 },
150 };
151
152 GLenum imageFormats[] =
153 {
154 GL_R32F,
155 GL_RG32F,
156 GL_RGB32F,
157 GL_RGBA32F,
158 };
159
160 GLenum sourceUnsizedFormats[] =
161 {
162 GL_RED,
163 GL_RG,
164 GL_RGB,
165 GL_RGBA,
166 };
167
168 GLuint textures[2];
169
170 glGenTextures(2, textures);
171
172 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
173 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
174 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
175 GLenum destImageFormat = imageFormats[destImageChannels - 1];
176
177 glBindTexture(GL_TEXTURE_2D, textures[0]);
178 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
181 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
182
hendrikwb27f79a2015-03-04 11:26:46 -0800183 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500184 {
185 // This is not supported
186 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
187 }
188 else
189 {
190 ASSERT_GL_NO_ERROR();
191 }
192
193 GLuint fbo;
194 glGenFramebuffers(1, &fbo);
195 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
196 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
197
198 glBindTexture(GL_TEXTURE_2D, textures[1]);
199 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
202
203 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
204 ASSERT_GL_NO_ERROR();
205
206 glBindFramebuffer(GL_FRAMEBUFFER, 0);
207 drawQuad(m2DProgram, "position", 0.5f);
208 swapBuffers();
209
210 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
211
212 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
213 if (testImageChannels > 1)
214 {
215 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
216 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
217 if (testImageChannels > 2)
218 {
219 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
220 }
221 }
222
223 glDeleteFramebuffers(1, &fbo);
224 glDeleteTextures(2, textures);
225
226 ASSERT_GL_NO_ERROR();
227 }
228
Jamie Madilld4cfa572014-07-08 10:00:32 -0400229 GLuint mTexture2D;
230 GLuint mTextureCube;
Geoff Langc41e42d2014-04-28 10:58:16 -0400231
Jamie Madilld4cfa572014-07-08 10:00:32 -0400232 GLuint m2DProgram;
233 GLuint mCubeProgram;
234 GLint mTexture2DUniformLocation;
Jamie Madill9aca0592014-10-06 16:26:59 -0400235 GLint mTextureScaleUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400236};
237
Austin Kinross18b931d2014-09-29 12:58:31 -0700238TYPED_TEST(TextureTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400239{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400240 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400241 EXPECT_GL_ERROR(GL_NO_ERROR);
242
243 const GLubyte *pixels[20] = { 0 };
244 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
245 EXPECT_GL_ERROR(GL_INVALID_VALUE);
246}
Geoff Langc41e42d2014-04-28 10:58:16 -0400247
Austin Kinross18b931d2014-09-29 12:58:31 -0700248TYPED_TEST(TextureTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400249{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400250 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400251 EXPECT_GL_ERROR(GL_NO_ERROR);
252
253 // Use the texture first to make sure it's in video memory
Jamie Madilld4cfa572014-07-08 10:00:32 -0400254 glUseProgram(m2DProgram);
255 glUniform1i(mTexture2DUniformLocation, 0);
256 drawQuad(m2DProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400257
258 const GLubyte *pixel[4] = { 0 };
259
260 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
261 EXPECT_GL_NO_ERROR();
262
263 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
264 EXPECT_GL_NO_ERROR();
265
266 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
267 EXPECT_GL_NO_ERROR();
268}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400269
270// Test drawing with two texture types, to trigger an ANGLE bug in validation
Austin Kinross18b931d2014-09-29 12:58:31 -0700271TYPED_TEST(TextureTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400272{
273 glActiveTexture(GL_TEXTURE0);
274 glBindTexture(GL_TEXTURE_2D, mTexture2D);
275 glActiveTexture(GL_TEXTURE1);
276 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
277 EXPECT_GL_ERROR(GL_NO_ERROR);
278
279 glUseProgram(mCubeProgram);
280 GLint tex2DUniformLocation = glGetUniformLocation(mCubeProgram, "tex2D");
281 GLint texCubeUniformLocation = glGetUniformLocation(mCubeProgram, "texCube");
282 EXPECT_NE(-1, tex2DUniformLocation);
283 EXPECT_NE(-1, texCubeUniformLocation);
284 glUniform1i(tex2DUniformLocation, 0);
285 glUniform1i(texCubeUniformLocation, 1);
286 drawQuad(mCubeProgram, "position", 0.5f);
287 EXPECT_GL_NO_ERROR();
288}
Jamie Madill9aca0592014-10-06 16:26:59 -0400289
290// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
291TYPED_TEST(TextureTest, MipmapsTwice)
292{
293 int px = getWindowWidth() / 2;
294 int py = getWindowHeight() / 2;
295
296 glActiveTexture(GL_TEXTURE0);
297 glBindTexture(GL_TEXTURE_2D, mTexture2D);
298
299 // Fill with red
300 std::vector<GLubyte> pixels(4 * 16 * 16);
301 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
302 {
303 pixels[pixelId * 4 + 0] = 255;
304 pixels[pixelId * 4 + 1] = 0;
305 pixels[pixelId * 4 + 2] = 0;
306 pixels[pixelId * 4 + 3] = 255;
307 }
308
309 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
310 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
312 glGenerateMipmap(GL_TEXTURE_2D);
313
314 glUseProgram(m2DProgram);
315 glUniform1i(mTexture2DUniformLocation, 0);
316 glUniform2f(mTextureScaleUniformLocation, 0.0625f, 0.0625f);
317 drawQuad(m2DProgram, "position", 0.5f);
318 EXPECT_GL_NO_ERROR();
319 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
320
321 // Fill with blue
322 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
323 {
324 pixels[pixelId * 4 + 0] = 0;
325 pixels[pixelId * 4 + 1] = 0;
326 pixels[pixelId * 4 + 2] = 255;
327 pixels[pixelId * 4 + 3] = 255;
328 }
329
330 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
331 glGenerateMipmap(GL_TEXTURE_2D);
332
333 // Fill with green
334 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
335 {
336 pixels[pixelId * 4 + 0] = 0;
337 pixels[pixelId * 4 + 1] = 255;
338 pixels[pixelId * 4 + 2] = 0;
339 pixels[pixelId * 4 + 3] = 255;
340 }
341
342 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
343 glGenerateMipmap(GL_TEXTURE_2D);
344
345 drawQuad(m2DProgram, "position", 0.5f);
346
347 EXPECT_GL_NO_ERROR();
348 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
349}
Jamie Madillf8fccb32014-11-12 15:05:26 -0500350
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500351// Test creating a FBO with a cube map render target, to test an ANGLE bug
352// https://code.google.com/p/angleproject/issues/detail?id=849
353TYPED_TEST(TextureTest, CubeMapFBO)
354{
355 GLuint fbo;
356 glGenFramebuffers(1, &fbo);
357 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
358
359 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
360 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
361
362 EXPECT_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
363
364 glDeleteFramebuffers(1, &fbo);
365
366 EXPECT_GL_NO_ERROR();
367}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000368
369// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
370TYPED_TEST(TextureTest, TexStorage)
371{
372 int width = getWindowWidth();
373 int height = getWindowHeight();
374
375 GLuint tex2D;
376 glGenTextures(1, &tex2D);
377 glActiveTexture(GL_TEXTURE0);
378 glBindTexture(GL_TEXTURE_2D, tex2D);
379
380 // Fill with red
381 std::vector<GLubyte> pixels(3 * 16 * 16);
382 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
383 {
384 pixels[pixelId * 3 + 0] = 255;
385 pixels[pixelId * 3 + 1] = 0;
386 pixels[pixelId * 3 + 2] = 0;
387 }
388
389 // ANGLE internally uses RGBA as the DirectX format for RGB images
390 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
391 // The data is kept in a CPU-side image and the image is marked as dirty.
392 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
393
394 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
395 // glTexSubImage2D should take into account that the image is dirty.
396 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
397 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
398 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
399
400 glUseProgram(m2DProgram);
401 glUniform1i(mTexture2DUniformLocation, 0);
402 glUniform2f(mTextureScaleUniformLocation, 1.f, 1.f);
403 drawQuad(m2DProgram, "position", 0.5f);
404 glDeleteTextures(1, &tex2D);
405 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000406 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -0400407
408 // Validate that the region of the texture without data has an alpha of 1.0
409 GLubyte pixel[4];
410 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
411 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000412}
413
414// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color.
415TYPED_TEST(TextureTest, TexStorageWithPBO)
416{
417 if (extensionEnabled("NV_pixel_buffer_object"))
418 {
419 int width = getWindowWidth();
420 int height = getWindowHeight();
421
422 GLuint tex2D;
423 glGenTextures(1, &tex2D);
424 glActiveTexture(GL_TEXTURE0);
425 glBindTexture(GL_TEXTURE_2D, tex2D);
426
427 // Fill with red
428 std::vector<GLubyte> pixels(3 * 16 * 16);
429 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
430 {
431 pixels[pixelId * 3 + 0] = 255;
432 pixels[pixelId * 3 + 1] = 0;
433 pixels[pixelId * 3 + 2] = 0;
434 }
435
436 // Read 16x16 region from red backbuffer to PBO
437 GLuint pbo;
438 glGenBuffers(1, &pbo);
439 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
440 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
441
442 // ANGLE internally uses RGBA as the DirectX format for RGB images
443 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
444 // The data is kept in a CPU-side image and the image is marked as dirty.
445 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
446
447 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
448 // glTexSubImage2D should take into account that the image is dirty.
449 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
450 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
451 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
452
453 glUseProgram(m2DProgram);
454 glUniform1i(mTexture2DUniformLocation, 0);
455 glUniform2f(mTextureScaleUniformLocation, 1.f, 1.f);
456 drawQuad(m2DProgram, "position", 0.5f);
457 glDeleteTextures(1, &tex2D);
458 glDeleteTextures(1, &pbo);
459 EXPECT_GL_NO_ERROR();
460 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
461 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
462 }
463}
Jamie Madillbc393df2015-01-29 13:46:07 -0500464
465// See description on testFloatCopySubImage
Geoff Langfbfa47c2015-03-31 11:26:00 -0400466TYPED_TEST(TextureTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500467{
468 testFloatCopySubImage(1, 1);
469}
470
Geoff Langfbfa47c2015-03-31 11:26:00 -0400471TYPED_TEST(TextureTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500472{
473 testFloatCopySubImage(2, 1);
474}
475
Geoff Langfbfa47c2015-03-31 11:26:00 -0400476TYPED_TEST(TextureTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500477{
478 testFloatCopySubImage(2, 2);
479}
480
Geoff Langfbfa47c2015-03-31 11:26:00 -0400481TYPED_TEST(TextureTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500482{
483 testFloatCopySubImage(3, 1);
484}
485
Geoff Langfbfa47c2015-03-31 11:26:00 -0400486TYPED_TEST(TextureTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500487{
488 testFloatCopySubImage(3, 2);
489}
490
491TYPED_TEST(TextureTest, CopySubImageFloat_RGB_RGB)
492{
Jamie Madillc3b9b262015-01-30 14:00:51 -0500493 // TODO(jmadill): Figure out why this is broken on Intel D3D11
494 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
495 {
496 std::cout << "Test skipped on Intel D3D11." << std::endl;
497 return;
498 }
499
Jamie Madillbc393df2015-01-29 13:46:07 -0500500 testFloatCopySubImage(3, 3);
501}
502
Geoff Langfbfa47c2015-03-31 11:26:00 -0400503TYPED_TEST(TextureTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500504{
505 testFloatCopySubImage(4, 1);
506}
507
Geoff Langfbfa47c2015-03-31 11:26:00 -0400508TYPED_TEST(TextureTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500509{
510 testFloatCopySubImage(4, 2);
511}
512
513TYPED_TEST(TextureTest, CopySubImageFloat_RGBA_RGB)
514{
Jamie Madillc3b9b262015-01-30 14:00:51 -0500515 // TODO(jmadill): Figure out why this is broken on Intel D3D11
516 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
517 {
518 std::cout << "Test skipped on Intel D3D11." << std::endl;
519 return;
520 }
521
Jamie Madillbc393df2015-01-29 13:46:07 -0500522 testFloatCopySubImage(4, 3);
523}
524
525TYPED_TEST(TextureTest, CopySubImageFloat_RGBA_RGBA)
526{
Jamie Madillc3b9b262015-01-30 14:00:51 -0500527 // TODO(jmadill): Figure out why this is broken on Intel D3D11
528 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
529 {
530 std::cout << "Test skipped on Intel D3D11." << std::endl;
531 return;
532 }
533
Jamie Madillbc393df2015-01-29 13:46:07 -0500534 testFloatCopySubImage(4, 4);
535}
Austin Kinross07285142015-03-26 11:36:16 -0700536
537// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
538// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA
539TYPED_TEST(TextureTest, TextureNPOT_GL_ALPHA_UBYTE)
540{
541 const int npotTexSize = 5;
542 const int potTexSize = 4; // Should be less than npotTexSize
543 GLuint tex2D;
544
545 if (extensionEnabled("GL_OES_texture_npot"))
546 {
547 // This test isn't applicable if texture_npot is enabled
548 return;
549 }
550
551 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
552
553 glActiveTexture(GL_TEXTURE0);
554 glGenTextures(1, &tex2D);
555 glBindTexture(GL_TEXTURE_2D, tex2D);
556
557 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
558 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
559 {
560 pixels[pixelId] = 64;
561 }
562
563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
565
566 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
567 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
568 EXPECT_GL_ERROR(GL_INVALID_VALUE);
569
570 // Check that an NPOT texture on level 0 succeeds
571 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
572 EXPECT_GL_NO_ERROR();
573
574 // Check that generateMipmap fails on NPOT
575 glGenerateMipmap(GL_TEXTURE_2D);
576 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
577
578 // Check that nothing is drawn if filtering is not correct for NPOT
579 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
581 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
582 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
583 glClear(GL_COLOR_BUFFER_BIT);
584 drawQuad(m2DProgram, "position", 1.0f);
585 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
586
587 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
588 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
589 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
591 glClear(GL_COLOR_BUFFER_BIT);
592 drawQuad(m2DProgram, "position", 1.0f);
593 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
594
595 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
596 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
597 glClear(GL_COLOR_BUFFER_BIT);
598 drawQuad(m2DProgram, "position", 1.0f);
599 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
600
601 // Check that glTexImage2D for POT texture succeeds
602 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
603 EXPECT_GL_NO_ERROR();
604
605 // Check that generateMipmap for an POT texture succeeds
606 glGenerateMipmap(GL_TEXTURE_2D);
607 EXPECT_GL_NO_ERROR();
608
609 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
611 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
613 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
614 glClear(GL_COLOR_BUFFER_BIT);
615 drawQuad(m2DProgram, "position", 1.0f);
616 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
617 EXPECT_GL_NO_ERROR();
618}