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 (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 3) 172 { 173 version = "3.3.0"; 174 shadingLanguageVersion = "3.30"; 175 } 176 else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 4) 177 { 178 version = "4.4.0"; 179 shadingLanguageVersion = "4.40"; 180 } 181 else 182 throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__); 183 184 if (isContextTypeES(ctxType)) 185 { 186 addExtension("GL_EXT_color_buffer_float"); 187 addExtension("GL_EXT_color_buffer_half_float"); 188 } 189 190 // support compressed formats 191 { 192 static deUint32 compressedFormats[] = 193 { 194 GL_ETC1_RGB8_OES, 195 GL_COMPRESSED_R11_EAC, 196 GL_COMPRESSED_SIGNED_R11_EAC, 197 GL_COMPRESSED_RG11_EAC, 198 GL_COMPRESSED_SIGNED_RG11_EAC, 199 GL_COMPRESSED_RGB8_ETC2, 200 GL_COMPRESSED_SRGB8_ETC2, 201 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 202 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 203 GL_COMPRESSED_RGBA8_ETC2_EAC, 204 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 205 GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 206 GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 207 GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 208 GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 209 GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 210 GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 211 GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 212 GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 213 GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 214 GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 215 GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 216 GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 217 GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 218 GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 219 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 220 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 221 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 222 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 223 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 224 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 225 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 226 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 227 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 228 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 229 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 230 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 231 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 232 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 233 }; 234 235 addExtension("GL_KHR_texture_compression_astc_hdr"); 236 addExtension("GL_KHR_texture_compression_astc_ldr"); 237 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compressedFormats); ++ndx) 238 compressedTextureList.push_back(compressedFormats[ndx]); 239 } 240 } 241 242 Context::~Context (void) 243 { 244 } 245 246 void Context::addExtension (const char* name) 247 { 248 if (!extensions.empty()) 249 extensions += " "; 250 extensions += name; 251 252 extensionList.push_back(name); 253 } 254 255 static de::ThreadLocal s_currentCtx; 256 257 void setCurrentContext (Context* context) 258 { 259 s_currentCtx.set((void*)context); 260 } 261 262 Context* getCurrentContext (void) 263 { 264 return (Context*)s_currentCtx.get(); 265 } 266 267 GLW_APICALL GLenum GLW_APIENTRY glGetError (void) 268 { 269 Context* const ctx = getCurrentContext(); 270 const GLenum lastErr = ctx->lastError; 271 272 ctx->lastError = GL_NO_ERROR; 273 274 return lastErr; 275 } 276 277 GLW_APICALL void GLW_APIENTRY glGetIntegerv (GLenum pname, GLint* params) 278 { 279 Context* const ctx = getCurrentContext(); 280 281 switch (pname) 282 { 283 case GL_NUM_EXTENSIONS: 284 *params = (int)ctx->extensionList.size(); 285 break; 286 287 case GL_MAX_VERTEX_ATTRIBS: 288 *params = 32; 289 break; 290 291 case GL_MAX_DRAW_BUFFERS: 292 case GL_MAX_COLOR_ATTACHMENTS: 293 *params = 8; 294 break; 295 296 case GL_MAX_TEXTURE_IMAGE_UNITS: 297 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 298 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 299 case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: 300 case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS: 301 case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS: 302 *params = 32; 303 break; 304 305 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: 306 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: 307 case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: 308 case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: 309 case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: 310 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: 311 *params = 8; 312 break; 313 314 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: 315 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: 316 case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS: 317 case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS: 318 case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS: 319 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: 320 *params = 8; 321 break; 322 323 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: 324 *params = 1u << 25; 325 break; 326 327 case GL_MAX_GEOMETRY_OUTPUT_VERTICES: 328 *params = 256; 329 break; 330 331 case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 332 *params = 2048; 333 break; 334 335 case GL_MAX_GEOMETRY_SHADER_INVOCATIONS: 336 *params = 4; 337 break; 338 339 case GL_MAX_COLOR_TEXTURE_SAMPLES: 340 *params = 8; 341 break; 342 343 case GL_MAX_TEXTURE_SIZE: 344 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 345 case GL_MAX_3D_TEXTURE_SIZE: 346 case GL_MAX_RENDERBUFFER_SIZE: 347 case GL_MAX_TEXTURE_BUFFER_SIZE: 348 *params = 2048; 349 break; 350 351 case GL_MAX_ARRAY_TEXTURE_LAYERS: 352 *params = 128; 353 break; 354 355 case GL_NUM_SHADER_BINARY_FORMATS: 356 *params = 0; 357 break; 358 359 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 360 *params = (int)ctx->compressedTextureList.size(); 361 break; 362 363 case GL_COMPRESSED_TEXTURE_FORMATS: 364 deMemcpy(params, &ctx->compressedTextureList[0], ctx->compressedTextureList.size()*sizeof(deUint32)); 365 break; 366 367 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 368 *params = 16; 369 break; 370 371 case GL_MAX_UNIFORM_BUFFER_BINDINGS: 372 *params = 32; 373 break; 374 375 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: 376 *params = 16; 377 break; 378 379 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 380 *params = GL_RGBA; 381 break; 382 383 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 384 *params = GL_UNSIGNED_BYTE; 385 break; 386 387 case GL_SAMPLE_BUFFERS: 388 *params = 0; 389 break; 390 391 default: 392 break; 393 } 394 } 395 396 GLW_APICALL void GLW_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params) 397 { 398 switch (pname) 399 { 400 case GL_SHADER_COMPILER: 401 *params = GL_TRUE; 402 break; 403 404 default: 405 break; 406 } 407 } 408 409 GLW_APICALL void GLW_APIENTRY glGetFloatv (GLenum pname, GLfloat* params) 410 { 411 switch (pname) 412 { 413 case GL_ALIASED_LINE_WIDTH_RANGE: 414 case GL_ALIASED_POINT_SIZE_RANGE: 415 params[0] = 0.0f; 416 params[1] = 64.0f; 417 break; 418 419 default: 420 break; 421 } 422 } 423 424 GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) 425 { 426 static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 }; 427 428 DE_UNREF(internalformat); 429 DE_UNREF(target); 430 431 switch (pname) 432 { 433 case GL_NUM_SAMPLE_COUNTS: 434 if (bufSize >= 1) 435 *params = DE_LENGTH_OF_ARRAY(s_sampleCounts); 436 break; 437 438 case GL_SAMPLES: 439 deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts))); 440 break; 441 442 default: 443 break; 444 } 445 } 446 447 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name) 448 { 449 Context* const ctx = getCurrentContext(); 450 451 switch (name) 452 { 453 case GL_VENDOR: return (const glw::GLubyte*)ctx->vendor.c_str(); 454 case GL_VERSION: return (const glw::GLubyte*)ctx->version.c_str(); 455 case GL_RENDERER: return (const glw::GLubyte*)ctx->renderer.c_str(); 456 case GL_SHADING_LANGUAGE_VERSION: return (const glw::GLubyte*)ctx->shadingLanguageVersion.c_str(); 457 case GL_EXTENSIONS: return (const glw::GLubyte*)ctx->extensions.c_str(); 458 default: 459 ctx->lastError = GL_INVALID_ENUM; 460 return DE_NULL; 461 } 462 } 463 464 GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetStringi (GLenum name, GLuint index) 465 { 466 Context* const ctx = getCurrentContext(); 467 468 if (name == GL_EXTENSIONS) 469 { 470 if ((size_t)index < ctx->extensionList.size()) 471 return (const glw::GLubyte*)ctx->extensionList[index].c_str(); 472 else 473 { 474 ctx->lastError = GL_INVALID_VALUE; 475 return DE_NULL; 476 } 477 } 478 else 479 { 480 ctx->lastError = GL_INVALID_ENUM; 481 return DE_NULL; 482 } 483 } 484 485 GLW_APICALL GLuint GLW_APIENTRY glCreateProgram () 486 { 487 Context* const ctx = getCurrentContext(); 488 return (GLuint)ctx->programs.allocate(); 489 } 490 491 GLW_APICALL GLuint GLW_APIENTRY glCreateShader (GLenum type) 492 { 493 Context* const ctx = getCurrentContext(); 494 DE_UNREF(type); 495 return (GLuint)ctx->shaders.allocate(); 496 } 497 498 GLW_APICALL void GLW_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params) 499 { 500 DE_UNREF(shader); 501 502 if (pname == GL_COMPILE_STATUS) 503 *params = GL_TRUE; 504 } 505 506 GLW_APICALL void GLW_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params) 507 { 508 DE_UNREF(program); 509 510 if (pname == GL_LINK_STATUS) 511 *params = GL_TRUE; 512 } 513 514 GLW_APICALL void GLW_APIENTRY glGenTextures (GLsizei n, GLuint* textures) 515 { 516 Context* const ctx = getCurrentContext(); 517 518 if (textures) 519 { 520 for (int ndx = 0; ndx < n; ndx++) 521 textures[ndx] = ctx->textures.allocate(); 522 } 523 } 524 525 GLW_APICALL void GLW_APIENTRY glGenQueries (GLsizei n, GLuint* ids) 526 { 527 Context* const ctx = getCurrentContext(); 528 529 if (ids) 530 { 531 for (int ndx = 0; ndx < n; ndx++) 532 ids[ndx] = ctx->queries.allocate(); 533 } 534 } 535 536 GLW_APICALL void GLW_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers) 537 { 538 Context* const ctx = getCurrentContext(); 539 540 if (buffers) 541 { 542 for (int ndx = 0; ndx < n; ndx++) 543 buffers[ndx] = ctx->buffers.allocate(); 544 } 545 } 546 547 GLW_APICALL void GLW_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers) 548 { 549 Context* const ctx = getCurrentContext(); 550 551 if (renderbuffers) 552 { 553 for (int ndx = 0; ndx < n; ndx++) 554 renderbuffers[ndx] = ctx->renderbuffers.allocate(); 555 } 556 } 557 558 GLW_APICALL void GLW_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers) 559 { 560 Context* const ctx = getCurrentContext(); 561 562 if (framebuffers) 563 { 564 for (int ndx = 0; ndx < n; ndx++) 565 framebuffers[ndx] = ctx->framebuffers.allocate(); 566 } 567 } 568 569 GLW_APICALL void GLW_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays) 570 { 571 Context* const ctx = getCurrentContext(); 572 573 if (arrays) 574 { 575 for (int ndx = 0; ndx < n; ndx++) 576 arrays[ndx] = ctx->vertexArrays.allocate(); 577 } 578 } 579 580 GLW_APICALL void GLW_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers) 581 { 582 Context* const ctx = getCurrentContext(); 583 584 if (samplers) 585 { 586 for (int ndx = 0; ndx < count; ndx++) 587 samplers[ndx] = ctx->samplers.allocate(); 588 } 589 } 590 591 GLW_APICALL void GLW_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids) 592 { 593 Context* const ctx = getCurrentContext(); 594 595 if (ids) 596 { 597 for (int ndx = 0; ndx < n; ndx++) 598 ids[ndx] = ctx->transformFeedbacks.allocate(); 599 } 600 } 601 602 GLW_APICALL void GLW_APIENTRY glGenProgramPipelines (GLsizei n, GLuint* pipelines) 603 { 604 Context* const ctx = getCurrentContext(); 605 606 if (pipelines) 607 { 608 for (int ndx = 0; ndx < n; ndx++) 609 pipelines[ndx] = ctx->programPipelines.allocate(); 610 } 611 } 612 613 GLW_APICALL GLvoid* GLW_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) 614 { 615 Context* const ctx = getCurrentContext(); 616 617 DE_UNREF(target); 618 DE_UNREF(offset); 619 DE_UNREF(length); 620 DE_UNREF(access); 621 622 if (ctx->lastError == GL_NO_ERROR) 623 ctx->lastError = GL_INVALID_OPERATION; 624 625 return (GLvoid*)0; 626 } 627 628 GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target) 629 { 630 DE_UNREF(target); 631 return GL_FRAMEBUFFER_COMPLETE; 632 } 633 634 GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) 635 { 636 DE_UNREF(x); 637 DE_UNREF(y); 638 639 Context* const ctx = getCurrentContext(); 640 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f); // black 641 const tcu::TextureFormat transferFormat = glu::mapGLTransferFormat(format, type); 642 643 // invalid formats 644 if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST) 645 { 646 if (ctx->lastError == GL_NO_ERROR) 647 ctx->lastError = GL_INVALID_ENUM; 648 return; 649 } 650 651 // unsupported formats 652 if (!(format == GL_RGBA && type == GL_UNSIGNED_BYTE) && 653 !(format == GL_RGBA_INTEGER && type == GL_INT) && 654 !(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT) && 655 !(format == GL_RGBA && type == GL_FLOAT)) 656 { 657 if (ctx->lastError == GL_NO_ERROR) 658 ctx->lastError = GL_INVALID_ENUM; 659 return; 660 } 661 662 // invalid arguments 663 if (width < 0 || height < 0) 664 { 665 if (ctx->lastError == GL_NO_ERROR) 666 ctx->lastError = GL_INVALID_OPERATION; 667 return; 668 } 669 670 // read to buffer 671 if (ctx->pixelPackBufferBufferBinding) 672 return; 673 674 // read to use pointer 675 { 676 const int targetRowLength = (ctx->pixelPackRowLength != 0) ? (ctx->pixelPackRowLength) : (width); 677 const int targetSkipRows = ctx->pixelPackSkipRows; 678 const int targetSkipPixels = ctx->pixelPackSkipPixels; 679 const int infiniteHeight = targetSkipRows + height; // as much as needed 680 const int targetRowPitch = (ctx->pixelPackAlignment == 0) ? (targetRowLength * transferFormat.getPixelSize()) : (deAlign32(targetRowLength * transferFormat.getPixelSize(), ctx->pixelPackAlignment)); 681 682 // Create access to the whole copy target 683 const tcu::PixelBufferAccess targetAccess (transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels); 684 685 // Select (skip_pixels, skip_rows, width, height) subregion from it. Clip to horizontal boundaries 686 const tcu::PixelBufferAccess targetRectAccess = tcu::getSubregion(targetAccess, 687 de::clamp(targetSkipPixels, 0, targetAccess.getWidth()-1), 688 targetSkipRows, 689 de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)), 690 height); 691 692 tcu::clear(targetRectAccess, clearColor); 693 } 694 } 695 696 GLW_APICALL void GLW_APIENTRY glBindBuffer (GLenum target, GLuint buffer) 697 { 698 Context* const ctx = getCurrentContext(); 699 700 if (target == GL_PIXEL_PACK_BUFFER) 701 ctx->pixelPackBufferBufferBinding = buffer; 702 } 703 704 GLW_APICALL void GLW_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers) 705 { 706 Context* const ctx = getCurrentContext(); 707 708 for (GLsizei ndx = 0; ndx < n; ++ndx) 709 if (buffers[ndx] && buffers[ndx] == ctx->pixelPackBufferBufferBinding) 710 ctx->pixelPackBufferBufferBinding = 0; 711 } 712 713 GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name) 714 { 715 DE_UNREF(program); 716 return (GLint)(deStringHash(name) & 0x7FFFFFFF); 717 } 718 719 void initFunctions (glw::Functions* gl) 720 { 721 # include "tcuNullRenderContextInitFuncs.inl" 722 } 723 724 static tcu::RenderTarget toRenderTarget (const RenderConfig& renderCfg) 725 { 726 const int width = getValueOrDefault(renderCfg, &RenderConfig::width, 256); 727 const int height = getValueOrDefault(renderCfg, &RenderConfig::height, 256); 728 const int redBits = getValueOrDefault(renderCfg, &RenderConfig::redBits, 8); 729 const int greenBits = getValueOrDefault(renderCfg, &RenderConfig::greenBits, 8); 730 const int blueBits = getValueOrDefault(renderCfg, &RenderConfig::blueBits, 8); 731 const int alphaBits = getValueOrDefault(renderCfg, &RenderConfig::alphaBits, 8); 732 const int depthBits = getValueOrDefault(renderCfg, &RenderConfig::depthBits, 24); 733 const int stencilBits = getValueOrDefault(renderCfg, &RenderConfig::stencilBits, 8); 734 const int numSamples = getValueOrDefault(renderCfg, &RenderConfig::numSamples, 0); 735 736 return tcu::RenderTarget(width, height, tcu::PixelFormat(redBits, greenBits, blueBits, alphaBits), depthBits, stencilBits, numSamples); 737 } 738 739 RenderContext::RenderContext (const RenderConfig& renderCfg) 740 : m_ctxType (renderCfg.type) 741 , m_renderTarget (toRenderTarget(renderCfg)) 742 , m_context (DE_NULL) 743 { 744 m_context = new Context(m_ctxType); 745 746 initFunctions(&m_functions); 747 setCurrentContext(m_context); 748 } 749 750 RenderContext::~RenderContext (void) 751 { 752 setCurrentContext(DE_NULL); 753 delete m_context; 754 } 755 756 void RenderContext::postIterate (void) 757 { 758 } 759 760 } // null 761 } // tcu 762