blob: e209dee69ff3f9c916b23b1dabd322c80bfe9e06 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002//
Geoff Langcec35902014-04-16 10:52:36 -04003// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
9// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
10
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000012
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013#include "libGLESv2/main.h"
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000014#include "common/utilities.h"
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +000015#include "libGLESv2/formatutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000016#include "libGLESv2/Texture.h"
17#include "libGLESv2/Context.h"
18#include "libGLESv2/renderer/Renderer.h"
19#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020
21namespace gl
22{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000023
daniel@transgaming.com16418b12012-11-28 19:32:22 +000024Framebuffer::Framebuffer(rx::Renderer *renderer)
25 : mRenderer(renderer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000026{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000027 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
28 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000029 mDrawBufferStates[colorAttachment] = GL_NONE;
30 }
31 mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
32 mReadBufferState = GL_COLOR_ATTACHMENT0_EXT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000033}
34
35Framebuffer::~Framebuffer()
36{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000037 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
38 {
Geoff Langc90d73a2013-07-22 16:39:23 -040039 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000040 }
Geoff Langc90d73a2013-07-22 16:39:23 -040041 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
42 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000043}
44
Jamie Madill3c7fa222014-06-05 13:08:51 -040045FramebufferAttachment *Framebuffer::lookupAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000046{
47 gl::Context *context = gl::getContext();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000048
Geoff Lang309c92a2013-07-25 16:23:19 -040049 switch (type)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000050 {
Geoff Lang309c92a2013-07-25 16:23:19 -040051 case GL_NONE:
52 return NULL;
53
54 case GL_RENDERBUFFER:
55 return context->getRenderbuffer(handle);
56
57 case GL_TEXTURE_2D:
58 {
59 Texture *texture = context->getTexture(handle);
60 if (texture && texture->getTarget() == GL_TEXTURE_2D)
61 {
Jamie Madill3c7fa222014-06-05 13:08:51 -040062 return static_cast<Texture2D*>(texture)->getAttachment(level);
Geoff Lang309c92a2013-07-25 16:23:19 -040063 }
64 else
65 {
66 return NULL;
67 }
68 }
69
70 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
71 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
72 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
73 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
74 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
75 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
76 {
77 Texture *texture = context->getTexture(handle);
78 if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
79 {
Jamie Madill3c7fa222014-06-05 13:08:51 -040080 return static_cast<TextureCubeMap*>(texture)->getAttachment(type, level);
Geoff Lang309c92a2013-07-25 16:23:19 -040081 }
82 else
83 {
84 return NULL;
85 }
86 }
87
88 case GL_TEXTURE_3D:
89 {
90 Texture *texture = context->getTexture(handle);
91 if (texture && texture->getTarget() == GL_TEXTURE_3D)
92 {
Jamie Madill3c7fa222014-06-05 13:08:51 -040093 return static_cast<Texture3D*>(texture)->getAttachment(level, layer);
Geoff Lang309c92a2013-07-25 16:23:19 -040094 }
95 else
96 {
97 return NULL;
98 }
99 }
100
101 case GL_TEXTURE_2D_ARRAY:
102 {
103 Texture *texture = context->getTexture(handle);
104 if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
105 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400106 return static_cast<Texture2DArray*>(texture)->getAttachment(level, layer);
Geoff Lang309c92a2013-07-25 16:23:19 -0400107 }
108 else
109 {
110 return NULL;
111 }
112 }
113
114 default:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000115 UNREACHABLE();
Geoff Lang309c92a2013-07-25 16:23:19 -0400116 return NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000117 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000118}
119
Geoff Lang309c92a2013-07-25 16:23:19 -0400120void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000121{
122 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madill3c7fa222014-06-05 13:08:51 -0400123 FramebufferAttachment *attachment = lookupAttachment(type, colorbuffer, level, layer);
124 if (attachment)
Geoff Langc90d73a2013-07-22 16:39:23 -0400125 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400126 mColorbuffers[colorAttachment].set(attachment, type, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400127 }
128 else
129 {
130 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
131 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000132}
133
Geoff Lang309c92a2013-07-25 16:23:19 -0400134void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400136 FramebufferAttachment *attachment = lookupAttachment(type, depthbuffer, level, layer);
137 if (attachment)
Geoff Langc90d73a2013-07-22 16:39:23 -0400138 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400139 mDepthbuffer.set(attachment, type, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400140 }
141 else
142 {
143 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
144 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000145}
146
Geoff Lang309c92a2013-07-25 16:23:19 -0400147void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000148{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400149 FramebufferAttachment *attachment = lookupAttachment(type, stencilbuffer, level, layer);
150 if (attachment)
Geoff Langc90d73a2013-07-22 16:39:23 -0400151 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400152 mStencilbuffer.set(attachment, type, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400153 }
154 else
155 {
156 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158}
159
Geoff Lang309c92a2013-07-25 16:23:19 -0400160void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400161{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400162 FramebufferAttachment *attachment = lookupAttachment(type, depthStencilBuffer, level, layer);
163 if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400164 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400165 mDepthbuffer.set(attachment, type, level, layer);
166 mStencilbuffer.set(attachment, type, level, layer);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400167 }
168 else
169 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400170 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
171 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400172 }
173}
174
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000175void Framebuffer::detachTexture(GLuint texture)
176{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000177 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400179 if (mColorbuffers[colorAttachment].id() == texture &&
Geoff Lang0fe19492013-07-25 17:04:31 -0400180 IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000181 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400182 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000183 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000185
Geoff Lang0fe19492013-07-25 17:04:31 -0400186 if (mDepthbuffer.id() == texture && IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000187 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400188 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000189 }
190
Geoff Lang0fe19492013-07-25 17:04:31 -0400191 if (mStencilbuffer.id() == texture && IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000192 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400193 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000194 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000195}
196
197void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
198{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000199 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000200 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400201 if (mColorbuffers[colorAttachment].id() == renderbuffer && mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000202 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400203 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000204 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000205 }
206
Geoff Langc90d73a2013-07-22 16:39:23 -0400207 if (mDepthbuffer.id() == renderbuffer && mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400209 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210 }
211
Geoff Langc90d73a2013-07-22 16:39:23 -0400212 if (mStencilbuffer.id() == renderbuffer && mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000213 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400214 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000215 }
216}
217
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000218unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000219{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000220 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
221
Jamie Madill3c7fa222014-06-05 13:08:51 -0400222 FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment].get();
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000223
224 if (colorbuffer)
225 {
226 return colorbuffer->getSerial();
227 }
228
229 return 0;
230}
231
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000232unsigned int Framebuffer::getDepthbufferSerial() const
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000233{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400234 FramebufferAttachment *depthbuffer = mDepthbuffer.get();
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000235
236 if (depthbuffer)
237 {
238 return depthbuffer->getSerial();
239 }
240
241 return 0;
242}
243
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000244unsigned int Framebuffer::getStencilbufferSerial() const
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000245{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400246 FramebufferAttachment *stencilbuffer = mStencilbuffer.get();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000247
248 if (stencilbuffer)
249 {
250 return stencilbuffer->getSerial();
251 }
252
253 return 0;
254}
255
Jamie Madill3c7fa222014-06-05 13:08:51 -0400256FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000257{
258 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400259 return mColorbuffers[colorAttachment].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000260}
261
Jamie Madill3c7fa222014-06-05 13:08:51 -0400262FramebufferAttachment *Framebuffer::getDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263{
Geoff Langc90d73a2013-07-22 16:39:23 -0400264 return mDepthbuffer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265}
266
Jamie Madill3c7fa222014-06-05 13:08:51 -0400267FramebufferAttachment *Framebuffer::getStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268{
Geoff Langc90d73a2013-07-22 16:39:23 -0400269 return mStencilbuffer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000270}
271
Jamie Madill3c7fa222014-06-05 13:08:51 -0400272FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
Geoff Lang646559f2013-08-15 11:08:15 -0400273{
274 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL;
275}
276
Jamie Madill3c7fa222014-06-05 13:08:51 -0400277FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000278{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400279 FramebufferAttachment *depthstencilbuffer = mDepthbuffer.get();
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000280
281 if (!depthstencilbuffer)
282 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400283 depthstencilbuffer = mStencilbuffer.get();
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000284 }
285
286 return depthstencilbuffer;
287}
288
Jamie Madill3c7fa222014-06-05 13:08:51 -0400289FramebufferAttachment *Framebuffer::getReadColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000290{
291 // Will require more logic if glReadBuffers is supported
Geoff Langc90d73a2013-07-22 16:39:23 -0400292 return mColorbuffers[0].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000293}
294
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000295GLenum Framebuffer::getReadColorbufferType() const
296{
297 // Will require more logic if glReadBuffers is supported
Geoff Langc90d73a2013-07-22 16:39:23 -0400298 return mColorbuffers[0].type();
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000299}
300
Jamie Madill3c7fa222014-06-05 13:08:51 -0400301FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000302{
303 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
304 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400305 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000306 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400307 return mColorbuffers[colorAttachment].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000308 }
309 }
310
311 return NULL;
312}
313
314GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
315{
316 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400317 return mColorbuffers[colorAttachment].type();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000318}
319
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000320GLenum Framebuffer::getDepthbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000321{
Geoff Langc90d73a2013-07-22 16:39:23 -0400322 return mDepthbuffer.type();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000323}
324
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000325GLenum Framebuffer::getStencilbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000326{
Geoff Langc90d73a2013-07-22 16:39:23 -0400327 return mStencilbuffer.type();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000328}
329
Geoff Lang55ba29c2013-07-11 16:57:53 -0400330GLenum Framebuffer::getDepthStencilbufferType() const
331{
Geoff Langc90d73a2013-07-22 16:39:23 -0400332 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.type() : GL_NONE;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400333}
334
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000335GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
336{
337 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400338 return mColorbuffers[colorAttachment].id();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000339}
340
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000341GLuint Framebuffer::getDepthbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000342{
Geoff Langc90d73a2013-07-22 16:39:23 -0400343 return mDepthbuffer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000344}
345
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000346GLuint Framebuffer::getStencilbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000347{
Geoff Langc90d73a2013-07-22 16:39:23 -0400348 return mStencilbuffer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000349}
350
Geoff Lang55ba29c2013-07-11 16:57:53 -0400351GLenum Framebuffer::getDepthStencilbufferHandle() const
352{
Geoff Langc90d73a2013-07-22 16:39:23 -0400353 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.id() : 0;
354}
355
356GLenum Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
357{
358 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
359 return mColorbuffers[colorAttachment].mipLevel();
360}
361
362GLenum Framebuffer::getDepthbufferMipLevel() const
363{
364 return mDepthbuffer.mipLevel();
365}
366
367GLenum Framebuffer::getStencilbufferMipLevel() const
368{
369 return mStencilbuffer.mipLevel();
370}
371
372GLenum Framebuffer::getDepthStencilbufferMipLevel() const
373{
374 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.mipLevel() : 0;
375}
376
377GLenum Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
378{
379 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
380 return mColorbuffers[colorAttachment].layer();
381}
382
383GLenum Framebuffer::getDepthbufferLayer() const
384{
385 return mDepthbuffer.layer();
386}
387
388GLenum Framebuffer::getStencilbufferLayer() const
389{
390 return mStencilbuffer.layer();
391}
392
393GLenum Framebuffer::getDepthStencilbufferLayer() const
394{
395 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.layer() : 0;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400396}
397
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000398GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
399{
400 return mDrawBufferStates[colorAttachment];
401}
402
403void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
404{
405 mDrawBufferStates[colorAttachment] = drawBuffer;
406}
407
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000408bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
409{
Geoff Langc90d73a2013-07-22 16:39:23 -0400410 return (mColorbuffers[colorAttachment].type() != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000411}
412
413bool Framebuffer::hasEnabledColorAttachment() const
414{
415 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
416 {
417 if (isEnabledColorAttachment(colorAttachment))
418 {
419 return true;
420 }
421 }
422
423 return false;
424}
425
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000426bool Framebuffer::hasStencil() const
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000427{
Geoff Langc90d73a2013-07-22 16:39:23 -0400428 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000429 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400430 const FramebufferAttachment *stencilbufferObject = getStencilbuffer();
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000431
432 if (stencilbufferObject)
433 {
434 return stencilbufferObject->getStencilSize() > 0;
435 }
436 }
437
438 return false;
439}
440
shannonwoods@chromium.org24ac8502013-05-30 00:01:37 +0000441bool Framebuffer::usingExtendedDrawBuffers() const
442{
443 for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
444 {
445 if (isEnabledColorAttachment(colorAttachment))
446 {
447 return true;
448 }
449 }
450
451 return false;
452}
453
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000454GLenum Framebuffer::completeness() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000455{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000456 int width = 0;
457 int height = 0;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000458 unsigned int colorbufferSize = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000459 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000460 bool missingAttachment = true;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000461 GLuint clientVersion = mRenderer->getCurrentClientVersion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000462
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000463 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000464 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400465 if (mColorbuffers[colorAttachment].type() != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000466 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400467 const FramebufferAttachment *colorbuffer = getColorbuffer(colorAttachment);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000469 if (!colorbuffer)
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000470 {
471 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
472 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000473
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000474 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000475 {
476 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
477 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000478
Geoff Langcec35902014-04-16 10:52:36 -0400479 GLenum internalformat = colorbuffer->getInternalFormat();
480 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400481 if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000482 {
Geoff Langcec35902014-04-16 10:52:36 -0400483 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000484 {
485 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
486 }
487 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400488 else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000489 {
Geoff Langcec35902014-04-16 10:52:36 -0400490 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000491 {
492 return GL_FRAMEBUFFER_UNSUPPORTED;
493 }
494
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000495 if (gl::GetDepthBits(internalformat, clientVersion) > 0 ||
496 gl::GetStencilBits(internalformat, clientVersion) > 0)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000497 {
498 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
499 }
500 }
501 else
502 {
503 UNREACHABLE();
504 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
505 }
506
507 if (!missingAttachment)
508 {
509 // all color attachments must have the same width and height
510 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
511 {
512 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
513 }
514
515 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
516 // all color attachments have the same number of samples for the FBO to be complete.
517 if (colorbuffer->getSamples() != samples)
518 {
519 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
520 }
521
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000522 // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
523 // in GLES 3.0, there is no such restriction
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000524 if (clientVersion < 3)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000525 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000526 if (gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion) != colorbufferSize)
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000527 {
528 return GL_FRAMEBUFFER_UNSUPPORTED;
529 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000530 }
531
532 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
533 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
534 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400535 if (mColorbuffers[colorAttachment].get() == mColorbuffers[previousColorAttachment].get())
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000536 {
537 return GL_FRAMEBUFFER_UNSUPPORTED;
538 }
539 }
540 }
541 else
542 {
543 width = colorbuffer->getWidth();
544 height = colorbuffer->getHeight();
545 samples = colorbuffer->getSamples();
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000546 colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000547 missingAttachment = false;
548 }
549 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000550 }
551
Jamie Madill3c7fa222014-06-05 13:08:51 -0400552 const FramebufferAttachment *depthbuffer = NULL;
553 const FramebufferAttachment *stencilbuffer = NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000554
Geoff Langc90d73a2013-07-22 16:39:23 -0400555 if (mDepthbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000556 {
557 depthbuffer = getDepthbuffer();
558
559 if (!depthbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000560 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000561 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000562 }
563
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000564 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000566 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
567 }
568
Geoff Langcec35902014-04-16 10:52:36 -0400569 GLenum internalformat = depthbuffer->getInternalFormat();
570 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400571 if (mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000572 {
Geoff Langcec35902014-04-16 10:52:36 -0400573 if (!formatCaps.depthRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000574 {
575 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
576 }
577 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400578 else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000579 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000580 // depth texture attachments require OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400581 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000582 {
583 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
584 }
585
Geoff Langcec35902014-04-16 10:52:36 -0400586 if (!formatCaps.depthRendering)
587 {
588 return GL_FRAMEBUFFER_UNSUPPORTED;
589 }
590
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000591 if (gl::GetDepthBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000592 {
593 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
594 }
595 }
596 else
597 {
598 UNREACHABLE();
599 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
600 }
601
602 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000603 {
604 width = depthbuffer->getWidth();
605 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000606 samples = depthbuffer->getSamples();
607 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000608 }
609 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
610 {
611 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
612 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000613 else if (samples != depthbuffer->getSamples())
614 {
615 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
616 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000617 }
618
Geoff Langc90d73a2013-07-22 16:39:23 -0400619 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000620 {
621 stencilbuffer = getStencilbuffer();
622
623 if (!stencilbuffer)
624 {
625 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
626 }
627
628 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
629 {
630 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
631 }
632
Geoff Langcec35902014-04-16 10:52:36 -0400633 GLenum internalformat = stencilbuffer->getInternalFormat();
634 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400635 if (mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000636 {
Geoff Langcec35902014-04-16 10:52:36 -0400637 if (!formatCaps.stencilRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000638 {
639 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
640 }
641 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400642 else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000643 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000644 // texture stencil attachments come along as part
645 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400646 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000647 {
648 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
649 }
650
Geoff Langcec35902014-04-16 10:52:36 -0400651 if (!formatCaps.stencilRendering)
652 {
653 return GL_FRAMEBUFFER_UNSUPPORTED;
654 }
655
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000656 if (gl::GetStencilBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000657 {
658 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
659 }
660 }
661 else
662 {
663 UNREACHABLE();
664 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
665 }
666
667 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000668 {
669 width = stencilbuffer->getWidth();
670 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000671 samples = stencilbuffer->getSamples();
672 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000673 }
674 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
675 {
676 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
677 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000678 else if (samples != stencilbuffer->getSamples())
679 {
680 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
681 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000682 }
683
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000684 // if we have both a depth and stencil buffer, they must refer to the same object
685 // since we only support packed_depth_stencil and not separate depth and stencil
686 if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000687 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000688 return GL_FRAMEBUFFER_UNSUPPORTED;
689 }
690
691 // we need to have at least one attachment to be complete
692 if (missingAttachment)
693 {
694 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000695 }
696
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000697 return GL_FRAMEBUFFER_COMPLETE;
698}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000699
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000700DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
701 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000702{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400703 mColorbuffers[0].set(new FramebufferAttachment(mRenderer, 0, colorbuffer), GL_RENDERBUFFER, 0, 0);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000704
Jamie Madill3c7fa222014-06-05 13:08:51 -0400705 FramebufferAttachment *depthStencilRenderbuffer = new FramebufferAttachment(mRenderer, 0, depthStencil);
Geoff Langc90d73a2013-07-22 16:39:23 -0400706 mDepthbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
707 mStencilbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000708
709 mDrawBufferStates[0] = GL_BACK;
710 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000711}
712
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000713int Framebuffer::getSamples() const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000714{
715 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
716 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000717 // for a complete framebuffer, all attachments must have the same sample count
718 // in this case return the first nonzero sample size
719 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
720 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400721 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000722 {
723 return getColorbuffer(colorAttachment)->getSamples();
724 }
725 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000726 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000727
728 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000729}
730
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000731GLenum DefaultFramebuffer::completeness() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000732{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000733 // The default framebuffer *must* always be complete, though it may not be
734 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000735 return GL_FRAMEBUFFER_COMPLETE;
736}
737
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000738}