1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
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.
18 #include "Framebuffer.h"
21 #include "Renderbuffer.h"
23 #include "utilities.h"
28 bool Framebuffer::IsRenderbuffer(GLenum type)
30 return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT;
33 Framebuffer::Framebuffer()
35 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
37 mColorbufferType[i] = GL_NONE;
39 mDepthbufferType = GL_NONE;
40 mStencilbufferType = GL_NONE;
43 drawBuffer[0] = GL_BACK;
44 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; ++i)
46 drawBuffer[i] = GL_NONE;
50 Framebuffer::~Framebuffer()
52 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
54 mColorbufferPointer[i] = nullptr;
56 mDepthbufferPointer = nullptr;
57 mStencilbufferPointer = nullptr;
60 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const
62 Context *context = getContext();
63 Renderbuffer *buffer = nullptr;
69 else if(IsRenderbuffer(type))
71 buffer = context->getRenderbuffer(handle);
73 else if(IsTextureTarget(type))
75 buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer);
77 else UNREACHABLE(type);
82 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer)
84 mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
85 mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer);
88 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
90 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
91 mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level, layer);
94 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
96 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
97 mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level, layer);
100 void Framebuffer::setReadBuffer(GLenum buf)
105 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf)
107 drawBuffer[index] = buf;
110 GLenum Framebuffer::getReadBuffer() const
115 GLenum Framebuffer::getDrawBuffer(GLuint index) const
117 return drawBuffer[index];
120 void Framebuffer::detachTexture(GLuint texture)
122 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
124 if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i]))
126 mColorbufferType[i] = GL_NONE;
127 mColorbufferPointer[i] = nullptr;
131 if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
133 mDepthbufferType = GL_NONE;
134 mDepthbufferPointer = nullptr;
137 if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
139 mStencilbufferType = GL_NONE;
140 mStencilbufferPointer = nullptr;
144 void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
146 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
148 if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i]))
150 mColorbufferType[i] = GL_NONE;
151 mColorbufferPointer[i] = nullptr;
155 if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType))
157 mDepthbufferType = GL_NONE;
158 mDepthbufferPointer = nullptr;
161 if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType))
163 mStencilbufferType = GL_NONE;
164 mStencilbufferPointer = nullptr;
168 // Increments refcount on surface.
169 // caller must Release() the returned surface
170 egl::Image *Framebuffer::getRenderTarget(GLuint index)
172 Renderbuffer *colorbuffer = mColorbufferPointer[index];
176 return colorbuffer->getRenderTarget();
182 egl::Image *Framebuffer::getReadRenderTarget()
184 Context *context = getContext();
185 return getRenderTarget(context->getReadFramebufferColorIndex());
188 // Increments refcount on surface.
189 // caller must Release() the returned surface
190 egl::Image *Framebuffer::getDepthBuffer()
192 Renderbuffer *depthbuffer = mDepthbufferPointer;
196 return depthbuffer->getRenderTarget();
202 // Increments refcount on surface.
203 // caller must Release() the returned surface
204 egl::Image *Framebuffer::getStencilBuffer()
206 Renderbuffer *stencilbuffer = mStencilbufferPointer;
210 return stencilbuffer->getRenderTarget();
216 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const
218 return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr;
221 Renderbuffer *Framebuffer::getReadColorbuffer() const
223 Context *context = getContext();
224 return getColorbuffer(context->getReadFramebufferColorIndex());
227 Renderbuffer *Framebuffer::getDepthbuffer() const
229 return mDepthbufferPointer;
232 Renderbuffer *Framebuffer::getStencilbuffer() const
234 return mStencilbufferPointer;
237 GLenum Framebuffer::getColorbufferType(GLuint index)
239 return mColorbufferType[index];
242 GLenum Framebuffer::getDepthbufferType()
244 return mDepthbufferType;
247 GLenum Framebuffer::getStencilbufferType()
249 return mStencilbufferType;
252 GLuint Framebuffer::getColorbufferName(GLuint index)
254 return mColorbufferPointer[index].name();
257 GLuint Framebuffer::getDepthbufferName()
259 return mDepthbufferPointer.name();
262 GLuint Framebuffer::getStencilbufferName()
264 return mStencilbufferPointer.name();
267 GLint Framebuffer::getColorbufferLayer(GLuint index)
269 Renderbuffer *colorbuffer = mColorbufferPointer[index];
270 return colorbuffer ? colorbuffer->getLayer() : 0;
273 GLint Framebuffer::getDepthbufferLayer()
275 return mDepthbufferPointer ? mDepthbufferPointer->getLayer() : 0;
278 GLint Framebuffer::getStencilbufferLayer()
280 return mStencilbufferPointer ? mStencilbufferPointer->getLayer() : 0;
283 bool Framebuffer::hasStencil()
285 if(mStencilbufferType != GL_NONE)
287 Renderbuffer *stencilbufferObject = getStencilbuffer();
289 if(stencilbufferObject)
291 return stencilbufferObject->getStencilSize() > 0;
298 GLenum Framebuffer::completeness()
304 return completeness(width, height, samples);
307 GLenum Framebuffer::completeness(int &width, int &height, int &samples)
313 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
315 if(mColorbufferType[i] != GL_NONE)
317 Renderbuffer *colorbuffer = getColorbuffer(i);
321 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
324 if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= colorbuffer->getLayer()))
326 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
329 if(IsRenderbuffer(mColorbufferType[i]))
331 if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion()))
333 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
336 else if(IsTextureTarget(mColorbufferType[i]))
338 GLenum format = colorbuffer->getFormat();
340 if(!IsColorRenderable(format, egl::getClientVersion()))
342 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
345 if(IsDepthTexture(format) || IsStencilTexture(format))
347 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
352 UNREACHABLE(mColorbufferType[i]);
353 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
356 width = colorbuffer->getWidth();
357 height = colorbuffer->getHeight();
361 samples = colorbuffer->getSamples();
363 else if(samples != colorbuffer->getSamples())
365 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
370 Renderbuffer *depthbuffer = nullptr;
371 Renderbuffer *stencilbuffer = nullptr;
373 if(mDepthbufferType != GL_NONE)
375 depthbuffer = getDepthbuffer();
379 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
382 if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
384 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
387 if(IsRenderbuffer(mDepthbufferType))
389 if(!es2::IsDepthRenderable(depthbuffer->getFormat()))
391 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
394 else if(IsTextureTarget(mDepthbufferType))
396 if(!es2::IsDepthTexture(depthbuffer->getFormat()))
398 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
403 UNREACHABLE(mDepthbufferType);
404 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
407 if(width == -1 || height == -1)
409 width = depthbuffer->getWidth();
410 height = depthbuffer->getHeight();
411 samples = depthbuffer->getSamples();
413 else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
415 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
417 else if(samples != depthbuffer->getSamples())
419 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
423 if(mStencilbufferType != GL_NONE)
425 stencilbuffer = getStencilbuffer();
429 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
432 if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
434 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
437 if(IsRenderbuffer(mStencilbufferType))
439 if(!es2::IsStencilRenderable(stencilbuffer->getFormat()))
441 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
444 else if(IsTextureTarget(mStencilbufferType))
446 GLenum internalformat = stencilbuffer->getFormat();
448 if(!es2::IsStencilTexture(internalformat))
450 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
455 UNREACHABLE(mStencilbufferType);
456 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
459 if(width == -1 || height == -1)
461 width = stencilbuffer->getWidth();
462 height = stencilbuffer->getHeight();
463 samples = stencilbuffer->getSamples();
465 else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
467 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
469 else if(samples != stencilbuffer->getSamples())
471 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
475 if((egl::getClientVersion() >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
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:
480 // Depth and stencil attachments, if present, are the same image.
481 // { FRAMEBUFFER_UNSUPPORTED }"
482 return GL_FRAMEBUFFER_UNSUPPORTED;
485 // We need to have at least one attachment to be complete
486 if(width == -1 || height == -1)
488 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
491 return GL_FRAMEBUFFER_COMPLETE;
494 GLenum Framebuffer::getImplementationColorReadFormat() const
496 Renderbuffer *colorbuffer = getReadColorbuffer();
500 switch(colorbuffer->getInternalFormat())
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;
550 UNREACHABLE(colorbuffer->getInternalFormat());
557 GLenum Framebuffer::getImplementationColorReadType() const
559 Renderbuffer *colorbuffer = getReadColorbuffer();
563 switch(colorbuffer->getInternalFormat())
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;
614 UNREACHABLE(colorbuffer->getInternalFormat());
618 return GL_UNSIGNED_BYTE;
621 GLenum Framebuffer::getDepthReadFormat() const
623 Renderbuffer *depthbuffer = getDepthbuffer();
627 // There is only one depth read format.
628 return GL_DEPTH_COMPONENT;
631 // If there is no depth buffer, GL_INVALID_OPERATION occurs.
635 GLenum Framebuffer::getDepthReadType() const
637 Renderbuffer *depthbuffer = getDepthbuffer();
641 switch(depthbuffer->getInternalFormat())
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;
652 UNREACHABLE(depthbuffer->getInternalFormat());
656 // If there is no depth buffer, GL_INVALID_OPERATION occurs.
660 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
662 GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
663 mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer);
664 mColorbufferType[0] = defaultRenderbufferType;
666 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
668 mColorbufferPointer[i] = nullptr;
669 mColorbufferType[i] = GL_NONE;
672 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
673 mDepthbufferPointer = depthStencilRenderbuffer;
674 mStencilbufferPointer = depthStencilRenderbuffer;
676 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? defaultRenderbufferType : GL_NONE;
677 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? defaultRenderbufferType : GL_NONE;