Fix missing dependency on sparse binds
[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 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
262 Context::~Context (void)
263 {
264 }
265
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
277 void setCurrentContext (Context* context)
278 {
279         s_currentCtx.set((void*)context);
280 }
281
282 Context* getCurrentContext (void)
283 {
284         return (Context*)s_currentCtx.get();
285 }
286
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
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
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
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
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
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
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
505 GLW_APICALL GLuint GLW_APIENTRY glCreateProgram ()
506 {
507         Context* const ctx = getCurrentContext();
508         return (GLuint)ctx->programs.allocate();
509 }
510
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
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
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
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
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
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
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
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
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
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
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
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
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
648 GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target)
649 {
650         DE_UNREF(target);
651         return GL_FRAMEBUFFER_COMPLETE;
652 }
653
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
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
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
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
739 void initFunctions (glw::Functions* gl)
740 {
741 #       include "tcuNullRenderContextInitFuncs.inl"
742 }
743
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
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
770 RenderContext::~RenderContext (void)
771 {
772         setCurrentContext(DE_NULL);
773         delete m_context;
774 }
775
776 void RenderContext::postIterate (void)
777 {
778 }
779
780 void RenderContext::makeCurrent (void)
781 {
782 }
783
784 } // null
785 } // tcu