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