blob: 97d37d005add2e2ec90c06a974d5f05de85a028b [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//
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +00003// Copyright (c) 2002-2013 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
Geoff Lang309c92a2013-07-25 16:23:19 -040045Renderbuffer *Framebuffer::lookupRenderbuffer(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 {
Geoff Lang8040f572013-07-25 16:49:54 -040062 return static_cast<Texture2D*>(texture)->getRenderbuffer(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 {
Geoff Lang8040f572013-07-25 16:49:54 -040080 return static_cast<TextureCubeMap*>(texture)->getRenderbuffer(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 {
Geoff Lang8040f572013-07-25 16:49:54 -040093 return static_cast<Texture3D*>(texture)->getRenderbuffer(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 {
Geoff Lang8040f572013-07-25 16:49:54 -0400106 return static_cast<Texture2DArray*>(texture)->getRenderbuffer(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);
Geoff Lang309c92a2013-07-25 16:23:19 -0400123 Renderbuffer *renderBuffer = lookupRenderbuffer(type, colorbuffer, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400124 if (renderBuffer)
125 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400126 mColorbuffers[colorAttachment].set(renderBuffer, 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{
Geoff Lang309c92a2013-07-25 16:23:19 -0400136 Renderbuffer *renderBuffer = lookupRenderbuffer(type, depthbuffer, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400137 if (renderBuffer)
138 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400139 mDepthbuffer.set(renderBuffer, 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{
Geoff Lang309c92a2013-07-25 16:23:19 -0400149 Renderbuffer *renderBuffer = lookupRenderbuffer(type, stencilbuffer, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400150 if (renderBuffer)
151 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400152 mStencilbuffer.set(renderBuffer, 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{
Geoff Lang309c92a2013-07-25 16:23:19 -0400162 Renderbuffer *renderBuffer = lookupRenderbuffer(type, depthStencilBuffer, level, layer);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400163 if (renderBuffer && renderBuffer->getDepthSize() > 0 && renderBuffer->getStencilSize() > 0)
164 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400165 mDepthbuffer.set(renderBuffer, type, level, layer);
166 mStencilbuffer.set(renderBuffer, 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
Geoff Langc90d73a2013-07-22 16:39:23 -0400222 Renderbuffer *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{
Geoff Langc90d73a2013-07-22 16:39:23 -0400234 Renderbuffer *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{
Geoff Langc90d73a2013-07-22 16:39:23 -0400246 Renderbuffer *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
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000256Renderbuffer *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
257{
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
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000262Renderbuffer *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
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000267Renderbuffer *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
Geoff Lang646559f2013-08-15 11:08:15 -0400272Renderbuffer *Framebuffer::getDepthStencilBuffer() const
273{
274 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL;
275}
276
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000277Renderbuffer *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000278{
Geoff Langc90d73a2013-07-22 16:39:23 -0400279 Renderbuffer *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
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000289Renderbuffer *Framebuffer::getReadColorbuffer() const
290{
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
shannon.woods%transgaming.com@gtempaccount.com882434c2013-04-13 03:34:14 +0000301Renderbuffer *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 {
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000430 const Renderbuffer *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 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000467 const Renderbuffer *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 Langc90d73a2013-07-22 16:39:23 -0400479 if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000480 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000481 if (!gl::IsColorRenderingSupported(colorbuffer->getInternalFormat(), mRenderer))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000482 {
483 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
484 }
485 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400486 else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000487 {
Geoff Lang005df412013-10-16 14:12:50 -0400488 GLenum internalformat = colorbuffer->getInternalFormat();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000489
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000490 if (!gl::IsColorRenderingSupported(internalformat, mRenderer))
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
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000552 const Renderbuffer *depthbuffer = NULL;
553 const Renderbuffer *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 Langc90d73a2013-07-22 16:39:23 -0400569 if (mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000570 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000571 if (!gl::IsDepthRenderingSupported(depthbuffer->getInternalFormat(), mRenderer))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000572 {
573 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
574 }
575 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400576 else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000577 {
Geoff Lang005df412013-10-16 14:12:50 -0400578 GLenum internalformat = depthbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000579
580 // depth texture attachments require OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000581 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000582 {
583 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
584 }
585
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000586 if (gl::GetDepthBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000587 {
588 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
589 }
590 }
591 else
592 {
593 UNREACHABLE();
594 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
595 }
596
597 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000598 {
599 width = depthbuffer->getWidth();
600 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000601 samples = depthbuffer->getSamples();
602 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000603 }
604 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
605 {
606 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
607 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000608 else if (samples != depthbuffer->getSamples())
609 {
610 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
611 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000612 }
613
Geoff Langc90d73a2013-07-22 16:39:23 -0400614 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000615 {
616 stencilbuffer = getStencilbuffer();
617
618 if (!stencilbuffer)
619 {
620 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
621 }
622
623 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
624 {
625 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
626 }
627
Geoff Langc90d73a2013-07-22 16:39:23 -0400628 if (mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000629 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000630 if (!gl::IsStencilRenderingSupported(stencilbuffer->getInternalFormat(), mRenderer))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000631 {
632 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
633 }
634 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400635 else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000636 {
Geoff Lang005df412013-10-16 14:12:50 -0400637 GLenum internalformat = stencilbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000638
639 // texture stencil attachments come along as part
640 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000641 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000642 {
643 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
644 }
645
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000646 if (gl::GetStencilBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000647 {
648 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
649 }
650 }
651 else
652 {
653 UNREACHABLE();
654 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
655 }
656
657 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000658 {
659 width = stencilbuffer->getWidth();
660 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000661 samples = stencilbuffer->getSamples();
662 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000663 }
664 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
665 {
666 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
667 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000668 else if (samples != stencilbuffer->getSamples())
669 {
670 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
671 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000672 }
673
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000674 // if we have both a depth and stencil buffer, they must refer to the same object
675 // since we only support packed_depth_stencil and not separate depth and stencil
676 if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000677 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000678 return GL_FRAMEBUFFER_UNSUPPORTED;
679 }
680
681 // we need to have at least one attachment to be complete
682 if (missingAttachment)
683 {
684 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000685 }
686
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000687 return GL_FRAMEBUFFER_COMPLETE;
688}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000689
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000690DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
691 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000692{
Geoff Langc90d73a2013-07-22 16:39:23 -0400693 mColorbuffers[0].set(new Renderbuffer(mRenderer, 0, colorbuffer), GL_RENDERBUFFER, 0, 0);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000694
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000695 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
Geoff Langc90d73a2013-07-22 16:39:23 -0400696 mDepthbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
697 mStencilbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000698
699 mDrawBufferStates[0] = GL_BACK;
700 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000701}
702
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000703int Framebuffer::getSamples() const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000704{
705 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
706 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000707 // for a complete framebuffer, all attachments must have the same sample count
708 // in this case return the first nonzero sample size
709 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
710 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400711 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000712 {
713 return getColorbuffer(colorAttachment)->getSamples();
714 }
715 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000716 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000717
718 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000719}
720
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000721GLenum DefaultFramebuffer::completeness() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000722{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000723 // The default framebuffer *must* always be complete, though it may not be
724 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000725 return GL_FRAMEBUFFER_COMPLETE;
726}
727
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728}