1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer 16 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. 17 18 #include "Framebuffer.h" 19 20 #include "main.h" 21 #include "Renderbuffer.h" 22 #include "Texture.h" 23 #include "utilities.h" 24 25 namespace es2 26 { 27 28 bool Framebuffer::IsRenderbuffer(GLenum type) 29 { 30 return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT; 31 } 32 33 Framebuffer::Framebuffer() 34 { 35 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 36 { 37 mColorbufferType[i] = GL_NONE; 38 } 39 mDepthbufferType = GL_NONE; 40 mStencilbufferType = GL_NONE; 41 42 readBuffer = GL_BACK; 43 drawBuffer[0] = GL_BACK; 44 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; ++i) 45 { 46 drawBuffer[i] = GL_NONE; 47 } 48 } 49 50 Framebuffer::~Framebuffer() 51 { 52 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 53 { 54 mColorbufferPointer[i] = nullptr; 55 } 56 mDepthbufferPointer = nullptr; 57 mStencilbufferPointer = nullptr; 58 } 59 60 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const 61 { 62 Context *context = getContext(); 63 Renderbuffer *buffer = nullptr; 64 65 if(type == GL_NONE) 66 { 67 buffer = nullptr; 68 } 69 else if(IsRenderbuffer(type)) 70 { 71 buffer = context->getRenderbuffer(handle); 72 } 73 else if(IsTextureTarget(type)) 74 { 75 buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer); 76 } 77 else UNREACHABLE(type); 78 79 return buffer; 80 } 81 82 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer) 83 { 84 mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE; 85 mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer); 86 } 87 88 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer) 89 { 90 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE; 91 mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level, layer); 92 } 93 94 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer) 95 { 96 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE; 97 mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level, layer); 98 } 99 100 void Framebuffer::setReadBuffer(GLenum buf) 101 { 102 readBuffer = buf; 103 } 104 105 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf) 106 { 107 drawBuffer[index] = buf; 108 } 109 110 GLenum Framebuffer::getReadBuffer() const 111 { 112 return readBuffer; 113 } 114 115 GLenum Framebuffer::getDrawBuffer(GLuint index) const 116 { 117 return drawBuffer[index]; 118 } 119 120 void Framebuffer::detachTexture(GLuint texture) 121 { 122 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 123 { 124 if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i])) 125 { 126 mColorbufferType[i] = GL_NONE; 127 mColorbufferPointer[i] = nullptr; 128 } 129 } 130 131 if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType)) 132 { 133 mDepthbufferType = GL_NONE; 134 mDepthbufferPointer = nullptr; 135 } 136 137 if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType)) 138 { 139 mStencilbufferType = GL_NONE; 140 mStencilbufferPointer = nullptr; 141 } 142 } 143 144 void Framebuffer::detachRenderbuffer(GLuint renderbuffer) 145 { 146 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 147 { 148 if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i])) 149 { 150 mColorbufferType[i] = GL_NONE; 151 mColorbufferPointer[i] = nullptr; 152 } 153 } 154 155 if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType)) 156 { 157 mDepthbufferType = GL_NONE; 158 mDepthbufferPointer = nullptr; 159 } 160 161 if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType)) 162 { 163 mStencilbufferType = GL_NONE; 164 mStencilbufferPointer = nullptr; 165 } 166 } 167 168 // Increments refcount on surface. 169 // caller must Release() the returned surface 170 egl::Image *Framebuffer::getRenderTarget(GLuint index) 171 { 172 Renderbuffer *colorbuffer = mColorbufferPointer[index]; 173 174 if(colorbuffer) 175 { 176 return colorbuffer->getRenderTarget(); 177 } 178 179 return nullptr; 180 } 181 182 egl::Image *Framebuffer::getReadRenderTarget() 183 { 184 Context *context = getContext(); 185 return getRenderTarget(context->getReadFramebufferColorIndex()); 186 } 187 188 // Increments refcount on surface. 189 // caller must Release() the returned surface 190 egl::Image *Framebuffer::getDepthBuffer() 191 { 192 Renderbuffer *depthbuffer = mDepthbufferPointer; 193 194 if(depthbuffer) 195 { 196 return depthbuffer->getRenderTarget(); 197 } 198 199 return nullptr; 200 } 201 202 // Increments refcount on surface. 203 // caller must Release() the returned surface 204 egl::Image *Framebuffer::getStencilBuffer() 205 { 206 Renderbuffer *stencilbuffer = mStencilbufferPointer; 207 208 if(stencilbuffer) 209 { 210 return stencilbuffer->getRenderTarget(); 211 } 212 213 return nullptr; 214 } 215 216 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const 217 { 218 return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr; 219 } 220 221 Renderbuffer *Framebuffer::getReadColorbuffer() const 222 { 223 Context *context = getContext(); 224 return getColorbuffer(context->getReadFramebufferColorIndex()); 225 } 226 227 Renderbuffer *Framebuffer::getDepthbuffer() const 228 { 229 return mDepthbufferPointer; 230 } 231 232 Renderbuffer *Framebuffer::getStencilbuffer() const 233 { 234 return mStencilbufferPointer; 235 } 236 237 GLenum Framebuffer::getColorbufferType(GLuint index) 238 { 239 return mColorbufferType[index]; 240 } 241 242 GLenum Framebuffer::getDepthbufferType() 243 { 244 return mDepthbufferType; 245 } 246 247 GLenum Framebuffer::getStencilbufferType() 248 { 249 return mStencilbufferType; 250 } 251 252 GLuint Framebuffer::getColorbufferName(GLuint index) 253 { 254 return mColorbufferPointer[index].name(); 255 } 256 257 GLuint Framebuffer::getDepthbufferName() 258 { 259 return mDepthbufferPointer.name(); 260 } 261 262 GLuint Framebuffer::getStencilbufferName() 263 { 264 return mStencilbufferPointer.name(); 265 } 266 267 GLint Framebuffer::getColorbufferLayer(GLuint index) 268 { 269 Renderbuffer *colorbuffer = mColorbufferPointer[index]; 270 return colorbuffer ? colorbuffer->getLayer() : 0; 271 } 272 273 GLint Framebuffer::getDepthbufferLayer() 274 { 275 return mDepthbufferPointer ? mDepthbufferPointer->getLayer() : 0; 276 } 277 278 GLint Framebuffer::getStencilbufferLayer() 279 { 280 return mStencilbufferPointer ? mStencilbufferPointer->getLayer() : 0; 281 } 282 283 bool Framebuffer::hasStencil() 284 { 285 if(mStencilbufferType != GL_NONE) 286 { 287 Renderbuffer *stencilbufferObject = getStencilbuffer(); 288 289 if(stencilbufferObject) 290 { 291 return stencilbufferObject->getStencilSize() > 0; 292 } 293 } 294 295 return false; 296 } 297 298 GLenum Framebuffer::completeness() 299 { 300 int width; 301 int height; 302 int samples; 303 304 return completeness(width, height, samples); 305 } 306 307 GLenum Framebuffer::completeness(int &width, int &height, int &samples) 308 { 309 width = -1; 310 height = -1; 311 samples = -1; 312 313 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 314 { 315 if(mColorbufferType[i] != GL_NONE) 316 { 317 Renderbuffer *colorbuffer = getColorbuffer(i); 318 319 if(!colorbuffer) 320 { 321 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 322 } 323 324 if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= colorbuffer->getLayer())) 325 { 326 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 327 } 328 329 if(IsRenderbuffer(mColorbufferType[i])) 330 { 331 if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion(), false)) 332 { 333 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 334 } 335 } 336 else if(IsTextureTarget(mColorbufferType[i])) 337 { 338 GLenum format = colorbuffer->getFormat(); 339 340 if(!IsColorRenderable(format, egl::getClientVersion(), true)) 341 { 342 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 343 } 344 345 if(IsDepthTexture(format) || IsStencilTexture(format)) 346 { 347 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 348 } 349 } 350 else 351 { 352 UNREACHABLE(mColorbufferType[i]); 353 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 354 } 355 356 width = colorbuffer->getWidth(); 357 height = colorbuffer->getHeight(); 358 359 if(samples == -1) 360 { 361 samples = colorbuffer->getSamples(); 362 } 363 else if(samples != colorbuffer->getSamples()) 364 { 365 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; 366 } 367 } 368 } 369 370 Renderbuffer *depthbuffer = nullptr; 371 Renderbuffer *stencilbuffer = nullptr; 372 373 if(mDepthbufferType != GL_NONE) 374 { 375 depthbuffer = getDepthbuffer(); 376 377 if(!depthbuffer) 378 { 379 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 380 } 381 382 if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0) 383 { 384 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 385 } 386 387 if(IsRenderbuffer(mDepthbufferType)) 388 { 389 if(!es2::IsDepthRenderable(depthbuffer->getFormat(), egl::getClientVersion())) 390 { 391 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 392 } 393 } 394 else if(IsTextureTarget(mDepthbufferType)) 395 { 396 if(!es2::IsDepthTexture(depthbuffer->getFormat())) 397 { 398 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 399 } 400 } 401 else 402 { 403 UNREACHABLE(mDepthbufferType); 404 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 405 } 406 407 if(width == -1 || height == -1) 408 { 409 width = depthbuffer->getWidth(); 410 height = depthbuffer->getHeight(); 411 samples = depthbuffer->getSamples(); 412 } 413 else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight()) 414 { 415 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 416 } 417 else if(samples != depthbuffer->getSamples()) 418 { 419 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; 420 } 421 } 422 423 if(mStencilbufferType != GL_NONE) 424 { 425 stencilbuffer = getStencilbuffer(); 426 427 if(!stencilbuffer) 428 { 429 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 430 } 431 432 if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0) 433 { 434 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 435 } 436 437 if(IsRenderbuffer(mStencilbufferType)) 438 { 439 if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), egl::getClientVersion())) 440 { 441 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 442 } 443 } 444 else if(IsTextureTarget(mStencilbufferType)) 445 { 446 GLenum internalformat = stencilbuffer->getFormat(); 447 448 if(!es2::IsStencilTexture(internalformat)) 449 { 450 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 451 } 452 } 453 else 454 { 455 UNREACHABLE(mStencilbufferType); 456 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 457 } 458 459 if(width == -1 || height == -1) 460 { 461 width = stencilbuffer->getWidth(); 462 height = stencilbuffer->getHeight(); 463 samples = stencilbuffer->getSamples(); 464 } 465 else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight()) 466 { 467 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 468 } 469 else if(samples != stencilbuffer->getSamples()) 470 { 471 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; 472 } 473 } 474 475 if((egl::getClientVersion() >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer)) 476 { 477 // In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness: 478 // "The framebuffer object target is said to be framebuffer complete if all the following conditions are true: 479 // [...] 480 // Depth and stencil attachments, if present, are the same image. 481 // { FRAMEBUFFER_UNSUPPORTED }" 482 return GL_FRAMEBUFFER_UNSUPPORTED; 483 } 484 485 // We need to have at least one attachment to be complete 486 if(width == -1 || height == -1) 487 { 488 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; 489 } 490 491 return GL_FRAMEBUFFER_COMPLETE; 492 } 493 494 GLenum Framebuffer::getImplementationColorReadFormat() const 495 { 496 Renderbuffer *colorbuffer = getReadColorbuffer(); 497 498 if(colorbuffer) 499 { 500 switch(colorbuffer->getInternalFormat()) 501 { 502 case sw::FORMAT_A8B8G8R8I: return GL_RGBA_INTEGER; 503 case sw::FORMAT_A8B8G8R8UI: return GL_RGBA_INTEGER; 504 case sw::FORMAT_A16B16G16R16I: return GL_RGBA_INTEGER; 505 case sw::FORMAT_A16B16G16R16UI: return GL_RGBA_INTEGER; 506 case sw::FORMAT_A32B32G32R32I: return GL_RGBA_INTEGER; 507 case sw::FORMAT_A32B32G32R32UI: return GL_RGBA_INTEGER; 508 case sw::FORMAT_A2B10G10R10: return GL_RGB10_A2; 509 case sw::FORMAT_A8B8G8R8I_SNORM: return GL_RGBA; 510 case sw::FORMAT_A8B8G8R8: return GL_RGBA; 511 case sw::FORMAT_SRGB8_A8: return GL_RGBA; 512 case sw::FORMAT_A8R8G8B8: return GL_BGRA_EXT; 513 case sw::FORMAT_A1R5G5B5: return GL_BGRA_EXT; 514 case sw::FORMAT_X8B8G8R8I: return GL_RGBA_INTEGER; 515 case sw::FORMAT_X8B8G8R8UI: return GL_RGBA_INTEGER; 516 case sw::FORMAT_X16B16G16R16I: return GL_RGBA_INTEGER; 517 case sw::FORMAT_X16B16G16R16UI: return GL_RGBA_INTEGER; 518 case sw::FORMAT_X32B32G32R32I: return GL_RGBA_INTEGER; 519 case sw::FORMAT_X32B32G32R32UI: return GL_RGBA_INTEGER; 520 case sw::FORMAT_X8B8G8R8I_SNORM: return GL_RGBA; 521 case sw::FORMAT_SRGB8_X8: return GL_RGBA; 522 case sw::FORMAT_X8B8G8R8: return GL_RGBA; 523 case sw::FORMAT_X8R8G8B8: return GL_BGRA_EXT; 524 case sw::FORMAT_R5G6B5: return GL_RGB; 525 case sw::FORMAT_G8R8I: return GL_RG_INTEGER; 526 case sw::FORMAT_G8R8UI: return GL_RG_INTEGER; 527 case sw::FORMAT_G16R16I: return GL_RG_INTEGER; 528 case sw::FORMAT_G16R16UI: return GL_RG_INTEGER; 529 case sw::FORMAT_G32R32I: return GL_RG_INTEGER; 530 case sw::FORMAT_G32R32UI: return GL_RG_INTEGER; 531 case sw::FORMAT_R8I: return GL_RED_INTEGER; 532 case sw::FORMAT_R8UI: return GL_RED_INTEGER; 533 case sw::FORMAT_R16I: return GL_RED_INTEGER; 534 case sw::FORMAT_R16UI: return GL_RED_INTEGER; 535 case sw::FORMAT_R32I: return GL_RED_INTEGER; 536 case sw::FORMAT_R32UI: return GL_RED_INTEGER; 537 case sw::FORMAT_R8: return GL_RED; 538 case sw::FORMAT_R8I_SNORM: return GL_RED; 539 case sw::FORMAT_R16F: return GL_RED; 540 case sw::FORMAT_R32F: return GL_RED; 541 case sw::FORMAT_G8R8: return GL_RG; 542 case sw::FORMAT_G8R8I_SNORM: return GL_RG; 543 case sw::FORMAT_G16R16F: return GL_RG; 544 case sw::FORMAT_G32R32F: return GL_RG; 545 case sw::FORMAT_B16G16R16F: return GL_RGB; 546 case sw::FORMAT_X32B32G32R32F: return GL_RGBA; 547 case sw::FORMAT_A16B16G16R16F: return GL_RGBA; 548 case sw::FORMAT_A32B32G32R32F: return GL_RGBA; 549 default: 550 UNREACHABLE(colorbuffer->getInternalFormat()); 551 } 552 } 553 554 return GL_RGBA; 555 } 556 557 GLenum Framebuffer::getImplementationColorReadType() const 558 { 559 Renderbuffer *colorbuffer = getReadColorbuffer(); 560 561 if(colorbuffer) 562 { 563 switch(colorbuffer->getInternalFormat()) 564 { 565 case sw::FORMAT_R16F: return GL_FLOAT; 566 case sw::FORMAT_G16R16F: return GL_FLOAT; 567 case sw::FORMAT_B16G16R16F: return GL_FLOAT; 568 case sw::FORMAT_A16B16G16R16F: return GL_FLOAT; 569 case sw::FORMAT_R32F: return GL_FLOAT; 570 case sw::FORMAT_G32R32F: return GL_FLOAT; 571 case sw::FORMAT_B32G32R32F: return GL_FLOAT; 572 case sw::FORMAT_X32B32G32R32F: return GL_FLOAT; 573 case sw::FORMAT_A32B32G32R32F: return GL_FLOAT; 574 case sw::FORMAT_R8I_SNORM: return GL_BYTE; 575 case sw::FORMAT_G8R8I_SNORM: return GL_BYTE; 576 case sw::FORMAT_X8B8G8R8I_SNORM: return GL_BYTE; 577 case sw::FORMAT_A8B8G8R8I_SNORM: return GL_BYTE; 578 case sw::FORMAT_R8: return GL_UNSIGNED_BYTE; 579 case sw::FORMAT_G8R8: return GL_UNSIGNED_BYTE; 580 case sw::FORMAT_SRGB8_X8: return GL_UNSIGNED_BYTE; 581 case sw::FORMAT_SRGB8_A8: return GL_UNSIGNED_BYTE; 582 case sw::FORMAT_A8R8G8B8: return GL_UNSIGNED_BYTE; 583 case sw::FORMAT_A8B8G8R8: return GL_UNSIGNED_BYTE; 584 case sw::FORMAT_X8R8G8B8: return GL_UNSIGNED_BYTE; 585 case sw::FORMAT_X8B8G8R8: return GL_UNSIGNED_BYTE; 586 case sw::FORMAT_R8I: return GL_INT; 587 case sw::FORMAT_G8R8I: return GL_INT; 588 case sw::FORMAT_X8B8G8R8I: return GL_INT; 589 case sw::FORMAT_A8B8G8R8I: return GL_INT; 590 case sw::FORMAT_R16I: return GL_INT; 591 case sw::FORMAT_G16R16I: return GL_INT; 592 case sw::FORMAT_X16B16G16R16I: return GL_INT; 593 case sw::FORMAT_A16B16G16R16I: return GL_INT; 594 case sw::FORMAT_R32I: return GL_INT; 595 case sw::FORMAT_G32R32I: return GL_INT; 596 case sw::FORMAT_X32B32G32R32I: return GL_INT; 597 case sw::FORMAT_A32B32G32R32I: return GL_INT; 598 case sw::FORMAT_R8UI: return GL_UNSIGNED_INT; 599 case sw::FORMAT_G8R8UI: return GL_UNSIGNED_INT; 600 case sw::FORMAT_X8B8G8R8UI: return GL_UNSIGNED_INT; 601 case sw::FORMAT_A8B8G8R8UI: return GL_UNSIGNED_INT; 602 case sw::FORMAT_R16UI: return GL_UNSIGNED_INT; 603 case sw::FORMAT_G16R16UI: return GL_UNSIGNED_INT; 604 case sw::FORMAT_X16B16G16R16UI: return GL_UNSIGNED_INT; 605 case sw::FORMAT_A16B16G16R16UI: return GL_UNSIGNED_INT; 606 case sw::FORMAT_R32UI: return GL_UNSIGNED_INT; 607 case sw::FORMAT_G32R32UI: return GL_UNSIGNED_INT; 608 case sw::FORMAT_X32B32G32R32UI: return GL_UNSIGNED_INT; 609 case sw::FORMAT_A32B32G32R32UI: return GL_UNSIGNED_INT; 610 case sw::FORMAT_A2B10G10R10: return GL_UNSIGNED_INT_10_10_10_2_OES; 611 case sw::FORMAT_A1R5G5B5: return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT; 612 case sw::FORMAT_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5; 613 default: 614 UNREACHABLE(colorbuffer->getInternalFormat()); 615 } 616 } 617 618 return GL_UNSIGNED_BYTE; 619 } 620 621 GLenum Framebuffer::getDepthReadFormat() const 622 { 623 Renderbuffer *depthbuffer = getDepthbuffer(); 624 625 if(depthbuffer) 626 { 627 // There is only one depth read format. 628 return GL_DEPTH_COMPONENT; 629 } 630 631 // If there is no depth buffer, GL_INVALID_OPERATION occurs. 632 return GL_NONE; 633 } 634 635 GLenum Framebuffer::getDepthReadType() const 636 { 637 Renderbuffer *depthbuffer = getDepthbuffer(); 638 639 if(depthbuffer) 640 { 641 switch(depthbuffer->getInternalFormat()) 642 { 643 case sw::FORMAT_D16: return GL_UNSIGNED_SHORT; 644 case sw::FORMAT_D24S8: return GL_UNSIGNED_INT_24_8_OES; 645 case sw::FORMAT_D32: return GL_UNSIGNED_INT; 646 case sw::FORMAT_D32F: 647 case sw::FORMAT_D32F_COMPLEMENTARY: 648 case sw::FORMAT_D32F_LOCKABLE: 649 case sw::FORMAT_D32FS8_TEXTURE: 650 case sw::FORMAT_D32FS8_SHADOW: return GL_FLOAT; 651 default: 652 UNREACHABLE(depthbuffer->getInternalFormat()); 653 } 654 } 655 656 // If there is no depth buffer, GL_INVALID_OPERATION occurs. 657 return GL_NONE; 658 } 659 660 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) 661 { 662 GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT; 663 mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer); 664 mColorbufferType[0] = defaultRenderbufferType; 665 666 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++) 667 { 668 mColorbufferPointer[i] = nullptr; 669 mColorbufferType[i] = GL_NONE; 670 } 671 672 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil); 673 mDepthbufferPointer = depthStencilRenderbuffer; 674 mStencilbufferPointer = depthStencilRenderbuffer; 675 676 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? defaultRenderbufferType : GL_NONE; 677 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? defaultRenderbufferType : GL_NONE; 678 } 679 680 } 681