blob: 5fc8232a99c26e4fd28d113389466e4a746a4f50 [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"
Jamie Madille261b442014-06-25 12:42:21 -040020#include "libGLESv2/FramebufferAttachment.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000021
22namespace gl
23{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000024
daniel@transgaming.com16418b12012-11-28 19:32:22 +000025Framebuffer::Framebuffer(rx::Renderer *renderer)
Jamie Madille261b442014-06-25 12:42:21 -040026 : mRenderer(renderer),
27 mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
28 mDepthbuffer(NULL),
29 mStencilbuffer(NULL)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000031 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
32 {
Jamie Madille261b442014-06-25 12:42:21 -040033 mColorbuffers[colorAttachment] = NULL;
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000034 mDrawBufferStates[colorAttachment] = GL_NONE;
35 }
36 mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037}
38
39Framebuffer::~Framebuffer()
40{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000041 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
42 {
Jamie Madille261b442014-06-25 12:42:21 -040043 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +000044 }
Jamie Madille261b442014-06-25 12:42:21 -040045 SafeDelete(mDepthbuffer);
46 SafeDelete(mStencilbuffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000047}
48
Jamie Madille261b442014-06-25 12:42:21 -040049FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000050{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040051 if (handle == 0)
52 {
53 return NULL;
54 }
55
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000056 gl::Context *context = gl::getContext();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000057
Geoff Lang309c92a2013-07-25 16:23:19 -040058 switch (type)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000059 {
Geoff Lang309c92a2013-07-25 16:23:19 -040060 case GL_NONE:
61 return NULL;
62
63 case GL_RENDERBUFFER:
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040064 return new RenderbufferAttachment(context->getRenderbuffer(handle));
Geoff Lang309c92a2013-07-25 16:23:19 -040065
66 case GL_TEXTURE_2D:
67 {
68 Texture *texture = context->getTexture(handle);
69 if (texture && texture->getTarget() == GL_TEXTURE_2D)
70 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040071 Texture2D *tex2D = static_cast<Texture2D*>(texture);
72 return new Texture2DAttachment(tex2D, level);
Geoff Lang309c92a2013-07-25 16:23:19 -040073 }
74 else
75 {
76 return NULL;
77 }
78 }
79
80 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
81 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
82 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
83 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
84 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
85 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
86 {
87 Texture *texture = context->getTexture(handle);
88 if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
89 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -040090 TextureCubeMap *texCube = static_cast<TextureCubeMap*>(texture);
91 return new TextureCubeMapAttachment(texCube, type, level);
Geoff Lang309c92a2013-07-25 16:23:19 -040092 }
93 else
94 {
95 return NULL;
96 }
97 }
98
99 case GL_TEXTURE_3D:
100 {
101 Texture *texture = context->getTexture(handle);
102 if (texture && texture->getTarget() == GL_TEXTURE_3D)
103 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400104 Texture3D *tex3D = static_cast<Texture3D*>(texture);
105 return new Texture3DAttachment(tex3D, level, layer);
Geoff Lang309c92a2013-07-25 16:23:19 -0400106 }
107 else
108 {
109 return NULL;
110 }
111 }
112
113 case GL_TEXTURE_2D_ARRAY:
114 {
115 Texture *texture = context->getTexture(handle);
116 if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
117 {
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400118 Texture2DArray *tex2DArray = static_cast<Texture2DArray*>(texture);
119 return new Texture2DArrayAttachment(tex2DArray, level, layer);
Geoff Lang309c92a2013-07-25 16:23:19 -0400120 }
121 else
122 {
123 return NULL;
124 }
125 }
126
127 default:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000128 UNREACHABLE();
Geoff Lang309c92a2013-07-25 16:23:19 -0400129 return NULL;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000130 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131}
132
Geoff Lang309c92a2013-07-25 16:23:19 -0400133void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000134{
135 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400136 SafeDelete(mColorbuffers[colorAttachment]);
137 mColorbuffers[colorAttachment] = createAttachment(type, colorbuffer, level, layer);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000138}
139
Geoff Lang309c92a2013-07-25 16:23:19 -0400140void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141{
Jamie Madille261b442014-06-25 12:42:21 -0400142 SafeDelete(mDepthbuffer);
143 mDepthbuffer = createAttachment(type, depthbuffer, level, layer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144}
145
Geoff Lang309c92a2013-07-25 16:23:19 -0400146void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000147{
Jamie Madille261b442014-06-25 12:42:21 -0400148 SafeDelete(mStencilbuffer);
149 mStencilbuffer = createAttachment(type, stencilbuffer, level, layer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150}
151
Geoff Lang309c92a2013-07-25 16:23:19 -0400152void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400153{
Jamie Madille261b442014-06-25 12:42:21 -0400154 FramebufferAttachment *attachment = createAttachment(type, depthStencilBuffer, level, layer);
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400155
Jamie Madille261b442014-06-25 12:42:21 -0400156 SafeDelete(mDepthbuffer);
157 SafeDelete(mStencilbuffer);
158
159 // ensure this is a legitimate depth+stencil format
160 int clientVersion = mRenderer->getCurrentClientVersion();
161 if (attachment && attachment->getDepthSize(clientVersion) > 0 && attachment->getStencilSize(clientVersion) > 0)
Geoff Lang55ba29c2013-07-11 16:57:53 -0400162 {
Jamie Madille261b442014-06-25 12:42:21 -0400163 mDepthbuffer = attachment;
164 mStencilbuffer = attachment;
Geoff Lang55ba29c2013-07-11 16:57:53 -0400165 }
166}
167
Jamie Madille261b442014-06-25 12:42:21 -0400168void Framebuffer::detachTexture(GLuint textureId)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000170 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000171 {
Jamie Madille261b442014-06-25 12:42:21 -0400172 FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
173
174 if (attachment && attachment->isTextureWithId(textureId))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000175 {
Jamie Madille261b442014-06-25 12:42:21 -0400176 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000177 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000179
Jamie Madille261b442014-06-25 12:42:21 -0400180 if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000181 {
Jamie Madille261b442014-06-25 12:42:21 -0400182 SafeDelete(mDepthbuffer);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000183 }
184
Jamie Madille261b442014-06-25 12:42:21 -0400185 if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000186 {
Jamie Madille261b442014-06-25 12:42:21 -0400187 SafeDelete(mStencilbuffer);
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000188 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189}
190
Jamie Madille261b442014-06-25 12:42:21 -0400191void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000192{
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000193 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194 {
Jamie Madille261b442014-06-25 12:42:21 -0400195 FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
196
197 if (attachment && attachment->isRenderbufferWithId(renderbufferId))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000198 {
Jamie Madille261b442014-06-25 12:42:21 -0400199 SafeDelete(mColorbuffers[colorAttachment]);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000200 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201 }
202
Jamie Madille261b442014-06-25 12:42:21 -0400203 if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204 {
Jamie Madille261b442014-06-25 12:42:21 -0400205 SafeDelete(mDepthbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000206 }
207
Jamie Madille261b442014-06-25 12:42:21 -0400208 if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209 {
Jamie Madille261b442014-06-25 12:42:21 -0400210 SafeDelete(mStencilbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211 }
212}
213
Jamie Madill3c7fa222014-06-05 13:08:51 -0400214FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000215{
216 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400217 return mColorbuffers[colorAttachment];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000218}
219
Jamie Madill3c7fa222014-06-05 13:08:51 -0400220FramebufferAttachment *Framebuffer::getDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000221{
Jamie Madille261b442014-06-25 12:42:21 -0400222 return mDepthbuffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223}
224
Jamie Madill3c7fa222014-06-05 13:08:51 -0400225FramebufferAttachment *Framebuffer::getStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000226{
Jamie Madille261b442014-06-25 12:42:21 -0400227 return mStencilbuffer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228}
229
Jamie Madill3c7fa222014-06-05 13:08:51 -0400230FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
Geoff Lang646559f2013-08-15 11:08:15 -0400231{
Jamie Madille261b442014-06-25 12:42:21 -0400232 return (hasValidDepthStencil() ? mDepthbuffer : NULL);
Geoff Lang646559f2013-08-15 11:08:15 -0400233}
234
Jamie Madill3c7fa222014-06-05 13:08:51 -0400235FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000236{
Jamie Madille261b442014-06-25 12:42:21 -0400237 FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000238
239 if (!depthstencilbuffer)
240 {
Jamie Madille261b442014-06-25 12:42:21 -0400241 depthstencilbuffer = mStencilbuffer;
daniel@transgaming.comd2b47022012-11-28 19:40:10 +0000242 }
243
244 return depthstencilbuffer;
245}
246
Jamie Madill3c7fa222014-06-05 13:08:51 -0400247FramebufferAttachment *Framebuffer::getReadColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000248{
249 // Will require more logic if glReadBuffers is supported
Jamie Madille261b442014-06-25 12:42:21 -0400250 return mColorbuffers[0];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000251}
252
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000253GLenum Framebuffer::getReadColorbufferType() const
254{
255 // Will require more logic if glReadBuffers is supported
Jamie Madille261b442014-06-25 12:42:21 -0400256 return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comf6863e02013-04-13 03:34:00 +0000257}
258
Jamie Madill3c7fa222014-06-05 13:08:51 -0400259FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000260{
261 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
262 {
Jamie Madille261b442014-06-25 12:42:21 -0400263 if (mColorbuffers[colorAttachment])
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000264 {
Jamie Madille261b442014-06-25 12:42:21 -0400265 return mColorbuffers[colorAttachment];
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000266 }
267 }
268
269 return NULL;
270}
271
272GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
273{
274 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400275 return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->type() : GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000276}
277
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000278GLenum Framebuffer::getDepthbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000279{
Jamie Madille261b442014-06-25 12:42:21 -0400280 return (mDepthbuffer ? mDepthbuffer->type() : GL_NONE);
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000281}
282
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000283GLenum Framebuffer::getStencilbufferType() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000284{
Jamie Madille261b442014-06-25 12:42:21 -0400285 return (mStencilbuffer ? mStencilbuffer->type() : GL_NONE);
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000286}
287
Geoff Lang55ba29c2013-07-11 16:57:53 -0400288GLenum Framebuffer::getDepthStencilbufferType() const
289{
Jamie Madille261b442014-06-25 12:42:21 -0400290 return (hasValidDepthStencil() ? mDepthbuffer->type() : GL_NONE);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400291}
292
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000293GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
294{
295 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400296 return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->id() : 0);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000297}
298
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000299GLuint Framebuffer::getDepthbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000300{
Jamie Madille261b442014-06-25 12:42:21 -0400301 return (mDepthbuffer ? mDepthbuffer->id() : 0);
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000302}
303
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000304GLuint Framebuffer::getStencilbufferHandle() const
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000305{
Jamie Madille261b442014-06-25 12:42:21 -0400306 return (mStencilbuffer ? mStencilbuffer->id() : 0);
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000307}
308
Jamie Madille261b442014-06-25 12:42:21 -0400309GLuint Framebuffer::getDepthStencilbufferHandle() const
Geoff Lang55ba29c2013-07-11 16:57:53 -0400310{
Jamie Madille261b442014-06-25 12:42:21 -0400311 return (hasValidDepthStencil() ? mDepthbuffer->id() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400312}
313
Jamie Madille261b442014-06-25 12:42:21 -0400314GLint Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
Geoff Langc90d73a2013-07-22 16:39:23 -0400315{
316 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400317 return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->mipLevel() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400318}
319
Jamie Madille261b442014-06-25 12:42:21 -0400320GLint Framebuffer::getDepthbufferMipLevel() const
Geoff Langc90d73a2013-07-22 16:39:23 -0400321{
Jamie Madille261b442014-06-25 12:42:21 -0400322 return (mDepthbuffer ? mDepthbuffer->mipLevel() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400323}
324
Jamie Madille261b442014-06-25 12:42:21 -0400325GLint Framebuffer::getStencilbufferMipLevel() const
Geoff Langc90d73a2013-07-22 16:39:23 -0400326{
Jamie Madille261b442014-06-25 12:42:21 -0400327 return (mStencilbuffer ? mStencilbuffer->mipLevel() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400328}
329
Jamie Madille261b442014-06-25 12:42:21 -0400330GLint Framebuffer::getDepthStencilbufferMipLevel() const
Geoff Langc90d73a2013-07-22 16:39:23 -0400331{
Jamie Madille261b442014-06-25 12:42:21 -0400332 return (hasValidDepthStencil() ? mDepthbuffer->mipLevel() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400333}
334
Jamie Madille261b442014-06-25 12:42:21 -0400335GLint Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
Geoff Langc90d73a2013-07-22 16:39:23 -0400336{
337 ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
Jamie Madille261b442014-06-25 12:42:21 -0400338 return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->layer() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400339}
340
Jamie Madille261b442014-06-25 12:42:21 -0400341GLint Framebuffer::getDepthbufferLayer() const
Geoff Langc90d73a2013-07-22 16:39:23 -0400342{
Jamie Madille261b442014-06-25 12:42:21 -0400343 return (mDepthbuffer ? mDepthbuffer->layer() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400344}
345
Jamie Madille261b442014-06-25 12:42:21 -0400346GLint Framebuffer::getStencilbufferLayer() const
Geoff Langc90d73a2013-07-22 16:39:23 -0400347{
Jamie Madille261b442014-06-25 12:42:21 -0400348 return (mStencilbuffer ? mStencilbuffer->layer() : 0);
Geoff Langc90d73a2013-07-22 16:39:23 -0400349}
350
Jamie Madille261b442014-06-25 12:42:21 -0400351GLint Framebuffer::getDepthStencilbufferLayer() const
Geoff Langc90d73a2013-07-22 16:39:23 -0400352{
Jamie Madille261b442014-06-25 12:42:21 -0400353 return (hasValidDepthStencil() ? mDepthbuffer->layer() : 0);
Geoff Lang55ba29c2013-07-11 16:57:53 -0400354}
355
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000356GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
357{
358 return mDrawBufferStates[colorAttachment];
359}
360
361void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
362{
363 mDrawBufferStates[colorAttachment] = drawBuffer;
364}
365
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000366bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
367{
Jamie Madille261b442014-06-25 12:42:21 -0400368 return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +0000369}
370
371bool Framebuffer::hasEnabledColorAttachment() const
372{
373 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
374 {
375 if (isEnabledColorAttachment(colorAttachment))
376 {
377 return true;
378 }
379 }
380
381 return false;
382}
383
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000384bool Framebuffer::hasStencil() const
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000385{
Jamie Madille261b442014-06-25 12:42:21 -0400386 if (mStencilbuffer)
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000387 {
Jamie Madille261b442014-06-25 12:42:21 -0400388 int clientVersion = mRenderer->getCurrentClientVersion();
389 return (mStencilbuffer->getStencilSize(clientVersion) > 0);
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000390 }
391
392 return false;
393}
394
shannonwoods@chromium.org24ac8502013-05-30 00:01:37 +0000395bool Framebuffer::usingExtendedDrawBuffers() const
396{
397 for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
398 {
399 if (isEnabledColorAttachment(colorAttachment))
400 {
401 return true;
402 }
403 }
404
405 return false;
406}
407
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000408GLenum Framebuffer::completeness() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000409{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000410 int width = 0;
411 int height = 0;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000412 unsigned int colorbufferSize = 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000413 int samples = -1;
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000414 bool missingAttachment = true;
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000415 GLuint clientVersion = mRenderer->getCurrentClientVersion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000416
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000417 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000418 {
Jamie Madille261b442014-06-25 12:42:21 -0400419 if (mColorbuffers[colorAttachment])
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000420 {
Jamie Madille261b442014-06-25 12:42:21 -0400421 const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000422
Jamie Madille261b442014-06-25 12:42:21 -0400423 if (colorbuffer->type() == GL_NONE)
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000424 {
425 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
426 }
daniel@transgaming.comd885df02012-05-31 01:14:36 +0000427
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000428 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000429 {
430 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
431 }
daniel@transgaming.com01868132010-08-24 19:21:17 +0000432
Geoff Langcec35902014-04-16 10:52:36 -0400433 GLenum internalformat = colorbuffer->getInternalFormat();
434 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Jamie Madille261b442014-06-25 12:42:21 -0400435 if (colorbuffer->type() == GL_RENDERBUFFER)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000436 {
Geoff Langcec35902014-04-16 10:52:36 -0400437 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000438 {
439 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
440 }
441 }
Jamie Madille261b442014-06-25 12:42:21 -0400442 else if (IsInternalTextureTarget(colorbuffer->type(), mRenderer->getCurrentClientVersion()))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000443 {
Geoff Langcec35902014-04-16 10:52:36 -0400444 if (!formatCaps.colorRendering)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000445 {
446 return GL_FRAMEBUFFER_UNSUPPORTED;
447 }
448
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000449 if (gl::GetDepthBits(internalformat, clientVersion) > 0 ||
450 gl::GetStencilBits(internalformat, clientVersion) > 0)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000451 {
452 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
453 }
454 }
455 else
456 {
457 UNREACHABLE();
458 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
459 }
460
461 if (!missingAttachment)
462 {
463 // all color attachments must have the same width and height
464 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
465 {
466 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
467 }
468
469 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
470 // all color attachments have the same number of samples for the FBO to be complete.
471 if (colorbuffer->getSamples() != samples)
472 {
473 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
474 }
475
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000476 // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
477 // in GLES 3.0, there is no such restriction
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000478 if (clientVersion < 3)
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000479 {
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000480 if (gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion) != colorbufferSize)
shannon.woods%transgaming.com@gtempaccount.comc3471522013-04-13 03:34:52 +0000481 {
482 return GL_FRAMEBUFFER_UNSUPPORTED;
483 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000484 }
485
486 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
487 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
488 {
Jamie Madille261b442014-06-25 12:42:21 -0400489 if (colorbuffer->id() == getColorbufferHandle(previousColorAttachment) &&
490 colorbuffer->type() == getColorbufferType(previousColorAttachment))
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000491 {
492 return GL_FRAMEBUFFER_UNSUPPORTED;
493 }
494 }
495 }
496 else
497 {
498 width = colorbuffer->getWidth();
499 height = colorbuffer->getHeight();
500 samples = colorbuffer->getSamples();
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000501 colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000502 missingAttachment = false;
503 }
504 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000505 }
506
Jamie Madille261b442014-06-25 12:42:21 -0400507 if (mDepthbuffer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000508 {
Jamie Madille261b442014-06-25 12:42:21 -0400509 if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000511 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512 }
513
Jamie Madille261b442014-06-25 12:42:21 -0400514 GLenum internalformat = mDepthbuffer->getInternalFormat();
Geoff Langcec35902014-04-16 10:52:36 -0400515 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Jamie Madille261b442014-06-25 12:42:21 -0400516 if (mDepthbuffer->type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000517 {
Geoff Langcec35902014-04-16 10:52:36 -0400518 if (!formatCaps.depthRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000519 {
520 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
521 }
522 }
Jamie Madille261b442014-06-25 12:42:21 -0400523 else if (IsInternalTextureTarget(mDepthbuffer->type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000524 {
Jamie Madille261b442014-06-25 12:42:21 -0400525 GLenum internalformat = mDepthbuffer->getInternalFormat();
526
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000527 // depth texture attachments require OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400528 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000529 {
530 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
531 }
532
Geoff Langcec35902014-04-16 10:52:36 -0400533 if (!formatCaps.depthRendering)
534 {
535 return GL_FRAMEBUFFER_UNSUPPORTED;
536 }
537
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000538 if (gl::GetDepthBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000539 {
540 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
541 }
542 }
543 else
544 {
545 UNREACHABLE();
546 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
547 }
548
549 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000550 {
Jamie Madille261b442014-06-25 12:42:21 -0400551 width = mDepthbuffer->getWidth();
552 height = mDepthbuffer->getHeight();
553 samples = mDepthbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000554 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000555 }
Jamie Madille261b442014-06-25 12:42:21 -0400556 else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000557 {
558 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
559 }
Jamie Madille261b442014-06-25 12:42:21 -0400560 else if (samples != mDepthbuffer->getSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000561 {
562 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
563 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000564 }
565
Jamie Madille261b442014-06-25 12:42:21 -0400566 if (mStencilbuffer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000567 {
Jamie Madille261b442014-06-25 12:42:21 -0400568 if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000569 {
570 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
571 }
572
Jamie Madille261b442014-06-25 12:42:21 -0400573 GLenum internalformat = mStencilbuffer->getInternalFormat();
Geoff Langcec35902014-04-16 10:52:36 -0400574 const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
Jamie Madille261b442014-06-25 12:42:21 -0400575 if (mStencilbuffer->type() == GL_RENDERBUFFER)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000576 {
Geoff Langcec35902014-04-16 10:52:36 -0400577 if (!formatCaps.stencilRendering)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000578 {
579 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
580 }
581 }
Jamie Madille261b442014-06-25 12:42:21 -0400582 else if (IsInternalTextureTarget(mStencilbuffer->type(), mRenderer->getCurrentClientVersion()))
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000583 {
Jamie Madille261b442014-06-25 12:42:21 -0400584 GLenum internalformat = mStencilbuffer->getInternalFormat();
585
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000586 // texture stencil attachments come along as part
587 // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
Geoff Langcec35902014-04-16 10:52:36 -0400588 if (!mRenderer->getCaps().extensions.depthTextures)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000589 {
590 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
591 }
592
Geoff Langcec35902014-04-16 10:52:36 -0400593 if (!formatCaps.stencilRendering)
594 {
595 return GL_FRAMEBUFFER_UNSUPPORTED;
596 }
597
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +0000598 if (gl::GetStencilBits(internalformat, clientVersion) == 0)
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000599 {
600 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
601 }
602 }
603 else
604 {
605 UNREACHABLE();
606 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
607 }
608
609 if (missingAttachment)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000610 {
Jamie Madille261b442014-06-25 12:42:21 -0400611 width = mStencilbuffer->getWidth();
612 height = mStencilbuffer->getHeight();
613 samples = mStencilbuffer->getSamples();
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000614 missingAttachment = false;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000615 }
Jamie Madille261b442014-06-25 12:42:21 -0400616 else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000617 {
618 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
619 }
Jamie Madille261b442014-06-25 12:42:21 -0400620 else if (samples != mStencilbuffer->getSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000621 {
622 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
623 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000624 }
625
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000626 // if we have both a depth and stencil buffer, they must refer to the same object
627 // since we only support packed_depth_stencil and not separate depth and stencil
Jamie Madille261b442014-06-25 12:42:21 -0400628 if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000629 {
daniel@transgaming.com6b7c84c2012-05-31 01:14:39 +0000630 return GL_FRAMEBUFFER_UNSUPPORTED;
631 }
632
633 // we need to have at least one attachment to be complete
634 if (missingAttachment)
635 {
636 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000637 }
638
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000639 return GL_FRAMEBUFFER_COMPLETE;
640}
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000641
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000642DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
643 : Framebuffer(renderer)
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000644{
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400645 Renderbuffer *colorRenderbuffer = new Renderbuffer(mRenderer, 0, colorbuffer);
Jamie Madille261b442014-06-25 12:42:21 -0400646 mColorbuffers[0] = new RenderbufferAttachment(colorRenderbuffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000647
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400648 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
Jamie Madille261b442014-06-25 12:42:21 -0400649 FramebufferAttachment *depthStencilAttachment = new RenderbufferAttachment(depthStencilRenderbuffer);
650 mDepthbuffer = (depthStencilRenderbuffer->getDepthSize() != 0 ? depthStencilAttachment : NULL);
651 mStencilbuffer = (depthStencilRenderbuffer->getStencilSize() != 0 ? depthStencilAttachment : NULL);
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000652
653 mDrawBufferStates[0] = GL_BACK;
654 mReadBufferState = GL_BACK;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000655}
656
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000657int Framebuffer::getSamples() const
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000658{
659 if (completeness() == GL_FRAMEBUFFER_COMPLETE)
660 {
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000661 // for a complete framebuffer, all attachments must have the same sample count
662 // in this case return the first nonzero sample size
663 for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
664 {
Jamie Madille261b442014-06-25 12:42:21 -0400665 if (mColorbuffers[colorAttachment])
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000666 {
Jamie Madille261b442014-06-25 12:42:21 -0400667 return mColorbuffers[colorAttachment]->getSamples();
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000668 }
669 }
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000670 }
shannon.woods%transgaming.com@gtempaccount.comf30ccc22013-04-13 03:28:36 +0000671
672 return 0;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000673}
674
Jamie Madille261b442014-06-25 12:42:21 -0400675bool Framebuffer::hasValidDepthStencil() const
676{
677 // A valid depth-stencil attachment has the same resource bound to both the
678 // depth and stencil attachment points.
679 return (mDepthbuffer && mStencilbuffer &&
680 mDepthbuffer->type() == mStencilbuffer->type() &&
681 mDepthbuffer->id() == mStencilbuffer->id());
682}
683
shannon.woods%transgaming.com@gtempaccount.com3b57b4f2013-04-13 03:28:29 +0000684GLenum DefaultFramebuffer::completeness() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000685{
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000686 // The default framebuffer *must* always be complete, though it may not be
687 // subject to the same rules as application FBOs. ie, it could have 0x0 size.
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000688 return GL_FRAMEBUFFER_COMPLETE;
689}
690
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000691}