1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Render context implementation that does no rendering.
22 *//*--------------------------------------------------------------------*/
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"
42 #include "tcuNullRenderContextFuncs.inl"
56 deUint32 allocate (void)
58 deUint32 object = ++m_lastObject;
60 object = ++m_lastObject; // Just ignore overflow.
64 void free (deUint32 object)
70 deUint32 m_lastObject;
76 Context (ContextType ctxType_);
80 Context (const Context&);
81 Context& operator= (const Context&);
83 void addExtension (const char* name);
86 // GL state exposed to implementation functions.
87 const ContextType ctxType;
92 string shadingLanguageVersion;
94 vector<string> extensionList;
95 vector<deUint32> compressedTextureList;
99 int pixelPackRowLength;
100 int pixelPackSkipRows;
101 int pixelPackSkipPixels;
102 int pixelPackAlignment;
104 GLuint pixelPackBufferBufferBinding;
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;
119 Context::Context (ContextType ctxType_)
121 , vendor ("drawElements")
123 , lastError (GL_NO_ERROR)
124 , pixelPackRowLength (0)
125 , pixelPackSkipRows (0)
126 , pixelPackSkipPixels (0)
127 , pixelPackAlignment (0)
128 , pixelPackBufferBufferBinding (0)
132 if (ctxType.getAPI() == ApiType::es(2, 0))
134 version = "OpenGL ES 2.0";
135 shadingLanguageVersion = "OpenGL ES GLSL ES 1.0";
137 else if (ctxType.getAPI() == ApiType::es(3, 0))
139 version = "OpenGL ES 3.0";
140 shadingLanguageVersion = "OpenGL ES GLSL ES 3.0";
142 else if (ctxType.getAPI() == ApiType::es(3, 1))
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");
171 else if (ctxType.getAPI() == ApiType::es(3, 2))
173 version = "OpenGL ES 3.2";
174 shadingLanguageVersion = "OpenGL ES GLSL ES 3.2";
176 else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 3)
179 shadingLanguageVersion = "3.30";
181 else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 4)
184 shadingLanguageVersion = "4.40";
186 else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 5)
189 shadingLanguageVersion = "4.50";
191 else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 6)
194 shadingLanguageVersion = "4.60";
197 throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__);
199 if (isContextTypeES(ctxType))
201 addExtension("GL_EXT_color_buffer_float");
202 addExtension("GL_EXT_color_buffer_half_float");
205 // support compressed formats
207 static deUint32 compressedFormats[] =
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,
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]);
257 Context::~Context (void)
261 void Context::addExtension (const char* name)
263 if (!extensions.empty())
267 extensionList.push_back(name);
270 static de::ThreadLocal s_currentCtx;
272 void setCurrentContext (Context* context)
274 s_currentCtx.set((void*)context);
277 Context* getCurrentContext (void)
279 return (Context*)s_currentCtx.get();
282 GLW_APICALL GLenum GLW_APIENTRY glGetError (void)
284 Context* const ctx = getCurrentContext();
285 const GLenum lastErr = ctx->lastError;
287 ctx->lastError = GL_NO_ERROR;
292 GLW_APICALL void GLW_APIENTRY glGetIntegerv (GLenum pname, GLint* params)
294 Context* const ctx = getCurrentContext();
298 case GL_NUM_EXTENSIONS:
299 *params = (int)ctx->extensionList.size();
302 case GL_MAX_VERTEX_ATTRIBS:
306 case GL_MAX_DRAW_BUFFERS:
307 case GL_MAX_COLOR_ATTACHMENTS:
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:
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:
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:
338 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
342 case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
346 case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
350 case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
354 case GL_MAX_COLOR_TEXTURE_SAMPLES:
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:
366 case GL_MAX_ARRAY_TEXTURE_LAYERS:
370 case GL_NUM_SHADER_BINARY_FORMATS:
374 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
375 *params = (int)ctx->compressedTextureList.size();
378 case GL_COMPRESSED_TEXTURE_FORMATS:
379 deMemcpy(params, &ctx->compressedTextureList[0], ctx->compressedTextureList.size()*sizeof(deUint32));
382 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
386 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
390 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
394 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
398 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
399 *params = GL_UNSIGNED_BYTE;
402 case GL_SAMPLE_BUFFERS:
411 GLW_APICALL void GLW_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params)
415 case GL_SHADER_COMPILER:
424 GLW_APICALL void GLW_APIENTRY glGetFloatv (GLenum pname, GLfloat* params)
428 case GL_ALIASED_LINE_WIDTH_RANGE:
429 case GL_ALIASED_POINT_SIZE_RANGE:
439 GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
441 static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 };
443 DE_UNREF(internalformat);
448 case GL_NUM_SAMPLE_COUNTS:
450 *params = DE_LENGTH_OF_ARRAY(s_sampleCounts);
454 deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts)));
462 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name)
464 Context* const ctx = getCurrentContext();
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();
474 ctx->lastError = GL_INVALID_ENUM;
479 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetStringi (GLenum name, GLuint index)
481 Context* const ctx = getCurrentContext();
483 if (name == GL_EXTENSIONS)
485 if ((size_t)index < ctx->extensionList.size())
486 return (const glw::GLubyte*)ctx->extensionList[index].c_str();
489 ctx->lastError = GL_INVALID_VALUE;
495 ctx->lastError = GL_INVALID_ENUM;
500 GLW_APICALL GLuint GLW_APIENTRY glCreateProgram ()
502 Context* const ctx = getCurrentContext();
503 return (GLuint)ctx->programs.allocate();
506 GLW_APICALL GLuint GLW_APIENTRY glCreateShader (GLenum type)
508 Context* const ctx = getCurrentContext();
510 return (GLuint)ctx->shaders.allocate();
513 GLW_APICALL void GLW_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params)
517 if (pname == GL_COMPILE_STATUS)
521 GLW_APICALL void GLW_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params)
525 if (pname == GL_LINK_STATUS)
529 GLW_APICALL void GLW_APIENTRY glGenTextures (GLsizei n, GLuint* textures)
531 Context* const ctx = getCurrentContext();
535 for (int ndx = 0; ndx < n; ndx++)
536 textures[ndx] = ctx->textures.allocate();
540 GLW_APICALL void GLW_APIENTRY glGenQueries (GLsizei n, GLuint* ids)
542 Context* const ctx = getCurrentContext();
546 for (int ndx = 0; ndx < n; ndx++)
547 ids[ndx] = ctx->queries.allocate();
551 GLW_APICALL void GLW_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers)
553 Context* const ctx = getCurrentContext();
557 for (int ndx = 0; ndx < n; ndx++)
558 buffers[ndx] = ctx->buffers.allocate();
562 GLW_APICALL void GLW_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
564 Context* const ctx = getCurrentContext();
568 for (int ndx = 0; ndx < n; ndx++)
569 renderbuffers[ndx] = ctx->renderbuffers.allocate();
573 GLW_APICALL void GLW_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers)
575 Context* const ctx = getCurrentContext();
579 for (int ndx = 0; ndx < n; ndx++)
580 framebuffers[ndx] = ctx->framebuffers.allocate();
584 GLW_APICALL void GLW_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays)
586 Context* const ctx = getCurrentContext();
590 for (int ndx = 0; ndx < n; ndx++)
591 arrays[ndx] = ctx->vertexArrays.allocate();
595 GLW_APICALL void GLW_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers)
597 Context* const ctx = getCurrentContext();
601 for (int ndx = 0; ndx < count; ndx++)
602 samplers[ndx] = ctx->samplers.allocate();
606 GLW_APICALL void GLW_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids)
608 Context* const ctx = getCurrentContext();
612 for (int ndx = 0; ndx < n; ndx++)
613 ids[ndx] = ctx->transformFeedbacks.allocate();
617 GLW_APICALL void GLW_APIENTRY glGenProgramPipelines (GLsizei n, GLuint* pipelines)
619 Context* const ctx = getCurrentContext();
623 for (int ndx = 0; ndx < n; ndx++)
624 pipelines[ndx] = ctx->programPipelines.allocate();
628 GLW_APICALL GLvoid* GLW_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
630 Context* const ctx = getCurrentContext();
637 if (ctx->lastError == GL_NO_ERROR)
638 ctx->lastError = GL_INVALID_OPERATION;
643 GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target)
646 return GL_FRAMEBUFFER_COMPLETE;
649 GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
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);
659 if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST)
661 if (ctx->lastError == GL_NO_ERROR)
662 ctx->lastError = GL_INVALID_ENUM;
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))
672 if (ctx->lastError == GL_NO_ERROR)
673 ctx->lastError = GL_INVALID_ENUM;
678 if (width < 0 || height < 0)
680 if (ctx->lastError == GL_NO_ERROR)
681 ctx->lastError = GL_INVALID_OPERATION;
686 if (ctx->pixelPackBufferBufferBinding)
689 // read to use pointer
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));
697 // Create access to the whole copy target
698 const tcu::PixelBufferAccess targetAccess (transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels);
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),
704 de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)),
707 tcu::clear(targetRectAccess, clearColor);
711 GLW_APICALL void GLW_APIENTRY glBindBuffer (GLenum target, GLuint buffer)
713 Context* const ctx = getCurrentContext();
715 if (target == GL_PIXEL_PACK_BUFFER)
716 ctx->pixelPackBufferBufferBinding = buffer;
719 GLW_APICALL void GLW_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers)
721 Context* const ctx = getCurrentContext();
723 for (GLsizei ndx = 0; ndx < n; ++ndx)
724 if (buffers[ndx] && buffers[ndx] == ctx->pixelPackBufferBufferBinding)
725 ctx->pixelPackBufferBufferBinding = 0;
728 GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
731 return (GLint)(deStringHash(name) & 0x7FFFFFFF);
734 void initFunctions (glw::Functions* gl)
736 # include "tcuNullRenderContextInitFuncs.inl"
739 static tcu::RenderTarget toRenderTarget (const RenderConfig& renderCfg)
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);
751 return tcu::RenderTarget(width, height, tcu::PixelFormat(redBits, greenBits, blueBits, alphaBits), depthBits, stencilBits, numSamples);
754 RenderContext::RenderContext (const RenderConfig& renderCfg)
755 : m_ctxType (renderCfg.type)
756 , m_renderTarget (toRenderTarget(renderCfg))
757 , m_context (DE_NULL)
759 m_context = new Context(m_ctxType);
761 initFunctions(&m_functions);
762 setCurrentContext(m_context);
765 RenderContext::~RenderContext (void)
767 setCurrentContext(DE_NULL);
771 void RenderContext::postIterate (void)
775 void RenderContext::makeCurrent (void)