1 // Copyright 2017 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "gtest/gtest.h"
16 #include "gmock/gmock.h"
17
18 #include <EGL/egl.h>
19 #include <GLES2/gl2.h>
20 #include <GLES2/gl2ext.h>
21 #include <GLES3/gl3.h>
22
23 #if defined(_WIN32)
24 #include <Windows.h>
25 #endif
26
27 #define EXPECT_GLENUM_EQ(expected, actual) EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
28
29 class SwiftShaderTest : public testing::Test
30 {
31 protected:
SetUp()32 void SetUp() override
33 {
34 #if defined(_WIN32) && !defined(STANDALONE)
35 // The DLLs are delay loaded (see BUILD.gn), so we can load
36 // the correct ones from Chrome's swiftshader subdirectory.
37 HMODULE libEGL = LoadLibraryA("swiftshader\\libEGL.dll");
38 EXPECT_NE((HMODULE)NULL, libEGL);
39
40 HMODULE libGLESv2 = LoadLibraryA("swiftshader\\libGLESv2.dll");
41 EXPECT_NE((HMODULE)NULL, libGLESv2);
42 #endif
43 }
44
compareColor(unsigned char referenceColor[4])45 void compareColor(unsigned char referenceColor[4])
46 {
47 unsigned char color[4] = { 0 };
48 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
49 EXPECT_EQ(color[0], referenceColor[0]);
50 EXPECT_EQ(color[1], referenceColor[1]);
51 EXPECT_EQ(color[2], referenceColor[2]);
52 EXPECT_EQ(color[3], referenceColor[3]);
53 }
54
Initialize(int version,bool withChecks)55 void Initialize(int version, bool withChecks)
56 {
57 EXPECT_EQ(EGL_SUCCESS, eglGetError());
58
59 display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
60
61 if(withChecks)
62 {
63 EXPECT_EQ(EGL_SUCCESS, eglGetError());
64 EXPECT_NE(EGL_NO_DISPLAY, display);
65
66 eglQueryString(display, EGL_VENDOR);
67 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
68 }
69
70 EGLint major;
71 EGLint minor;
72 EGLBoolean initialized = eglInitialize(display, &major, &minor);
73
74 if(withChecks)
75 {
76 EXPECT_EQ(EGL_SUCCESS, eglGetError());
77 EXPECT_EQ((EGLBoolean)EGL_TRUE, initialized);
78 EXPECT_EQ(1, major);
79 EXPECT_EQ(4, minor);
80
81 const char *eglVendor = eglQueryString(display, EGL_VENDOR);
82 EXPECT_EQ(EGL_SUCCESS, eglGetError());
83 EXPECT_STREQ("Google Inc.", eglVendor);
84
85 const char *eglVersion = eglQueryString(display, EGL_VERSION);
86 EXPECT_EQ(EGL_SUCCESS, eglGetError());
87 EXPECT_THAT(eglVersion, testing::HasSubstr("1.4 SwiftShader "));
88 }
89
90 eglBindAPI(EGL_OPENGL_ES_API);
91 EXPECT_EQ(EGL_SUCCESS, eglGetError());
92
93 const EGLint configAttributes[] =
94 {
95 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
96 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
97 EGL_ALPHA_SIZE, 8,
98 EGL_NONE
99 };
100
101 EGLint num_config = -1;
102 EGLBoolean success = eglChooseConfig(display, configAttributes, &config, 1, &num_config);
103 EXPECT_EQ(EGL_SUCCESS, eglGetError());
104 EXPECT_EQ(num_config, 1);
105 EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
106
107 if(withChecks)
108 {
109 EGLint conformant = 0;
110 eglGetConfigAttrib(display, config, EGL_CONFORMANT, &conformant);
111 EXPECT_EQ(EGL_SUCCESS, eglGetError());
112 EXPECT_TRUE(conformant & EGL_OPENGL_ES2_BIT);
113
114 EGLint renderableType = 0;
115 eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
116 EXPECT_EQ(EGL_SUCCESS, eglGetError());
117 EXPECT_TRUE(renderableType & EGL_OPENGL_ES2_BIT);
118
119 EGLint surfaceType = 0;
120 eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &surfaceType);
121 EXPECT_EQ(EGL_SUCCESS, eglGetError());
122 EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT);
123 }
124
125 EGLint surfaceAttributes[] =
126 {
127 EGL_WIDTH, 1920,
128 EGL_HEIGHT, 1080,
129 EGL_NONE
130 };
131
132 surface = eglCreatePbufferSurface(display, config, surfaceAttributes);
133 EXPECT_EQ(EGL_SUCCESS, eglGetError());
134 EXPECT_NE(EGL_NO_SURFACE, surface);
135
136 EGLint contextAttributes[] =
137 {
138 EGL_CONTEXT_CLIENT_VERSION, version,
139 EGL_NONE
140 };
141
142 context = eglCreateContext(display, config, NULL, contextAttributes);
143 EXPECT_EQ(EGL_SUCCESS, eglGetError());
144 EXPECT_NE(EGL_NO_CONTEXT, context);
145
146 success = eglMakeCurrent(display, surface, surface, context);
147 EXPECT_EQ(EGL_SUCCESS, eglGetError());
148 EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
149
150 if(withChecks)
151 {
152 EGLDisplay currentDisplay = eglGetCurrentDisplay();
153 EXPECT_EQ(EGL_SUCCESS, eglGetError());
154 EXPECT_EQ(display, currentDisplay);
155
156 EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
157 EXPECT_EQ(EGL_SUCCESS, eglGetError());
158 EXPECT_EQ(surface, currentDrawSurface);
159
160 EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
161 EXPECT_EQ(EGL_SUCCESS, eglGetError());
162 EXPECT_EQ(surface, currentReadSurface);
163
164 EGLContext currentContext = eglGetCurrentContext();
165 EXPECT_EQ(EGL_SUCCESS, eglGetError());
166 EXPECT_EQ(context, currentContext);
167 }
168
169 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
170 }
171
Uninitialize()172 void Uninitialize()
173 {
174 EGLBoolean success = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
175 EXPECT_EQ(EGL_SUCCESS, eglGetError());
176 EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
177
178 EGLDisplay currentDisplay = eglGetCurrentDisplay();
179 EXPECT_EQ(EGL_SUCCESS, eglGetError());
180 EXPECT_EQ(EGL_NO_DISPLAY, currentDisplay);
181
182 EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
183 EXPECT_EQ(EGL_SUCCESS, eglGetError());
184 EXPECT_EQ(EGL_NO_SURFACE, currentDrawSurface);
185
186 EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
187 EXPECT_EQ(EGL_SUCCESS, eglGetError());
188 EXPECT_EQ(EGL_NO_SURFACE, currentReadSurface);
189
190 EGLContext currentContext = eglGetCurrentContext();
191 EXPECT_EQ(EGL_SUCCESS, eglGetError());
192 EXPECT_EQ(EGL_NO_CONTEXT, currentContext);
193
194 success = eglDestroyContext(display, context);
195 EXPECT_EQ(EGL_SUCCESS, eglGetError());
196 EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
197
198 success = eglDestroySurface(display, surface);
199 EXPECT_EQ(EGL_SUCCESS, eglGetError());
200 EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
201
202 success = eglTerminate(display);
203 EXPECT_EQ(EGL_SUCCESS, eglGetError());
204 EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
205 }
206
207 struct ProgramHandles {
208 GLuint program;
209 GLuint vsShader;
210 GLuint fsShader;
211 };
212
createProgram(const std::string & vs,const std::string & fs)213 ProgramHandles createProgram(const std::string& vs, const std::string& fs)
214 {
215 ProgramHandles ph;
216 ph.program = glCreateProgram();
217 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
218
219 ph.vsShader = glCreateShader(GL_VERTEX_SHADER);
220 const char* vsSource[1] = { vs.c_str() };
221 glShaderSource(ph.vsShader, 1, vsSource, nullptr);
222 glCompileShader(ph.vsShader);
223 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
224
225 ph.fsShader = glCreateShader(GL_FRAGMENT_SHADER);
226 const char* fsSource[1] = { fs.c_str() };
227 glShaderSource(ph.fsShader, 1, fsSource, nullptr);
228 glCompileShader(ph.fsShader);
229 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
230
231 glAttachShader(ph.program, ph.vsShader);
232 glAttachShader(ph.program, ph.fsShader);
233 glLinkProgram(ph.program);
234 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
235
236 return ph;
237 }
238
deleteProgram(const ProgramHandles & ph)239 void deleteProgram(const ProgramHandles& ph)
240 {
241 glDeleteShader(ph.fsShader);
242 glDeleteShader(ph.vsShader);
243 glDeleteProgram(ph.program);
244 }
245
drawQuad(GLuint program)246 void drawQuad(GLuint program)
247 {
248 GLint prevProgram = 0;
249 glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);
250
251 glUseProgram(program);
252 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
253
254 GLint posLoc = glGetAttribLocation(program, "position");
255 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
256
257 GLint location = glGetUniformLocation(program, "tex");
258 ASSERT_NE(-1, location);
259 glUniform1i(location, 0);
260
261 float vertices[18] = { -1.0f, 1.0f, 0.5f,
262 -1.0f, -1.0f, 0.5f,
263 1.0f, -1.0f, 0.5f,
264 -1.0f, 1.0f, 0.5f,
265 1.0f, -1.0f, 0.5f,
266 1.0f, 1.0f, 0.5f };
267
268 glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices);
269 glEnableVertexAttribArray(posLoc);
270 glDrawArrays(GL_TRIANGLES, 0, 6);
271 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
272
273 glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
274 glDisableVertexAttribArray(posLoc);
275 glUseProgram(prevProgram);
276 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
277 }
278
getDisplay() const279 EGLDisplay getDisplay() const { return display; }
getConfig() const280 EGLConfig getConfig() const { return config; }
getSurface() const281 EGLSurface getSurface() const { return surface; }
getContext() const282 EGLContext getContext() const { return context; }
283 private:
284 EGLDisplay display;
285 EGLConfig config;
286 EGLSurface surface;
287 EGLContext context;
288 };
289
TEST_F(SwiftShaderTest,Initalization)290 TEST_F(SwiftShaderTest, Initalization)
291 {
292 Initialize(2, true);
293
294 const GLubyte *glVendor = glGetString(GL_VENDOR);
295 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
296 EXPECT_STREQ("Google Inc.", (const char*)glVendor);
297
298 const GLubyte *glRenderer = glGetString(GL_RENDERER);
299 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
300 EXPECT_STREQ("Google SwiftShader", (const char*)glRenderer);
301
302 const GLubyte *glVersion = glGetString(GL_VERSION);
303 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
304 EXPECT_THAT((const char*)glVersion, testing::HasSubstr("OpenGL ES 2.0 SwiftShader "));
305
306 Uninitialize();
307 }
308
309 // Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo
310 // GL_ARB_texture_rectangle
311 #ifndef GL_ARB_texture_rectangle
312 #define GL_ARB_texture_rectangle 1
313
314 #ifndef GL_SAMPLER_2D_RECT_ARB
315 #define GL_SAMPLER_2D_RECT_ARB 0x8B63
316 #endif
317
318 #ifndef GL_TEXTURE_BINDING_RECTANGLE_ARB
319 #define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
320 #endif
321
322 #ifndef GL_TEXTURE_RECTANGLE_ARB
323 #define GL_TEXTURE_RECTANGLE_ARB 0x84F5
324 #endif
325
326 #ifndef GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB
327 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
328 #endif
329
330 #endif // GL_ARB_texture_rectangle
331
332 // Test using TexImage2D to define a rectangle texture
333
TEST_F(SwiftShaderTest,TextureRectangle_TexImage2D)334 TEST_F(SwiftShaderTest, TextureRectangle_TexImage2D)
335 {
336 Initialize(2, false);
337
338 GLuint tex = 1;
339 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
340
341 // Defining level 0 is allowed
342 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
343 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
344
345 // Defining level other than 0 is not allowed
346 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
347 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
348
349 GLint maxSize = 0;
350 glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &maxSize);
351
352 // Defining a texture of the max size is allowed
353 {
354 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize, maxSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
355 GLenum error = glGetError();
356 ASSERT_TRUE(error == GL_NO_ERROR || error == GL_OUT_OF_MEMORY);
357 }
358
359 // Defining a texture larger than the max size is disallowed
360 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize + 1, maxSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
361 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
362 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize, maxSize + 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
363 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
364
365 Uninitialize();
366 }
367
368 // Test using CompressedTexImage2D cannot be used on a retangle texture
TEST_F(SwiftShaderTest,TextureRectangle_CompressedTexImage2DDisallowed)369 TEST_F(SwiftShaderTest, TextureRectangle_CompressedTexImage2DDisallowed)
370 {
371 Initialize(2, false);
372
373 const char data[128] = { 0 };
374
375 // Control case: 2D texture
376 {
377 GLuint tex = 1;
378 glBindTexture(GL_TEXTURE_2D, tex);
379 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128, data);
380 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
381 }
382
383 // Rectangle textures cannot be compressed
384 {
385 GLuint tex = 2;
386 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
387 glCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128, data);
388 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
389 }
390
391 Uninitialize();
392 }
393
394 // Test using TexStorage2D to define a rectangle texture (ES3)
TEST_F(SwiftShaderTest,TextureRectangle_TexStorage2D)395 TEST_F(SwiftShaderTest, TextureRectangle_TexStorage2D)
396 {
397 Initialize(3, false);
398
399 // Defining one level is allowed
400 {
401 GLuint tex = 1;
402 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
403 glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, 16, 16);
404 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
405 }
406
407 // Having more than one level is not allowed
408 {
409 GLuint tex = 2;
410 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
411 // Use 5 levels because the EXT_texture_storage extension requires a mip chain all the way
412 // to a 1x1 mip.
413 glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 5, GL_RGBA8UI, 16, 16);
414 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
415 }
416
417 GLint maxSize = 0;
418 glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &maxSize);
419
420 // Defining a texture of the max size is allowed but still allow for OOM
421 {
422 GLuint tex = 3;
423 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
424 glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize, maxSize);
425 GLenum error = glGetError();
426 ASSERT_TRUE(error == GL_NO_ERROR || error == GL_OUT_OF_MEMORY);
427 }
428
429 // Defining a texture larger than the max size is disallowed
430 {
431 GLuint tex = 4;
432 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
433 glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize + 1, maxSize);
434 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
435 glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize, maxSize + 1);
436 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
437 }
438
439 // Compressed formats are disallowed
440 GLuint tex = 5;
441 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
442 glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16);
443 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
444
445 Uninitialize();
446 }
447
448 // Test validation of disallowed texture parameters
TEST_F(SwiftShaderTest,TextureRectangle_TexParameterRestriction)449 TEST_F(SwiftShaderTest, TextureRectangle_TexParameterRestriction)
450 {
451 Initialize(3, false);
452
453 GLuint tex = 1;
454 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
455
456 // Only wrap mode CLAMP_TO_EDGE is supported
457 // Wrap S
458 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
459 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
460 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT);
461 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
462 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
463 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
464
465 // Wrap T
466 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
467 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
468 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT);
469 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
470 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
471 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
472
473 // Min filter has to be nearest or linear
474 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
475 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
476 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
477 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
478 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
479 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
480 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
481 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
482 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
483 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
484 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
485 EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
486
487 // Base level has to be 0
488 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0);
489 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
490 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 1);
491 EXPECT_GLENUM_EQ(GL_INVALID_OPERATION, glGetError());
492
493 Uninitialize();
494 }
495
496 // Test validation of "level" in FramebufferTexture2D
TEST_F(SwiftShaderTest,TextureRectangle_FramebufferTexture2DLevel)497 TEST_F(SwiftShaderTest, TextureRectangle_FramebufferTexture2DLevel)
498 {
499 Initialize(3, false);
500
501 GLuint tex = 1;
502 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
503 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
504 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
505
506 GLuint fbo = 1;
507 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
508
509 // Using level 0 of a rectangle texture is valid.
510 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
511 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
512 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
513
514 // Setting level != 0 is invalid
515 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 1);
516 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
517
518 Uninitialize();
519 }
520
521 // Test sampling from a rectangle texture
TEST_F(SwiftShaderTest,TextureRectangle_SamplingFromRectangle)522 TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle)
523 {
524 Initialize(3, false);
525
526 GLuint tex = 1;
527 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
528 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
529
530 unsigned char green[4] = { 0, 255, 0, 255 };
531 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
532 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
533
534 const std::string vs =
535 "attribute vec4 position;\n"
536 "void main()\n"
537 "{\n"
538 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
539 "}\n";
540
541 const std::string fs =
542 "#extension GL_ARB_texture_rectangle : require\n"
543 "precision mediump float;\n"
544 "uniform sampler2DRect tex;\n"
545 "void main()\n"
546 "{\n"
547 " gl_FragColor = texture2DRect(tex, vec2(0, 0));\n"
548 "}\n";
549
550 const ProgramHandles ph = createProgram(vs, fs);
551
552 glUseProgram(ph.program);
553 GLint location = glGetUniformLocation(ph.program, "tex");
554 ASSERT_NE(-1, location);
555 glUniform1i(location, 0);
556
557 glClearColor(0.0, 0.0, 0.0, 0.0);
558 glClear(GL_COLOR_BUFFER_BIT);
559 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
560
561 drawQuad(ph.program);
562
563 deleteProgram(ph);
564
565 compareColor(green);
566
567 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
568
569 Uninitialize();
570 }
571
572 // Test sampling from a rectangle texture
TEST_F(SwiftShaderTest,TextureRectangle_SamplingFromRectangleESSL3)573 TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3)
574 {
575 Initialize(3, false);
576
577 GLuint tex = 1;
578 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
579 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
580
581 unsigned char green[4] = { 0, 255, 0, 255 };
582 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
583 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
584
585 const std::string vs =
586 "#version 300 es\n"
587 "in vec4 position;\n"
588 "void main()\n"
589 "{\n"
590 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
591 "}\n";
592
593 const std::string fs =
594 "#version 300 es\n"
595 "#extension GL_ARB_texture_rectangle : require\n"
596 "precision mediump float;\n"
597 "uniform sampler2DRect tex;\n"
598 "out vec4 fragColor;\n"
599 "void main()\n"
600 "{\n"
601 " fragColor = texture(tex, vec2(0, 0));\n"
602 "}\n";
603
604 const ProgramHandles ph = createProgram(vs, fs);
605
606 glUseProgram(ph.program);
607 GLint location = glGetUniformLocation(ph.program, "tex");
608 ASSERT_NE(-1, location);
609 glUniform1i(location, 0);
610
611 glClearColor(0.0, 0.0, 0.0, 0.0);
612 glClear(GL_COLOR_BUFFER_BIT);
613 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
614
615 drawQuad(ph.program);
616
617 deleteProgram(ph);
618
619 compareColor(green);
620
621 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
622
623 Uninitialize();
624 }
625
626 // Test attaching a rectangle texture and rendering to it.
TEST_F(SwiftShaderTest,TextureRectangle_RenderToRectangle)627 TEST_F(SwiftShaderTest, TextureRectangle_RenderToRectangle)
628 {
629 Initialize(3, false);
630
631 GLuint tex = 1;
632 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
633 unsigned char black[4] = { 0, 0, 0, 255 };
634 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
635
636 GLuint fbo = 1;
637 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
638 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
639 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
640 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
641
642 // Clearing a texture is just as good as checking we can render to it, right?
643 glClearColor(0.0, 1.0, 0.0, 1.0);
644 glClear(GL_COLOR_BUFFER_BIT);
645
646 unsigned char green[4] = { 0, 255, 0, 255 };
647 compareColor(green);
648 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
649
650 Uninitialize();
651 }
652
TEST_F(SwiftShaderTest,TextureRectangle_DefaultSamplerParameters)653 TEST_F(SwiftShaderTest, TextureRectangle_DefaultSamplerParameters)
654 {
655 Initialize(3, false);
656
657 GLuint tex = 1;
658 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
659
660 GLint minFilter = 0;
661 glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, &minFilter);
662 EXPECT_GLENUM_EQ(GL_LINEAR, minFilter);
663
664 GLint wrapS = 0;
665 glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, &wrapS);
666 EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, wrapS);
667
668 GLint wrapT = 0;
669 glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, &wrapT);
670 EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, wrapT);
671
672 Uninitialize();
673 }
674
675 // Test glCopyTexImage with rectangle textures (ES3)
TEST_F(SwiftShaderTest,TextureRectangle_CopyTexImage)676 TEST_F(SwiftShaderTest, TextureRectangle_CopyTexImage)
677 {
678 Initialize(3, false);
679
680 GLuint tex = 1;
681 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
682
683 glBindFramebuffer(GL_FRAMEBUFFER, 0);
684 glClearColor(0, 1, 0, 1);
685 glClear(GL_COLOR_BUFFER_BIT);
686 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
687
688 // Error case: level != 0
689 glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8, 0, 0, 1, 1, 0);
690 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
691
692 // level = 0 works and defines the texture.
693 glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 0, 0, 1, 1, 0);
694 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
695
696 GLuint fbo = 1;
697 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
698 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
699
700 unsigned char green[4] = { 0, 255, 0, 255 };
701 compareColor(green);
702 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
703
704 Uninitialize();
705 }
706
707 // Test glCopyTexSubImage with rectangle textures (ES3)
TEST_F(SwiftShaderTest,TextureRectangle_CopyTexSubImage)708 TEST_F(SwiftShaderTest, TextureRectangle_CopyTexSubImage)
709 {
710 Initialize(3, false);
711
712 GLuint tex = 1;
713 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
714 unsigned char black[4] = { 0, 0, 0, 255 };
715 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
716
717 glBindFramebuffer(GL_FRAMEBUFFER, 0);
718 glClearColor(0, 1, 0, 1);
719 glClear(GL_COLOR_BUFFER_BIT);
720 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
721
722 // Error case: level != 0
723 glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, 0, 0, 0, 0, 1, 1);
724 EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
725
726 // level = 0 works and defines the texture.
727 glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 0, 0, 1, 1);
728 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
729
730 GLuint fbo = 1;
731 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
732 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
733
734 unsigned char green[4] = { 0, 255, 0, 255 };
735 compareColor(green);
736 EXPECT_GLENUM_EQ(GL_NONE, glGetError());
737
738 Uninitialize();
739 }
740
741 #ifndef EGL_ANGLE_iosurface_client_buffer
742 #define EGL_ANGLE_iosurface_client_buffer 1
743 #define EGL_IOSURFACE_ANGLE 0x3454
744 #define EGL_IOSURFACE_PLANE_ANGLE 0x345A
745 #define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
746 #define EGL_TEXTURE_TYPE_ANGLE 0x345C
747 #define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
748 #endif /* EGL_ANGLE_iosurface_client_buffer */
749
750 #if defined(__APPLE__)
751 #include <CoreFoundation/CoreFoundation.h>
752 #include <IOSurface/IOSurface.h>
753
754 namespace
755 {
AddIntegerValue(CFMutableDictionaryRef dictionary,const CFStringRef key,int32_t value)756 void AddIntegerValue(CFMutableDictionaryRef dictionary, const CFStringRef key, int32_t value)
757 {
758 CFNumberRef number = CFNumberCreate(nullptr, kCFNumberSInt32Type, &value);
759 CFDictionaryAddValue(dictionary, key, number);
760 CFRelease(number);
761 }
762 } // anonymous namespace
763
764 class EGLClientBufferWrapper
765 {
766 public:
EGLClientBufferWrapper(int width=1,int height=1)767 EGLClientBufferWrapper(int width = 1, int height = 1)
768 {
769 // Create a 1 by 1 BGRA8888 IOSurface
770 ioSurface = nullptr;
771
772 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
773 kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
774 AddIntegerValue(dict, kIOSurfaceWidth, width);
775 AddIntegerValue(dict, kIOSurfaceHeight, height);
776 AddIntegerValue(dict, kIOSurfacePixelFormat, 'BGRA');
777 AddIntegerValue(dict, kIOSurfaceBytesPerElement, 4);
778
779 ioSurface = IOSurfaceCreate(dict);
780 CFRelease(dict);
781
782 EXPECT_NE(nullptr, ioSurface);
783 }
784
~EGLClientBufferWrapper()785 ~EGLClientBufferWrapper()
786 {
787 IOSurfaceUnlock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
788
789 CFRelease(ioSurface);
790 }
791
getClientBuffer() const792 EGLClientBuffer getClientBuffer() const
793 {
794 return ioSurface;
795 }
796
lockColor()797 const unsigned char* lockColor()
798 {
799 IOSurfaceLock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
800 return reinterpret_cast<const unsigned char*>(IOSurfaceGetBaseAddress(ioSurface));
801 }
802
unlockColor()803 void unlockColor()
804 {
805 IOSurfaceUnlock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
806 }
807
writeColor(void * data,size_t dataSize)808 void writeColor(void* data, size_t dataSize)
809 {
810 // Write the data to the IOSurface
811 IOSurfaceLock(ioSurface, 0, nullptr);
812 memcpy(IOSurfaceGetBaseAddress(ioSurface), data, dataSize);
813 IOSurfaceUnlock(ioSurface, 0, nullptr);
814 }
815 private:
816 IOSurfaceRef ioSurface;
817 };
818
819 #else // __APPLE__
820
821 class EGLClientBufferWrapper
822 {
823 public:
EGLClientBufferWrapper(int width=1,int height=1)824 EGLClientBufferWrapper(int width = 1, int height = 1)
825 {
826 clientBuffer = new unsigned char[4 * width * height];
827 }
828
~EGLClientBufferWrapper()829 ~EGLClientBufferWrapper()
830 {
831 delete[] clientBuffer;
832 }
833
getClientBuffer() const834 EGLClientBuffer getClientBuffer() const
835 {
836 return clientBuffer;
837 }
838
lockColor()839 const unsigned char* lockColor()
840 {
841 return clientBuffer;
842 }
843
unlockColor()844 void unlockColor()
845 {
846 }
847
writeColor(void * data,size_t dataSize)848 void writeColor(void* data, size_t dataSize)
849 {
850 memcpy(clientBuffer, data, dataSize);
851 }
852 private:
853 unsigned char* clientBuffer;
854 };
855
856 #endif
857
858 class IOSurfaceClientBufferTest : public SwiftShaderTest
859 {
860 protected:
createIOSurfacePbuffer(EGLClientBuffer buffer,EGLint width,EGLint height,EGLint plane,GLenum internalFormat,GLenum type) const861 EGLSurface createIOSurfacePbuffer(EGLClientBuffer buffer, EGLint width, EGLint height, EGLint plane, GLenum internalFormat, GLenum type) const
862 {
863 // Make a PBuffer from it using the EGL_ANGLE_iosurface_client_buffer extension
864 const EGLint attribs[] = {
865 EGL_WIDTH, width,
866 EGL_HEIGHT, height,
867 EGL_IOSURFACE_PLANE_ANGLE, plane,
868 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
869 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, (EGLint)internalFormat,
870 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
871 EGL_TEXTURE_TYPE_ANGLE, (EGLint)type,
872 EGL_NONE, EGL_NONE,
873 };
874
875 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, buffer, getConfig(), attribs);
876 EXPECT_NE(EGL_NO_SURFACE, pbuffer);
877 return pbuffer;
878 }
879
bindIOSurfaceToTexture(EGLClientBuffer buffer,EGLint width,EGLint height,EGLint plane,GLenum internalFormat,GLenum type,EGLSurface * pbuffer,GLuint * texture) const880 void bindIOSurfaceToTexture(EGLClientBuffer buffer, EGLint width, EGLint height, EGLint plane, GLenum internalFormat, GLenum type, EGLSurface *pbuffer, GLuint *texture) const
881 {
882 *pbuffer = createIOSurfacePbuffer(buffer, width, height, plane, internalFormat, type);
883
884 // Bind the pbuffer
885 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, *texture);
886 EGLBoolean result = eglBindTexImage(getDisplay(), *pbuffer, EGL_BACK_BUFFER);
887 EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
888 EXPECT_EQ(EGL_SUCCESS, eglGetError());
889 }
890
doClear(GLenum internalFormat,bool clearToZero)891 void doClear(GLenum internalFormat, bool clearToZero)
892 {
893 if(internalFormat == GL_R16UI)
894 {
895 GLuint color = clearToZero ? 0 : 257;
896 glClearBufferuiv(GL_COLOR, 0, &color);
897 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
898 }
899 else
900 {
901 glClearColor(clearToZero ? 0.0f : 1.0f / 255.0f,
902 clearToZero ? 0.0f : 2.0f / 255.0f,
903 clearToZero ? 0.0f : 3.0f / 255.0f,
904 clearToZero ? 0.0f : 4.0f / 255.0f);
905 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
906 glClear(GL_COLOR_BUFFER_BIT);
907 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
908 }
909 }
910
doClearTest(EGLClientBufferWrapper & clientBufferWrapper,GLenum internalFormat,GLenum type,void * data,size_t dataSize)911 void doClearTest(EGLClientBufferWrapper& clientBufferWrapper, GLenum internalFormat, GLenum type, void *data, size_t dataSize)
912 {
913 ASSERT_TRUE(dataSize <= 4);
914
915 // Bind the IOSurface to a texture and clear it.
916 GLuint texture = 1;
917 EGLSurface pbuffer;
918 bindIOSurfaceToTexture(clientBufferWrapper.getClientBuffer(), 1, 1, 0, internalFormat, type, &pbuffer, &texture);
919
920 // glClear the pbuffer
921 GLuint fbo = 2;
922 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
923 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
924 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, texture, 0);
925 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
926 EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
927 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
928
929 doClear(internalFormat, false);
930
931 // Unbind pbuffer and check content.
932 EGLBoolean result = eglReleaseTexImage(getDisplay(), pbuffer, EGL_BACK_BUFFER);
933 EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
934 EXPECT_EQ(EGL_SUCCESS, eglGetError());
935
936 const unsigned char* color = clientBufferWrapper.lockColor();
937 for(size_t i = 0; i < dataSize; ++i)
938 {
939 EXPECT_EQ(color[i], reinterpret_cast<unsigned char*>(data)[i]);
940 }
941
942 result = eglDestroySurface(getDisplay(), pbuffer);
943 EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
944 EXPECT_EQ(EGL_SUCCESS, eglGetError());
945 }
946
doSampleTest(EGLClientBufferWrapper & clientBufferWrapper,GLenum internalFormat,GLenum type,void * data,size_t dataSize)947 void doSampleTest(EGLClientBufferWrapper& clientBufferWrapper, GLenum internalFormat, GLenum type, void *data, size_t dataSize)
948 {
949 ASSERT_TRUE(dataSize <= 4);
950
951 clientBufferWrapper.writeColor(data, dataSize);
952
953 // Bind the IOSurface to a texture and clear it.
954 GLuint texture = 1;
955 EGLSurface pbuffer;
956 bindIOSurfaceToTexture(clientBufferWrapper.getClientBuffer(), 1, 1, 0, internalFormat, type, &pbuffer, &texture);
957
958 doClear(internalFormat, true);
959
960 // Create program and draw quad using it
961 const std::string vs =
962 "attribute vec4 position;\n"
963 "void main()\n"
964 "{\n"
965 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
966 "}\n";
967
968 const std::string fs =
969 "#extension GL_ARB_texture_rectangle : require\n"
970 "precision mediump float;\n"
971 "uniform sampler2DRect tex;\n"
972 "void main()\n"
973 "{\n"
974 " gl_FragColor = texture2DRect(tex, vec2(0, 0));\n"
975 "}\n";
976
977 const ProgramHandles ph = createProgram(vs, fs);
978
979 drawQuad(ph.program);
980
981 deleteProgram(ph);
982
983 EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
984
985 // Unbind pbuffer and check content.
986 EGLBoolean result = eglReleaseTexImage(getDisplay(), pbuffer, EGL_BACK_BUFFER);
987 EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
988 EXPECT_EQ(EGL_SUCCESS, eglGetError());
989
990 const unsigned char* color = clientBufferWrapper.lockColor();
991 for(size_t i = 0; i < dataSize; ++i)
992 {
993 EXPECT_EQ(color[i], reinterpret_cast<unsigned char*>(data)[i]);
994 }
995 clientBufferWrapper.unlockColor();
996 }
997 };
998
999 // Tests for the EGL_ANGLE_iosurface_client_buffer extension
TEST_F(IOSurfaceClientBufferTest,RenderToBGRA8888IOSurface)1000 TEST_F(IOSurfaceClientBufferTest, RenderToBGRA8888IOSurface)
1001 {
1002 Initialize(3, false);
1003
1004 { // EGLClientBufferWrapper scope
1005 EGLClientBufferWrapper clientBufferWrapper;
1006 unsigned char data[4] = { 3, 2, 1, 4 };
1007 doClearTest(clientBufferWrapper, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data, 4);
1008 } // end of EGLClientBufferWrapper scope
1009
1010 Uninitialize();
1011 }
1012
1013 // Test reading from BGRA8888 IOSurfaces
TEST_F(IOSurfaceClientBufferTest,ReadFromBGRA8888IOSurface)1014 TEST_F(IOSurfaceClientBufferTest, ReadFromBGRA8888IOSurface)
1015 {
1016 Initialize(3, false);
1017
1018 { // EGLClientBufferWrapper scope
1019 EGLClientBufferWrapper clientBufferWrapper;
1020 unsigned char data[4] = { 3, 2, 1, 4 };
1021 doSampleTest(clientBufferWrapper, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data, 4);
1022 } // end of EGLClientBufferWrapper scope
1023
1024 Uninitialize();
1025 }
1026
1027 // Test using RG88 IOSurfaces for rendering
TEST_F(IOSurfaceClientBufferTest,RenderToRG88IOSurface)1028 TEST_F(IOSurfaceClientBufferTest, RenderToRG88IOSurface)
1029 {
1030 Initialize(3, false);
1031
1032 { // EGLClientBufferWrapper scope
1033 EGLClientBufferWrapper clientBufferWrapper;
1034 unsigned char data[2] = { 1, 2 };
1035 doClearTest(clientBufferWrapper, GL_RG, GL_UNSIGNED_BYTE, data, 2);
1036 } // end of EGLClientBufferWrapper scope
1037
1038 Uninitialize();
1039 }
1040
1041 // Test reading from RG88 IOSurfaces
TEST_F(IOSurfaceClientBufferTest,ReadFromRG88IOSurface)1042 TEST_F(IOSurfaceClientBufferTest, ReadFromRG88IOSurface)
1043 {
1044 Initialize(3, false);
1045
1046 { // EGLClientBufferWrapper scope
1047 EGLClientBufferWrapper clientBufferWrapper;
1048 unsigned char data[2] = { 1, 2 };
1049 doSampleTest(clientBufferWrapper, GL_RG, GL_UNSIGNED_BYTE, data, 2);
1050 } // end of EGLClientBufferWrapper scope
1051
1052 Uninitialize();
1053 }
1054
1055 // Test using R8 IOSurfaces for rendering
TEST_F(IOSurfaceClientBufferTest,RenderToR8IOSurface)1056 TEST_F(IOSurfaceClientBufferTest, RenderToR8IOSurface)
1057 {
1058 Initialize(3, false);
1059
1060 { // EGLClientBufferWrapper scope
1061 EGLClientBufferWrapper clientBufferWrapper;
1062 unsigned char data[1] = { 1 };
1063 doClearTest(clientBufferWrapper, GL_RED, GL_UNSIGNED_BYTE, data, 1);
1064 } // end of EGLClientBufferWrapper scope
1065
1066 Uninitialize();
1067 }
1068
1069 // Test reading from R8 IOSurfaces
TEST_F(IOSurfaceClientBufferTest,ReadFromR8IOSurface)1070 TEST_F(IOSurfaceClientBufferTest, ReadFromR8IOSurface)
1071 {
1072 Initialize(3, false);
1073
1074 { // EGLClientBufferWrapper scope
1075 EGLClientBufferWrapper clientBufferWrapper;
1076 unsigned char data[1] = { 1 };
1077 doSampleTest(clientBufferWrapper, GL_RED, GL_UNSIGNED_BYTE, data, 1);
1078 } // end of EGLClientBufferWrapper scope
1079
1080 Uninitialize();
1081 }
1082
1083 // Test using R16 IOSurfaces for rendering
TEST_F(IOSurfaceClientBufferTest,RenderToR16IOSurface)1084 TEST_F(IOSurfaceClientBufferTest, RenderToR16IOSurface)
1085 {
1086 Initialize(3, false);
1087
1088 { // EGLClientBufferWrapper scope
1089 EGLClientBufferWrapper clientBufferWrapper;
1090 uint16_t data[1] = { 257 };
1091 doClearTest(clientBufferWrapper, GL_R16UI, GL_UNSIGNED_SHORT, data, 2);
1092 } // end of EGLClientBufferWrapper scope
1093
1094 Uninitialize();
1095 }
1096
1097 // Test reading from R8 IOSurfaces
TEST_F(IOSurfaceClientBufferTest,ReadFromR16IOSurface)1098 TEST_F(IOSurfaceClientBufferTest, ReadFromR16IOSurface)
1099 {
1100 Initialize(3, false);
1101
1102 { // EGLClientBufferWrapper scope
1103 EGLClientBufferWrapper clientBufferWrapper;
1104 uint16_t data[1] = { 257 };
1105 doSampleTest(clientBufferWrapper, GL_R16UI, GL_UNSIGNED_SHORT, data, 1);
1106 } // end of EGLClientBufferWrapper scope
1107
1108 Uninitialize();
1109 }
1110
1111 // Test the validation errors for missing attributes for eglCreatePbufferFromClientBuffer with
1112 // IOSurface
TEST_F(IOSurfaceClientBufferTest,NegativeValidationMissingAttributes)1113 TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
1114 {
1115 Initialize(3, false);
1116
1117 {
1118 EGLClientBufferWrapper clientBufferWrapper(10, 10);
1119
1120 // Success case
1121 {
1122 const EGLint attribs[] = {
1123 EGL_WIDTH, 10,
1124 EGL_HEIGHT, 10,
1125 EGL_IOSURFACE_PLANE_ANGLE, 0,
1126 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1127 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1128 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1129 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1130 EGL_NONE, EGL_NONE,
1131 };
1132
1133 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1134 EXPECT_NE(EGL_NO_SURFACE, pbuffer);
1135
1136 EGLBoolean result = eglDestroySurface(getDisplay(), pbuffer);
1137 EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
1138 EXPECT_EQ(EGL_SUCCESS, eglGetError());
1139 }
1140
1141 // Missing EGL_WIDTH
1142 {
1143 const EGLint attribs[] = {
1144 EGL_HEIGHT, 10,
1145 EGL_IOSURFACE_PLANE_ANGLE, 0,
1146 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1147 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1148 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1149 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1150 EGL_NONE, EGL_NONE,
1151 };
1152
1153 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1154 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1155 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
1156 }
1157
1158 // Missing EGL_HEIGHT
1159 {
1160 const EGLint attribs[] = {
1161 EGL_WIDTH, 10,
1162 EGL_IOSURFACE_PLANE_ANGLE, 0,
1163 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1164 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1165 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1166 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1167 EGL_NONE, EGL_NONE,
1168 };
1169
1170 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1171 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1172 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
1173 }
1174
1175 // Missing EGL_IOSURFACE_PLANE_ANGLE
1176 {
1177 const EGLint attribs[] = {
1178 EGL_WIDTH, 10,
1179 EGL_HEIGHT, 10,
1180 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1181 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1182 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1183 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1184 EGL_NONE, EGL_NONE,
1185 };
1186
1187 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1188 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1189 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
1190 }
1191
1192 // Missing EGL_TEXTURE_TARGET - EGL_BAD_MATCH from the base spec of
1193 // eglCreatePbufferFromClientBuffer
1194 {
1195 const EGLint attribs[] = {
1196 EGL_WIDTH, 10,
1197 EGL_HEIGHT, 10,
1198 EGL_IOSURFACE_PLANE_ANGLE, 0,
1199 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1200 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1201 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1202 EGL_NONE, EGL_NONE,
1203 };
1204
1205 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1206 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1207 EXPECT_EQ(EGL_BAD_MATCH, eglGetError());
1208 }
1209
1210 // Missing EGL_TEXTURE_INTERNAL_FORMAT_ANGLE
1211 {
1212 const EGLint attribs[] = {
1213 EGL_WIDTH, 10,
1214 EGL_HEIGHT, 10,
1215 EGL_IOSURFACE_PLANE_ANGLE, 0,
1216 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1217 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1218 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1219 EGL_NONE, EGL_NONE,
1220 };
1221
1222 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1223 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1224 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
1225 }
1226
1227 // Missing EGL_TEXTURE_FORMAT - EGL_BAD_MATCH from the base spec of
1228 // eglCreatePbufferFromClientBuffer
1229 {
1230 const EGLint attribs[] = {
1231 EGL_WIDTH, 10,
1232 EGL_HEIGHT, 10,
1233 EGL_IOSURFACE_PLANE_ANGLE, 0,
1234 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1235 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1236 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1237 EGL_NONE, EGL_NONE,
1238 };
1239
1240 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1241 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1242 EXPECT_EQ(EGL_BAD_MATCH, eglGetError());
1243 }
1244
1245 // Missing EGL_TEXTURE_TYPE_ANGLE
1246 {
1247 const EGLint attribs[] = {
1248 EGL_WIDTH, 10,
1249 EGL_HEIGHT, 10,
1250 EGL_IOSURFACE_PLANE_ANGLE, 0,
1251 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1252 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1253 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1254 EGL_NONE, EGL_NONE,
1255 };
1256
1257 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1258 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1259 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
1260 }
1261 }
1262
1263 Uninitialize();
1264 }
1265
1266 // Test the validation errors for bad parameters for eglCreatePbufferFromClientBuffer with IOSurface
TEST_F(IOSurfaceClientBufferTest,NegativeValidationBadAttributes)1267 TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
1268 {
1269 Initialize(3, false);
1270
1271 {
1272 EGLClientBufferWrapper clientBufferWrapper(10, 10);
1273
1274 // Success case
1275 {
1276 const EGLint attribs[] = {
1277 EGL_WIDTH, 10,
1278 EGL_HEIGHT, 10,
1279 EGL_IOSURFACE_PLANE_ANGLE, 0,
1280 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1281 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1282 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1283 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1284 EGL_NONE, EGL_NONE,
1285 };
1286
1287 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1288 EXPECT_NE(EGL_NO_SURFACE, pbuffer);
1289
1290 EGLBoolean result = eglDestroySurface(getDisplay(), pbuffer);
1291 EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
1292 EXPECT_EQ(EGL_SUCCESS, eglGetError());
1293 }
1294
1295 // EGL_TEXTURE_FORMAT must be EGL_TEXTURE_RGBA
1296 {
1297 const EGLint attribs[] = {
1298 EGL_WIDTH, 10,
1299 EGL_HEIGHT, 10,
1300 EGL_IOSURFACE_PLANE_ANGLE, 0,
1301 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1302 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1303 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
1304 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1305 EGL_NONE, EGL_NONE,
1306 };
1307
1308 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1309 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1310 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1311 }
1312
1313 // EGL_WIDTH must be at least 1
1314 {
1315 const EGLint attribs[] = {
1316 EGL_WIDTH, 0,
1317 EGL_HEIGHT, 10,
1318 EGL_IOSURFACE_PLANE_ANGLE, 0,
1319 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1320 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1321 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1322 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1323 EGL_NONE, EGL_NONE,
1324 };
1325
1326 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1327 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1328 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1329 }
1330
1331 // EGL_HEIGHT must be at least 1
1332 {
1333 const EGLint attribs[] = {
1334 EGL_WIDTH, 10,
1335 EGL_HEIGHT, 0,
1336 EGL_IOSURFACE_PLANE_ANGLE, 0,
1337 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1338 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1339 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1340 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1341 EGL_NONE, EGL_NONE,
1342 };
1343
1344 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1345 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1346 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1347 }
1348
1349 #if defined(__APPLE__)
1350 // EGL_WIDTH must be at most the width of the IOSurface
1351 {
1352 const EGLint attribs[] = {
1353 EGL_WIDTH, 11,
1354 EGL_HEIGHT, 10,
1355 EGL_IOSURFACE_PLANE_ANGLE, 0,
1356 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1357 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1358 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1359 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1360 EGL_NONE, EGL_NONE,
1361 };
1362
1363 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1364 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1365 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1366 }
1367
1368 // EGL_HEIGHT must be at most the height of the IOSurface
1369 {
1370 const EGLint attribs[] = {
1371 EGL_WIDTH, 10,
1372 EGL_HEIGHT, 11,
1373 EGL_IOSURFACE_PLANE_ANGLE, 0,
1374 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1375 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1376 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1377 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1378 EGL_NONE, EGL_NONE,
1379 };
1380
1381 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1382 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1383 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1384 }
1385
1386 // EGL_IOSURFACE_PLANE_ANGLE must less than the number of planes of the IOSurface
1387 {
1388 const EGLint attribs[] = {
1389 EGL_WIDTH, 10,
1390 EGL_HEIGHT, 10,
1391 EGL_IOSURFACE_PLANE_ANGLE, 1,
1392 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1393 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1394 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1395 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1396 EGL_NONE, EGL_NONE,
1397 };
1398
1399 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1400 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1401 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1402 }
1403 #endif
1404
1405 // EGL_TEXTURE_FORMAT must be at EGL_TEXTURE_RECTANGLE_ANGLE
1406 {
1407 const EGLint attribs[] = {
1408 EGL_WIDTH, 10,
1409 EGL_HEIGHT, 10,
1410 EGL_IOSURFACE_PLANE_ANGLE, 0,
1411 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
1412 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1413 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1414 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1415 EGL_NONE, EGL_NONE,
1416 };
1417
1418 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1419 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1420 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1421 }
1422
1423 // EGL_IOSURFACE_PLANE_ANGLE must be at least 0
1424 {
1425 const EGLint attribs[] = {
1426 EGL_WIDTH, 10,
1427 EGL_HEIGHT, 10,
1428 EGL_IOSURFACE_PLANE_ANGLE, -1,
1429 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1430 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
1431 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1432 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1433 EGL_NONE, EGL_NONE,
1434 };
1435
1436 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1437 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1438 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1439 }
1440
1441 // The internal format / type most be listed in the table
1442 {
1443 const EGLint attribs[] = {
1444 EGL_WIDTH, 10,
1445 EGL_HEIGHT, 10,
1446 EGL_IOSURFACE_PLANE_ANGLE, 0,
1447 EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
1448 EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RGBA,
1449 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
1450 EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
1451 EGL_NONE, EGL_NONE,
1452 };
1453
1454 EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
1455 EXPECT_EQ(EGL_NO_SURFACE, pbuffer);
1456 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
1457 }
1458 }
1459
1460 Uninitialize();
1461 }
1462
1463 // Test IOSurface pbuffers cannot be made current
TEST_F(IOSurfaceClientBufferTest,MakeCurrentDisallowed)1464 TEST_F(IOSurfaceClientBufferTest, MakeCurrentDisallowed)
1465 {
1466 Initialize(3, false);
1467
1468 {
1469 EGLClientBufferWrapper clientBufferWrapper(10, 10);
1470
1471 EGLSurface pbuffer = createIOSurfacePbuffer(clientBufferWrapper.getClientBuffer(), 10, 10, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE);
1472
1473 EGLBoolean result = eglMakeCurrent(getDisplay(), pbuffer, pbuffer, getContext());
1474 EXPECT_EQ((EGLBoolean)EGL_FALSE, result);
1475 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError());
1476 }
1477
1478 Uninitialize();
1479 }
1480