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