Home | History | Annotate | Download | only in libGLESv2
      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 #include <algorithm>
     26 
     27 namespace es2
     28 {
     29 
     30 bool Framebuffer::IsRenderbuffer(GLenum type)
     31 {
     32 	return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT;
     33 }
     34 
     35 Framebuffer::Framebuffer()
     36 {
     37 	readBuffer = GL_COLOR_ATTACHMENT0;
     38 	drawBuffer[0] = GL_COLOR_ATTACHMENT0;
     39 	for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
     40 	{
     41 		drawBuffer[i] = GL_NONE;
     42 	}
     43 
     44 	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
     45 	{
     46 		mColorbufferType[i] = GL_NONE;
     47 		mColorbufferLayer[i] = 0;
     48 	}
     49 
     50 	mDepthbufferType = GL_NONE;
     51 	mDepthbufferLayer = 0;
     52 	mStencilbufferType = GL_NONE;
     53 	mStencilbufferLayer = 0;
     54 }
     55 
     56 Framebuffer::~Framebuffer()
     57 {
     58 	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
     59 	{
     60 		mColorbufferPointer[i] = nullptr;
     61 	}
     62 	mDepthbufferPointer = nullptr;
     63 	mStencilbufferPointer = nullptr;
     64 }
     65 
     66 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const
     67 {
     68 	Context *context = getContext();
     69 	Renderbuffer *buffer = nullptr;
     70 
     71 	if(type == GL_NONE)
     72 	{
     73 		buffer = nullptr;
     74 	}
     75 	else if(IsRenderbuffer(type))
     76 	{
     77 		buffer = context->getRenderbuffer(handle);
     78 	}
     79 	else if(IsTextureTarget(type))
     80 	{
     81 		buffer = context->getTexture(handle)->getRenderbuffer(type, level);
     82 	}
     83 	else UNREACHABLE(type);
     84 
     85 	return buffer;
     86 }
     87 
     88 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer)
     89 {
     90 	mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
     91 	mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level);
     92 	mColorbufferLayer[index] = layer;
     93 }
     94 
     95 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
     96 {
     97 	mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
     98 	mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level);
     99 	mDepthbufferLayer = layer;
    100 }
    101 
    102 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
    103 {
    104 	mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
    105 	mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level);
    106 	mStencilbufferLayer = layer;
    107 }
    108 
    109 void Framebuffer::setReadBuffer(GLenum buf)
    110 {
    111 	readBuffer = buf;
    112 }
    113 
    114 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf)
    115 {
    116 	drawBuffer[index] = buf;
    117 }
    118 
    119 GLenum Framebuffer::getReadBuffer() const
    120 {
    121 	return readBuffer;
    122 }
    123 
    124 GLenum Framebuffer::getDrawBuffer(GLuint index) const
    125 {
    126 	return drawBuffer[index];
    127 }
    128 
    129 void Framebuffer::detachTexture(GLuint texture)
    130 {
    131 	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
    132 	{
    133 		if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i]))
    134 		{
    135 			mColorbufferType[i] = GL_NONE;
    136 			mColorbufferPointer[i] = nullptr;
    137 		}
    138 	}
    139 
    140 	if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
    141 	{
    142 		mDepthbufferType = GL_NONE;
    143 		mDepthbufferPointer = nullptr;
    144 	}
    145 
    146 	if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
    147 	{
    148 		mStencilbufferType = GL_NONE;
    149 		mStencilbufferPointer = nullptr;
    150 	}
    151 }
    152 
    153 void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
    154 {
    155 	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
    156 	{
    157 		if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i]))
    158 		{
    159 			mColorbufferType[i] = GL_NONE;
    160 			mColorbufferPointer[i] = nullptr;
    161 		}
    162 	}
    163 
    164 	if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType))
    165 	{
    166 		mDepthbufferType = GL_NONE;
    167 		mDepthbufferPointer = nullptr;
    168 	}
    169 
    170 	if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType))
    171 	{
    172 		mStencilbufferType = GL_NONE;
    173 		mStencilbufferPointer = nullptr;
    174 	}
    175 }
    176 
    177 // Increments refcount on surface.
    178 // caller must Release() the returned surface
    179 egl::Image *Framebuffer::getRenderTarget(GLuint index)
    180 {
    181 	if(index < MAX_COLOR_ATTACHMENTS)
    182 	{
    183 		Renderbuffer *colorbuffer = mColorbufferPointer[index];
    184 
    185 		if(colorbuffer)
    186 		{
    187 			return colorbuffer->getRenderTarget();
    188 		}
    189 	}
    190 
    191 	return nullptr;
    192 }
    193 
    194 egl::Image *Framebuffer::getReadRenderTarget()
    195 {
    196 	return getRenderTarget(getReadBufferIndex());
    197 }
    198 
    199 // Increments refcount on surface.
    200 // caller must Release() the returned surface
    201 egl::Image *Framebuffer::getDepthBuffer()
    202 {
    203 	Renderbuffer *depthbuffer = mDepthbufferPointer;
    204 
    205 	if(depthbuffer)
    206 	{
    207 		return depthbuffer->getRenderTarget();
    208 	}
    209 
    210 	return nullptr;
    211 }
    212 
    213 // Increments refcount on surface.
    214 // caller must Release() the returned surface
    215 egl::Image *Framebuffer::getStencilBuffer()
    216 {
    217 	Renderbuffer *stencilbuffer = mStencilbufferPointer;
    218 
    219 	if(stencilbuffer)
    220 	{
    221 		return stencilbuffer->getRenderTarget();
    222 	}
    223 
    224 	return nullptr;
    225 }
    226 
    227 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const
    228 {
    229 	return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr;
    230 }
    231 
    232 Renderbuffer *Framebuffer::getReadColorbuffer() const
    233 {
    234 	return getColorbuffer(getReadBufferIndex());
    235 }
    236 
    237 Renderbuffer *Framebuffer::getDepthbuffer() const
    238 {
    239 	return mDepthbufferPointer;
    240 }
    241 
    242 Renderbuffer *Framebuffer::getStencilbuffer() const
    243 {
    244 	return mStencilbufferPointer;
    245 }
    246 
    247 GLenum Framebuffer::getReadBufferType()
    248 {
    249 	if(readBuffer == GL_NONE)
    250 	{
    251 		return GL_NONE;
    252 	}
    253 
    254 	return mColorbufferType[getReadBufferIndex()];
    255 }
    256 
    257 GLenum Framebuffer::getColorbufferType(GLuint index)
    258 {
    259 	return mColorbufferType[index];
    260 }
    261 
    262 GLenum Framebuffer::getDepthbufferType()
    263 {
    264 	return mDepthbufferType;
    265 }
    266 
    267 GLenum Framebuffer::getStencilbufferType()
    268 {
    269 	return mStencilbufferType;
    270 }
    271 
    272 GLuint Framebuffer::getColorbufferName(GLuint index)
    273 {
    274 	return mColorbufferPointer[index].name();
    275 }
    276 
    277 GLuint Framebuffer::getDepthbufferName()
    278 {
    279 	return mDepthbufferPointer.name();
    280 }
    281 
    282 GLuint Framebuffer::getStencilbufferName()
    283 {
    284 	return mStencilbufferPointer.name();
    285 }
    286 
    287 GLint Framebuffer::getColorbufferLayer(GLuint index)
    288 {
    289 	return mColorbufferLayer[index];
    290 }
    291 
    292 GLint Framebuffer::getDepthbufferLayer()
    293 {
    294 	return mDepthbufferLayer;
    295 }
    296 
    297 GLint Framebuffer::getStencilbufferLayer()
    298 {
    299 	return mStencilbufferLayer;
    300 }
    301 
    302 bool Framebuffer::hasStencil()
    303 {
    304 	if(mStencilbufferType != GL_NONE)
    305 	{
    306 		Renderbuffer *stencilbufferObject = getStencilbuffer();
    307 
    308 		if(stencilbufferObject)
    309 		{
    310 			return stencilbufferObject->getStencilSize() > 0;
    311 		}
    312 	}
    313 
    314 	return false;
    315 }
    316 
    317 GLenum Framebuffer::completeness()
    318 {
    319 	int width;
    320 	int height;
    321 	int samples;
    322 
    323 	return completeness(width, height, samples);
    324 }
    325 
    326 GLenum Framebuffer::completeness(int &width, int &height, int &samples)
    327 {
    328 	width = -1;
    329 	height = -1;
    330 	samples = -1;
    331 
    332 	GLint version = egl::getClientVersion();
    333 
    334 	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
    335 	{
    336 		if(mColorbufferType[i] != GL_NONE)
    337 		{
    338 			Renderbuffer *colorbuffer = getColorbuffer(i);
    339 
    340 			if(!colorbuffer)
    341 			{
    342 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    343 			}
    344 
    345 			if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= mColorbufferLayer[i]))
    346 			{
    347 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    348 			}
    349 
    350 			if(IsRenderbuffer(mColorbufferType[i]))
    351 			{
    352 				if(!IsColorRenderable(colorbuffer->getFormat(), version))
    353 				{
    354 					return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    355 				}
    356 			}
    357 			else if(IsTextureTarget(mColorbufferType[i]))
    358 			{
    359 				GLenum format = colorbuffer->getFormat();
    360 
    361 				if(!IsColorRenderable(format, version))
    362 				{
    363 					return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    364 				}
    365 
    366 				if(IsDepthTexture(format) || IsStencilTexture(format))
    367 				{
    368 					return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    369 				}
    370 			}
    371 			else
    372 			{
    373 				UNREACHABLE(mColorbufferType[i]);
    374 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    375 			}
    376 
    377 			if(width == -1 || height == -1)
    378 			{
    379 				width = colorbuffer->getWidth();
    380 				height = colorbuffer->getHeight();
    381 				samples = colorbuffer->getSamples();
    382 			}
    383 			else
    384 			{
    385 				if(version < 3 && (width != colorbuffer->getWidth() || height != colorbuffer->getHeight()))
    386 				{
    387 					return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
    388 				}
    389 
    390 				if(samples != colorbuffer->getSamples())
    391 				{
    392 					return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
    393 				}
    394 
    395 				width = std::min(width, colorbuffer->getWidth());
    396 				height = std::min(height, colorbuffer->getHeight());
    397 			}
    398 		}
    399 	}
    400 
    401 	Renderbuffer *depthbuffer = nullptr;
    402 	Renderbuffer *stencilbuffer = nullptr;
    403 
    404 	if(mDepthbufferType != GL_NONE)
    405 	{
    406 		depthbuffer = getDepthbuffer();
    407 
    408 		if(!depthbuffer)
    409 		{
    410 			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    411 		}
    412 
    413 		if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0 || (depthbuffer->getDepth() <= mDepthbufferLayer))
    414 		{
    415 			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    416 		}
    417 
    418 		if(IsRenderbuffer(mDepthbufferType))
    419 		{
    420 			if(!es2::IsDepthRenderable(depthbuffer->getFormat(), version))
    421 			{
    422 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    423 			}
    424 		}
    425 		else if(IsTextureTarget(mDepthbufferType))
    426 		{
    427 			if(!es2::IsDepthTexture(depthbuffer->getFormat()))
    428 			{
    429 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    430 			}
    431 		}
    432 		else
    433 		{
    434 			UNREACHABLE(mDepthbufferType);
    435 			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    436 		}
    437 
    438 		if(width == -1 || height == -1)
    439 		{
    440 			width = depthbuffer->getWidth();
    441 			height = depthbuffer->getHeight();
    442 			samples = depthbuffer->getSamples();
    443 		}
    444 		else
    445 		{
    446 			if(version < 3 && (width != depthbuffer->getWidth() || height != depthbuffer->getHeight()))
    447 			{
    448 				return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
    449 			}
    450 
    451 			if(samples != depthbuffer->getSamples())
    452 			{
    453 				return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
    454 			}
    455 
    456 			width = std::min(width, depthbuffer->getWidth());
    457 			height = std::min(height, depthbuffer->getHeight());
    458 		}
    459 	}
    460 
    461 	if(mStencilbufferType != GL_NONE)
    462 	{
    463 		stencilbuffer = getStencilbuffer();
    464 
    465 		if(!stencilbuffer)
    466 		{
    467 			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    468 		}
    469 
    470 		if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0 || (stencilbuffer->getDepth() <= mStencilbufferLayer))
    471 		{
    472 			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    473 		}
    474 
    475 		if(IsRenderbuffer(mStencilbufferType))
    476 		{
    477 			if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), version))
    478 			{
    479 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    480 			}
    481 		}
    482 		else if(IsTextureTarget(mStencilbufferType))
    483 		{
    484 			GLenum internalformat = stencilbuffer->getFormat();
    485 
    486 			if(!es2::IsStencilTexture(internalformat))
    487 			{
    488 				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    489 			}
    490 		}
    491 		else
    492 		{
    493 			UNREACHABLE(mStencilbufferType);
    494 			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
    495 		}
    496 
    497 		if(width == -1 || height == -1)
    498 		{
    499 			width = stencilbuffer->getWidth();
    500 			height = stencilbuffer->getHeight();
    501 			samples = stencilbuffer->getSamples();
    502 		}
    503 		else
    504 		{
    505 			if(version < 3 && (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight()))
    506 			{
    507 				return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
    508 			}
    509 
    510 			if(samples != stencilbuffer->getSamples())
    511 			{
    512 				return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
    513 			}
    514 
    515 			width = std::min(width, stencilbuffer->getWidth());
    516 			height = std::min(height, stencilbuffer->getHeight());
    517 		}
    518 	}
    519 
    520 	if((version >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
    521 	{
    522 		// In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness:
    523 		// "The framebuffer object target is said to be framebuffer complete if all the following conditions are true:
    524 		//  [...]
    525 		//  Depth and stencil attachments, if present, are the same image.
    526 		//  { FRAMEBUFFER_UNSUPPORTED }"
    527 		return GL_FRAMEBUFFER_UNSUPPORTED;
    528 	}
    529 
    530 	// We need to have at least one attachment to be complete
    531 	if(width == -1 || height == -1)
    532 	{
    533 		return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
    534 	}
    535 
    536 	return GL_FRAMEBUFFER_COMPLETE;
    537 }
    538 
    539 GLenum Framebuffer::getImplementationColorReadFormat() const
    540 {
    541 	Renderbuffer *colorbuffer = getReadColorbuffer();
    542 
    543 	if(colorbuffer)
    544 	{
    545 		switch(colorbuffer->getFormat())
    546 		{
    547 		case GL_BGRA8_EXT:      return GL_BGRA_EXT;
    548 		case GL_RGBA4:          return GL_RGBA;
    549 		case GL_RGB5_A1:        return GL_RGBA;
    550 		case GL_RGBA8:          return GL_RGBA;
    551 		case GL_RGB565:         return GL_RGBA;
    552 		case GL_RGB8:           return GL_RGB;
    553 		case GL_R8:             return GL_RED;
    554 		case GL_RG8:            return GL_RG;
    555 		case GL_R8I:            return GL_RED_INTEGER;
    556 		case GL_RG8I:           return GL_RG_INTEGER;
    557 		case GL_RGB8I:          return GL_RGB_INTEGER;
    558 		case GL_RGBA8I:         return GL_RGBA_INTEGER;
    559 		case GL_R8UI:           return GL_RED_INTEGER;
    560 		case GL_RG8UI:          return GL_RG_INTEGER;
    561 		case GL_RGB8UI:         return GL_RGB_INTEGER;
    562 		case GL_RGBA8UI:        return GL_RGBA_INTEGER;
    563 		case GL_R16I:           return GL_RED_INTEGER;
    564 		case GL_RG16I:          return GL_RG_INTEGER;
    565 		case GL_RGB16I:         return GL_RGB_INTEGER;
    566 		case GL_RGBA16I:        return GL_RGBA_INTEGER;
    567 		case GL_R16UI:          return GL_RED_INTEGER;
    568 		case GL_RG16UI:         return GL_RG_INTEGER;
    569 		case GL_RGB16UI:        return GL_RGB_INTEGER;
    570 		case GL_RGB10_A2UI:     return GL_RGBA_INTEGER;
    571 		case GL_RGBA16UI:       return GL_RGBA_INTEGER;
    572 		case GL_R32I:           return GL_RED_INTEGER;
    573 		case GL_RG32I:          return GL_RG_INTEGER;
    574 		case GL_RGB32I:         return GL_RGB_INTEGER;
    575 		case GL_RGBA32I:        return GL_RGBA_INTEGER;
    576 		case GL_R32UI:          return GL_RED_INTEGER;
    577 		case GL_RG32UI:         return GL_RG_INTEGER;
    578 		case GL_RGB32UI:        return GL_RGB_INTEGER;
    579 		case GL_RGBA32UI:       return GL_RGBA_INTEGER;
    580 		case GL_R16F:           return GL_RED;
    581 		case GL_RG16F:          return GL_RG;
    582 		case GL_R11F_G11F_B10F: return GL_RGB;
    583 		case GL_RGB16F:         return GL_RGB;
    584 		case GL_RGBA16F:        return GL_RGBA;
    585 		case GL_R32F:           return GL_RED;
    586 		case GL_RG32F:          return GL_RG;
    587 		case GL_RGB32F:         return GL_RGB;
    588 		case GL_RGBA32F:        return GL_RGBA;
    589 		case GL_RGB10_A2:       return GL_RGBA;
    590 		case GL_SRGB8:          return GL_RGB;
    591 		case GL_SRGB8_ALPHA8:   return GL_RGBA;
    592 		default:
    593 			UNREACHABLE(colorbuffer->getFormat());
    594 		}
    595 	}
    596 
    597 	return GL_RGBA;
    598 }
    599 
    600 GLenum Framebuffer::getImplementationColorReadType() const
    601 {
    602 	Renderbuffer *colorbuffer = getReadColorbuffer();
    603 
    604 	if(colorbuffer)
    605 	{
    606 		switch(colorbuffer->getFormat())
    607 		{
    608 		case GL_BGRA8_EXT:      return GL_UNSIGNED_BYTE;
    609 		case GL_RGBA4:          return GL_UNSIGNED_SHORT_4_4_4_4;
    610 		case GL_RGB5_A1:        return GL_UNSIGNED_SHORT_5_5_5_1;
    611 		case GL_RGBA8:          return GL_UNSIGNED_BYTE;
    612 		case GL_RGB565:         return GL_UNSIGNED_SHORT_5_6_5;
    613 		case GL_RGB8:           return GL_UNSIGNED_BYTE;
    614 		case GL_R8:             return GL_UNSIGNED_BYTE;
    615 		case GL_RG8:            return GL_UNSIGNED_BYTE;
    616 		case GL_R8I:            return GL_INT;
    617 		case GL_RG8I:           return GL_INT;
    618 		case GL_RGB8I:          return GL_INT;
    619 		case GL_RGBA8I:         return GL_INT;
    620 		case GL_R8UI:           return GL_UNSIGNED_BYTE;
    621 		case GL_RG8UI:          return GL_UNSIGNED_BYTE;
    622 		case GL_RGB8UI:         return GL_UNSIGNED_BYTE;
    623 		case GL_RGBA8UI:        return GL_UNSIGNED_BYTE;
    624 		case GL_R16I:           return GL_INT;
    625 		case GL_RG16I:          return GL_INT;
    626 		case GL_RGB16I:         return GL_INT;
    627 		case GL_RGBA16I:        return GL_INT;
    628 		case GL_R16UI:          return GL_UNSIGNED_INT;
    629 		case GL_RG16UI:         return GL_UNSIGNED_INT;
    630 		case GL_RGB16UI:        return GL_UNSIGNED_INT;
    631 		case GL_RGB10_A2UI:     return GL_UNSIGNED_INT_2_10_10_10_REV;
    632 		case GL_RGBA16UI:       return GL_UNSIGNED_INT;
    633 		case GL_R32I:           return GL_INT;
    634 		case GL_RG32I:          return GL_INT;
    635 		case GL_RGB32I:         return GL_INT;
    636 		case GL_RGBA32I:        return GL_INT;
    637 		case GL_R32UI:          return GL_UNSIGNED_INT;
    638 		case GL_RG32UI:         return GL_UNSIGNED_INT;
    639 		case GL_RGB32UI:        return GL_UNSIGNED_INT;
    640 		case GL_RGBA32UI:       return GL_UNSIGNED_INT;
    641 		case GL_R16F:           return GL_FLOAT;
    642 		case GL_RG16F:          return GL_FLOAT;
    643 		case GL_R11F_G11F_B10F: return GL_FLOAT;
    644 		case GL_RGB16F:         return GL_FLOAT;
    645 		case GL_RGBA16F:        return GL_FLOAT;
    646 		case GL_R32F:           return GL_FLOAT;
    647 		case GL_RG32F:          return GL_FLOAT;
    648 		case GL_RGB32F:         return GL_FLOAT;
    649 		case GL_RGBA32F:        return GL_FLOAT;
    650 		case GL_RGB10_A2:       return GL_UNSIGNED_INT_2_10_10_10_REV;
    651 		case GL_SRGB8:          return GL_UNSIGNED_BYTE;
    652 		case GL_SRGB8_ALPHA8:   return GL_UNSIGNED_BYTE;
    653 		default:
    654 			UNREACHABLE(colorbuffer->getFormat());
    655 		}
    656 	}
    657 
    658 	return GL_UNSIGNED_BYTE;
    659 }
    660 
    661 GLenum Framebuffer::getDepthReadFormat() const
    662 {
    663 	Renderbuffer *depthbuffer = getDepthbuffer();
    664 
    665 	if(depthbuffer)
    666 	{
    667 		// There is only one depth read format.
    668 		return GL_DEPTH_COMPONENT;
    669 	}
    670 
    671 	// If there is no depth buffer, GL_INVALID_OPERATION occurs.
    672 	return GL_NONE;
    673 }
    674 
    675 GLenum Framebuffer::getDepthReadType() const
    676 {
    677 	Renderbuffer *depthbuffer = getDepthbuffer();
    678 
    679 	if(depthbuffer)
    680 	{
    681 		switch(depthbuffer->getFormat())
    682 		{
    683 		case GL_DEPTH_COMPONENT16:     return GL_UNSIGNED_SHORT;
    684 		case GL_DEPTH_COMPONENT24:     return GL_UNSIGNED_INT;
    685 		case GL_DEPTH_COMPONENT32_OES: return GL_UNSIGNED_INT;
    686 		case GL_DEPTH_COMPONENT32F:    return GL_FLOAT;
    687 		case GL_DEPTH24_STENCIL8:      return GL_UNSIGNED_INT_24_8_OES;
    688 		case GL_DEPTH32F_STENCIL8:     return GL_FLOAT;
    689 		default:
    690 			UNREACHABLE(depthbuffer->getFormat());
    691 		}
    692 	}
    693 
    694 	// If there is no depth buffer, GL_INVALID_OPERATION occurs.
    695 	return GL_NONE;
    696 }
    697 
    698 GLuint Framebuffer::getReadBufferIndex() const
    699 {
    700 	switch(readBuffer)
    701 	{
    702 	case GL_BACK:
    703 		return 0;
    704 	case GL_NONE:
    705 		return GL_INVALID_INDEX;
    706 	default:
    707 		return readBuffer - GL_COLOR_ATTACHMENT0;
    708 	}
    709 }
    710 
    711 DefaultFramebuffer::DefaultFramebuffer()
    712 {
    713 	readBuffer = GL_BACK;
    714 	drawBuffer[0] = GL_BACK;
    715 }
    716 
    717 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
    718 {
    719 	GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
    720 	mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer);
    721 	mColorbufferType[0] = defaultRenderbufferType;
    722 
    723 	readBuffer = GL_BACK;
    724 	drawBuffer[0] = GL_BACK;
    725 	for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
    726 	{
    727 		mColorbufferPointer[i] = nullptr;
    728 		mColorbufferType[i] = GL_NONE;
    729 	}
    730 
    731 	Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
    732 	mDepthbufferPointer = depthStencilRenderbuffer;
    733 	mStencilbufferPointer = depthStencilRenderbuffer;
    734 
    735 	mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? defaultRenderbufferType : GL_NONE;
    736 	mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? defaultRenderbufferType : GL_NONE;
    737 }
    738 
    739 }
    740