• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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