blob: f0dd5f2a11cef10bf3d97bf5a9145bcd565d1b89 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com911cd6d2012-06-01 01:45:20 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
8// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
9
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000010#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012#include "libGLESv2/main.h"
daniel@transgaming.com93a81472010-04-20 18:52:58 +000013#include "libGLESv2/utilities.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000014#include "libGLESv2/Texture.h"
15#include "libGLESv2/Context.h"
16#include "libGLESv2/renderer/Renderer.h"
17#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000018
19namespace gl
20{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000021
daniel@transgaming.com16418b12012-11-28 19:32:22 +000022Framebuffer::Framebuffer(rx::Renderer *renderer)
23 : mRenderer(renderer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024{
25 mColorbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000026 mDepthbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027 mStencilbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028}
29
30Framebuffer::~Framebuffer()
31{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000032 mColorbufferPointer.set(NULL);
33 mDepthbufferPointer.set(NULL);
34 mStencilbufferPointer.set(NULL);
35}
36
37Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
38{
39 gl::Context *context = gl::getContext();
40 Renderbuffer *buffer = NULL;
41
42 if (type == GL_NONE)
43 {
44 buffer = NULL;
45 }
46 else if (type == GL_RENDERBUFFER)
47 {
48 buffer = context->getRenderbuffer(handle);
49 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +000050 else if (IsInternalTextureTarget(type))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000051 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +000052 buffer = context->getTexture(handle)->getRenderbuffer(type);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000053 }
54 else
55 {
56 UNREACHABLE();
57 }
58
59 return buffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060}
61
62void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
63{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000064 mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000065 mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000066}
67
68void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
69{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000070 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000071 mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072}
73
74void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
75{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000076 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000077 mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000078}
79
80void Framebuffer::detachTexture(GLuint texture)
81{
apatrick@chromium.org551022e2012-01-23 19:56:54 +000082 if (mColorbufferPointer.id() == texture && IsInternalTextureTarget(mColorbufferType))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000083 {
84 mColorbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000085 mColorbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000087
apatrick@chromium.org551022e2012-01-23 19:56:54 +000088 if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000089 {
90 mDepthbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000091 mDepthbufferPointer.set(NULL);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000092 }
93
apatrick@chromium.org551022e2012-01-23 19:56:54 +000094 if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000095 {
96 mStencilbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000097 mStencilbufferPointer.set(NULL);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000098 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000099}
100
101void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
102{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000103 if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000104 {
105 mColorbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000106 mColorbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107 }
108
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000109 if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110 {
111 mDepthbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000112 mDepthbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000113 }
114
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000115 if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000116 {
117 mStencilbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000118 mStencilbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119 }
120}
121
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000122unsigned int Framebuffer::getRenderTargetSerial()
123{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000124 Renderbuffer *colorbuffer = mColorbufferPointer.get();
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000125
126 if (colorbuffer)
127 {
128 return colorbuffer->getSerial();
129 }
130
131 return 0;
132}
133
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000134unsigned int Framebuffer::getDepthbufferSerial()
135{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000136 Renderbuffer *depthbuffer = mDepthbufferPointer.get();
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000137
138 if (depthbuffer)
139 {
140 return depthbuffer->getSerial();
141 }
142
143 return 0;
144}
145
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000146unsigned int Framebuffer::getStencilbufferSerial()
147{
148 Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
149
150 if (stencilbuffer)
151 {
152 return stencilbuffer->getSerial();
153 }
154
155 return 0;
156}
157
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000158Renderbuffer *Framebuffer::getColorbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000159{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000160 return mColorbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161}
162
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000163Renderbuffer *Framebuffer::getDepthbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000165 return mDepthbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166}
167
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000168Renderbuffer *Framebuffer::getStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000170 return mStencilbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000171}
172
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000173Renderbuffer *Framebuffer::getDepthOrStencilbuffer()
174{
175 Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
176
177 if (!depthstencilbuffer)
178 {
179 depthstencilbuffer = mStencilbufferPointer.get();
180 }
181
182 return depthstencilbuffer;
183}
184
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000185GLenum Framebuffer::getColorbufferType()
186{
187 return mColorbufferType;
188}
189
190GLenum Framebuffer::getDepthbufferType()
191{
192 return mDepthbufferType;
193}
194
195GLenum Framebuffer::getStencilbufferType()
196{
197 return mStencilbufferType;
198}
199
200GLuint Framebuffer::getColorbufferHandle()
201{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000202 return mColorbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000203}
204
205GLuint Framebuffer::getDepthbufferHandle()
206{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000207 return mDepthbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000208}
209
210GLuint Framebuffer::getStencilbufferHandle()
211{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000212 return mStencilbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000213}
214
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000215bool Framebuffer::hasStencil()
216{
217 if (mStencilbufferType != GL_NONE)
218 {
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000219 Renderbuffer *stencilbufferObject = getStencilbuffer();
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000220
221 if (stencilbufferObject)
222 {
223 return stencilbufferObject->getStencilSize() > 0;
224 }
225 }
226
227 return false;
228}
229
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000230GLenum Framebuffer::completeness()
231{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000232 int width = 0;
233 int height = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000234 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000235 bool missingAttachment = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000237 if (mColorbufferType != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238 {
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000239 Renderbuffer *colorbuffer = getColorbuffer();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000240
241 if (!colorbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000242 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000243 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244 }
245
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000246 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000248 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249 }
250
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000251 if (mColorbufferType == GL_RENDERBUFFER)
252 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000253 if (!gl::IsColorRenderable(colorbuffer->getInternalFormat()))
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000254 {
255 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
256 }
257 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +0000258 else if (IsInternalTextureTarget(mColorbufferType))
daniel@transgaming.com01868132010-08-24 19:21:17 +0000259 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000260 GLint internalformat = colorbuffer->getInternalFormat();
261 GLenum format = gl::ExtractFormat(internalformat);
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000262
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000263 if (IsCompressed(format) ||
264 format == GL_ALPHA ||
265 format == GL_LUMINANCE ||
266 format == GL_LUMINANCE_ALPHA)
daniel@transgaming.com01868132010-08-24 19:21:17 +0000267 {
268 return GL_FRAMEBUFFER_UNSUPPORTED;
269 }
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000270
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000271 bool filtering, renderable;
272
273 if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
274 (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
daniel@transgaming.comb6b2e672010-10-15 17:57:47 +0000275 {
276 return GL_FRAMEBUFFER_UNSUPPORTED;
277 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000278
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000279 if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000280 {
281 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
282 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000283 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000284 else
285 {
286 UNREACHABLE();
287 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
288 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000289
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000290 width = colorbuffer->getWidth();
291 height = colorbuffer->getHeight();
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000292 samples = colorbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000293 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000294 }
295
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000296 Renderbuffer *depthbuffer = NULL;
297 Renderbuffer *stencilbuffer = NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000298
299 if (mDepthbufferType != GL_NONE)
300 {
301 depthbuffer = getDepthbuffer();
302
303 if (!depthbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000305 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306 }
307
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000308 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000309 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000310 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
311 }
312
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000313 if (mDepthbufferType == GL_RENDERBUFFER)
314 {
315 if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat()))
316 {
317 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
318 }
319 }
320 else if (IsInternalTextureTarget(mDepthbufferType))
321 {
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000322 GLint internalformat = depthbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000323
324 // depth texture attachments require OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000325 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000326 {
327 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
328 }
329
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000330 if (!gl::IsDepthTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000331 {
332 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
333 }
334 }
335 else
336 {
337 UNREACHABLE();
338 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
339 }
340
341 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000342 {
343 width = depthbuffer->getWidth();
344 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000345 samples = depthbuffer->getSamples();
346 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000347 }
348 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
349 {
350 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
351 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000352 else if (samples != depthbuffer->getSamples())
353 {
354 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
355 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000356 }
357
358 if (mStencilbufferType != GL_NONE)
359 {
360 stencilbuffer = getStencilbuffer();
361
362 if (!stencilbuffer)
363 {
364 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
365 }
366
367 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
368 {
369 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
370 }
371
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000372 if (mStencilbufferType == GL_RENDERBUFFER)
373 {
374 if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat()))
375 {
376 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
377 }
378 }
379 else if (IsInternalTextureTarget(mStencilbufferType))
380 {
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000381 GLint internalformat = stencilbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000382
383 // texture stencil attachments come along as part
384 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000385 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000386 {
387 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
388 }
389
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000390 if (!gl::IsStencilTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000391 {
392 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
393 }
394 }
395 else
396 {
397 UNREACHABLE();
398 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
399 }
400
401 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000402 {
403 width = stencilbuffer->getWidth();
404 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000405 samples = stencilbuffer->getSamples();
406 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000407 }
408 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
409 {
410 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
411 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000412 else if (samples != stencilbuffer->getSamples())
413 {
414 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
415 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000416 }
417
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000418 // if we have both a depth and stencil buffer, they must refer to the same object
419 // since we only support packed_depth_stencil and not separate depth and stencil
420 if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000421 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000422 return GL_FRAMEBUFFER_UNSUPPORTED;
423 }
424
425 // we need to have at least one attachment to be complete
426 if (missingAttachment)
427 {
428 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000429 }
430
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000431 return GL_FRAMEBUFFER_COMPLETE;
432}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000433
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000434DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
435 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000436{
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000437 mColorbufferPointer.set(new Renderbuffer(mRenderer, 0, colorbuffer));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000438
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000439 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000440 mDepthbufferPointer.set(depthStencilRenderbuffer);
441 mStencilbufferPointer.set(depthStencilRenderbuffer);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000442
443 mColorbufferType = GL_RENDERBUFFER;
444 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
445 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000446}
447
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000448int Framebuffer::getSamples()
449{
450 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
451 {
452 return getColorbuffer()->getSamples();
453 }
454 else
455 {
456 return 0;
457 }
458}
459
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000460GLenum DefaultFramebuffer::completeness()
461{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000462 // The default framebuffer *must* always be complete, though it may not be
463 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000464 return GL_FRAMEBUFFER_COMPLETE;
465}
466
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000467}