• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
3  * ------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Render context implementation that does no rendering.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "tcuNullRenderContext.hpp"
25 #include "tcuTexture.hpp"
26 #include "tcuTextureUtil.hpp"
27 #include "deThreadLocal.hpp"
28 #include "gluRenderConfig.hpp"
29 #include "gluTextureUtil.hpp"
30 #include "glwEnums.hpp"
31 
32 #include <string>
33 #include <vector>
34 
35 namespace tcu
36 {
37 namespace null
38 {
39 
40 using namespace glw;
41 
42 #include "tcuNullRenderContextFuncs.inl"
43 
44 using namespace glu;
45 using std::string;
46 using std::vector;
47 
48 class ObjectManager
49 {
50 public:
ObjectManager(void)51 	ObjectManager (void)
52 		: m_lastObject(0)
53 	{
54 	}
55 
allocate(void)56 	deUint32 allocate (void)
57 	{
58 		deUint32 object = ++m_lastObject;
59 		if (object == 0)
60 			object = ++m_lastObject; // Just ignore overflow.
61 		return object;
62 	}
63 
free(deUint32 object)64 	void free (deUint32 object)
65 	{
66 		DE_UNREF(object);
67 	}
68 
69 private:
70 	deUint32 m_lastObject;
71 };
72 
73 class Context
74 {
75 public:
76 							Context				(ContextType ctxType_);
77 							~Context			(void);
78 
79 private:
80 							Context				(const Context&);
81 	Context&				operator=			(const Context&);
82 
83 	void					addExtension		(const char* name);
84 
85 public:
86 	// GL state exposed to implementation functions.
87 	const ContextType		ctxType;
88 
89 	string					vendor;
90 	string					version;
91 	string					renderer;
92 	string					shadingLanguageVersion;
93 	string					extensions;
94 	vector<string>			extensionList;
95 	vector<deUint32>		compressedTextureList;
96 
97 	GLenum					lastError;
98 
99 	int						pixelPackRowLength;
100 	int						pixelPackSkipRows;
101 	int						pixelPackSkipPixels;
102 	int						pixelPackAlignment;
103 
104 	GLuint					pixelPackBufferBufferBinding;
105 
106 	ObjectManager			shaders;
107 	ObjectManager			programs;
108 	ObjectManager			textures;
109 	ObjectManager			buffers;
110 	ObjectManager			renderbuffers;
111 	ObjectManager			framebuffers;
112 	ObjectManager			samplers;
113 	ObjectManager			vertexArrays;
114 	ObjectManager			queries;
115 	ObjectManager			transformFeedbacks;
116 	ObjectManager			programPipelines;
117 };
118 
Context(ContextType ctxType_)119 Context::Context (ContextType ctxType_)
120 	: ctxType						(ctxType_)
121 	, vendor						("drawElements")
122 	, renderer						("dummy")
123 	, lastError						(GL_NO_ERROR)
124 	, pixelPackRowLength			(0)
125 	, pixelPackSkipRows				(0)
126 	, pixelPackSkipPixels			(0)
127 	, pixelPackAlignment			(0)
128 	, pixelPackBufferBufferBinding	(0)
129 {
130 	using glu::ApiType;
131 
132 	if (ctxType.getAPI() == ApiType::es(2, 0))
133 	{
134 		version					= "OpenGL ES 2.0";
135 		shadingLanguageVersion	= "OpenGL ES GLSL ES 1.0";
136 	}
137 	else if (ctxType.getAPI() == ApiType::es(3, 0))
138 	{
139 		version					= "OpenGL ES 3.0";
140 		shadingLanguageVersion	= "OpenGL ES GLSL ES 3.0";
141 	}
142 	else if (ctxType.getAPI() == ApiType::es(3, 1))
143 	{
144 		version					= "OpenGL ES 3.1";
145 		shadingLanguageVersion	= "OpenGL ES GLSL ES 3.1";
146 		addExtension("GL_OES_texture_stencil8");
147 		addExtension("GL_OES_sample_shading");
148 		addExtension("GL_OES_sample_variables");
149 		addExtension("GL_OES_shader_multisample_interpolation");
150 		addExtension("GL_OES_shader_image_atomic");
151 		addExtension("GL_OES_texture_storage_multisample_2d_array");
152 		addExtension("GL_KHR_blend_equation_advanced");
153 		addExtension("GL_KHR_blend_equation_advanced_coherent");
154 		addExtension("GL_EXT_shader_io_blocks");
155 		addExtension("GL_EXT_geometry_shader");
156 		addExtension("GL_EXT_geometry_point_size");
157 		addExtension("GL_EXT_tessellation_shader");
158 		addExtension("GL_EXT_tessellation_point_size");
159 		addExtension("GL_EXT_gpu_shader5");
160 		addExtension("GL_EXT_shader_implicit_conversions");
161 		addExtension("GL_EXT_texture_buffer");
162 		addExtension("GL_EXT_texture_cube_map_array");
163 		addExtension("GL_EXT_draw_buffers_indexed");
164 		addExtension("GL_EXT_texture_sRGB_decode");
165 		addExtension("GL_EXT_texture_border_clamp");
166 		addExtension("GL_KHR_debug");
167 		addExtension("GL_EXT_primitive_bounding_box");
168 		addExtension("GL_ANDROID_extension_pack_es31a");
169 		addExtension("GL_EXT_copy_image");
170 	}
171 	else if (ctxType.getAPI() == ApiType::es(3, 2))
172 	{
173 		version					= "OpenGL ES 3.2";
174 		shadingLanguageVersion	= "OpenGL ES GLSL ES 3.2";
175 	}
176 	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 3)
177 	{
178 		version					= "3.3.0";
179 		shadingLanguageVersion	= "3.30";
180 	}
181 	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 4)
182 	{
183 		version					= "4.4.0";
184 		shadingLanguageVersion	= "4.40";
185 	}
186 	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 5)
187 	{
188 		version					= "4.5.0";
189 		shadingLanguageVersion	= "4.50";
190 	}
191 	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 6)
192 	{
193 		version					= "4.6.0";
194 		shadingLanguageVersion	= "4.60";
195 	}
196 	else if (glu::isContextTypeGLCompatibility(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 2)
197 	{
198 		version					= "4.2.0";
199 		shadingLanguageVersion	= "4.20";
200 	}
201 	else
202 		throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__);
203 
204 	if (isContextTypeES(ctxType))
205 	{
206 		addExtension("GL_EXT_color_buffer_float");
207 		addExtension("GL_EXT_color_buffer_half_float");
208 	}
209 
210 	// support compressed formats
211 	{
212 		static deUint32 compressedFormats[] =
213 		{
214 			GL_ETC1_RGB8_OES,
215 			GL_COMPRESSED_R11_EAC,
216 			GL_COMPRESSED_SIGNED_R11_EAC,
217 			GL_COMPRESSED_RG11_EAC,
218 			GL_COMPRESSED_SIGNED_RG11_EAC,
219 			GL_COMPRESSED_RGB8_ETC2,
220 			GL_COMPRESSED_SRGB8_ETC2,
221 			GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
222 			GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
223 			GL_COMPRESSED_RGBA8_ETC2_EAC,
224 			GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
225 			GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
226 			GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
227 			GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
228 			GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
229 			GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
230 			GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
231 			GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
232 			GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
233 			GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
234 			GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
235 			GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
236 			GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
237 			GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
238 			GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
239 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
240 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
241 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
242 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
243 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
244 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
245 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
246 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
247 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
248 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
249 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
250 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
251 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
252 			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
253 		};
254 
255 		addExtension("GL_KHR_texture_compression_astc_hdr");
256 		addExtension("GL_KHR_texture_compression_astc_ldr");
257 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compressedFormats); ++ndx)
258 			compressedTextureList.push_back(compressedFormats[ndx]);
259 	}
260 }
261 
~Context(void)262 Context::~Context (void)
263 {
264 }
265 
addExtension(const char * name)266 void Context::addExtension (const char* name)
267 {
268 	if (!extensions.empty())
269 		extensions += " ";
270 	extensions += name;
271 
272 	extensionList.push_back(name);
273 }
274 
275 static de::ThreadLocal s_currentCtx;
276 
setCurrentContext(Context * context)277 void setCurrentContext (Context* context)
278 {
279 	s_currentCtx.set((void*)context);
280 }
281 
getCurrentContext(void)282 Context* getCurrentContext (void)
283 {
284 	return (Context*)s_currentCtx.get();
285 }
286 
glGetError(void)287 GLW_APICALL GLenum GLW_APIENTRY glGetError (void)
288 {
289 	Context* const	ctx		= getCurrentContext();
290 	const GLenum	lastErr	= ctx->lastError;
291 
292 	ctx->lastError = GL_NO_ERROR;
293 
294 	return lastErr;
295 }
296 
glGetIntegerv(GLenum pname,GLint * params)297 GLW_APICALL void GLW_APIENTRY glGetIntegerv (GLenum pname, GLint* params)
298 {
299 	Context* const ctx = getCurrentContext();
300 
301 	switch (pname)
302 	{
303 		case GL_NUM_EXTENSIONS:
304 			*params = (int)ctx->extensionList.size();
305 			break;
306 
307 		case GL_MAX_VERTEX_ATTRIBS:
308 			*params = 32;
309 			break;
310 
311 		case GL_MAX_DRAW_BUFFERS:
312 		case GL_MAX_COLOR_ATTACHMENTS:
313 			*params = 8;
314 			break;
315 
316 		case GL_MAX_TEXTURE_IMAGE_UNITS:
317 		case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
318 		case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
319 		case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
320 		case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS:
321 		case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS:
322 			*params = 32;
323 			break;
324 
325 		case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
326 		case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
327 		case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS:
328 		case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS:
329 		case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS:
330 		case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
331 			*params = 8;
332 			break;
333 
334 		case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
335 		case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
336 		case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS:
337 		case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS:
338 		case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS:
339 		case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
340 			*params = 8;
341 			break;
342 
343 		case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
344 			*params = 1u << 25;
345 			break;
346 
347 		case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
348 			*params = 256;
349 			break;
350 
351 		case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
352 			*params = 2048;
353 			break;
354 
355 		case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
356 			*params = 4;
357 			break;
358 
359 		case GL_MAX_COLOR_TEXTURE_SAMPLES:
360 			*params = 8;
361 			break;
362 
363 		case GL_MAX_TEXTURE_SIZE:
364 		case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
365 		case GL_MAX_3D_TEXTURE_SIZE:
366 		case GL_MAX_RENDERBUFFER_SIZE:
367 		case GL_MAX_TEXTURE_BUFFER_SIZE:
368 			*params = 2048;
369 			break;
370 
371 		case GL_MAX_ARRAY_TEXTURE_LAYERS:
372 			*params = 128;
373 			break;
374 
375 		case GL_NUM_SHADER_BINARY_FORMATS:
376 			*params = 0;
377 			break;
378 
379 		case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
380 			*params = (int)ctx->compressedTextureList.size();
381 			break;
382 
383 		case GL_COMPRESSED_TEXTURE_FORMATS:
384 			deMemcpy(params, &ctx->compressedTextureList[0], ctx->compressedTextureList.size()*sizeof(deUint32));
385 			break;
386 
387 		case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
388 			*params = 16;
389 			break;
390 
391 		case GL_MAX_UNIFORM_BUFFER_BINDINGS:
392 			*params = 32;
393 			break;
394 
395 		case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
396 			*params = 16;
397 			break;
398 
399 		case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
400 			*params = GL_RGBA;
401 			break;
402 
403 		case GL_IMPLEMENTATION_COLOR_READ_TYPE:
404 			*params = GL_UNSIGNED_BYTE;
405 			break;
406 
407 		case GL_SAMPLE_BUFFERS:
408 			*params = 0;
409 			break;
410 
411 		default:
412 			break;
413 	}
414 }
415 
glGetBooleanv(GLenum pname,GLboolean * params)416 GLW_APICALL void GLW_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params)
417 {
418 	switch (pname)
419 	{
420 		case GL_SHADER_COMPILER:
421 			*params = GL_TRUE;
422 			break;
423 
424 		default:
425 			break;
426 	}
427 }
428 
glGetFloatv(GLenum pname,GLfloat * params)429 GLW_APICALL void GLW_APIENTRY glGetFloatv (GLenum pname, GLfloat* params)
430 {
431 	switch (pname)
432 	{
433 		case GL_ALIASED_LINE_WIDTH_RANGE:
434 		case GL_ALIASED_POINT_SIZE_RANGE:
435 			params[0] = 0.0f;
436 			params[1] = 64.0f;
437 			break;
438 
439 		default:
440 			break;
441 	}
442 }
443 
glGetInternalformativ(GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)444 GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
445 {
446 	static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 };
447 
448 	DE_UNREF(internalformat);
449 	DE_UNREF(target);
450 
451 	switch (pname)
452 	{
453 		case GL_NUM_SAMPLE_COUNTS:
454 			if (bufSize >= 1)
455 				*params = DE_LENGTH_OF_ARRAY(s_sampleCounts);
456 			break;
457 
458 		case GL_SAMPLES:
459 			deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts)));
460 			break;
461 
462 		default:
463 			break;
464 	}
465 }
466 
glGetString(GLenum name)467 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name)
468 {
469 	Context* const ctx = getCurrentContext();
470 
471 	switch (name)
472 	{
473 		case GL_VENDOR:						return (const glw::GLubyte*)ctx->vendor.c_str();
474 		case GL_VERSION:					return (const glw::GLubyte*)ctx->version.c_str();
475 		case GL_RENDERER:					return (const glw::GLubyte*)ctx->renderer.c_str();
476 		case GL_SHADING_LANGUAGE_VERSION:	return (const glw::GLubyte*)ctx->shadingLanguageVersion.c_str();
477 		case GL_EXTENSIONS:					return (const glw::GLubyte*)ctx->extensions.c_str();
478 		default:
479 			ctx->lastError = GL_INVALID_ENUM;
480 			return DE_NULL;
481 	}
482 }
483 
glGetStringi(GLenum name,GLuint index)484 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetStringi (GLenum name, GLuint index)
485 {
486 	Context* const ctx = getCurrentContext();
487 
488 	if (name == GL_EXTENSIONS)
489 	{
490 		if ((size_t)index < ctx->extensionList.size())
491 			return (const glw::GLubyte*)ctx->extensionList[index].c_str();
492 		else
493 		{
494 			ctx->lastError = GL_INVALID_VALUE;
495 			return DE_NULL;
496 		}
497 	}
498 	else
499 	{
500 		ctx->lastError = GL_INVALID_ENUM;
501 		return DE_NULL;
502 	}
503 }
504 
glCreateProgram()505 GLW_APICALL GLuint GLW_APIENTRY glCreateProgram ()
506 {
507 	Context* const ctx = getCurrentContext();
508 	return (GLuint)ctx->programs.allocate();
509 }
510 
glCreateShader(GLenum type)511 GLW_APICALL GLuint GLW_APIENTRY glCreateShader (GLenum type)
512 {
513 	Context* const ctx = getCurrentContext();
514 	DE_UNREF(type);
515 	return (GLuint)ctx->shaders.allocate();
516 }
517 
glGetShaderiv(GLuint shader,GLenum pname,GLint * params)518 GLW_APICALL void GLW_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params)
519 {
520 	DE_UNREF(shader);
521 
522 	if (pname == GL_COMPILE_STATUS)
523 		*params = GL_TRUE;
524 }
525 
glGetProgramiv(GLuint program,GLenum pname,GLint * params)526 GLW_APICALL void GLW_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params)
527 {
528 	DE_UNREF(program);
529 
530 	if (pname == GL_LINK_STATUS)
531 		*params = GL_TRUE;
532 }
533 
glGenTextures(GLsizei n,GLuint * textures)534 GLW_APICALL void GLW_APIENTRY glGenTextures (GLsizei n, GLuint* textures)
535 {
536 	Context* const ctx = getCurrentContext();
537 
538 	if (textures)
539 	{
540 		for (int ndx = 0; ndx < n; ndx++)
541 			textures[ndx] = ctx->textures.allocate();
542 	}
543 }
544 
glGenQueries(GLsizei n,GLuint * ids)545 GLW_APICALL void GLW_APIENTRY glGenQueries (GLsizei n, GLuint* ids)
546 {
547 	Context* const ctx = getCurrentContext();
548 
549 	if (ids)
550 	{
551 		for (int ndx = 0; ndx < n; ndx++)
552 			ids[ndx] = ctx->queries.allocate();
553 	}
554 }
555 
glGenBuffers(GLsizei n,GLuint * buffers)556 GLW_APICALL void GLW_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers)
557 {
558 	Context* const ctx = getCurrentContext();
559 
560 	if (buffers)
561 	{
562 		for (int ndx = 0; ndx < n; ndx++)
563 			buffers[ndx] = ctx->buffers.allocate();
564 	}
565 }
566 
glGenRenderbuffers(GLsizei n,GLuint * renderbuffers)567 GLW_APICALL void GLW_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
568 {
569 	Context* const ctx = getCurrentContext();
570 
571 	if (renderbuffers)
572 	{
573 		for (int ndx = 0; ndx < n; ndx++)
574 			renderbuffers[ndx] = ctx->renderbuffers.allocate();
575 	}
576 }
577 
glGenFramebuffers(GLsizei n,GLuint * framebuffers)578 GLW_APICALL void GLW_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers)
579 {
580 	Context* const ctx = getCurrentContext();
581 
582 	if (framebuffers)
583 	{
584 		for (int ndx = 0; ndx < n; ndx++)
585 			framebuffers[ndx] = ctx->framebuffers.allocate();
586 	}
587 }
588 
glGenVertexArrays(GLsizei n,GLuint * arrays)589 GLW_APICALL void GLW_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays)
590 {
591 	Context* const ctx = getCurrentContext();
592 
593 	if (arrays)
594 	{
595 		for (int ndx = 0; ndx < n; ndx++)
596 			arrays[ndx] = ctx->vertexArrays.allocate();
597 	}
598 }
599 
glGenSamplers(GLsizei count,GLuint * samplers)600 GLW_APICALL void GLW_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers)
601 {
602 	Context* const ctx = getCurrentContext();
603 
604 	if (samplers)
605 	{
606 		for (int ndx = 0; ndx < count; ndx++)
607 			samplers[ndx] = ctx->samplers.allocate();
608 	}
609 }
610 
glGenTransformFeedbacks(GLsizei n,GLuint * ids)611 GLW_APICALL void GLW_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids)
612 {
613 	Context* const ctx = getCurrentContext();
614 
615 	if (ids)
616 	{
617 		for (int ndx = 0; ndx < n; ndx++)
618 			ids[ndx] = ctx->transformFeedbacks.allocate();
619 	}
620 }
621 
glGenProgramPipelines(GLsizei n,GLuint * pipelines)622 GLW_APICALL void GLW_APIENTRY glGenProgramPipelines (GLsizei n, GLuint* pipelines)
623 {
624 	Context* const ctx = getCurrentContext();
625 
626 	if (pipelines)
627 	{
628 		for (int ndx = 0; ndx < n; ndx++)
629 			pipelines[ndx] = ctx->programPipelines.allocate();
630 	}
631 }
632 
glMapBufferRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)633 GLW_APICALL GLvoid* GLW_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
634 {
635 	Context* const ctx = getCurrentContext();
636 
637 	DE_UNREF(target);
638 	DE_UNREF(offset);
639 	DE_UNREF(length);
640 	DE_UNREF(access);
641 
642 	if (ctx->lastError == GL_NO_ERROR)
643 		ctx->lastError = GL_INVALID_OPERATION;
644 
645 	return (GLvoid*)0;
646 }
647 
glCheckFramebufferStatus(GLenum target)648 GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target)
649 {
650 	DE_UNREF(target);
651 	return GL_FRAMEBUFFER_COMPLETE;
652 }
653 
glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)654 GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
655 {
656 	DE_UNREF(x);
657 	DE_UNREF(y);
658 
659 	Context* const					ctx					= getCurrentContext();
660 	const tcu::Vec4					clearColor			(0.0f, 0.0f, 0.0f, 1.0f); // black
661 	const tcu::TextureFormat		transferFormat		= glu::mapGLTransferFormat(format, type);
662 
663 	// invalid formats
664 	if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST)
665 	{
666 		if (ctx->lastError == GL_NO_ERROR)
667 			ctx->lastError = GL_INVALID_ENUM;
668 		return;
669 	}
670 
671 	// unsupported formats
672 	if (!(format == GL_RGBA			&& type == GL_UNSIGNED_BYTE)	&&
673 		!(format == GL_RGBA_INTEGER	&& type == GL_INT)				&&
674 		!(format == GL_RGBA_INTEGER	&& type == GL_UNSIGNED_INT)		&&
675 		!(format == GL_RGBA			&& type == GL_FLOAT))
676 	{
677 		if (ctx->lastError == GL_NO_ERROR)
678 			ctx->lastError = GL_INVALID_ENUM;
679 		return;
680 	}
681 
682 	// invalid arguments
683 	if (width < 0 || height < 0)
684 	{
685 		if (ctx->lastError == GL_NO_ERROR)
686 			ctx->lastError = GL_INVALID_OPERATION;
687 		return;
688 	}
689 
690 	// read to buffer
691 	if (ctx->pixelPackBufferBufferBinding)
692 		return;
693 
694 	// read to use pointer
695 	{
696 		const int						targetRowLength		= (ctx->pixelPackRowLength != 0) ? (ctx->pixelPackRowLength) : (width);
697 		const int						targetSkipRows		= ctx->pixelPackSkipRows;
698 		const int						targetSkipPixels	= ctx->pixelPackSkipPixels;
699 		const int						infiniteHeight		= targetSkipRows + height; // as much as needed
700 		const int						targetRowPitch		= (ctx->pixelPackAlignment == 0) ? (targetRowLength * transferFormat.getPixelSize()) : (deAlign32(targetRowLength * transferFormat.getPixelSize(), ctx->pixelPackAlignment));
701 
702 		// Create access to the whole copy target
703 		const tcu::PixelBufferAccess	targetAccess		(transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels);
704 
705 		// Select (skip_pixels, skip_rows, width, height) subregion from it. Clip to horizontal boundaries
706 		const tcu::PixelBufferAccess	targetRectAccess	= tcu::getSubregion(targetAccess,
707 																				de::clamp(targetSkipPixels, 0, targetAccess.getWidth()-1),
708 																				targetSkipRows,
709 																				de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)),
710 																				height);
711 
712 		tcu::clear(targetRectAccess, clearColor);
713 	}
714 }
715 
glBindBuffer(GLenum target,GLuint buffer)716 GLW_APICALL void GLW_APIENTRY glBindBuffer (GLenum target, GLuint buffer)
717 {
718 	Context* const ctx = getCurrentContext();
719 
720 	if (target == GL_PIXEL_PACK_BUFFER)
721 		ctx->pixelPackBufferBufferBinding = buffer;
722 }
723 
glDeleteBuffers(GLsizei n,const GLuint * buffers)724 GLW_APICALL void GLW_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers)
725 {
726 	Context* const ctx = getCurrentContext();
727 
728 	for (GLsizei ndx = 0; ndx < n; ++ndx)
729 		if (buffers[ndx] && buffers[ndx] == ctx->pixelPackBufferBufferBinding)
730 			ctx->pixelPackBufferBufferBinding = 0;
731 }
732 
glGetAttribLocation(GLuint program,const GLchar * name)733 GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
734 {
735 	DE_UNREF(program);
736 	return (GLint)(deStringHash(name) & 0x7FFFFFFF);
737 }
738 
initFunctions(glw::Functions * gl)739 void initFunctions (glw::Functions* gl)
740 {
741 #	include "tcuNullRenderContextInitFuncs.inl"
742 }
743 
toRenderTarget(const RenderConfig & renderCfg)744 static tcu::RenderTarget toRenderTarget (const RenderConfig& renderCfg)
745 {
746 	const int		width			= getValueOrDefault(renderCfg, &RenderConfig::width,		256);
747 	const int		height			= getValueOrDefault(renderCfg, &RenderConfig::height,		256);
748 	const int		redBits			= getValueOrDefault(renderCfg, &RenderConfig::redBits,		8);
749 	const int		greenBits		= getValueOrDefault(renderCfg, &RenderConfig::greenBits,	8);
750 	const int		blueBits		= getValueOrDefault(renderCfg, &RenderConfig::blueBits,		8);
751 	const int		alphaBits		= getValueOrDefault(renderCfg, &RenderConfig::alphaBits,	8);
752 	const int		depthBits		= getValueOrDefault(renderCfg, &RenderConfig::depthBits,	24);
753 	const int		stencilBits		= getValueOrDefault(renderCfg, &RenderConfig::stencilBits,	8);
754 	const int		numSamples		= getValueOrDefault(renderCfg, &RenderConfig::numSamples,	0);
755 
756 	return tcu::RenderTarget(width, height, tcu::PixelFormat(redBits, greenBits, blueBits, alphaBits), depthBits, stencilBits, numSamples);
757 }
758 
RenderContext(const RenderConfig & renderCfg)759 RenderContext::RenderContext (const RenderConfig& renderCfg)
760 	: m_ctxType			(renderCfg.type)
761 	, m_renderTarget	(toRenderTarget(renderCfg))
762 	, m_context			(DE_NULL)
763 {
764 	m_context = new Context(m_ctxType);
765 
766 	initFunctions(&m_functions);
767 	setCurrentContext(m_context);
768 }
769 
~RenderContext(void)770 RenderContext::~RenderContext (void)
771 {
772 	setCurrentContext(DE_NULL);
773 	delete m_context;
774 }
775 
postIterate(void)776 void RenderContext::postIterate (void)
777 {
778 }
779 
makeCurrent(void)780 void RenderContext::makeCurrent (void)
781 {
782 }
783 
784 } // null
785 } // tcu
786