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 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