blob: 9cd9e25cb4b3571e656e1a71574a645c2c274c2b [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
8// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
9
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000010#include "libGLESv2/Framebuffer.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/main.h"
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +000012#include "libGLESv2/formatutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000013#include "libGLESv2/Texture.h"
14#include "libGLESv2/Context.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000015#include "libGLESv2/Renderbuffer.h"
Jamie Madille261b442014-06-25 12:42:21 -040016#include "libGLESv2/FramebufferAttachment.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040017#include "libGLESv2/renderer/Renderer.h"
Jamie Madill400a4412014-08-29 15:46:45 -040018#include "libGLESv2/renderer/RenderTarget.h"
Jamie Madill7acae0a2014-09-24 17:10:51 -040019#include "libGLESv2/renderer/Workarounds.h"
Jamie Madill9f0b42a2014-09-12 10:25:27 -040020#include "libGLESv2/renderer/d3d/TextureD3D.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040021
22#include "common/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000023
Jamie Madill9f0b42a2014-09-12 10:25:27 -040024namespace rx
25{
Geoff Lang64f23f62014-09-10 14:40:12 -040026gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
Jamie Madill9f0b42a2014-09-12 10:25:27 -040027{
28 if (attachment->isTexture())
29 {
30 gl::Texture *texture = attachment->getTexture();
31 ASSERT(texture);
32 TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
Jamie Madillac7579c2014-09-17 16:59:33 -040033 const gl::ImageIndex *index = attachment->getTextureImageIndex();
34 ASSERT(index);
Geoff Lang64f23f62014-09-10 14:40:12 -040035 return textureD3D->getRenderTarget(*index, outRT);
Jamie Madill9f0b42a2014-09-12 10:25:27 -040036 }
Geoff Lang64f23f62014-09-10 14:40:12 -040037 else
38 {
39 gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
40 ASSERT(renderbuffer);
Shannon Woodsf108df22014-10-30 18:53:29 +000041
42 // TODO: cast to RenderbufferD3D
43 *outRT = renderbuffer->getStorage()->getRenderTarget();
Geoff Lang64f23f62014-09-10 14:40:12 -040044 return gl::Error(GL_NO_ERROR);
45 }
Jamie Madill9f0b42a2014-09-12 10:25:27 -040046}
47
Jamie Madill612e2e42014-09-12 13:26:55 -040048// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
49unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
50{
51 if (attachment->isTexture())
52 {
53 gl::Texture *texture = attachment->getTexture();
54 ASSERT(texture);
55 TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
Jamie Madillac7579c2014-09-17 16:59:33 -040056 const gl::ImageIndex *index = attachment->getTextureImageIndex();
57 ASSERT(index);
58 return textureD3D->getRenderTargetSerial(*index);
Jamie Madill612e2e42014-09-12 13:26:55 -040059 }
60
61 gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
62 ASSERT(renderbuffer);
Shannon Woodsf108df22014-10-30 18:53:29 +000063
64 // TODO: cast to RenderbufferD3D
65 return renderbuffer->getStorage()->getSerial();
Jamie Madill612e2e42014-09-12 13:26:55 -040066}
67
Jamie Madill9f0b42a2014-09-12 10:25:27 -040068}
69
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070namespace gl
71{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000072
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040073Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id)
Jamie Madille261b442014-06-25 12:42:21 -040074 : mRenderer(renderer),
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040075 mId(id),
Jamie Madille261b442014-06-25 12:42:21 -040076 mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
77 mDepthbuffer(NULL),
78 mStencilbuffer(NULL)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000079{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000080 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
81 {
Jamie Madille261b442014-06-25 12:42:21 -040082 mColorbuffers[colorAttachment] = NULL;
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000083 mDrawBufferStates[colorAttachment] = GL_NONE;
84 }
85 mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086}
87
88Framebuffer::~Framebuffer()
89{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000090 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
91 {
Jamie Madille261b442014-06-25 12:42:21 -040092 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000093 }
Jamie Madille261b442014-06-25 12:42:21 -040094 SafeDelete(mDepthbuffer);
95 SafeDelete(mStencilbuffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000096}
97
Jamie Madillaef95de2014-09-05 10:12:41 -040098FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000099{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400100 if (handle == 0)
101 {
102 return NULL;
103 }
104
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000105 gl::Context *context = gl::getContext();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000106
Geoff Lang309c92a2013-07-25 16:23:19 -0400107 switch (type)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000108 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400109 case GL_NONE:
110 return NULL;
111
112 case GL_RENDERBUFFER:
Jamie Madillaef95de2014-09-05 10:12:41 -0400113 return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
Geoff Lang309c92a2013-07-25 16:23:19 -0400114
115 case GL_TEXTURE_2D:
116 {
117 Texture *texture = context->getTexture(handle);
118 if (texture && texture->getTarget() == GL_TEXTURE_2D)
119 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400120 return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
Geoff Lang309c92a2013-07-25 16:23:19 -0400121 }
122 else
123 {
124 return NULL;
125 }
126 }
127
128 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
129 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
130 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
131 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
132 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
133 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
134 {
135 Texture *texture = context->getTexture(handle);
136 if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
137 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400138 return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
Geoff Lang309c92a2013-07-25 16:23:19 -0400139 }
140 else
141 {
142 return NULL;
143 }
144 }
145
146 case GL_TEXTURE_3D:
147 {
148 Texture *texture = context->getTexture(handle);
149 if (texture && texture->getTarget() == GL_TEXTURE_3D)
150 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400151 return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
Geoff Lang309c92a2013-07-25 16:23:19 -0400152 }
153 else
154 {
155 return NULL;
156 }
157 }
158
159 case GL_TEXTURE_2D_ARRAY:
160 {
161 Texture *texture = context->getTexture(handle);
162 if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
163 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400164 return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
Geoff Lang309c92a2013-07-25 16:23:19 -0400165 }
166 else
167 {
168 return NULL;
169 }
170 }
171
172 default:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000173 UNREACHABLE();
Geoff Lang309c92a2013-07-25 16:23:19 -0400174 return NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000175 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000176}
177
Geoff Lang309c92a2013-07-25 16:23:19 -0400178void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000179{
180 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400181 SafeDelete(mColorbuffers[colorAttachment]);
Jamie Madillaef95de2014-09-05 10:12:41 -0400182 GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
183 mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000184}
185
Geoff Lang309c92a2013-07-25 16:23:19 -0400186void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000187{
Jamie Madille261b442014-06-25 12:42:21 -0400188 SafeDelete(mDepthbuffer);
Jamie Madillaef95de2014-09-05 10:12:41 -0400189 mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000190}
191
Geoff Lang309c92a2013-07-25 16:23:19 -0400192void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193{
Jamie Madille261b442014-06-25 12:42:21 -0400194 SafeDelete(mStencilbuffer);
Jamie Madillaef95de2014-09-05 10:12:41 -0400195 mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196}
197
Geoff Lang309c92a2013-07-25 16:23:19 -0400198void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400199{
Jamie Madillaef95de2014-09-05 10:12:41 -0400200 FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400201
Jamie Madille261b442014-06-25 12:42:21 -0400202 SafeDelete(mDepthbuffer);
203 SafeDelete(mStencilbuffer);
204
205 // ensure this is a legitimate depth+stencil format
Geoff Lange4a492b2014-06-19 14:14:41 -0400206 if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400207 {
Jamie Madille261b442014-06-25 12:42:21 -0400208 mDepthbuffer = attachment;
Jamie Madill28bedaf2014-06-26 13:17:22 -0400209
210 // Make a new attachment object to ensure we do not double-delete
211 // See angle issue 686
Jamie Madillaef95de2014-09-05 10:12:41 -0400212 mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400213 }
214}
215
Jamie Madille261b442014-06-25 12:42:21 -0400216void Framebuffer::detachTexture(GLuint textureId)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000217{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000218 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000219 {
Jamie Madille261b442014-06-25 12:42:21 -0400220 FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
221
222 if (attachment && attachment->isTextureWithId(textureId))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000223 {
Jamie Madille261b442014-06-25 12:42:21 -0400224 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000225 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000226 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000227
Jamie Madille261b442014-06-25 12:42:21 -0400228 if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000229 {
Jamie Madille261b442014-06-25 12:42:21 -0400230 SafeDelete(mDepthbuffer);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000231 }
232
Jamie Madille261b442014-06-25 12:42:21 -0400233 if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000234 {
Jamie Madille261b442014-06-25 12:42:21 -0400235 SafeDelete(mStencilbuffer);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000236 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237}
238
Jamie Madille261b442014-06-25 12:42:21 -0400239void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000240{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000241 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000242 {
Jamie Madille261b442014-06-25 12:42:21 -0400243 FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
244
245 if (attachment && attachment->isRenderbufferWithId(renderbufferId))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000246 {
Jamie Madille261b442014-06-25 12:42:21 -0400247 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000248 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249 }
250
Jamie Madille261b442014-06-25 12:42:21 -0400251 if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252 {
Jamie Madille261b442014-06-25 12:42:21 -0400253 SafeDelete(mDepthbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000254 }
255
Jamie Madille261b442014-06-25 12:42:21 -0400256 if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257 {
Jamie Madille261b442014-06-25 12:42:21 -0400258 SafeDelete(mStencilbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000259 }
260}
261
Jamie Madill3c7fa222014-06-05 13:08:51 -0400262FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000263{
264 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400265 return mColorbuffers[colorAttachment];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000266}
267
Jamie Madill3c7fa222014-06-05 13:08:51 -0400268FramebufferAttachment *Framebuffer::getDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000269{
Jamie Madille261b442014-06-25 12:42:21 -0400270 return mDepthbuffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271}
272
Jamie Madill3c7fa222014-06-05 13:08:51 -0400273FramebufferAttachment *Framebuffer::getStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274{
Jamie Madille261b442014-06-25 12:42:21 -0400275 return mStencilbuffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276}
277
Jamie Madill3c7fa222014-06-05 13:08:51 -0400278FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
Geoff Lang646559f2013-08-15 11:08:15 -0400279{
Jamie Madille261b442014-06-25 12:42:21 -0400280 return (hasValidDepthStencil() ? mDepthbuffer : NULL);
Geoff Lang646559f2013-08-15 11:08:15 -0400281}
282
Jamie Madill3c7fa222014-06-05 13:08:51 -0400283FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000284{
Jamie Madille261b442014-06-25 12:42:21 -0400285 FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000286
287 if (!depthstencilbuffer)
288 {
Jamie Madille261b442014-06-25 12:42:21 -0400289 depthstencilbuffer = mStencilbuffer;
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000290 }
291
292 return depthstencilbuffer;
293}
294
Jamie Madill3c7fa222014-06-05 13:08:51 -0400295FramebufferAttachment *Framebuffer::getReadColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000296{
297 // Will require more logic if glReadBuffers is supported
Jamie Madille261b442014-06-25 12:42:21 -0400298 return mColorbuffers[0];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000299}
300
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000301GLenum Framebuffer::getReadColorbufferType() const
302{
303 // Will require more logic if glReadBuffers is supported
Jamie Madille261b442014-06-25 12:42:21 -0400304 return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000305}
306
Jamie Madill3c7fa222014-06-05 13:08:51 -0400307FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000308{
309 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
310 {
Jamie Madille261b442014-06-25 12:42:21 -0400311 if (mColorbuffers[colorAttachment])
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000312 {
Jamie Madille261b442014-06-25 12:42:21 -0400313 return mColorbuffers[colorAttachment];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000314 }
315 }
316
317 return NULL;
318}
319
Jamie Madille92a3542014-07-03 10:38:58 -0400320FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000321{
Jamie Madille92a3542014-07-03 10:38:58 -0400322 if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
323 {
324 return getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
325 }
326 else
327 {
328 switch (attachment)
329 {
330 case GL_DEPTH_ATTACHMENT:
331 return getDepthbuffer();
332 case GL_STENCIL_ATTACHMENT:
333 return getStencilbuffer();
334 case GL_DEPTH_STENCIL_ATTACHMENT:
335 return getDepthStencilBuffer();
336 default:
337 UNREACHABLE();
338 return NULL;
339 }
340 }
Geoff Lang55ba29c2013-07-11 16:57:53 -0400341}
342
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000343GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
344{
345 return mDrawBufferStates[colorAttachment];
346}
347
348void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
349{
350 mDrawBufferStates[colorAttachment] = drawBuffer;
351}
352
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000353bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
354{
Jamie Madille261b442014-06-25 12:42:21 -0400355 return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000356}
357
358bool Framebuffer::hasEnabledColorAttachment() const
359{
360 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
361 {
362 if (isEnabledColorAttachment(colorAttachment))
363 {
364 return true;
365 }
366 }
367
368 return false;
369}
370
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000371bool Framebuffer::hasStencil() const
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000372{
Geoff Lange4a492b2014-06-19 14:14:41 -0400373 return (mStencilbuffer && mStencilbuffer->getStencilSize() > 0);
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000374}
375
shannonwoods@chromium.org24ac8502013-05-30 00:01:37 +0000376bool Framebuffer::usingExtendedDrawBuffers() const
377{
378 for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
379 {
380 if (isEnabledColorAttachment(colorAttachment))
381 {
382 return true;
383 }
384 }
385
386 return false;
387}
388
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000389GLenum Framebuffer::completeness() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000390{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391 int width = 0;
392 int height = 0;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000393 unsigned int colorbufferSize = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000394 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000395 bool missingAttachment = true;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000396 GLuint clientVersion = mRenderer->getCurrentClientVersion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000397
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000398 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000399 {
Jamie Madillbb94f342014-06-23 15:23:02 -0400400 const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
401
402 if (colorbuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000403 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000404 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000405 {
406 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
407 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000408
Geoff Langcec35902014-04-16 10:52:36 -0400409 GLenum internalformat = colorbuffer->getInternalFormat();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400410 // TODO(geofflang): use context's texture caps
411 const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -0400412 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madillbb94f342014-06-23 15:23:02 -0400413 if (colorbuffer->isTexture())
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000414 {
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400415 if (!formatCaps.renderable)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000416 {
417 return GL_FRAMEBUFFER_UNSUPPORTED;
418 }
419
Geoff Lang5d601382014-07-22 15:14:06 -0400420 if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000421 {
422 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
423 }
424 }
425 else
426 {
Geoff Lang5d601382014-07-22 15:14:06 -0400427 if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
Jamie Madillbb94f342014-06-23 15:23:02 -0400428 {
429 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
430 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000431 }
432
433 if (!missingAttachment)
434 {
435 // all color attachments must have the same width and height
436 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
437 {
438 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
439 }
440
441 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
442 // all color attachments have the same number of samples for the FBO to be complete.
443 if (colorbuffer->getSamples() != samples)
444 {
445 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
446 }
447
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000448 // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
449 // in GLES 3.0, there is no such restriction
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000450 if (clientVersion < 3)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000451 {
Geoff Lang5d601382014-07-22 15:14:06 -0400452 if (formatInfo.pixelBytes != colorbufferSize)
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000453 {
454 return GL_FRAMEBUFFER_UNSUPPORTED;
455 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000456 }
457
458 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
459 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
460 {
Jamie Madille92a3542014-07-03 10:38:58 -0400461 const FramebufferAttachment *previousAttachment = mColorbuffers[previousColorAttachment];
462
463 if (previousAttachment &&
464 (colorbuffer->id() == previousAttachment->id() &&
465 colorbuffer->type() == previousAttachment->type()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000466 {
467 return GL_FRAMEBUFFER_UNSUPPORTED;
468 }
469 }
470 }
471 else
472 {
473 width = colorbuffer->getWidth();
474 height = colorbuffer->getHeight();
475 samples = colorbuffer->getSamples();
Geoff Lang5d601382014-07-22 15:14:06 -0400476 colorbufferSize = formatInfo.pixelBytes;
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000477 missingAttachment = false;
478 }
479 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000480 }
481
Jamie Madille261b442014-06-25 12:42:21 -0400482 if (mDepthbuffer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000483 {
Jamie Madille261b442014-06-25 12:42:21 -0400484 if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000485 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000486 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000487 }
488
Jamie Madille261b442014-06-25 12:42:21 -0400489 GLenum internalformat = mDepthbuffer->getInternalFormat();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400490 // TODO(geofflang): use context's texture caps
491 const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -0400492 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madillbb94f342014-06-23 15:23:02 -0400493 if (mDepthbuffer->isTexture())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000494 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000495 // depth texture attachments require OES/ANGLE_depth_texture
Geoff Langc0b9ef42014-07-02 10:02:37 -0400496 // TODO(geofflang): use context's extensions
497 if (!mRenderer->getRendererExtensions().depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000498 {
499 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
500 }
501
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400502 if (!formatCaps.renderable)
Geoff Langcec35902014-04-16 10:52:36 -0400503 {
504 return GL_FRAMEBUFFER_UNSUPPORTED;
505 }
506
Geoff Lang5d601382014-07-22 15:14:06 -0400507 if (formatInfo.depthBits == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000508 {
509 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
510 }
511 }
512 else
513 {
Geoff Lang5d601382014-07-22 15:14:06 -0400514 if (!formatCaps.renderable || formatInfo.depthBits == 0)
Jamie Madillbb94f342014-06-23 15:23:02 -0400515 {
516 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
517 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000518 }
519
520 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000521 {
Jamie Madille261b442014-06-25 12:42:21 -0400522 width = mDepthbuffer->getWidth();
523 height = mDepthbuffer->getHeight();
524 samples = mDepthbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000525 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000526 }
Jamie Madille261b442014-06-25 12:42:21 -0400527 else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000528 {
529 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
530 }
Jamie Madille261b442014-06-25 12:42:21 -0400531 else if (samples != mDepthbuffer->getSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000532 {
533 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
534 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000535 }
536
Jamie Madille261b442014-06-25 12:42:21 -0400537 if (mStencilbuffer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000538 {
Jamie Madille261b442014-06-25 12:42:21 -0400539 if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000540 {
541 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
542 }
543
Jamie Madille261b442014-06-25 12:42:21 -0400544 GLenum internalformat = mStencilbuffer->getInternalFormat();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400545 // TODO(geofflang): use context's texture caps
546 const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -0400547 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madillbb94f342014-06-23 15:23:02 -0400548 if (mStencilbuffer->isTexture())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000549 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000550 // texture stencil attachments come along as part
551 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
Geoff Langc0b9ef42014-07-02 10:02:37 -0400552 // TODO(geofflang): use context's extensions
553 if (!mRenderer->getRendererExtensions().depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000554 {
555 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
556 }
557
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400558 if (!formatCaps.renderable)
Geoff Langcec35902014-04-16 10:52:36 -0400559 {
560 return GL_FRAMEBUFFER_UNSUPPORTED;
561 }
562
Geoff Lang5d601382014-07-22 15:14:06 -0400563 if (formatInfo.stencilBits == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000564 {
565 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
566 }
567 }
568 else
569 {
Geoff Lang5d601382014-07-22 15:14:06 -0400570 if (!formatCaps.renderable || formatInfo.stencilBits == 0)
Jamie Madillbb94f342014-06-23 15:23:02 -0400571 {
572 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
573 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000574 }
575
576 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000577 {
Jamie Madille261b442014-06-25 12:42:21 -0400578 width = mStencilbuffer->getWidth();
579 height = mStencilbuffer->getHeight();
580 samples = mStencilbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000581 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000582 }
Jamie Madille261b442014-06-25 12:42:21 -0400583 else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000584 {
585 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
586 }
Jamie Madille261b442014-06-25 12:42:21 -0400587 else if (samples != mStencilbuffer->getSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000588 {
589 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
590 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000591 }
592
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000593 // if we have both a depth and stencil buffer, they must refer to the same object
594 // since we only support packed_depth_stencil and not separate depth and stencil
Jamie Madille261b442014-06-25 12:42:21 -0400595 if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000596 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000597 return GL_FRAMEBUFFER_UNSUPPORTED;
598 }
599
600 // we need to have at least one attachment to be complete
601 if (missingAttachment)
602 {
603 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000604 }
605
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000606 return GL_FRAMEBUFFER_COMPLETE;
607}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000608
Geoff Lang64f23f62014-09-10 14:40:12 -0400609Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
Jamie Madill2d96b9e2014-08-29 15:46:47 -0400610{
611 GLuint maxDimension = caps.maxRenderbufferSize;
Geoff Lang64f23f62014-09-10 14:40:12 -0400612 return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
Jamie Madill2d96b9e2014-08-29 15:46:47 -0400613}
614
Geoff Lang64f23f62014-09-10 14:40:12 -0400615Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madill400a4412014-08-29 15:46:45 -0400616{
617 ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
Jamie Madill6d708262014-09-03 15:07:13 -0400618 for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
Jamie Madill400a4412014-08-29 15:46:45 -0400619 {
Jamie Madill6d708262014-09-03 15:07:13 -0400620 GLenum attachmentTarget = attachments[attachIndex];
Jamie Madill400a4412014-08-29 15:46:45 -0400621
Geoff Lang64f23f62014-09-10 14:40:12 -0400622 FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
623 : getAttachment(attachmentTarget);
Jamie Madill400a4412014-08-29 15:46:45 -0400624
Jamie Madill6d708262014-09-03 15:07:13 -0400625 if (attachment)
Jamie Madill400a4412014-08-29 15:46:45 -0400626 {
Geoff Lang64f23f62014-09-10 14:40:12 -0400627 rx::RenderTarget *renderTarget = NULL;
628 Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
629 if (error.isError())
Jamie Madill6d708262014-09-03 15:07:13 -0400630 {
Geoff Lang64f23f62014-09-10 14:40:12 -0400631 return error;
Jamie Madill6d708262014-09-03 15:07:13 -0400632 }
Geoff Lang64f23f62014-09-10 14:40:12 -0400633
634 renderTarget->invalidate(x, y, width, height);
Jamie Madill400a4412014-08-29 15:46:45 -0400635 }
636 }
Geoff Lang64f23f62014-09-10 14:40:12 -0400637
638 return Error(GL_NO_ERROR);
Jamie Madill400a4412014-08-29 15:46:45 -0400639}
640
Shannon Woodsf108df22014-10-30 18:53:29 +0000641DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400642 : Framebuffer(renderer, 0)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000643{
Shannon Woodsf108df22014-10-30 18:53:29 +0000644 Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
Jamie Madillaef95de2014-09-05 10:12:41 -0400645 mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000646
Shannon Woodsf108df22014-10-30 18:53:29 +0000647 Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
Jamie Madill28bedaf2014-06-26 13:17:22 -0400648
649 // Make a new attachment objects to ensure we do not double-delete
650 // See angle issue 686
Jamie Madillaef95de2014-09-05 10:12:41 -0400651 mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
652 mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000653
654 mDrawBufferStates[0] = GL_BACK;
655 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000656}
657
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000658int Framebuffer::getSamples() const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000659{
660 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
661 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000662 // for a complete framebuffer, all attachments must have the same sample count
663 // in this case return the first nonzero sample size
664 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
665 {
Jamie Madille261b442014-06-25 12:42:21 -0400666 if (mColorbuffers[colorAttachment])
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000667 {
Jamie Madille261b442014-06-25 12:42:21 -0400668 return mColorbuffers[colorAttachment]->getSamples();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000669 }
670 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000671 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000672
673 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000674}
675
Jamie Madille261b442014-06-25 12:42:21 -0400676bool Framebuffer::hasValidDepthStencil() const
677{
678 // A valid depth-stencil attachment has the same resource bound to both the
679 // depth and stencil attachment points.
680 return (mDepthbuffer && mStencilbuffer &&
681 mDepthbuffer->type() == mStencilbuffer->type() &&
682 mDepthbuffer->id() == mStencilbuffer->id());
683}
684
Jamie Madillce20c7f2014-09-03 11:56:29 -0400685ColorbufferInfo Framebuffer::getColorbuffersForRender() const
686{
687 ColorbufferInfo colorbuffersForRender;
688
689 for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
690 {
691 GLenum drawBufferState = mDrawBufferStates[colorAttachment];
692 FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
693
694 if (colorbuffer != NULL && drawBufferState != GL_NONE)
695 {
696 ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
697 colorbuffersForRender.push_back(colorbuffer);
698 }
Jamie Madill7acae0a2014-09-24 17:10:51 -0400699 else if (!mRenderer->getWorkarounds().mrtPerfWorkaround)
Jamie Madillce20c7f2014-09-03 11:56:29 -0400700 {
701 colorbuffersForRender.push_back(NULL);
702 }
703 }
704
705 return colorbuffersForRender;
706}
707
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000708GLenum DefaultFramebuffer::completeness() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000709{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000710 // The default framebuffer *must* always be complete, though it may not be
711 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000712 return GL_FRAMEBUFFER_COMPLETE;
713}
714
Jamie Madille92a3542014-07-03 10:38:58 -0400715FramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) const
716{
717 switch (attachment)
718 {
Jamie Madill6d708262014-09-03 15:07:13 -0400719 case GL_COLOR:
Jamie Madille92a3542014-07-03 10:38:58 -0400720 case GL_BACK:
721 return getColorbuffer(0);
722 case GL_DEPTH:
723 return getDepthbuffer();
724 case GL_STENCIL:
725 return getStencilbuffer();
726 case GL_DEPTH_STENCIL:
727 return getDepthStencilBuffer();
728 default:
729 UNREACHABLE();
730 return NULL;
731 }
732}
733
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000734}