blob: a37af9d596add84735fb9306e5044ded110d5134 [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//
daniel@transgaming.com911cd6d2012-06-01 01:45:20 +00003// Copyright (c) 2002-2012 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"
daniel@transgaming.com93a81472010-04-20 18:52:58 +000014#include "libGLESv2/utilities.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000015#include "libGLESv2/Texture.h"
16#include "libGLESv2/Context.h"
17#include "libGLESv2/renderer/Renderer.h"
18#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019
20namespace gl
21{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000022
daniel@transgaming.com16418b12012-11-28 19:32:22 +000023Framebuffer::Framebuffer(rx::Renderer *renderer)
24 : mRenderer(renderer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025{
26 mColorbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027 mDepthbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028 mStencilbufferType = GL_NONE;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029}
30
31Framebuffer::~Framebuffer()
32{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000033 mColorbufferPointer.set(NULL);
34 mDepthbufferPointer.set(NULL);
35 mStencilbufferPointer.set(NULL);
36}
37
38Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
39{
40 gl::Context *context = gl::getContext();
41 Renderbuffer *buffer = NULL;
42
43 if (type == GL_NONE)
44 {
45 buffer = NULL;
46 }
47 else if (type == GL_RENDERBUFFER)
48 {
49 buffer = context->getRenderbuffer(handle);
50 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +000051 else if (IsInternalTextureTarget(type))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000052 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +000053 buffer = context->getTexture(handle)->getRenderbuffer(type);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000054 }
55 else
56 {
57 UNREACHABLE();
58 }
59
60 return buffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000061}
62
63void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
64{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000065 mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000066 mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000067}
68
69void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
70{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000071 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000072 mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000073}
74
75void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
76{
daniel@transgaming.com2fa45512011-10-04 18:43:18 +000077 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000078 mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000079}
80
81void Framebuffer::detachTexture(GLuint texture)
82{
apatrick@chromium.org551022e2012-01-23 19:56:54 +000083 if (mColorbufferPointer.id() == texture && IsInternalTextureTarget(mColorbufferType))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084 {
85 mColorbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000086 mColorbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000087 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000088
apatrick@chromium.org551022e2012-01-23 19:56:54 +000089 if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000090 {
91 mDepthbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000092 mDepthbufferPointer.set(NULL);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000093 }
94
apatrick@chromium.org551022e2012-01-23 19:56:54 +000095 if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000096 {
97 mStencilbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000098 mStencilbufferPointer.set(NULL);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000099 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000100}
101
102void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
103{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000104 if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105 {
106 mColorbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000107 mColorbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108 }
109
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000110 if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111 {
112 mDepthbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000113 mDepthbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000114 }
115
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000116 if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000117 {
118 mStencilbufferType = GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000119 mStencilbufferPointer.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000120 }
121}
122
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000123unsigned int Framebuffer::getRenderTargetSerial()
124{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000125 Renderbuffer *colorbuffer = mColorbufferPointer.get();
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000126
127 if (colorbuffer)
128 {
129 return colorbuffer->getSerial();
130 }
131
132 return 0;
133}
134
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000135unsigned int Framebuffer::getDepthbufferSerial()
136{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000137 Renderbuffer *depthbuffer = mDepthbufferPointer.get();
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000138
139 if (depthbuffer)
140 {
141 return depthbuffer->getSerial();
142 }
143
144 return 0;
145}
146
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000147unsigned int Framebuffer::getStencilbufferSerial()
148{
149 Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
150
151 if (stencilbuffer)
152 {
153 return stencilbuffer->getSerial();
154 }
155
156 return 0;
157}
158
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000159Renderbuffer *Framebuffer::getColorbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000161 return mColorbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162}
163
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000164Renderbuffer *Framebuffer::getDepthbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000165{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000166 return mDepthbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167}
168
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000169Renderbuffer *Framebuffer::getStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000170{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000171 return mStencilbufferPointer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000172}
173
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000174Renderbuffer *Framebuffer::getDepthOrStencilbuffer()
175{
176 Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
177
178 if (!depthstencilbuffer)
179 {
180 depthstencilbuffer = mStencilbufferPointer.get();
181 }
182
183 return depthstencilbuffer;
184}
185
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000186GLenum Framebuffer::getColorbufferType()
187{
188 return mColorbufferType;
189}
190
191GLenum Framebuffer::getDepthbufferType()
192{
193 return mDepthbufferType;
194}
195
196GLenum Framebuffer::getStencilbufferType()
197{
198 return mStencilbufferType;
199}
200
201GLuint Framebuffer::getColorbufferHandle()
202{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000203 return mColorbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000204}
205
206GLuint Framebuffer::getDepthbufferHandle()
207{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000208 return mDepthbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000209}
210
211GLuint Framebuffer::getStencilbufferHandle()
212{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000213 return mStencilbufferPointer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000214}
215
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000216bool Framebuffer::hasStencil()
217{
218 if (mStencilbufferType != GL_NONE)
219 {
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000220 Renderbuffer *stencilbufferObject = getStencilbuffer();
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000221
222 if (stencilbufferObject)
223 {
224 return stencilbufferObject->getStencilSize() > 0;
225 }
226 }
227
228 return false;
229}
230
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000231GLenum Framebuffer::completeness()
232{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233 int width = 0;
234 int height = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000235 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000236 bool missingAttachment = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000238 if (mColorbufferType != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239 {
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000240 Renderbuffer *colorbuffer = getColorbuffer();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000241
242 if (!colorbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000243 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000244 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000245 }
246
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000247 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000249 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000250 }
251
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000252 if (mColorbufferType == GL_RENDERBUFFER)
253 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000254 if (!gl::IsColorRenderable(colorbuffer->getInternalFormat()))
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000255 {
256 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
257 }
258 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +0000259 else if (IsInternalTextureTarget(mColorbufferType))
daniel@transgaming.com01868132010-08-24 19:21:17 +0000260 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000261 GLint internalformat = colorbuffer->getInternalFormat();
262 GLenum format = gl::ExtractFormat(internalformat);
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000263
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000264 if (IsCompressed(format) ||
265 format == GL_ALPHA ||
266 format == GL_LUMINANCE ||
267 format == GL_LUMINANCE_ALPHA)
daniel@transgaming.com01868132010-08-24 19:21:17 +0000268 {
269 return GL_FRAMEBUFFER_UNSUPPORTED;
270 }
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000271
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000272 bool filtering, renderable;
273
274 if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
275 (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
daniel@transgaming.comb6b2e672010-10-15 17:57:47 +0000276 {
277 return GL_FRAMEBUFFER_UNSUPPORTED;
278 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000279
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000280 if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000281 {
282 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
283 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000284 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000285 else
286 {
287 UNREACHABLE();
288 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
289 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000290
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000291 width = colorbuffer->getWidth();
292 height = colorbuffer->getHeight();
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000293 samples = colorbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000294 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000295 }
296
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000297 Renderbuffer *depthbuffer = NULL;
298 Renderbuffer *stencilbuffer = NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000299
300 if (mDepthbufferType != GL_NONE)
301 {
302 depthbuffer = getDepthbuffer();
303
304 if (!depthbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000306 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307 }
308
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000309 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000310 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000311 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
312 }
313
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000314 if (mDepthbufferType == GL_RENDERBUFFER)
315 {
316 if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat()))
317 {
318 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
319 }
320 }
321 else if (IsInternalTextureTarget(mDepthbufferType))
322 {
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000323 GLint internalformat = depthbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000324
325 // depth texture attachments require OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000326 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000327 {
328 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
329 }
330
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000331 if (!gl::IsDepthTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000332 {
333 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
334 }
335 }
336 else
337 {
338 UNREACHABLE();
339 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
340 }
341
342 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000343 {
344 width = depthbuffer->getWidth();
345 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000346 samples = depthbuffer->getSamples();
347 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000348 }
349 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
350 {
351 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
352 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000353 else if (samples != depthbuffer->getSamples())
354 {
355 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
356 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000357 }
358
359 if (mStencilbufferType != GL_NONE)
360 {
361 stencilbuffer = getStencilbuffer();
362
363 if (!stencilbuffer)
364 {
365 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
366 }
367
368 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
369 {
370 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
371 }
372
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000373 if (mStencilbufferType == GL_RENDERBUFFER)
374 {
375 if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat()))
376 {
377 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
378 }
379 }
380 else if (IsInternalTextureTarget(mStencilbufferType))
381 {
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000382 GLint internalformat = stencilbuffer->getInternalFormat();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000383
384 // texture stencil attachments come along as part
385 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
daniel@transgaming.comea32d482012-11-28 19:33:18 +0000386 if (!mRenderer->getDepthTextureSupport())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000387 {
388 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
389 }
390
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000391 if (!gl::IsStencilTexture(internalformat))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000392 {
393 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
394 }
395 }
396 else
397 {
398 UNREACHABLE();
399 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
400 }
401
402 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000403 {
404 width = stencilbuffer->getWidth();
405 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000406 samples = stencilbuffer->getSamples();
407 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000408 }
409 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
410 {
411 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
412 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000413 else if (samples != stencilbuffer->getSamples())
414 {
415 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
416 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000417 }
418
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000419 // if we have both a depth and stencil buffer, they must refer to the same object
420 // since we only support packed_depth_stencil and not separate depth and stencil
421 if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000422 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000423 return GL_FRAMEBUFFER_UNSUPPORTED;
424 }
425
426 // we need to have at least one attachment to be complete
427 if (missingAttachment)
428 {
429 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000430 }
431
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000432 return GL_FRAMEBUFFER_COMPLETE;
433}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000434
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000435DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
436 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000437{
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000438 mColorbufferPointer.set(new Renderbuffer(mRenderer, 0, colorbuffer));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000439
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000440 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000441 mDepthbufferPointer.set(depthStencilRenderbuffer);
442 mStencilbufferPointer.set(depthStencilRenderbuffer);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000443
444 mColorbufferType = GL_RENDERBUFFER;
445 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
446 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000447}
448
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000449int Framebuffer::getSamples()
450{
451 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
452 {
453 return getColorbuffer()->getSamples();
454 }
455 else
456 {
457 return 0;
458 }
459}
460
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000461GLenum DefaultFramebuffer::completeness()
462{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000463 // The default framebuffer *must* always be complete, though it may not be
464 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000465 return GL_FRAMEBUFFER_COMPLETE;
466}
467
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468}