blob: 875a7a10e2f406b6d883f5214c5b0123e04e97b8 [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"
Shannon Woodse2632d22014-10-17 13:08:51 -040019#include "libGLESv2/renderer/RenderbufferImpl.h"
Jamie Madill7acae0a2014-09-24 17:10:51 -040020#include "libGLESv2/renderer/Workarounds.h"
Jamie Madill9f0b42a2014-09-12 10:25:27 -040021#include "libGLESv2/renderer/d3d/TextureD3D.h"
Shannon Woodse2632d22014-10-17 13:08:51 -040022#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040023
24#include "common/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025
Jamie Madill9f0b42a2014-09-12 10:25:27 -040026namespace rx
27{
Shannon Woodse2632d22014-10-17 13:08:51 -040028// TODO: Move these functions, and the D3D-specific header inclusions above,
29// to FramebufferD3D.
Geoff Lang64f23f62014-09-10 14:40:12 -040030gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
Jamie Madill9f0b42a2014-09-12 10:25:27 -040031{
32 if (attachment->isTexture())
33 {
34 gl::Texture *texture = attachment->getTexture();
35 ASSERT(texture);
36 TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
Jamie Madillac7579c2014-09-17 16:59:33 -040037 const gl::ImageIndex *index = attachment->getTextureImageIndex();
38 ASSERT(index);
Geoff Lang64f23f62014-09-10 14:40:12 -040039 return textureD3D->getRenderTarget(*index, outRT);
Jamie Madill9f0b42a2014-09-12 10:25:27 -040040 }
Geoff Lang64f23f62014-09-10 14:40:12 -040041 else
42 {
43 gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
44 ASSERT(renderbuffer);
Shannon Woodse2632d22014-10-17 13:08:51 -040045 RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
46 *outRT = renderbufferD3D->getRenderTarget();
Geoff Lang64f23f62014-09-10 14:40:12 -040047 return gl::Error(GL_NO_ERROR);
48 }
Jamie Madill9f0b42a2014-09-12 10:25:27 -040049}
50
Jamie Madill612e2e42014-09-12 13:26:55 -040051// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
52unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
53{
54 if (attachment->isTexture())
55 {
56 gl::Texture *texture = attachment->getTexture();
57 ASSERT(texture);
58 TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
Jamie Madillac7579c2014-09-17 16:59:33 -040059 const gl::ImageIndex *index = attachment->getTextureImageIndex();
60 ASSERT(index);
61 return textureD3D->getRenderTargetSerial(*index);
Jamie Madill612e2e42014-09-12 13:26:55 -040062 }
63
64 gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
65 ASSERT(renderbuffer);
Shannon Woodse2632d22014-10-17 13:08:51 -040066 RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
67 return renderbufferD3D->getRenderTargetSerial();
Jamie Madill612e2e42014-09-12 13:26:55 -040068}
69
Jamie Madill9f0b42a2014-09-12 10:25:27 -040070}
71
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072namespace gl
73{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000074
Jamie Madill48faf802014-11-06 15:27:22 -050075Framebuffer::Framebuffer(GLuint id)
76 : mId(id),
Jamie Madille261b442014-06-25 12:42:21 -040077 mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
78 mDepthbuffer(NULL),
79 mStencilbuffer(NULL)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000080{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000081 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
82 {
Jamie Madille261b442014-06-25 12:42:21 -040083 mColorbuffers[colorAttachment] = NULL;
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000084 mDrawBufferStates[colorAttachment] = GL_NONE;
85 }
86 mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000087}
88
89Framebuffer::~Framebuffer()
90{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000091 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
92 {
Jamie Madille261b442014-06-25 12:42:21 -040093 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000094 }
Jamie Madille261b442014-06-25 12:42:21 -040095 SafeDelete(mDepthbuffer);
96 SafeDelete(mStencilbuffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000097}
98
Jamie Madillaef95de2014-09-05 10:12:41 -040099FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000100{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400101 if (handle == 0)
102 {
103 return NULL;
104 }
105
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000106 gl::Context *context = gl::getContext();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000107
Geoff Lang309c92a2013-07-25 16:23:19 -0400108 switch (type)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000109 {
Geoff Lang309c92a2013-07-25 16:23:19 -0400110 case GL_NONE:
111 return NULL;
112
113 case GL_RENDERBUFFER:
Jamie Madillaef95de2014-09-05 10:12:41 -0400114 return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
Geoff Lang309c92a2013-07-25 16:23:19 -0400115
116 case GL_TEXTURE_2D:
117 {
118 Texture *texture = context->getTexture(handle);
119 if (texture && texture->getTarget() == GL_TEXTURE_2D)
120 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400121 return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
Geoff Lang309c92a2013-07-25 16:23:19 -0400122 }
123 else
124 {
125 return NULL;
126 }
127 }
128
129 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
130 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
131 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
132 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
133 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
134 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
135 {
136 Texture *texture = context->getTexture(handle);
137 if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
138 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400139 return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
Geoff Lang309c92a2013-07-25 16:23:19 -0400140 }
141 else
142 {
143 return NULL;
144 }
145 }
146
147 case GL_TEXTURE_3D:
148 {
149 Texture *texture = context->getTexture(handle);
150 if (texture && texture->getTarget() == GL_TEXTURE_3D)
151 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400152 return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
Geoff Lang309c92a2013-07-25 16:23:19 -0400153 }
154 else
155 {
156 return NULL;
157 }
158 }
159
160 case GL_TEXTURE_2D_ARRAY:
161 {
162 Texture *texture = context->getTexture(handle);
163 if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
164 {
Jamie Madilleeb7b0e2014-09-03 15:07:20 -0400165 return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
Geoff Lang309c92a2013-07-25 16:23:19 -0400166 }
167 else
168 {
169 return NULL;
170 }
171 }
172
173 default:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000174 UNREACHABLE();
Geoff Lang309c92a2013-07-25 16:23:19 -0400175 return NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000176 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000177}
178
Geoff Lang309c92a2013-07-25 16:23:19 -0400179void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000180{
181 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400182 SafeDelete(mColorbuffers[colorAttachment]);
Jamie Madillaef95de2014-09-05 10:12:41 -0400183 GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
184 mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000185}
186
Geoff Lang309c92a2013-07-25 16:23:19 -0400187void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188{
Jamie Madille261b442014-06-25 12:42:21 -0400189 SafeDelete(mDepthbuffer);
Jamie Madillaef95de2014-09-05 10:12:41 -0400190 mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191}
192
Geoff Lang309c92a2013-07-25 16:23:19 -0400193void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194{
Jamie Madille261b442014-06-25 12:42:21 -0400195 SafeDelete(mStencilbuffer);
Jamie Madillaef95de2014-09-05 10:12:41 -0400196 mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000197}
198
Geoff Lang309c92a2013-07-25 16:23:19 -0400199void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400200{
Jamie Madillaef95de2014-09-05 10:12:41 -0400201 FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400202
Jamie Madille261b442014-06-25 12:42:21 -0400203 SafeDelete(mDepthbuffer);
204 SafeDelete(mStencilbuffer);
205
206 // ensure this is a legitimate depth+stencil format
Geoff Lange4a492b2014-06-19 14:14:41 -0400207 if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400208 {
Jamie Madille261b442014-06-25 12:42:21 -0400209 mDepthbuffer = attachment;
Jamie Madill28bedaf2014-06-26 13:17:22 -0400210
211 // Make a new attachment object to ensure we do not double-delete
212 // See angle issue 686
Jamie Madillaef95de2014-09-05 10:12:41 -0400213 mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400214 }
215}
216
Jamie Madille261b442014-06-25 12:42:21 -0400217void Framebuffer::detachTexture(GLuint textureId)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000219 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000220 {
Jamie Madille261b442014-06-25 12:42:21 -0400221 FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
222
223 if (attachment && attachment->isTextureWithId(textureId))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000224 {
Jamie Madille261b442014-06-25 12:42:21 -0400225 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000226 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000228
Jamie Madille261b442014-06-25 12:42:21 -0400229 if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000230 {
Jamie Madille261b442014-06-25 12:42:21 -0400231 SafeDelete(mDepthbuffer);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000232 }
233
Jamie Madille261b442014-06-25 12:42:21 -0400234 if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000235 {
Jamie Madille261b442014-06-25 12:42:21 -0400236 SafeDelete(mStencilbuffer);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000237 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238}
239
Jamie Madille261b442014-06-25 12:42:21 -0400240void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000241{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000242 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000243 {
Jamie Madille261b442014-06-25 12:42:21 -0400244 FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
245
246 if (attachment && attachment->isRenderbufferWithId(renderbufferId))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000247 {
Jamie Madille261b442014-06-25 12:42:21 -0400248 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000249 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000250 }
251
Jamie Madille261b442014-06-25 12:42:21 -0400252 if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000253 {
Jamie Madille261b442014-06-25 12:42:21 -0400254 SafeDelete(mDepthbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000255 }
256
Jamie Madille261b442014-06-25 12:42:21 -0400257 if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000258 {
Jamie Madille261b442014-06-25 12:42:21 -0400259 SafeDelete(mStencilbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260 }
261}
262
Jamie Madill3c7fa222014-06-05 13:08:51 -0400263FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000264{
265 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400266 return mColorbuffers[colorAttachment];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000267}
268
Jamie Madill3c7fa222014-06-05 13:08:51 -0400269FramebufferAttachment *Framebuffer::getDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000270{
Jamie Madille261b442014-06-25 12:42:21 -0400271 return mDepthbuffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000272}
273
Jamie Madill3c7fa222014-06-05 13:08:51 -0400274FramebufferAttachment *Framebuffer::getStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275{
Jamie Madille261b442014-06-25 12:42:21 -0400276 return mStencilbuffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277}
278
Jamie Madill3c7fa222014-06-05 13:08:51 -0400279FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
Geoff Lang646559f2013-08-15 11:08:15 -0400280{
Jamie Madille261b442014-06-25 12:42:21 -0400281 return (hasValidDepthStencil() ? mDepthbuffer : NULL);
Geoff Lang646559f2013-08-15 11:08:15 -0400282}
283
Jamie Madill3c7fa222014-06-05 13:08:51 -0400284FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000285{
Jamie Madille261b442014-06-25 12:42:21 -0400286 FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000287
288 if (!depthstencilbuffer)
289 {
Jamie Madille261b442014-06-25 12:42:21 -0400290 depthstencilbuffer = mStencilbuffer;
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000291 }
292
293 return depthstencilbuffer;
294}
295
Jamie Madill3c7fa222014-06-05 13:08:51 -0400296FramebufferAttachment *Framebuffer::getReadColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000297{
298 // Will require more logic if glReadBuffers is supported
Jamie Madille261b442014-06-25 12:42:21 -0400299 return mColorbuffers[0];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000300}
301
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000302GLenum Framebuffer::getReadColorbufferType() const
303{
304 // Will require more logic if glReadBuffers is supported
Jamie Madille261b442014-06-25 12:42:21 -0400305 return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000306}
307
Jamie Madill3c7fa222014-06-05 13:08:51 -0400308FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000309{
310 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
311 {
Jamie Madille261b442014-06-25 12:42:21 -0400312 if (mColorbuffers[colorAttachment])
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000313 {
Jamie Madille261b442014-06-25 12:42:21 -0400314 return mColorbuffers[colorAttachment];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000315 }
316 }
317
318 return NULL;
319}
320
Jamie Madille92a3542014-07-03 10:38:58 -0400321FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000322{
Jamie Madille92a3542014-07-03 10:38:58 -0400323 if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
324 {
325 return getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
326 }
327 else
328 {
329 switch (attachment)
330 {
331 case GL_DEPTH_ATTACHMENT:
332 return getDepthbuffer();
333 case GL_STENCIL_ATTACHMENT:
334 return getStencilbuffer();
335 case GL_DEPTH_STENCIL_ATTACHMENT:
336 return getDepthStencilBuffer();
337 default:
338 UNREACHABLE();
339 return NULL;
340 }
341 }
Geoff Lang55ba29c2013-07-11 16:57:53 -0400342}
343
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000344GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
345{
346 return mDrawBufferStates[colorAttachment];
347}
348
349void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
350{
351 mDrawBufferStates[colorAttachment] = drawBuffer;
352}
353
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000354bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
355{
Jamie Madille261b442014-06-25 12:42:21 -0400356 return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000357}
358
359bool Framebuffer::hasEnabledColorAttachment() const
360{
361 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
362 {
363 if (isEnabledColorAttachment(colorAttachment))
364 {
365 return true;
366 }
367 }
368
369 return false;
370}
371
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000372bool Framebuffer::hasStencil() const
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000373{
Geoff Lange4a492b2014-06-19 14:14:41 -0400374 return (mStencilbuffer && mStencilbuffer->getStencilSize() > 0);
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000375}
376
shannonwoods@chromium.org24ac8502013-05-30 00:01:37 +0000377bool Framebuffer::usingExtendedDrawBuffers() const
378{
379 for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
380 {
381 if (isEnabledColorAttachment(colorAttachment))
382 {
383 return true;
384 }
385 }
386
387 return false;
388}
389
Jamie Madill48faf802014-11-06 15:27:22 -0500390GLenum Framebuffer::completeness(const gl::Data &data) const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000392 int width = 0;
393 int height = 0;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000394 unsigned int colorbufferSize = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000395 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000396 bool missingAttachment = true;
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();
Jamie Madill48faf802014-11-06 15:27:22 -0500410 const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -0400411 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madillbb94f342014-06-23 15:23:02 -0400412 if (colorbuffer->isTexture())
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000413 {
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400414 if (!formatCaps.renderable)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000415 {
416 return GL_FRAMEBUFFER_UNSUPPORTED;
417 }
418
Geoff Lang5d601382014-07-22 15:14:06 -0400419 if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000420 {
421 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
422 }
423 }
424 else
425 {
Geoff Lang5d601382014-07-22 15:14:06 -0400426 if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
Jamie Madillbb94f342014-06-23 15:23:02 -0400427 {
428 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
429 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000430 }
431
432 if (!missingAttachment)
433 {
434 // all color attachments must have the same width and height
435 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
436 {
437 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
438 }
439
440 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
441 // all color attachments have the same number of samples for the FBO to be complete.
442 if (colorbuffer->getSamples() != samples)
443 {
444 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
445 }
446
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000447 // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
448 // in GLES 3.0, there is no such restriction
Jamie Madill48faf802014-11-06 15:27:22 -0500449 if (data.clientVersion < 3)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000450 {
Geoff Lang5d601382014-07-22 15:14:06 -0400451 if (formatInfo.pixelBytes != colorbufferSize)
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000452 {
453 return GL_FRAMEBUFFER_UNSUPPORTED;
454 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000455 }
456
457 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
458 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
459 {
Jamie Madille92a3542014-07-03 10:38:58 -0400460 const FramebufferAttachment *previousAttachment = mColorbuffers[previousColorAttachment];
461
462 if (previousAttachment &&
463 (colorbuffer->id() == previousAttachment->id() &&
464 colorbuffer->type() == previousAttachment->type()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000465 {
466 return GL_FRAMEBUFFER_UNSUPPORTED;
467 }
468 }
469 }
470 else
471 {
472 width = colorbuffer->getWidth();
473 height = colorbuffer->getHeight();
474 samples = colorbuffer->getSamples();
Geoff Lang5d601382014-07-22 15:14:06 -0400475 colorbufferSize = formatInfo.pixelBytes;
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000476 missingAttachment = false;
477 }
478 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000479 }
480
Jamie Madille261b442014-06-25 12:42:21 -0400481 if (mDepthbuffer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000482 {
Jamie Madille261b442014-06-25 12:42:21 -0400483 if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000485 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000486 }
487
Jamie Madille261b442014-06-25 12:42:21 -0400488 GLenum internalformat = mDepthbuffer->getInternalFormat();
Jamie Madill48faf802014-11-06 15:27:22 -0500489 const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -0400490 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madillbb94f342014-06-23 15:23:02 -0400491 if (mDepthbuffer->isTexture())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000492 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000493 // depth texture attachments require OES/ANGLE_depth_texture
Jamie Madill48faf802014-11-06 15:27:22 -0500494 if (!data.extensions->depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000495 {
496 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
497 }
498
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400499 if (!formatCaps.renderable)
Geoff Langcec35902014-04-16 10:52:36 -0400500 {
501 return GL_FRAMEBUFFER_UNSUPPORTED;
502 }
503
Geoff Lang5d601382014-07-22 15:14:06 -0400504 if (formatInfo.depthBits == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000505 {
506 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
507 }
508 }
509 else
510 {
Geoff Lang5d601382014-07-22 15:14:06 -0400511 if (!formatCaps.renderable || formatInfo.depthBits == 0)
Jamie Madillbb94f342014-06-23 15:23:02 -0400512 {
513 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
514 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000515 }
516
517 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000518 {
Jamie Madille261b442014-06-25 12:42:21 -0400519 width = mDepthbuffer->getWidth();
520 height = mDepthbuffer->getHeight();
521 samples = mDepthbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000522 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000523 }
Jamie Madille261b442014-06-25 12:42:21 -0400524 else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000525 {
526 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
527 }
Jamie Madille261b442014-06-25 12:42:21 -0400528 else if (samples != mDepthbuffer->getSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000529 {
530 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
531 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000532 }
533
Jamie Madille261b442014-06-25 12:42:21 -0400534 if (mStencilbuffer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000535 {
Jamie Madille261b442014-06-25 12:42:21 -0400536 if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000537 {
538 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
539 }
540
Jamie Madille261b442014-06-25 12:42:21 -0400541 GLenum internalformat = mStencilbuffer->getInternalFormat();
Jamie Madill48faf802014-11-06 15:27:22 -0500542 const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -0400543 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madillbb94f342014-06-23 15:23:02 -0400544 if (mStencilbuffer->isTexture())
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000545 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000546 // texture stencil attachments come along as part
547 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
Jamie Madill48faf802014-11-06 15:27:22 -0500548 if (!data.extensions->depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000549 {
550 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
551 }
552
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400553 if (!formatCaps.renderable)
Geoff Langcec35902014-04-16 10:52:36 -0400554 {
555 return GL_FRAMEBUFFER_UNSUPPORTED;
556 }
557
Geoff Lang5d601382014-07-22 15:14:06 -0400558 if (formatInfo.stencilBits == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000559 {
560 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
561 }
562 }
563 else
564 {
Geoff Lang5d601382014-07-22 15:14:06 -0400565 if (!formatCaps.renderable || formatInfo.stencilBits == 0)
Jamie Madillbb94f342014-06-23 15:23:02 -0400566 {
567 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
568 }
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000569 }
570
571 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000572 {
Jamie Madille261b442014-06-25 12:42:21 -0400573 width = mStencilbuffer->getWidth();
574 height = mStencilbuffer->getHeight();
575 samples = mStencilbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000576 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000577 }
Jamie Madille261b442014-06-25 12:42:21 -0400578 else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000579 {
580 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
581 }
Jamie Madille261b442014-06-25 12:42:21 -0400582 else if (samples != mStencilbuffer->getSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000583 {
584 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
585 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000586 }
587
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000588 // if we have both a depth and stencil buffer, they must refer to the same object
589 // since we only support packed_depth_stencil and not separate depth and stencil
Jamie Madille261b442014-06-25 12:42:21 -0400590 if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000591 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000592 return GL_FRAMEBUFFER_UNSUPPORTED;
593 }
594
595 // we need to have at least one attachment to be complete
596 if (missingAttachment)
597 {
598 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000599 }
600
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000601 return GL_FRAMEBUFFER_COMPLETE;
602}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000603
Geoff Lang64f23f62014-09-10 14:40:12 -0400604Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
Jamie Madill2d96b9e2014-08-29 15:46:47 -0400605{
606 GLuint maxDimension = caps.maxRenderbufferSize;
Geoff Lang64f23f62014-09-10 14:40:12 -0400607 return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
Jamie Madill2d96b9e2014-08-29 15:46:47 -0400608}
609
Geoff Lang64f23f62014-09-10 14:40:12 -0400610Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madill400a4412014-08-29 15:46:45 -0400611{
Jamie Madill6d708262014-09-03 15:07:13 -0400612 for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
Jamie Madill400a4412014-08-29 15:46:45 -0400613 {
Jamie Madill6d708262014-09-03 15:07:13 -0400614 GLenum attachmentTarget = attachments[attachIndex];
Jamie Madill400a4412014-08-29 15:46:45 -0400615
Geoff Lang64f23f62014-09-10 14:40:12 -0400616 FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
617 : getAttachment(attachmentTarget);
Jamie Madill400a4412014-08-29 15:46:45 -0400618
Jamie Madill6d708262014-09-03 15:07:13 -0400619 if (attachment)
Jamie Madill400a4412014-08-29 15:46:45 -0400620 {
Geoff Lang64f23f62014-09-10 14:40:12 -0400621 rx::RenderTarget *renderTarget = NULL;
622 Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
623 if (error.isError())
Jamie Madill6d708262014-09-03 15:07:13 -0400624 {
Geoff Lang64f23f62014-09-10 14:40:12 -0400625 return error;
Jamie Madill6d708262014-09-03 15:07:13 -0400626 }
Geoff Lang64f23f62014-09-10 14:40:12 -0400627
628 renderTarget->invalidate(x, y, width, height);
Jamie Madill400a4412014-08-29 15:46:45 -0400629 }
630 }
Geoff Lang64f23f62014-09-10 14:40:12 -0400631
632 return Error(GL_NO_ERROR);
Jamie Madill400a4412014-08-29 15:46:45 -0400633}
634
Jamie Madill48faf802014-11-06 15:27:22 -0500635DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
636 : Framebuffer(0)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000637{
Shannon Woodse2632d22014-10-17 13:08:51 -0400638 Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
Jamie Madillaef95de2014-09-05 10:12:41 -0400639 mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000640
Shannon Woodse2632d22014-10-17 13:08:51 -0400641 Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
Jamie Madill28bedaf2014-06-26 13:17:22 -0400642
643 // Make a new attachment objects to ensure we do not double-delete
644 // See angle issue 686
Jamie Madillaef95de2014-09-05 10:12:41 -0400645 mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
646 mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000647
648 mDrawBufferStates[0] = GL_BACK;
649 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000650}
651
Jamie Madill48faf802014-11-06 15:27:22 -0500652int Framebuffer::getSamples(const gl::Data &data) const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000653{
Jamie Madill48faf802014-11-06 15:27:22 -0500654 if (completeness(data) == GL_FRAMEBUFFER_COMPLETE)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000655 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000656 // for a complete framebuffer, all attachments must have the same sample count
657 // in this case return the first nonzero sample size
658 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
659 {
Jamie Madille261b442014-06-25 12:42:21 -0400660 if (mColorbuffers[colorAttachment])
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000661 {
Jamie Madille261b442014-06-25 12:42:21 -0400662 return mColorbuffers[colorAttachment]->getSamples();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000663 }
664 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000665 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000666
667 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000668}
669
Jamie Madille261b442014-06-25 12:42:21 -0400670bool Framebuffer::hasValidDepthStencil() const
671{
672 // A valid depth-stencil attachment has the same resource bound to both the
673 // depth and stencil attachment points.
674 return (mDepthbuffer && mStencilbuffer &&
675 mDepthbuffer->type() == mStencilbuffer->type() &&
676 mDepthbuffer->id() == mStencilbuffer->id());
677}
678
Jamie Madill48faf802014-11-06 15:27:22 -0500679ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const
Jamie Madillce20c7f2014-09-03 11:56:29 -0400680{
681 ColorbufferInfo colorbuffersForRender;
682
683 for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
684 {
685 GLenum drawBufferState = mDrawBufferStates[colorAttachment];
686 FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
687
688 if (colorbuffer != NULL && drawBufferState != GL_NONE)
689 {
690 ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
691 colorbuffersForRender.push_back(colorbuffer);
692 }
Jamie Madill48faf802014-11-06 15:27:22 -0500693 else if (!workarounds.mrtPerfWorkaround)
Jamie Madillce20c7f2014-09-03 11:56:29 -0400694 {
695 colorbuffersForRender.push_back(NULL);
696 }
697 }
698
699 return colorbuffersForRender;
700}
701
Jamie Madill48faf802014-11-06 15:27:22 -0500702GLenum DefaultFramebuffer::completeness(const gl::Data &) const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000703{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000704 // The default framebuffer *must* always be complete, though it may not be
705 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000706 return GL_FRAMEBUFFER_COMPLETE;
707}
708
Jamie Madille92a3542014-07-03 10:38:58 -0400709FramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) const
710{
711 switch (attachment)
712 {
Jamie Madill6d708262014-09-03 15:07:13 -0400713 case GL_COLOR:
Jamie Madille92a3542014-07-03 10:38:58 -0400714 case GL_BACK:
715 return getColorbuffer(0);
716 case GL_DEPTH:
717 return getDepthbuffer();
718 case GL_STENCIL:
719 return getStencilbuffer();
720 case GL_DEPTH_STENCIL:
721 return getDepthStencilBuffer();
722 default:
723 UNREACHABLE();
724 return NULL;
725 }
726}
727
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728}