Add CTS_ARB_gl_spirv test implementation
[platform/upstream/VK-GL-CTS.git] / framework / platform / null / tcuNullRenderContext.cpp
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:
51         ObjectManager (void)
52                 : m_lastObject(0)
53         {
54         }
55
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
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
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
197                 throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__);
198
199         if (isContextTypeES(ctxType))
200         {
201                 addExtension("GL_EXT_color_buffer_float");
202                 addExtension("GL_EXT_color_buffer_half_float");
203         }
204
205         // support compressed formats
206         {
207                 static deUint32 compressedFormats[] =
208                 {
209                         GL_ETC1_RGB8_OES,
210                         GL_COMPRESSED_R11_EAC,
211                         GL_COMPRESSED_SIGNED_R11_EAC,
212                         GL_COMPRESSED_RG11_EAC,
213                         GL_COMPRESSED_SIGNED_RG11_EAC,
214                         GL_COMPRESSED_RGB8_ETC2,
215                         GL_COMPRESSED_SRGB8_ETC2,
216                         GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
217                         GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
218                         GL_COMPRESSED_RGBA8_ETC2_EAC,
219                         GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
220                         GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
221                         GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
222                         GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
223                         GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
224                         GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
225                         GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
226                         GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
227                         GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
228                         GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
229                         GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
230                         GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
231                         GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
232                         GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
233                         GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
234                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
235                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
236                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
237                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
238                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
239                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
240                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
241                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
242                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
243                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
244                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
245                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
246                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
247                         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
248                 };
249
250                 addExtension("GL_KHR_texture_compression_astc_hdr");
251                 addExtension("GL_KHR_texture_compression_astc_ldr");
252                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compressedFormats); ++ndx)
253                         compressedTextureList.push_back(compressedFormats[ndx]);
254         }
255 }
256
257 Context::~Context (void)
258 {
259 }
260
261 void Context::addExtension (const char* name)
262 {
263         if (!extensions.empty())
264                 extensions += " ";
265         extensions += name;
266
267         extensionList.push_back(name);
268 }
269
270 static de::ThreadLocal s_currentCtx;
271
272 void setCurrentContext (Context* context)
273 {
274         s_currentCtx.set((void*)context);
275 }
276
277 Context* getCurrentContext (void)
278 {
279         return (Context*)s_currentCtx.get();
280 }
281
282 GLW_APICALL GLenum GLW_APIENTRY glGetError (void)
283 {
284         Context* const  ctx             = getCurrentContext();
285         const GLenum    lastErr = ctx->lastError;
286
287         ctx->lastError = GL_NO_ERROR;
288
289         return lastErr;
290 }
291
292 GLW_APICALL void GLW_APIENTRY glGetIntegerv (GLenum pname, GLint* params)
293 {
294         Context* const ctx = getCurrentContext();
295
296         switch (pname)
297         {
298                 case GL_NUM_EXTENSIONS:
299                         *params = (int)ctx->extensionList.size();
300                         break;
301
302                 case GL_MAX_VERTEX_ATTRIBS:
303                         *params = 32;
304                         break;
305
306                 case GL_MAX_DRAW_BUFFERS:
307                 case GL_MAX_COLOR_ATTACHMENTS:
308                         *params = 8;
309                         break;
310
311                 case GL_MAX_TEXTURE_IMAGE_UNITS:
312                 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
313                 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
314                 case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
315                 case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS:
316                 case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS:
317                         *params = 32;
318                         break;
319
320                 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
321                 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
322                 case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS:
323                 case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS:
324                 case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS:
325                 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
326                         *params = 8;
327                         break;
328
329                 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
330                 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
331                 case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS:
332                 case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS:
333                 case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS:
334                 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
335                         *params = 8;
336                         break;
337
338                 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
339                         *params = 1u << 25;
340                         break;
341
342                 case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
343                         *params = 256;
344                         break;
345
346                 case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
347                         *params = 2048;
348                         break;
349
350                 case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
351                         *params = 4;
352                         break;
353
354                 case GL_MAX_COLOR_TEXTURE_SAMPLES:
355                         *params = 8;
356                         break;
357
358                 case GL_MAX_TEXTURE_SIZE:
359                 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
360                 case GL_MAX_3D_TEXTURE_SIZE:
361                 case GL_MAX_RENDERBUFFER_SIZE:
362                 case GL_MAX_TEXTURE_BUFFER_SIZE:
363                         *params = 2048;
364                         break;
365
366                 case GL_MAX_ARRAY_TEXTURE_LAYERS:
367                         *params = 128;
368                         break;
369
370                 case GL_NUM_SHADER_BINARY_FORMATS:
371                         *params = 0;
372                         break;
373
374                 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
375                         *params = (int)ctx->compressedTextureList.size();
376                         break;
377
378                 case GL_COMPRESSED_TEXTURE_FORMATS:
379                         deMemcpy(params, &ctx->compressedTextureList[0], ctx->compressedTextureList.size()*sizeof(deUint32));
380                         break;
381
382                 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
383                         *params = 16;
384                         break;
385
386                 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
387                         *params = 32;
388                         break;
389
390                 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
391                         *params = 16;
392                         break;
393
394                 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
395                         *params = GL_RGBA;
396                         break;
397
398                 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
399                         *params = GL_UNSIGNED_BYTE;
400                         break;
401
402                 case GL_SAMPLE_BUFFERS:
403                         *params = 0;
404                         break;
405
406                 default:
407                         break;
408         }
409 }
410
411 GLW_APICALL void GLW_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params)
412 {
413         switch (pname)
414         {
415                 case GL_SHADER_COMPILER:
416                         *params = GL_TRUE;
417                         break;
418
419                 default:
420                         break;
421         }
422 }
423
424 GLW_APICALL void GLW_APIENTRY glGetFloatv (GLenum pname, GLfloat* params)
425 {
426         switch (pname)
427         {
428                 case GL_ALIASED_LINE_WIDTH_RANGE:
429                 case GL_ALIASED_POINT_SIZE_RANGE:
430                         params[0] = 0.0f;
431                         params[1] = 64.0f;
432                         break;
433
434                 default:
435                         break;
436         }
437 }
438
439 GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
440 {
441         static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 };
442
443         DE_UNREF(internalformat);
444         DE_UNREF(target);
445
446         switch (pname)
447         {
448                 case GL_NUM_SAMPLE_COUNTS:
449                         if (bufSize >= 1)
450                                 *params = DE_LENGTH_OF_ARRAY(s_sampleCounts);
451                         break;
452
453                 case GL_SAMPLES:
454                         deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts)));
455                         break;
456
457                 default:
458                         break;
459         }
460 }
461
462 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name)
463 {
464         Context* const ctx = getCurrentContext();
465
466         switch (name)
467         {
468                 case GL_VENDOR:                                         return (const glw::GLubyte*)ctx->vendor.c_str();
469                 case GL_VERSION:                                        return (const glw::GLubyte*)ctx->version.c_str();
470                 case GL_RENDERER:                                       return (const glw::GLubyte*)ctx->renderer.c_str();
471                 case GL_SHADING_LANGUAGE_VERSION:       return (const glw::GLubyte*)ctx->shadingLanguageVersion.c_str();
472                 case GL_EXTENSIONS:                                     return (const glw::GLubyte*)ctx->extensions.c_str();
473                 default:
474                         ctx->lastError = GL_INVALID_ENUM;
475                         return DE_NULL;
476         }
477 }
478
479 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetStringi (GLenum name, GLuint index)
480 {
481         Context* const ctx = getCurrentContext();
482
483         if (name == GL_EXTENSIONS)
484         {
485                 if ((size_t)index < ctx->extensionList.size())
486                         return (const glw::GLubyte*)ctx->extensionList[index].c_str();
487                 else
488                 {
489                         ctx->lastError = GL_INVALID_VALUE;
490                         return DE_NULL;
491                 }
492         }
493         else
494         {
495                 ctx->lastError = GL_INVALID_ENUM;
496                 return DE_NULL;
497         }
498 }
499
500 GLW_APICALL GLuint GLW_APIENTRY glCreateProgram ()
501 {
502         Context* const ctx = getCurrentContext();
503         return (GLuint)ctx->programs.allocate();
504 }
505
506 GLW_APICALL GLuint GLW_APIENTRY glCreateShader (GLenum type)
507 {
508         Context* const ctx = getCurrentContext();
509         DE_UNREF(type);
510         return (GLuint)ctx->shaders.allocate();
511 }
512
513 GLW_APICALL void GLW_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params)
514 {
515         DE_UNREF(shader);
516
517         if (pname == GL_COMPILE_STATUS)
518                 *params = GL_TRUE;
519 }
520
521 GLW_APICALL void GLW_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params)
522 {
523         DE_UNREF(program);
524
525         if (pname == GL_LINK_STATUS)
526                 *params = GL_TRUE;
527 }
528
529 GLW_APICALL void GLW_APIENTRY glGenTextures (GLsizei n, GLuint* textures)
530 {
531         Context* const ctx = getCurrentContext();
532
533         if (textures)
534         {
535                 for (int ndx = 0; ndx < n; ndx++)
536                         textures[ndx] = ctx->textures.allocate();
537         }
538 }
539
540 GLW_APICALL void GLW_APIENTRY glGenQueries (GLsizei n, GLuint* ids)
541 {
542         Context* const ctx = getCurrentContext();
543
544         if (ids)
545         {
546                 for (int ndx = 0; ndx < n; ndx++)
547                         ids[ndx] = ctx->queries.allocate();
548         }
549 }
550
551 GLW_APICALL void GLW_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers)
552 {
553         Context* const ctx = getCurrentContext();
554
555         if (buffers)
556         {
557                 for (int ndx = 0; ndx < n; ndx++)
558                         buffers[ndx] = ctx->buffers.allocate();
559         }
560 }
561
562 GLW_APICALL void GLW_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
563 {
564         Context* const ctx = getCurrentContext();
565
566         if (renderbuffers)
567         {
568                 for (int ndx = 0; ndx < n; ndx++)
569                         renderbuffers[ndx] = ctx->renderbuffers.allocate();
570         }
571 }
572
573 GLW_APICALL void GLW_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers)
574 {
575         Context* const ctx = getCurrentContext();
576
577         if (framebuffers)
578         {
579                 for (int ndx = 0; ndx < n; ndx++)
580                         framebuffers[ndx] = ctx->framebuffers.allocate();
581         }
582 }
583
584 GLW_APICALL void GLW_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays)
585 {
586         Context* const ctx = getCurrentContext();
587
588         if (arrays)
589         {
590                 for (int ndx = 0; ndx < n; ndx++)
591                         arrays[ndx] = ctx->vertexArrays.allocate();
592         }
593 }
594
595 GLW_APICALL void GLW_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers)
596 {
597         Context* const ctx = getCurrentContext();
598
599         if (samplers)
600         {
601                 for (int ndx = 0; ndx < count; ndx++)
602                         samplers[ndx] = ctx->samplers.allocate();
603         }
604 }
605
606 GLW_APICALL void GLW_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids)
607 {
608         Context* const ctx = getCurrentContext();
609
610         if (ids)
611         {
612                 for (int ndx = 0; ndx < n; ndx++)
613                         ids[ndx] = ctx->transformFeedbacks.allocate();
614         }
615 }
616
617 GLW_APICALL void GLW_APIENTRY glGenProgramPipelines (GLsizei n, GLuint* pipelines)
618 {
619         Context* const ctx = getCurrentContext();
620
621         if (pipelines)
622         {
623                 for (int ndx = 0; ndx < n; ndx++)
624                         pipelines[ndx] = ctx->programPipelines.allocate();
625         }
626 }
627
628 GLW_APICALL GLvoid* GLW_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
629 {
630         Context* const ctx = getCurrentContext();
631
632         DE_UNREF(target);
633         DE_UNREF(offset);
634         DE_UNREF(length);
635         DE_UNREF(access);
636
637         if (ctx->lastError == GL_NO_ERROR)
638                 ctx->lastError = GL_INVALID_OPERATION;
639
640         return (GLvoid*)0;
641 }
642
643 GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target)
644 {
645         DE_UNREF(target);
646         return GL_FRAMEBUFFER_COMPLETE;
647 }
648
649 GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
650 {
651         DE_UNREF(x);
652         DE_UNREF(y);
653
654         Context* const                                  ctx                                     = getCurrentContext();
655         const tcu::Vec4                                 clearColor                      (0.0f, 0.0f, 0.0f, 1.0f); // black
656         const tcu::TextureFormat                transferFormat          = glu::mapGLTransferFormat(format, type);
657
658         // invalid formats
659         if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST)
660         {
661                 if (ctx->lastError == GL_NO_ERROR)
662                         ctx->lastError = GL_INVALID_ENUM;
663                 return;
664         }
665
666         // unsupported formats
667         if (!(format == GL_RGBA                 && type == GL_UNSIGNED_BYTE)    &&
668                 !(format == GL_RGBA_INTEGER     && type == GL_INT)                              &&
669                 !(format == GL_RGBA_INTEGER     && type == GL_UNSIGNED_INT)             &&
670                 !(format == GL_RGBA                     && type == GL_FLOAT))
671         {
672                 if (ctx->lastError == GL_NO_ERROR)
673                         ctx->lastError = GL_INVALID_ENUM;
674                 return;
675         }
676
677         // invalid arguments
678         if (width < 0 || height < 0)
679         {
680                 if (ctx->lastError == GL_NO_ERROR)
681                         ctx->lastError = GL_INVALID_OPERATION;
682                 return;
683         }
684
685         // read to buffer
686         if (ctx->pixelPackBufferBufferBinding)
687                 return;
688
689         // read to use pointer
690         {
691                 const int                                               targetRowLength         = (ctx->pixelPackRowLength != 0) ? (ctx->pixelPackRowLength) : (width);
692                 const int                                               targetSkipRows          = ctx->pixelPackSkipRows;
693                 const int                                               targetSkipPixels        = ctx->pixelPackSkipPixels;
694                 const int                                               infiniteHeight          = targetSkipRows + height; // as much as needed
695                 const int                                               targetRowPitch          = (ctx->pixelPackAlignment == 0) ? (targetRowLength * transferFormat.getPixelSize()) : (deAlign32(targetRowLength * transferFormat.getPixelSize(), ctx->pixelPackAlignment));
696
697                 // Create access to the whole copy target
698                 const tcu::PixelBufferAccess    targetAccess            (transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels);
699
700                 // Select (skip_pixels, skip_rows, width, height) subregion from it. Clip to horizontal boundaries
701                 const tcu::PixelBufferAccess    targetRectAccess        = tcu::getSubregion(targetAccess,
702                                                                                                                                                                 de::clamp(targetSkipPixels, 0, targetAccess.getWidth()-1),
703                                                                                                                                                                 targetSkipRows,
704                                                                                                                                                                 de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)),
705                                                                                                                                                                 height);
706
707                 tcu::clear(targetRectAccess, clearColor);
708         }
709 }
710
711 GLW_APICALL void GLW_APIENTRY glBindBuffer (GLenum target, GLuint buffer)
712 {
713         Context* const ctx = getCurrentContext();
714
715         if (target == GL_PIXEL_PACK_BUFFER)
716                 ctx->pixelPackBufferBufferBinding = buffer;
717 }
718
719 GLW_APICALL void GLW_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers)
720 {
721         Context* const ctx = getCurrentContext();
722
723         for (GLsizei ndx = 0; ndx < n; ++ndx)
724                 if (buffers[ndx] && buffers[ndx] == ctx->pixelPackBufferBufferBinding)
725                         ctx->pixelPackBufferBufferBinding = 0;
726 }
727
728 GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
729 {
730         DE_UNREF(program);
731         return (GLint)(deStringHash(name) & 0x7FFFFFFF);
732 }
733
734 void initFunctions (glw::Functions* gl)
735 {
736 #       include "tcuNullRenderContextInitFuncs.inl"
737 }
738
739 static tcu::RenderTarget toRenderTarget (const RenderConfig& renderCfg)
740 {
741         const int               width                   = getValueOrDefault(renderCfg, &RenderConfig::width,            256);
742         const int               height                  = getValueOrDefault(renderCfg, &RenderConfig::height,           256);
743         const int               redBits                 = getValueOrDefault(renderCfg, &RenderConfig::redBits,          8);
744         const int               greenBits               = getValueOrDefault(renderCfg, &RenderConfig::greenBits,        8);
745         const int               blueBits                = getValueOrDefault(renderCfg, &RenderConfig::blueBits,         8);
746         const int               alphaBits               = getValueOrDefault(renderCfg, &RenderConfig::alphaBits,        8);
747         const int               depthBits               = getValueOrDefault(renderCfg, &RenderConfig::depthBits,        24);
748         const int               stencilBits             = getValueOrDefault(renderCfg, &RenderConfig::stencilBits,      8);
749         const int               numSamples              = getValueOrDefault(renderCfg, &RenderConfig::numSamples,       0);
750
751         return tcu::RenderTarget(width, height, tcu::PixelFormat(redBits, greenBits, blueBits, alphaBits), depthBits, stencilBits, numSamples);
752 }
753
754 RenderContext::RenderContext (const RenderConfig& renderCfg)
755         : m_ctxType                     (renderCfg.type)
756         , m_renderTarget        (toRenderTarget(renderCfg))
757         , m_context                     (DE_NULL)
758 {
759         m_context = new Context(m_ctxType);
760
761         initFunctions(&m_functions);
762         setCurrentContext(m_context);
763 }
764
765 RenderContext::~RenderContext (void)
766 {
767         setCurrentContext(DE_NULL);
768         delete m_context;
769 }
770
771 void RenderContext::postIterate (void)
772 {
773 }
774
775 void RenderContext::makeCurrent (void)
776 {
777 }
778
779 } // null
780 } // tcu