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