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