blob: 146481ae0b947dd373eb3153a477f6a3a5aa7656 [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"
13#include "libGLESv2/Renderbuffer.h"
14#include "libGLESv2/Texture.h"
daniel@transgaming.com93a81472010-04-20 18:52:58 +000015#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
17namespace gl
18{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000019
daniel@transgaming.com16418b12012-11-28 19:32:22 +000020Framebuffer::Framebuffer(rx::Renderer *renderer)
21 : mRenderer(renderer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022{
23 mColorbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024 mDepthbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025 mStencilbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000026}
27
28Framebuffer::~Framebuffer()
29{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000030 mColorbufferPointer.set(NULL);
31 mDepthbufferPointer.set(NULL);
32 mStencilbufferPointer.set(NULL);
33}
34
35Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
36{
37 gl::Context *context = gl::getContext();
38 Renderbuffer *buffer = NULL;
39
40 if (type == GL_NONE)
41 {
42 buffer = NULL;
43 }
44 else if (type == GL_RENDERBUFFER)
45 {
46 buffer = context->getRenderbuffer(handle);
47 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +000048 else if (IsInternalTextureTarget(type))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000049 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +000050 buffer = context->getTexture(handle)->getRenderbuffer(type);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000051 }
52 else
53 {
54 UNREACHABLE();
55 }
56
57 return buffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058}
59
60void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
61{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000062 mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000063 mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000064}
65
66void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
67{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000068 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000069 mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070}
71
72void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
73{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000074 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000075 mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000076}
77
78void Framebuffer::detachTexture(GLuint texture)
79{
apatrick@chromium.org551022e2012-01-23 19:56:54 +000080 if (mColorbufferPointer.id() == texture && IsInternalTextureTarget(mColorbufferType))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000081 {
82 mColorbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000083 mColorbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000085
apatrick@chromium.org551022e2012-01-23 19:56:54 +000086 if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000087 {
88 mDepthbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000089 mDepthbufferPointer.set(NULL);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000090 }
91
apatrick@chromium.org551022e2012-01-23 19:56:54 +000092 if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000093 {
94 mStencilbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000095 mStencilbufferPointer.set(NULL);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000096 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097}
98
99void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
100{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000101 if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000102 {
103 mColorbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000104 mColorbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105 }
106
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000107 if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108 {
109 mDepthbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000110 mDepthbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111 }
112
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000113 if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000114 {
115 mStencilbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000116 mStencilbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000117 }
118}
119
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000120unsigned int Framebuffer::getRenderTargetSerial()
121{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000122 Renderbuffer *colorbuffer = mColorbufferPointer.get();
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000123
124 if (colorbuffer)
125 {
126 return colorbuffer->getSerial();
127 }
128
129 return 0;
130}
131
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000132unsigned int Framebuffer::getDepthbufferSerial()
133{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000134 Renderbuffer *depthbuffer = mDepthbufferPointer.get();
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000135
136 if (depthbuffer)
137 {
138 return depthbuffer->getSerial();
139 }
140
141 return 0;
142}
143
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000144unsigned int Framebuffer::getStencilbufferSerial()
145{
146 Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
147
148 if (stencilbuffer)
149 {
150 return stencilbuffer->getSerial();
151 }
152
153 return 0;
154}
155
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000156Renderbuffer *Framebuffer::getColorbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000158 return mColorbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000159}
160
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000161Renderbuffer *Framebuffer::getDepthbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000163 return mDepthbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164}
165
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000166Renderbuffer *Framebuffer::getStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000168 return mStencilbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169}
170
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000171Renderbuffer *Framebuffer::getDepthOrStencilbuffer()
172{
173 Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
174
175 if (!depthstencilbuffer)
176 {
177 depthstencilbuffer = mStencilbufferPointer.get();
178 }
179
180 return depthstencilbuffer;
181}
182
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000183GLenum Framebuffer::getColorbufferType()
184{
185 return mColorbufferType;
186}
187
188GLenum Framebuffer::getDepthbufferType()
189{
190 return mDepthbufferType;
191}
192
193GLenum Framebuffer::getStencilbufferType()
194{
195 return mStencilbufferType;
196}
197
198GLuint Framebuffer::getColorbufferHandle()
199{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000200 return mColorbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000201}
202
203GLuint Framebuffer::getDepthbufferHandle()
204{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000205 return mDepthbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000206}
207
208GLuint Framebuffer::getStencilbufferHandle()
209{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000210 return mStencilbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000211}
212
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000213bool Framebuffer::hasStencil()
214{
215 if (mStencilbufferType != GL_NONE)
216 {
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000217 Renderbuffer *stencilbufferObject = getStencilbuffer();
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000218
219 if (stencilbufferObject)
220 {
221 return stencilbufferObject->getStencilSize() > 0;
222 }
223 }
224
225 return false;
226}
227
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228GLenum Framebuffer::completeness()
229{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000230 int width = 0;
231 int height = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000232 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000233 bool missingAttachment = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000234
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000235 if (mColorbufferType != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236 {
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000237 Renderbuffer *colorbuffer = getColorbuffer();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000238
239 if (!colorbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000240 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000241 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000242 }
243
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000244 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000245 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000246 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247 }
248
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000249 if (mColorbufferType == GL_RENDERBUFFER)
250 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000251 if (!gl::IsColorRenderable(colorbuffer->getInternalFormat()))
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000252 {
253 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
254 }
255 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +0000256 else if (IsInternalTextureTarget(mColorbufferType))
daniel@transgaming.com01868132010-08-24 19:21:17 +0000257 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000258 GLint internalformat = colorbuffer->getInternalFormat();
259 GLenum format = gl::ExtractFormat(internalformat);
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000260
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000261 if (IsCompressed(format) ||
262 format == GL_ALPHA ||
263 format == GL_LUMINANCE ||
264 format == GL_LUMINANCE_ALPHA)
daniel@transgaming.com01868132010-08-24 19:21:17 +0000265 {
266 return GL_FRAMEBUFFER_UNSUPPORTED;
267 }
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000268
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000269 bool filtering, renderable;
270
271 if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
272 (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
daniel@transgaming.comb6b2e672010-10-15 17:57:47 +0000273 {
274 return GL_FRAMEBUFFER_UNSUPPORTED;
275 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000276
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000277 if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000278 {
279 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
280 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000281 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000282 else
283 {
284 UNREACHABLE();
285 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
286 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000287
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000288 width = colorbuffer->getWidth();
289 height = colorbuffer->getHeight();
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000290 samples = colorbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000291 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000292 }
293
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000294 Renderbuffer *depthbuffer = NULL;
295 Renderbuffer *stencilbuffer = NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000296
297 if (mDepthbufferType != GL_NONE)
298 {
299 depthbuffer = getDepthbuffer();
300
301 if (!depthbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000302 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000303 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304 }
305
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000306 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000308 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
309 }
310
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000311 if (mDepthbufferType == GL_RENDERBUFFER)
312 {
313 if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat()))
314 {
315 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
316 }
317 }
318 else if (IsInternalTextureTarget(mDepthbufferType))
319 {
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000320 GLint internalformat = depthbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000321
322 // depth texture attachments require OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000323 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000324 {
325 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
326 }
327
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000328 if (!gl::IsDepthTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000329 {
330 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
331 }
332 }
333 else
334 {
335 UNREACHABLE();
336 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
337 }
338
339 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000340 {
341 width = depthbuffer->getWidth();
342 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000343 samples = depthbuffer->getSamples();
344 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000345 }
346 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
347 {
348 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
349 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000350 else if (samples != depthbuffer->getSamples())
351 {
352 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
353 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000354 }
355
356 if (mStencilbufferType != GL_NONE)
357 {
358 stencilbuffer = getStencilbuffer();
359
360 if (!stencilbuffer)
361 {
362 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
363 }
364
365 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
366 {
367 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
368 }
369
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000370 if (mStencilbufferType == GL_RENDERBUFFER)
371 {
372 if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat()))
373 {
374 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
375 }
376 }
377 else if (IsInternalTextureTarget(mStencilbufferType))
378 {
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000379 GLint internalformat = stencilbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000380
381 // texture stencil attachments come along as part
382 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000383 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000384 {
385 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
386 }
387
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000388 if (!gl::IsStencilTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000389 {
390 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
391 }
392 }
393 else
394 {
395 UNREACHABLE();
396 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
397 }
398
399 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000400 {
401 width = stencilbuffer->getWidth();
402 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000403 samples = stencilbuffer->getSamples();
404 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000405 }
406 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
407 {
408 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
409 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000410 else if (samples != stencilbuffer->getSamples())
411 {
412 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
413 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000414 }
415
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000416 // if we have both a depth and stencil buffer, they must refer to the same object
417 // since we only support packed_depth_stencil and not separate depth and stencil
418 if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000419 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000420 return GL_FRAMEBUFFER_UNSUPPORTED;
421 }
422
423 // we need to have at least one attachment to be complete
424 if (missingAttachment)
425 {
426 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000427 }
428
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000429 return GL_FRAMEBUFFER_COMPLETE;
430}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000431
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000432DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
433 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000434{
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000435 mColorbufferPointer.set(new Renderbuffer(mRenderer, 0, colorbuffer));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000436
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000437 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000438 mDepthbufferPointer.set(depthStencilRenderbuffer);
439 mStencilbufferPointer.set(depthStencilRenderbuffer);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000440
441 mColorbufferType = GL_RENDERBUFFER;
442 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
443 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000444}
445
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000446int Framebuffer::getSamples()
447{
448 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
449 {
450 return getColorbuffer()->getSamples();
451 }
452 else
453 {
454 return 0;
455 }
456}
457
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000458GLenum DefaultFramebuffer::completeness()
459{
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000460 // The default framebuffer should always be complete
461 ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);
462
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000463 return GL_FRAMEBUFFER_COMPLETE;
464}
465
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000466}