blob: 806c9a047e2b85c0dc84068bde7d0e5978fefbb5 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002//
Geoff Langcec35902014-04-16 10:52:36 -04003// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
9// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
10
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000012
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013#include "libGLESv2/main.h"
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000014#include "common/utilities.h"
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +000015#include "libGLESv2/formatutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000016#include "libGLESv2/Texture.h"
17#include "libGLESv2/Context.h"
18#include "libGLESv2/renderer/Renderer.h"
19#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020
21namespace gl
22{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000023
daniel@transgaming.com16418b12012-11-28 19:32:22 +000024Framebuffer::Framebuffer(rx::Renderer *renderer)
25 : mRenderer(renderer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000026{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000027 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
28 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000029 mDrawBufferStates[colorAttachment] = GL_NONE;
30 }
31 mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
32 mReadBufferState = GL_COLOR_ATTACHMENT0_EXT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000033}
34
35Framebuffer::~Framebuffer()
36{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000037 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
38 {
Geoff Langc90d73a2013-07-22 16:39:23 -040039 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000040 }
Geoff Langc90d73a2013-07-22 16:39:23 -040041 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
42 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000043}
44
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040045FramebufferAttachmentImpl *Framebuffer::createAttachmentImpl(GLenum type, GLuint handle, GLint level, GLint layer) const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000046{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040047 if (handle == 0)
48 {
49 return NULL;
50 }
51
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000052 gl::Context *context = gl::getContext();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000053
Geoff Lang309c92a2013-07-25 16:23:19 -040054 switch (type)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000055 {
Geoff Lang309c92a2013-07-25 16:23:19 -040056 case GL_NONE:
57 return NULL;
58
59 case GL_RENDERBUFFER:
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040060 return new RenderbufferAttachment(context->getRenderbuffer(handle));
Geoff Lang309c92a2013-07-25 16:23:19 -040061
62 case GL_TEXTURE_2D:
63 {
64 Texture *texture = context->getTexture(handle);
65 if (texture && texture->getTarget() == GL_TEXTURE_2D)
66 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040067 Texture2D *tex2D = static_cast<Texture2D*>(texture);
68 return new Texture2DAttachment(tex2D, level);
Geoff Lang309c92a2013-07-25 16:23:19 -040069 }
70 else
71 {
72 return NULL;
73 }
74 }
75
76 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
77 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
78 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
79 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
80 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
81 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
82 {
83 Texture *texture = context->getTexture(handle);
84 if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
85 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040086 TextureCubeMap *texCube = static_cast<TextureCubeMap*>(texture);
87 return new TextureCubeMapAttachment(texCube, type, level);
Geoff Lang309c92a2013-07-25 16:23:19 -040088 }
89 else
90 {
91 return NULL;
92 }
93 }
94
95 case GL_TEXTURE_3D:
96 {
97 Texture *texture = context->getTexture(handle);
98 if (texture && texture->getTarget() == GL_TEXTURE_3D)
99 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400100 Texture3D *tex3D = static_cast<Texture3D*>(texture);
101 return new Texture3DAttachment(tex3D, level, layer);
Geoff Lang309c92a2013-07-25 16:23:19 -0400102 }
103 else
104 {
105 return NULL;
106 }
107 }
108
109 case GL_TEXTURE_2D_ARRAY:
110 {
111 Texture *texture = context->getTexture(handle);
112 if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
113 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400114 Texture2DArray *tex2DArray = static_cast<Texture2DArray*>(texture);
115 return new Texture2DArrayAttachment(tex2DArray, level, layer);
Geoff Lang309c92a2013-07-25 16:23:19 -0400116 }
117 else
118 {
119 return NULL;
120 }
121 }
122
123 default:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000124 UNREACHABLE();
Geoff Lang309c92a2013-07-25 16:23:19 -0400125 return NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000126 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000127}
128
Geoff Lang309c92a2013-07-25 16:23:19 -0400129void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000130{
131 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400132 FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, colorbuffer, level, layer);
133 if (attachmentImpl)
Geoff Langc90d73a2013-07-22 16:39:23 -0400134 {
Jamie Madill1e3fa742014-06-16 10:34:00 -0400135 FramebufferAttachment *newAttachment = new FramebufferAttachment(colorbuffer, attachmentImpl);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400136 mColorbuffers[colorAttachment].set(newAttachment, type, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400137 }
138 else
139 {
140 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
141 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000142}
143
Geoff Lang309c92a2013-07-25 16:23:19 -0400144void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000145{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400146 FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, depthbuffer, level, layer);
147 if (attachmentImpl)
Geoff Langc90d73a2013-07-22 16:39:23 -0400148 {
Jamie Madill1e3fa742014-06-16 10:34:00 -0400149 FramebufferAttachment *newAttachment = new FramebufferAttachment(depthbuffer, attachmentImpl);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400150 mDepthbuffer.set(newAttachment, type, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400151 }
152 else
153 {
154 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
155 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000156}
157
Geoff Lang309c92a2013-07-25 16:23:19 -0400158void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000159{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400160 FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, stencilbuffer, level, layer);
161 if (attachmentImpl)
Geoff Langc90d73a2013-07-22 16:39:23 -0400162 {
Jamie Madill1e3fa742014-06-16 10:34:00 -0400163 FramebufferAttachment *newAttachment = new FramebufferAttachment(stencilbuffer, attachmentImpl);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400164 mStencilbuffer.set(newAttachment, type, level, layer);
Geoff Langc90d73a2013-07-22 16:39:23 -0400165 }
166 else
167 {
168 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
169 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000170}
171
Geoff Lang309c92a2013-07-25 16:23:19 -0400172void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400173{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400174 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
175 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
176
177 FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, depthStencilBuffer, level, layer);
178 if (attachmentImpl)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400179 {
Jamie Madill1e3fa742014-06-16 10:34:00 -0400180 FramebufferAttachment *newAttachment = new FramebufferAttachment(depthStencilBuffer, attachmentImpl);
181 int clientVersion = mRenderer->getCurrentClientVersion();
182 if (newAttachment->getDepthSize(clientVersion) > 0 && newAttachment->getStencilSize(clientVersion) > 0)
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400183 {
184 mDepthbuffer.set(newAttachment, type, level, layer);
185 mStencilbuffer.set(newAttachment, type, level, layer);
186 }
Geoff Lang55ba29c2013-07-11 16:57:53 -0400187 }
188}
189
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000190void Framebuffer::detachTexture(GLuint texture)
191{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000192 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400194 if (mColorbuffers[colorAttachment].id() == texture &&
Geoff Lang0fe19492013-07-25 17:04:31 -0400195 IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000196 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400197 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000198 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000199 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000200
Geoff Lang0fe19492013-07-25 17:04:31 -0400201 if (mDepthbuffer.id() == texture && IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000202 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400203 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000204 }
205
Geoff Lang0fe19492013-07-25 17:04:31 -0400206 if (mStencilbuffer.id() == texture && IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000207 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400208 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000209 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210}
211
212void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
213{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000214 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000215 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400216 if (mColorbuffers[colorAttachment].id() == renderbuffer && mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000217 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400218 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000219 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000220 }
221
Geoff Langc90d73a2013-07-22 16:39:23 -0400222 if (mDepthbuffer.id() == renderbuffer && mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400224 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225 }
226
Geoff Langc90d73a2013-07-22 16:39:23 -0400227 if (mStencilbuffer.id() == renderbuffer && mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400229 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000230 }
231}
232
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000233unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000234{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000235 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
236
Jamie Madill3c7fa222014-06-05 13:08:51 -0400237 FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment].get();
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000238
239 if (colorbuffer)
240 {
241 return colorbuffer->getSerial();
242 }
243
244 return 0;
245}
246
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000247unsigned int Framebuffer::getDepthbufferSerial() const
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000248{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400249 FramebufferAttachment *depthbuffer = mDepthbuffer.get();
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000250
251 if (depthbuffer)
252 {
253 return depthbuffer->getSerial();
254 }
255
256 return 0;
257}
258
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000259unsigned int Framebuffer::getStencilbufferSerial() const
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000260{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400261 FramebufferAttachment *stencilbuffer = mStencilbuffer.get();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000262
263 if (stencilbuffer)
264 {
265 return stencilbuffer->getSerial();
266 }
267
268 return 0;
269}
270
Jamie Madill3c7fa222014-06-05 13:08:51 -0400271FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000272{
273 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400274 return mColorbuffers[colorAttachment].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000275}
276
Jamie Madill3c7fa222014-06-05 13:08:51 -0400277FramebufferAttachment *Framebuffer::getDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000278{
Geoff Langc90d73a2013-07-22 16:39:23 -0400279 return mDepthbuffer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000280}
281
Jamie Madill3c7fa222014-06-05 13:08:51 -0400282FramebufferAttachment *Framebuffer::getStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283{
Geoff Langc90d73a2013-07-22 16:39:23 -0400284 return mStencilbuffer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000285}
286
Jamie Madill3c7fa222014-06-05 13:08:51 -0400287FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
Geoff Lang646559f2013-08-15 11:08:15 -0400288{
289 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL;
290}
291
Jamie Madill3c7fa222014-06-05 13:08:51 -0400292FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000293{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400294 FramebufferAttachment *depthstencilbuffer = mDepthbuffer.get();
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000295
296 if (!depthstencilbuffer)
297 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400298 depthstencilbuffer = mStencilbuffer.get();
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000299 }
300
301 return depthstencilbuffer;
302}
303
Jamie Madill3c7fa222014-06-05 13:08:51 -0400304FramebufferAttachment *Framebuffer::getReadColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000305{
306 // Will require more logic if glReadBuffers is supported
Geoff Langc90d73a2013-07-22 16:39:23 -0400307 return mColorbuffers[0].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000308}
309
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000310GLenum Framebuffer::getReadColorbufferType() const
311{
312 // Will require more logic if glReadBuffers is supported
Geoff Langc90d73a2013-07-22 16:39:23 -0400313 return mColorbuffers[0].type();
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000314}
315
Jamie Madill3c7fa222014-06-05 13:08:51 -0400316FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000317{
318 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
319 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400320 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000321 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400322 return mColorbuffers[colorAttachment].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000323 }
324 }
325
326 return NULL;
327}
328
329GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
330{
331 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400332 return mColorbuffers[colorAttachment].type();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000333}
334
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000335GLenum Framebuffer::getDepthbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000336{
Geoff Langc90d73a2013-07-22 16:39:23 -0400337 return mDepthbuffer.type();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000338}
339
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000340GLenum Framebuffer::getStencilbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000341{
Geoff Langc90d73a2013-07-22 16:39:23 -0400342 return mStencilbuffer.type();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000343}
344
Geoff Lang55ba29c2013-07-11 16:57:53 -0400345GLenum Framebuffer::getDepthStencilbufferType() const
346{
Geoff Langc90d73a2013-07-22 16:39:23 -0400347 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.type() : GL_NONE;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400348}
349
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000350GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
351{
352 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400353 return mColorbuffers[colorAttachment].id();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000354}
355
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000356GLuint Framebuffer::getDepthbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000357{
Geoff Langc90d73a2013-07-22 16:39:23 -0400358 return mDepthbuffer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000359}
360
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000361GLuint Framebuffer::getStencilbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000362{
Geoff Langc90d73a2013-07-22 16:39:23 -0400363 return mStencilbuffer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000364}
365
Geoff Lang55ba29c2013-07-11 16:57:53 -0400366GLenum Framebuffer::getDepthStencilbufferHandle() const
367{
Geoff Langc90d73a2013-07-22 16:39:23 -0400368 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.id() : 0;
369}
370
371GLenum Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
372{
373 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
374 return mColorbuffers[colorAttachment].mipLevel();
375}
376
377GLenum Framebuffer::getDepthbufferMipLevel() const
378{
379 return mDepthbuffer.mipLevel();
380}
381
382GLenum Framebuffer::getStencilbufferMipLevel() const
383{
384 return mStencilbuffer.mipLevel();
385}
386
387GLenum Framebuffer::getDepthStencilbufferMipLevel() const
388{
389 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.mipLevel() : 0;
390}
391
392GLenum Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
393{
394 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
395 return mColorbuffers[colorAttachment].layer();
396}
397
398GLenum Framebuffer::getDepthbufferLayer() const
399{
400 return mDepthbuffer.layer();
401}
402
403GLenum Framebuffer::getStencilbufferLayer() const
404{
405 return mStencilbuffer.layer();
406}
407
408GLenum Framebuffer::getDepthStencilbufferLayer() const
409{
410 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.layer() : 0;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400411}
412
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000413GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
414{
415 return mDrawBufferStates[colorAttachment];
416}
417
418void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
419{
420 mDrawBufferStates[colorAttachment] = drawBuffer;
421}
422
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000423bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
424{
Geoff Langc90d73a2013-07-22 16:39:23 -0400425 return (mColorbuffers[colorAttachment].type() != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000426}
427
428bool Framebuffer::hasEnabledColorAttachment() const
429{
430 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
431 {
432 if (isEnabledColorAttachment(colorAttachment))
433 {
434 return true;
435 }
436 }
437
438 return false;
439}
440
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000441bool Framebuffer::hasStencil() const
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000442{
Geoff Langc90d73a2013-07-22 16:39:23 -0400443 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000444 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400445 const FramebufferAttachment *stencilbufferObject = getStencilbuffer();
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000446
447 if (stencilbufferObject)
448 {
Jamie Madill1e3fa742014-06-16 10:34:00 -0400449 int clientVersion = mRenderer->getCurrentClientVersion();
450 return stencilbufferObject->getStencilSize(clientVersion) > 0;
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000451 }
452 }
453
454 return false;
455}
456
shannonwoods@chromium.org24ac8502013-05-30 00:01:37 +0000457bool Framebuffer::usingExtendedDrawBuffers() const
458{
459 for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
460 {
461 if (isEnabledColorAttachment(colorAttachment))
462 {
463 return true;
464 }
465 }
466
467 return false;
468}
469
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000470GLenum Framebuffer::completeness() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000471{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000472 int width = 0;
473 int height = 0;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000474 unsigned int colorbufferSize = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000475 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000476 bool missingAttachment = true;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000477 GLuint clientVersion = mRenderer->getCurrentClientVersion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000478
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000479 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000480 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400481 if (mColorbuffers[colorAttachment].type() != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400483 const FramebufferAttachment *colorbuffer = getColorbuffer(colorAttachment);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000485 if (!colorbuffer)
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000486 {
487 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
488 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000489
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000490 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000491 {
492 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
493 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000494
Geoff Langcec35902014-04-16 10:52:36 -0400495 GLenum internalformat = colorbuffer->getInternalFormat();
496 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400497 if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000498 {
Geoff Langcec35902014-04-16 10:52:36 -0400499 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000500 {
501 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
502 }
503 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400504 else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000505 {
Geoff Langcec35902014-04-16 10:52:36 -0400506 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000507 {
508 return GL_FRAMEBUFFER_UNSUPPORTED;
509 }
510
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000511 if (gl::GetDepthBits(internalformat, clientVersion) > 0 ||
512 gl::GetStencilBits(internalformat, clientVersion) > 0)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000513 {
514 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
515 }
516 }
517 else
518 {
519 UNREACHABLE();
520 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
521 }
522
523 if (!missingAttachment)
524 {
525 // all color attachments must have the same width and height
526 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
527 {
528 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
529 }
530
531 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
532 // all color attachments have the same number of samples for the FBO to be complete.
533 if (colorbuffer->getSamples() != samples)
534 {
535 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
536 }
537
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000538 // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
539 // in GLES 3.0, there is no such restriction
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000540 if (clientVersion < 3)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000541 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000542 if (gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion) != colorbufferSize)
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000543 {
544 return GL_FRAMEBUFFER_UNSUPPORTED;
545 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000546 }
547
548 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
549 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
550 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400551 if (mColorbuffers[colorAttachment].get() == mColorbuffers[previousColorAttachment].get())
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000552 {
553 return GL_FRAMEBUFFER_UNSUPPORTED;
554 }
555 }
556 }
557 else
558 {
559 width = colorbuffer->getWidth();
560 height = colorbuffer->getHeight();
561 samples = colorbuffer->getSamples();
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000562 colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000563 missingAttachment = false;
564 }
565 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000566 }
567
Jamie Madill3c7fa222014-06-05 13:08:51 -0400568 const FramebufferAttachment *depthbuffer = NULL;
569 const FramebufferAttachment *stencilbuffer = NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000570
Geoff Langc90d73a2013-07-22 16:39:23 -0400571 if (mDepthbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000572 {
573 depthbuffer = getDepthbuffer();
574
575 if (!depthbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000576 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000577 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000578 }
579
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000580 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000582 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
583 }
584
Geoff Langcec35902014-04-16 10:52:36 -0400585 GLenum internalformat = depthbuffer->getInternalFormat();
586 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400587 if (mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000588 {
Geoff Langcec35902014-04-16 10:52:36 -0400589 if (!formatCaps.depthRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000590 {
591 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
592 }
593 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400594 else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000595 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000596 // depth texture attachments require OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400597 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000598 {
599 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
600 }
601
Geoff Langcec35902014-04-16 10:52:36 -0400602 if (!formatCaps.depthRendering)
603 {
604 return GL_FRAMEBUFFER_UNSUPPORTED;
605 }
606
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000607 if (gl::GetDepthBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000608 {
609 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
610 }
611 }
612 else
613 {
614 UNREACHABLE();
615 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
616 }
617
618 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000619 {
620 width = depthbuffer->getWidth();
621 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000622 samples = depthbuffer->getSamples();
623 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000624 }
625 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
626 {
627 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
628 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000629 else if (samples != depthbuffer->getSamples())
630 {
631 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
632 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000633 }
634
Geoff Langc90d73a2013-07-22 16:39:23 -0400635 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000636 {
637 stencilbuffer = getStencilbuffer();
638
639 if (!stencilbuffer)
640 {
641 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
642 }
643
644 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
645 {
646 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
647 }
648
Geoff Langcec35902014-04-16 10:52:36 -0400649 GLenum internalformat = stencilbuffer->getInternalFormat();
650 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400651 if (mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000652 {
Geoff Langcec35902014-04-16 10:52:36 -0400653 if (!formatCaps.stencilRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000654 {
655 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
656 }
657 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400658 else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000659 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000660 // texture stencil attachments come along as part
661 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400662 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000663 {
664 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
665 }
666
Geoff Langcec35902014-04-16 10:52:36 -0400667 if (!formatCaps.stencilRendering)
668 {
669 return GL_FRAMEBUFFER_UNSUPPORTED;
670 }
671
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000672 if (gl::GetStencilBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000673 {
674 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
675 }
676 }
677 else
678 {
679 UNREACHABLE();
680 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
681 }
682
683 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000684 {
685 width = stencilbuffer->getWidth();
686 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000687 samples = stencilbuffer->getSamples();
688 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000689 }
690 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
691 {
692 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
693 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000694 else if (samples != stencilbuffer->getSamples())
695 {
696 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
697 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000698 }
699
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000700 // if we have both a depth and stencil buffer, they must refer to the same object
701 // since we only support packed_depth_stencil and not separate depth and stencil
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400702 if (depthbuffer && stencilbuffer &&
703 !(depthbuffer->id() == stencilbuffer->id() &&
704 depthbuffer->isTexture() == stencilbuffer->isTexture()))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000705 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000706 return GL_FRAMEBUFFER_UNSUPPORTED;
707 }
708
709 // we need to have at least one attachment to be complete
710 if (missingAttachment)
711 {
712 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000713 }
714
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000715 return GL_FRAMEBUFFER_COMPLETE;
716}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000717
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000718DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
719 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000720{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400721 Renderbuffer *colorRenderbuffer = new Renderbuffer(mRenderer, 0, colorbuffer);
Jamie Madill1e3fa742014-06-16 10:34:00 -0400722 FramebufferAttachment *colorAttachment = new FramebufferAttachment(0, new RenderbufferAttachment(colorRenderbuffer));
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400723 mColorbuffers[0].set(colorAttachment, GL_RENDERBUFFER, 0, 0);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000724
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400725 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
Jamie Madill1e3fa742014-06-16 10:34:00 -0400726 FramebufferAttachment *depthStencilAttachment = new FramebufferAttachment(0, new RenderbufferAttachment(depthStencilRenderbuffer));
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400727 mDepthbuffer.set(depthStencilAttachment, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
728 mStencilbuffer.set(depthStencilAttachment, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000729
730 mDrawBufferStates[0] = GL_BACK;
731 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000732}
733
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000734int Framebuffer::getSamples() const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000735{
736 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
737 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000738 // for a complete framebuffer, all attachments must have the same sample count
739 // in this case return the first nonzero sample size
740 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
741 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400742 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000743 {
744 return getColorbuffer(colorAttachment)->getSamples();
745 }
746 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000747 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000748
749 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000750}
751
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000752GLenum DefaultFramebuffer::completeness() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000753{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000754 // The default framebuffer *must* always be complete, though it may not be
755 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000756 return GL_FRAMEBUFFER_COMPLETE;
757}
758
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000759}