blob: f07abede0b281b19fa6d7a868604371d3d4dd8b0 [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 Langf74fef52015-04-29 12:57:52 -04004ANGLE_TYPED_TEST_CASE(TextureTest, ES2_D3D9, ES2_D3D11, ES2_D3D11_FL9_3);
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 Langbde666a2015-04-07 17:17:08 -0400109 // TODO(jmadill): Figure out why this is broken on Intel D3D11
110 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
111 {
112 std::cout << "Test skipped on Intel D3D11." << std::endl;
113 return;
114 }
115
Geoff Langfbfa47c2015-03-31 11:26:00 -0400116 if (getClientVersion() < 3)
117 {
118 if (!extensionEnabled("GL_OES_texture_float"))
119 {
120 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
121 return;
122 }
123
124 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
125 {
126 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
127 return;
128 }
129 }
130
Jamie Madillbc393df2015-01-29 13:46:07 -0500131 GLfloat sourceImageData[4][16] =
132 {
133 { // R
134 1.0f,
135 0.0f,
136 0.0f,
137 1.0f
138 },
139 { // RG
140 1.0f, 0.0f,
141 0.0f, 1.0f,
142 0.0f, 0.0f,
143 1.0f, 1.0f
144 },
145 { // RGB
146 1.0f, 0.0f, 0.0f,
147 0.0f, 1.0f, 0.0f,
148 0.0f, 0.0f, 1.0f,
149 1.0f, 1.0f, 0.0f
150 },
151 { // RGBA
152 1.0f, 0.0f, 0.0f, 1.0f,
153 0.0f, 1.0f, 0.0f, 1.0f,
154 0.0f, 0.0f, 1.0f, 1.0f,
155 1.0f, 1.0f, 0.0f, 1.0f
156 },
157 };
158
159 GLenum imageFormats[] =
160 {
161 GL_R32F,
162 GL_RG32F,
163 GL_RGB32F,
164 GL_RGBA32F,
165 };
166
167 GLenum sourceUnsizedFormats[] =
168 {
169 GL_RED,
170 GL_RG,
171 GL_RGB,
172 GL_RGBA,
173 };
174
175 GLuint textures[2];
176
177 glGenTextures(2, textures);
178
179 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
180 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
181 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
182 GLenum destImageFormat = imageFormats[destImageChannels - 1];
183
184 glBindTexture(GL_TEXTURE_2D, textures[0]);
185 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
187 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
188 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
189
hendrikwb27f79a2015-03-04 11:26:46 -0800190 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500191 {
192 // This is not supported
193 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
194 }
195 else
196 {
197 ASSERT_GL_NO_ERROR();
198 }
199
200 GLuint fbo;
201 glGenFramebuffers(1, &fbo);
202 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
203 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
204
205 glBindTexture(GL_TEXTURE_2D, textures[1]);
206 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
209
210 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
211 ASSERT_GL_NO_ERROR();
212
213 glBindFramebuffer(GL_FRAMEBUFFER, 0);
214 drawQuad(m2DProgram, "position", 0.5f);
215 swapBuffers();
216
217 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
218
219 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
220 if (testImageChannels > 1)
221 {
222 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
223 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
224 if (testImageChannels > 2)
225 {
226 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
227 }
228 }
229
230 glDeleteFramebuffers(1, &fbo);
231 glDeleteTextures(2, textures);
232
233 ASSERT_GL_NO_ERROR();
234 }
235
Jamie Madilld4cfa572014-07-08 10:00:32 -0400236 GLuint mTexture2D;
237 GLuint mTextureCube;
Geoff Langc41e42d2014-04-28 10:58:16 -0400238
Jamie Madilld4cfa572014-07-08 10:00:32 -0400239 GLuint m2DProgram;
240 GLuint mCubeProgram;
241 GLint mTexture2DUniformLocation;
Jamie Madill9aca0592014-10-06 16:26:59 -0400242 GLint mTextureScaleUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400243};
244
Austin Kinross18b931d2014-09-29 12:58:31 -0700245TYPED_TEST(TextureTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400246{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400247 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400248 EXPECT_GL_ERROR(GL_NO_ERROR);
249
250 const GLubyte *pixels[20] = { 0 };
251 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
252 EXPECT_GL_ERROR(GL_INVALID_VALUE);
253}
Geoff Langc41e42d2014-04-28 10:58:16 -0400254
Austin Kinross18b931d2014-09-29 12:58:31 -0700255TYPED_TEST(TextureTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400256{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400257 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400258 EXPECT_GL_ERROR(GL_NO_ERROR);
259
260 // Use the texture first to make sure it's in video memory
Jamie Madilld4cfa572014-07-08 10:00:32 -0400261 glUseProgram(m2DProgram);
262 glUniform1i(mTexture2DUniformLocation, 0);
263 drawQuad(m2DProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400264
265 const GLubyte *pixel[4] = { 0 };
266
267 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
268 EXPECT_GL_NO_ERROR();
269
270 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
271 EXPECT_GL_NO_ERROR();
272
273 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
274 EXPECT_GL_NO_ERROR();
275}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400276
277// Test drawing with two texture types, to trigger an ANGLE bug in validation
Austin Kinross18b931d2014-09-29 12:58:31 -0700278TYPED_TEST(TextureTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400279{
280 glActiveTexture(GL_TEXTURE0);
281 glBindTexture(GL_TEXTURE_2D, mTexture2D);
282 glActiveTexture(GL_TEXTURE1);
283 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
284 EXPECT_GL_ERROR(GL_NO_ERROR);
285
286 glUseProgram(mCubeProgram);
287 GLint tex2DUniformLocation = glGetUniformLocation(mCubeProgram, "tex2D");
288 GLint texCubeUniformLocation = glGetUniformLocation(mCubeProgram, "texCube");
289 EXPECT_NE(-1, tex2DUniformLocation);
290 EXPECT_NE(-1, texCubeUniformLocation);
291 glUniform1i(tex2DUniformLocation, 0);
292 glUniform1i(texCubeUniformLocation, 1);
293 drawQuad(mCubeProgram, "position", 0.5f);
294 EXPECT_GL_NO_ERROR();
295}
Jamie Madill9aca0592014-10-06 16:26:59 -0400296
297// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
298TYPED_TEST(TextureTest, MipmapsTwice)
299{
300 int px = getWindowWidth() / 2;
301 int py = getWindowHeight() / 2;
302
303 glActiveTexture(GL_TEXTURE0);
304 glBindTexture(GL_TEXTURE_2D, mTexture2D);
305
306 // Fill with red
307 std::vector<GLubyte> pixels(4 * 16 * 16);
308 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
309 {
310 pixels[pixelId * 4 + 0] = 255;
311 pixels[pixelId * 4 + 1] = 0;
312 pixels[pixelId * 4 + 2] = 0;
313 pixels[pixelId * 4 + 3] = 255;
314 }
315
316 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
319 glGenerateMipmap(GL_TEXTURE_2D);
320
321 glUseProgram(m2DProgram);
322 glUniform1i(mTexture2DUniformLocation, 0);
323 glUniform2f(mTextureScaleUniformLocation, 0.0625f, 0.0625f);
324 drawQuad(m2DProgram, "position", 0.5f);
325 EXPECT_GL_NO_ERROR();
326 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
327
328 // Fill with blue
329 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
330 {
331 pixels[pixelId * 4 + 0] = 0;
332 pixels[pixelId * 4 + 1] = 0;
333 pixels[pixelId * 4 + 2] = 255;
334 pixels[pixelId * 4 + 3] = 255;
335 }
336
337 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
338 glGenerateMipmap(GL_TEXTURE_2D);
339
340 // Fill with green
341 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
342 {
343 pixels[pixelId * 4 + 0] = 0;
344 pixels[pixelId * 4 + 1] = 255;
345 pixels[pixelId * 4 + 2] = 0;
346 pixels[pixelId * 4 + 3] = 255;
347 }
348
349 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
350 glGenerateMipmap(GL_TEXTURE_2D);
351
352 drawQuad(m2DProgram, "position", 0.5f);
353
354 EXPECT_GL_NO_ERROR();
355 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
356}
Jamie Madillf8fccb32014-11-12 15:05:26 -0500357
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500358// Test creating a FBO with a cube map render target, to test an ANGLE bug
359// https://code.google.com/p/angleproject/issues/detail?id=849
360TYPED_TEST(TextureTest, CubeMapFBO)
361{
362 GLuint fbo;
363 glGenFramebuffers(1, &fbo);
364 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
365
366 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
367 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
368
369 EXPECT_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
370
371 glDeleteFramebuffers(1, &fbo);
372
373 EXPECT_GL_NO_ERROR();
374}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000375
376// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
377TYPED_TEST(TextureTest, TexStorage)
378{
379 int width = getWindowWidth();
380 int height = getWindowHeight();
381
382 GLuint tex2D;
383 glGenTextures(1, &tex2D);
384 glActiveTexture(GL_TEXTURE0);
385 glBindTexture(GL_TEXTURE_2D, tex2D);
386
387 // Fill with red
388 std::vector<GLubyte> pixels(3 * 16 * 16);
389 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
390 {
391 pixels[pixelId * 3 + 0] = 255;
392 pixels[pixelId * 3 + 1] = 0;
393 pixels[pixelId * 3 + 2] = 0;
394 }
395
396 // ANGLE internally uses RGBA as the DirectX format for RGB images
397 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
398 // The data is kept in a CPU-side image and the image is marked as dirty.
399 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
400
401 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
402 // glTexSubImage2D should take into account that the image is dirty.
403 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
406
407 glUseProgram(m2DProgram);
408 glUniform1i(mTexture2DUniformLocation, 0);
409 glUniform2f(mTextureScaleUniformLocation, 1.f, 1.f);
410 drawQuad(m2DProgram, "position", 0.5f);
411 glDeleteTextures(1, &tex2D);
412 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000413 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -0400414
415 // Validate that the region of the texture without data has an alpha of 1.0
416 GLubyte pixel[4];
417 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
418 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000419}
420
421// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color.
422TYPED_TEST(TextureTest, TexStorageWithPBO)
423{
424 if (extensionEnabled("NV_pixel_buffer_object"))
425 {
426 int width = getWindowWidth();
427 int height = getWindowHeight();
428
429 GLuint tex2D;
430 glGenTextures(1, &tex2D);
431 glActiveTexture(GL_TEXTURE0);
432 glBindTexture(GL_TEXTURE_2D, tex2D);
433
434 // Fill with red
435 std::vector<GLubyte> pixels(3 * 16 * 16);
436 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
437 {
438 pixels[pixelId * 3 + 0] = 255;
439 pixels[pixelId * 3 + 1] = 0;
440 pixels[pixelId * 3 + 2] = 0;
441 }
442
443 // Read 16x16 region from red backbuffer to PBO
444 GLuint pbo;
445 glGenBuffers(1, &pbo);
446 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
447 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
448
449 // ANGLE internally uses RGBA as the DirectX format for RGB images
450 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
451 // The data is kept in a CPU-side image and the image is marked as dirty.
452 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
453
454 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
455 // glTexSubImage2D should take into account that the image is dirty.
456 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
457 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
458 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
459
460 glUseProgram(m2DProgram);
461 glUniform1i(mTexture2DUniformLocation, 0);
462 glUniform2f(mTextureScaleUniformLocation, 1.f, 1.f);
463 drawQuad(m2DProgram, "position", 0.5f);
464 glDeleteTextures(1, &tex2D);
465 glDeleteTextures(1, &pbo);
466 EXPECT_GL_NO_ERROR();
467 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
468 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
469 }
470}
Jamie Madillbc393df2015-01-29 13:46:07 -0500471
472// See description on testFloatCopySubImage
Geoff Langfbfa47c2015-03-31 11:26:00 -0400473TYPED_TEST(TextureTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500474{
475 testFloatCopySubImage(1, 1);
476}
477
Geoff Langfbfa47c2015-03-31 11:26:00 -0400478TYPED_TEST(TextureTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500479{
480 testFloatCopySubImage(2, 1);
481}
482
Geoff Langfbfa47c2015-03-31 11:26:00 -0400483TYPED_TEST(TextureTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500484{
485 testFloatCopySubImage(2, 2);
486}
487
Geoff Langfbfa47c2015-03-31 11:26:00 -0400488TYPED_TEST(TextureTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500489{
490 testFloatCopySubImage(3, 1);
491}
492
Geoff Langfbfa47c2015-03-31 11:26:00 -0400493TYPED_TEST(TextureTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500494{
495 testFloatCopySubImage(3, 2);
496}
497
498TYPED_TEST(TextureTest, CopySubImageFloat_RGB_RGB)
499{
500 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{
515 testFloatCopySubImage(4, 3);
516}
517
518TYPED_TEST(TextureTest, CopySubImageFloat_RGBA_RGBA)
519{
520 testFloatCopySubImage(4, 4);
521}
Austin Kinross07285142015-03-26 11:36:16 -0700522
523// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
524// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA
525TYPED_TEST(TextureTest, TextureNPOT_GL_ALPHA_UBYTE)
526{
527 const int npotTexSize = 5;
528 const int potTexSize = 4; // Should be less than npotTexSize
529 GLuint tex2D;
530
531 if (extensionEnabled("GL_OES_texture_npot"))
532 {
533 // This test isn't applicable if texture_npot is enabled
534 return;
535 }
536
537 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
538
539 glActiveTexture(GL_TEXTURE0);
540 glGenTextures(1, &tex2D);
541 glBindTexture(GL_TEXTURE_2D, tex2D);
542
543 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
544 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
545 {
546 pixels[pixelId] = 64;
547 }
548
549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
550 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
551
552 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
553 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
554 EXPECT_GL_ERROR(GL_INVALID_VALUE);
555
556 // Check that an NPOT texture on level 0 succeeds
557 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
558 EXPECT_GL_NO_ERROR();
559
560 // Check that generateMipmap fails on NPOT
561 glGenerateMipmap(GL_TEXTURE_2D);
562 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
563
564 // Check that nothing is drawn if filtering is not correct for NPOT
565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
566 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
567 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
569 glClear(GL_COLOR_BUFFER_BIT);
570 drawQuad(m2DProgram, "position", 1.0f);
571 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
572
573 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
574 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
575 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
576 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
577 glClear(GL_COLOR_BUFFER_BIT);
578 drawQuad(m2DProgram, "position", 1.0f);
579 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
580
581 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
582 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
583 glClear(GL_COLOR_BUFFER_BIT);
584 drawQuad(m2DProgram, "position", 1.0f);
585 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
586
587 // Check that glTexImage2D for POT texture succeeds
588 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
589 EXPECT_GL_NO_ERROR();
590
591 // Check that generateMipmap for an POT texture succeeds
592 glGenerateMipmap(GL_TEXTURE_2D);
593 EXPECT_GL_NO_ERROR();
594
595 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
596 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
597 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
600 glClear(GL_COLOR_BUFFER_BIT);
601 drawQuad(m2DProgram, "position", 1.0f);
602 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
603 EXPECT_GL_NO_ERROR();
604}