• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IsRenderbuffer(GLenum type)28 bool Framebuffer::IsRenderbuffer(GLenum type)
29 {
30 	return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT;
31 }
32 
Framebuffer()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 
~Framebuffer()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 
lookupRenderbuffer(GLenum type,GLuint handle,GLint level,GLint layer) const60 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 
setColorbuffer(GLenum type,GLuint colorbuffer,GLuint index,GLint level,GLint layer)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 
setDepthbuffer(GLenum type,GLuint depthbuffer,GLint level,GLint layer)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 
setStencilbuffer(GLenum type,GLuint stencilbuffer,GLint level,GLint layer)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 
setReadBuffer(GLenum buf)100 void Framebuffer::setReadBuffer(GLenum buf)
101 {
102 	readBuffer = buf;
103 }
104 
setDrawBuffer(GLuint index,GLenum buf)105 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf)
106 {
107 	drawBuffer[index] = buf;
108 }
109 
getReadBuffer() const110 GLenum Framebuffer::getReadBuffer() const
111 {
112 	return readBuffer;
113 }
114 
getDrawBuffer(GLuint index) const115 GLenum Framebuffer::getDrawBuffer(GLuint index) const
116 {
117 	return drawBuffer[index];
118 }
119 
detachTexture(GLuint texture)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 
detachRenderbuffer(GLuint renderbuffer)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
getRenderTarget(GLuint index)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 
getReadRenderTarget()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
getDepthBuffer()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
getStencilBuffer()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 
getColorbuffer(GLuint index) const216 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const
217 {
218 	return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr;
219 }
220 
getReadColorbuffer() const221 Renderbuffer *Framebuffer::getReadColorbuffer() const
222 {
223 	Context *context = getContext();
224 	return getColorbuffer(context->getReadFramebufferColorIndex());
225 }
226 
getDepthbuffer() const227 Renderbuffer *Framebuffer::getDepthbuffer() const
228 {
229 	return mDepthbufferPointer;
230 }
231 
getStencilbuffer() const232 Renderbuffer *Framebuffer::getStencilbuffer() const
233 {
234 	return mStencilbufferPointer;
235 }
236 
getColorbufferType(GLuint index)237 GLenum Framebuffer::getColorbufferType(GLuint index)
238 {
239 	return mColorbufferType[index];
240 }
241 
getDepthbufferType()242 GLenum Framebuffer::getDepthbufferType()
243 {
244 	return mDepthbufferType;
245 }
246 
getStencilbufferType()247 GLenum Framebuffer::getStencilbufferType()
248 {
249 	return mStencilbufferType;
250 }
251 
getColorbufferName(GLuint index)252 GLuint Framebuffer::getColorbufferName(GLuint index)
253 {
254 	return mColorbufferPointer[index].name();
255 }
256 
getDepthbufferName()257 GLuint Framebuffer::getDepthbufferName()
258 {
259 	return mDepthbufferPointer.name();
260 }
261 
getStencilbufferName()262 GLuint Framebuffer::getStencilbufferName()
263 {
264 	return mStencilbufferPointer.name();
265 }
266 
getColorbufferLayer(GLuint index)267 GLint Framebuffer::getColorbufferLayer(GLuint index)
268 {
269 	Renderbuffer *colorbuffer = mColorbufferPointer[index];
270 	return colorbuffer ? colorbuffer->getLayer() : 0;
271 }
272 
getDepthbufferLayer()273 GLint Framebuffer::getDepthbufferLayer()
274 {
275 	return mDepthbufferPointer ? mDepthbufferPointer->getLayer() : 0;
276 }
277 
getStencilbufferLayer()278 GLint Framebuffer::getStencilbufferLayer()
279 {
280 	return mStencilbufferPointer ? mStencilbufferPointer->getLayer() : 0;
281 }
282 
hasStencil()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 
completeness()298 GLenum Framebuffer::completeness()
299 {
300 	int width;
301 	int height;
302 	int samples;
303 
304 	return completeness(width, height, samples);
305 }
306 
completeness(int & width,int & height,int & samples)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 
getImplementationColorReadFormat() const494 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 
getImplementationColorReadType() const557 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 
getDepthReadFormat() const621 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 
getDepthReadType() const635 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 
DefaultFramebuffer(Colorbuffer * colorbuffer,DepthStencilbuffer * depthStencil)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