blob: 1fba656852e97c8735ec05c73d52990208a133c9 [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 Madill6c7b4ad2014-06-16 10:33:59 -0400135 FramebufferAttachment *newAttachment = new FramebufferAttachment(mRenderer, colorbuffer, attachmentImpl);
136 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 Madill6c7b4ad2014-06-16 10:33:59 -0400149 FramebufferAttachment *newAttachment = new FramebufferAttachment(mRenderer, depthbuffer, attachmentImpl);
150 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 Madill6c7b4ad2014-06-16 10:33:59 -0400163 FramebufferAttachment *newAttachment = new FramebufferAttachment(mRenderer, stencilbuffer, attachmentImpl);
164 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 Madill6c7b4ad2014-06-16 10:33:59 -0400180 FramebufferAttachment *newAttachment = new FramebufferAttachment(mRenderer, depthStencilBuffer, attachmentImpl);
181 if (newAttachment->getDepthSize() > 0 && newAttachment->getStencilSize() > 0)
182 {
183 mDepthbuffer.set(newAttachment, type, level, layer);
184 mStencilbuffer.set(newAttachment, type, level, layer);
185 }
Geoff Lang55ba29c2013-07-11 16:57:53 -0400186 }
187}
188
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189void Framebuffer::detachTexture(GLuint texture)
190{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000191 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000192 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400193 if (mColorbuffers[colorAttachment].id() == texture &&
Geoff Lang0fe19492013-07-25 17:04:31 -0400194 IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000195 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400196 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000197 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000198 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000199
Geoff Lang0fe19492013-07-25 17:04:31 -0400200 if (mDepthbuffer.id() == texture && IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000201 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400202 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000203 }
204
Geoff Lang0fe19492013-07-25 17:04:31 -0400205 if (mStencilbuffer.id() == texture && IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000206 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400207 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000208 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209}
210
211void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
212{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000213 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400215 if (mColorbuffers[colorAttachment].id() == renderbuffer && mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000216 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400217 mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000218 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000219 }
220
Geoff Langc90d73a2013-07-22 16:39:23 -0400221 if (mDepthbuffer.id() == renderbuffer && mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000222 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400223 mDepthbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000224 }
225
Geoff Langc90d73a2013-07-22 16:39:23 -0400226 if (mStencilbuffer.id() == renderbuffer && mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400228 mStencilbuffer.set(NULL, GL_NONE, 0, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000229 }
230}
231
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000232unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000233{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000234 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
235
Jamie Madill3c7fa222014-06-05 13:08:51 -0400236 FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment].get();
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000237
238 if (colorbuffer)
239 {
240 return colorbuffer->getSerial();
241 }
242
243 return 0;
244}
245
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000246unsigned int Framebuffer::getDepthbufferSerial() const
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000247{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400248 FramebufferAttachment *depthbuffer = mDepthbuffer.get();
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000249
250 if (depthbuffer)
251 {
252 return depthbuffer->getSerial();
253 }
254
255 return 0;
256}
257
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000258unsigned int Framebuffer::getStencilbufferSerial() const
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000259{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400260 FramebufferAttachment *stencilbuffer = mStencilbuffer.get();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000261
262 if (stencilbuffer)
263 {
264 return stencilbuffer->getSerial();
265 }
266
267 return 0;
268}
269
Jamie Madill3c7fa222014-06-05 13:08:51 -0400270FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000271{
272 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400273 return mColorbuffers[colorAttachment].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000274}
275
Jamie Madill3c7fa222014-06-05 13:08:51 -0400276FramebufferAttachment *Framebuffer::getDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277{
Geoff Langc90d73a2013-07-22 16:39:23 -0400278 return mDepthbuffer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279}
280
Jamie Madill3c7fa222014-06-05 13:08:51 -0400281FramebufferAttachment *Framebuffer::getStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000282{
Geoff Langc90d73a2013-07-22 16:39:23 -0400283 return mStencilbuffer.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000284}
285
Jamie Madill3c7fa222014-06-05 13:08:51 -0400286FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
Geoff Lang646559f2013-08-15 11:08:15 -0400287{
288 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL;
289}
290
Jamie Madill3c7fa222014-06-05 13:08:51 -0400291FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000292{
Jamie Madill3c7fa222014-06-05 13:08:51 -0400293 FramebufferAttachment *depthstencilbuffer = mDepthbuffer.get();
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000294
295 if (!depthstencilbuffer)
296 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400297 depthstencilbuffer = mStencilbuffer.get();
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000298 }
299
300 return depthstencilbuffer;
301}
302
Jamie Madill3c7fa222014-06-05 13:08:51 -0400303FramebufferAttachment *Framebuffer::getReadColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000304{
305 // Will require more logic if glReadBuffers is supported
Geoff Langc90d73a2013-07-22 16:39:23 -0400306 return mColorbuffers[0].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000307}
308
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000309GLenum Framebuffer::getReadColorbufferType() const
310{
311 // Will require more logic if glReadBuffers is supported
Geoff Langc90d73a2013-07-22 16:39:23 -0400312 return mColorbuffers[0].type();
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000313}
314
Jamie Madill3c7fa222014-06-05 13:08:51 -0400315FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000316{
317 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
318 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400319 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000320 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400321 return mColorbuffers[colorAttachment].get();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000322 }
323 }
324
325 return NULL;
326}
327
328GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
329{
330 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400331 return mColorbuffers[colorAttachment].type();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000332}
333
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000334GLenum Framebuffer::getDepthbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000335{
Geoff Langc90d73a2013-07-22 16:39:23 -0400336 return mDepthbuffer.type();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000337}
338
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000339GLenum Framebuffer::getStencilbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000340{
Geoff Langc90d73a2013-07-22 16:39:23 -0400341 return mStencilbuffer.type();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000342}
343
Geoff Lang55ba29c2013-07-11 16:57:53 -0400344GLenum Framebuffer::getDepthStencilbufferType() const
345{
Geoff Langc90d73a2013-07-22 16:39:23 -0400346 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.type() : GL_NONE;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400347}
348
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000349GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
350{
351 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Geoff Langc90d73a2013-07-22 16:39:23 -0400352 return mColorbuffers[colorAttachment].id();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000353}
354
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000355GLuint Framebuffer::getDepthbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000356{
Geoff Langc90d73a2013-07-22 16:39:23 -0400357 return mDepthbuffer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000358}
359
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000360GLuint Framebuffer::getStencilbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000361{
Geoff Langc90d73a2013-07-22 16:39:23 -0400362 return mStencilbuffer.id();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000363}
364
Geoff Lang55ba29c2013-07-11 16:57:53 -0400365GLenum Framebuffer::getDepthStencilbufferHandle() const
366{
Geoff Langc90d73a2013-07-22 16:39:23 -0400367 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.id() : 0;
368}
369
370GLenum Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
371{
372 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
373 return mColorbuffers[colorAttachment].mipLevel();
374}
375
376GLenum Framebuffer::getDepthbufferMipLevel() const
377{
378 return mDepthbuffer.mipLevel();
379}
380
381GLenum Framebuffer::getStencilbufferMipLevel() const
382{
383 return mStencilbuffer.mipLevel();
384}
385
386GLenum Framebuffer::getDepthStencilbufferMipLevel() const
387{
388 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.mipLevel() : 0;
389}
390
391GLenum Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
392{
393 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
394 return mColorbuffers[colorAttachment].layer();
395}
396
397GLenum Framebuffer::getDepthbufferLayer() const
398{
399 return mDepthbuffer.layer();
400}
401
402GLenum Framebuffer::getStencilbufferLayer() const
403{
404 return mStencilbuffer.layer();
405}
406
407GLenum Framebuffer::getDepthStencilbufferLayer() const
408{
409 return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.layer() : 0;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400410}
411
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000412GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
413{
414 return mDrawBufferStates[colorAttachment];
415}
416
417void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
418{
419 mDrawBufferStates[colorAttachment] = drawBuffer;
420}
421
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000422bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
423{
Geoff Langc90d73a2013-07-22 16:39:23 -0400424 return (mColorbuffers[colorAttachment].type() != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000425}
426
427bool Framebuffer::hasEnabledColorAttachment() const
428{
429 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
430 {
431 if (isEnabledColorAttachment(colorAttachment))
432 {
433 return true;
434 }
435 }
436
437 return false;
438}
439
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000440bool Framebuffer::hasStencil() const
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000441{
Geoff Langc90d73a2013-07-22 16:39:23 -0400442 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000443 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400444 const FramebufferAttachment *stencilbufferObject = getStencilbuffer();
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000445
446 if (stencilbufferObject)
447 {
448 return stencilbufferObject->getStencilSize() > 0;
449 }
450 }
451
452 return false;
453}
454
shannonwoods@chromium.org24ac8502013-05-30 00:01:37 +0000455bool Framebuffer::usingExtendedDrawBuffers() const
456{
457 for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
458 {
459 if (isEnabledColorAttachment(colorAttachment))
460 {
461 return true;
462 }
463 }
464
465 return false;
466}
467
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000468GLenum Framebuffer::completeness() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000469{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000470 int width = 0;
471 int height = 0;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000472 unsigned int colorbufferSize = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000473 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000474 bool missingAttachment = true;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000475 GLuint clientVersion = mRenderer->getCurrentClientVersion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000476
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000477 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000478 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400479 if (mColorbuffers[colorAttachment].type() != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000480 {
Jamie Madill3c7fa222014-06-05 13:08:51 -0400481 const FramebufferAttachment *colorbuffer = getColorbuffer(colorAttachment);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000483 if (!colorbuffer)
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000484 {
485 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
486 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000487
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000488 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000489 {
490 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
491 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000492
Geoff Langcec35902014-04-16 10:52:36 -0400493 GLenum internalformat = colorbuffer->getInternalFormat();
494 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400495 if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000496 {
Geoff Langcec35902014-04-16 10:52:36 -0400497 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000498 {
499 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
500 }
501 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400502 else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000503 {
Geoff Langcec35902014-04-16 10:52:36 -0400504 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000505 {
506 return GL_FRAMEBUFFER_UNSUPPORTED;
507 }
508
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000509 if (gl::GetDepthBits(internalformat, clientVersion) > 0 ||
510 gl::GetStencilBits(internalformat, clientVersion) > 0)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000511 {
512 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
513 }
514 }
515 else
516 {
517 UNREACHABLE();
518 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
519 }
520
521 if (!missingAttachment)
522 {
523 // all color attachments must have the same width and height
524 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
525 {
526 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
527 }
528
529 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
530 // all color attachments have the same number of samples for the FBO to be complete.
531 if (colorbuffer->getSamples() != samples)
532 {
533 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
534 }
535
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000536 // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
537 // in GLES 3.0, there is no such restriction
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000538 if (clientVersion < 3)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000539 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000540 if (gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion) != colorbufferSize)
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000541 {
542 return GL_FRAMEBUFFER_UNSUPPORTED;
543 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000544 }
545
546 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
547 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
548 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400549 if (mColorbuffers[colorAttachment].get() == mColorbuffers[previousColorAttachment].get())
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000550 {
551 return GL_FRAMEBUFFER_UNSUPPORTED;
552 }
553 }
554 }
555 else
556 {
557 width = colorbuffer->getWidth();
558 height = colorbuffer->getHeight();
559 samples = colorbuffer->getSamples();
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000560 colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000561 missingAttachment = false;
562 }
563 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000564 }
565
Jamie Madill3c7fa222014-06-05 13:08:51 -0400566 const FramebufferAttachment *depthbuffer = NULL;
567 const FramebufferAttachment *stencilbuffer = NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000568
Geoff Langc90d73a2013-07-22 16:39:23 -0400569 if (mDepthbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000570 {
571 depthbuffer = getDepthbuffer();
572
573 if (!depthbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000574 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000575 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000576 }
577
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000578 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000579 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000580 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
581 }
582
Geoff Langcec35902014-04-16 10:52:36 -0400583 GLenum internalformat = depthbuffer->getInternalFormat();
584 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400585 if (mDepthbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000586 {
Geoff Langcec35902014-04-16 10:52:36 -0400587 if (!formatCaps.depthRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000588 {
589 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
590 }
591 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400592 else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000593 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000594 // depth texture attachments require OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400595 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000596 {
597 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
598 }
599
Geoff Langcec35902014-04-16 10:52:36 -0400600 if (!formatCaps.depthRendering)
601 {
602 return GL_FRAMEBUFFER_UNSUPPORTED;
603 }
604
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000605 if (gl::GetDepthBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000606 {
607 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
608 }
609 }
610 else
611 {
612 UNREACHABLE();
613 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
614 }
615
616 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000617 {
618 width = depthbuffer->getWidth();
619 height = depthbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000620 samples = depthbuffer->getSamples();
621 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000622 }
623 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
624 {
625 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
626 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000627 else if (samples != depthbuffer->getSamples())
628 {
629 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
630 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000631 }
632
Geoff Langc90d73a2013-07-22 16:39:23 -0400633 if (mStencilbuffer.type() != GL_NONE)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000634 {
635 stencilbuffer = getStencilbuffer();
636
637 if (!stencilbuffer)
638 {
639 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
640 }
641
642 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
643 {
644 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
645 }
646
Geoff Langcec35902014-04-16 10:52:36 -0400647 GLenum internalformat = stencilbuffer->getInternalFormat();
648 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Geoff Langc90d73a2013-07-22 16:39:23 -0400649 if (mStencilbuffer.type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000650 {
Geoff Langcec35902014-04-16 10:52:36 -0400651 if (!formatCaps.stencilRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000652 {
653 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
654 }
655 }
Geoff Lang0fe19492013-07-25 17:04:31 -0400656 else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000657 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000658 // texture stencil attachments come along as part
659 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400660 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000661 {
662 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
663 }
664
Geoff Langcec35902014-04-16 10:52:36 -0400665 if (!formatCaps.stencilRendering)
666 {
667 return GL_FRAMEBUFFER_UNSUPPORTED;
668 }
669
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000670 if (gl::GetStencilBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000671 {
672 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
673 }
674 }
675 else
676 {
677 UNREACHABLE();
678 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
679 }
680
681 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000682 {
683 width = stencilbuffer->getWidth();
684 height = stencilbuffer->getHeight();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000685 samples = stencilbuffer->getSamples();
686 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000687 }
688 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
689 {
690 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
691 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000692 else if (samples != stencilbuffer->getSamples())
693 {
694 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
695 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000696 }
697
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000698 // if we have both a depth and stencil buffer, they must refer to the same object
699 // since we only support packed_depth_stencil and not separate depth and stencil
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400700 if (depthbuffer && stencilbuffer &&
701 !(depthbuffer->id() == stencilbuffer->id() &&
702 depthbuffer->isTexture() == stencilbuffer->isTexture()))
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000703 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000704 return GL_FRAMEBUFFER_UNSUPPORTED;
705 }
706
707 // we need to have at least one attachment to be complete
708 if (missingAttachment)
709 {
710 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000711 }
712
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713 return GL_FRAMEBUFFER_COMPLETE;
714}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000715
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000716DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
717 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000718{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400719 Renderbuffer *colorRenderbuffer = new Renderbuffer(mRenderer, 0, colorbuffer);
720 FramebufferAttachment *colorAttachment = new FramebufferAttachment(mRenderer, 0, new RenderbufferAttachment(colorRenderbuffer));
721 mColorbuffers[0].set(colorAttachment, GL_RENDERBUFFER, 0, 0);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000722
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400723 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
724 FramebufferAttachment *depthStencilAttachment = new FramebufferAttachment(mRenderer, 0, new RenderbufferAttachment(depthStencilRenderbuffer));
725 mDepthbuffer.set(depthStencilAttachment, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
726 mStencilbuffer.set(depthStencilAttachment, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000727
728 mDrawBufferStates[0] = GL_BACK;
729 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000730}
731
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000732int Framebuffer::getSamples() const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000733{
734 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
735 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000736 // for a complete framebuffer, all attachments must have the same sample count
737 // in this case return the first nonzero sample size
738 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
739 {
Geoff Langc90d73a2013-07-22 16:39:23 -0400740 if (mColorbuffers[colorAttachment].type() != GL_NONE)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000741 {
742 return getColorbuffer(colorAttachment)->getSamples();
743 }
744 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000745 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000746
747 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000748}
749
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000750GLenum DefaultFramebuffer::completeness() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000751{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000752 // The default framebuffer *must* always be complete, though it may not be
753 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000754 return GL_FRAMEBUFFER_COMPLETE;
755}
756
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000757}