14f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com//
2cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
34f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
44f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// found in the LICENSE file.
54f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com//
64f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
74f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
84f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
94f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
10bbf56f755e0dd78c7650c52531ce412fcaaafa2bdaniel@transgaming.com#include "libGLESv2/Framebuffer.h"
11bbf56f755e0dd78c7650c52531ce412fcaaafa2bdaniel@transgaming.com#include "libGLESv2/main.h"
12f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org#include "libGLESv2/formatutils.h"
13486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/Texture.h"
14486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/Context.h"
15486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/Renderbuffer.h"
16e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill#include "libGLESv2/FramebufferAttachment.h"
170b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/Renderer.h"
18400a44188a51008af0748e6910d992dfc20871f8Jamie Madill#include "libGLESv2/renderer/RenderTarget.h"
199f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill#include "libGLESv2/renderer/d3d/TextureD3D.h"
200b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang
210b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "common/utilities.h"
224f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
239f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madillnamespace rx
249f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill{
259f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie MadillRenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
269f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill{
279f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    if (attachment->isTexture())
289f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    {
299f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill        gl::Texture *texture = attachment->getTexture();
309f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill        ASSERT(texture);
319f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill        TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
32ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        const gl::ImageIndex *index = attachment->getTextureImageIndex();
33ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        ASSERT(index);
34ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        return textureD3D->getRenderTarget(*index);
359f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    }
369f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
379f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
389f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    ASSERT(renderbuffer);
399f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
409f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    // TODO: cast to RenderbufferD3D
419f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill    return renderbuffer->getStorage()->getRenderTarget();
429f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill}
439f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
44612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
45612e2e4490ac8baac7da12de599e94d21a62538aJamie Madillunsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
46612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill{
47612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    if (attachment->isTexture())
48612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    {
49612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill        gl::Texture *texture = attachment->getTexture();
50612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill        ASSERT(texture);
51612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill        TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
52ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        const gl::ImageIndex *index = attachment->getTextureImageIndex();
53ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        ASSERT(index);
54ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        return textureD3D->getRenderTargetSerial(*index);
55612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    }
56612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill
57612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
58612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    ASSERT(renderbuffer);
59612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill
60612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    // TODO: cast to RenderbufferD3D
61612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill    return renderbuffer->getStorage()->getSerial();
62612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill}
63612e2e4490ac8baac7da12de599e94d21a62538aJamie Madill
649f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill}
659f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
664f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comnamespace gl
674f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
689ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
69aa2ab7d8c9112231b623ea3ebb85e3f28c26e526Shannon WoodsFramebuffer::Framebuffer(rx::Renderer *renderer, GLuint id)
70e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    : mRenderer(renderer),
71aa2ab7d8c9112231b623ea3ebb85e3f28c26e526Shannon Woods      mId(id),
72e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill      mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
73e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill      mDepthbuffer(NULL),
74e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill      mStencilbuffer(NULL)
754f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
76f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
77f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    {
78e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        mColorbuffers[colorAttachment] = NULL;
79f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        mDrawBufferStates[colorAttachment] = GL_NONE;
80f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    }
81f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
824f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
834f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
844f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comFramebuffer::~Framebuffer()
854f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
86f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
87f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    {
88e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        SafeDelete(mColorbuffers[colorAttachment]);
89f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    }
90e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mDepthbuffer);
91e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mStencilbuffer);
929ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com}
939ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
94aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie MadillFramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
959ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com{
966c7b4ada6bcb8ec0d929ff929b33f07c653d8e82Jamie Madill    if (handle == 0)
976c7b4ada6bcb8ec0d929ff929b33f07c653d8e82Jamie Madill    {
986c7b4ada6bcb8ec0d929ff929b33f07c653d8e82Jamie Madill        return NULL;
996c7b4ada6bcb8ec0d929ff929b33f07c653d8e82Jamie Madill    }
1006c7b4ada6bcb8ec0d929ff929b33f07c653d8e82Jamie Madill
1019ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    gl::Context *context = gl::getContext();
1029ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
103309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang    switch (type)
1049ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    {
105309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_NONE:
106309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        return NULL;
107309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang
108309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_RENDERBUFFER:
109aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill        return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
110309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang
111309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_2D:
112309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        {
113309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            Texture *texture = context->getTexture(handle);
114309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            if (texture && texture->getTarget() == GL_TEXTURE_2D)
115309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
116eeb7b0e9038b0fc57ead6a491541548159855dc2Jamie Madill                return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
117309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
118309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            else
119309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
120309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang                return NULL;
121309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
122309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        }
123309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang
124309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
125309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
126309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
127309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
128309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
129309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
130309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        {
131309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            Texture *texture = context->getTexture(handle);
132309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
133309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
134eeb7b0e9038b0fc57ead6a491541548159855dc2Jamie Madill                return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
135309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
136309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            else
137309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
138309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang                return NULL;
139309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
140309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        }
141309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang
142309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_3D:
143309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        {
144309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            Texture *texture = context->getTexture(handle);
145309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            if (texture && texture->getTarget() == GL_TEXTURE_3D)
146309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
147eeb7b0e9038b0fc57ead6a491541548159855dc2Jamie Madill                return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
148309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
149309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            else
150309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
151309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang                return NULL;
152309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
153309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        }
154309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang
155309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      case GL_TEXTURE_2D_ARRAY:
156309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        {
157309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            Texture *texture = context->getTexture(handle);
158309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
159309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
160eeb7b0e9038b0fc57ead6a491541548159855dc2Jamie Madill                return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
161309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
162309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            else
163309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            {
164309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang                return NULL;
165309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang            }
166309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        }
167309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang
168309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang      default:
1699ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com        UNREACHABLE();
170309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Lang        return NULL;
1719ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    }
1724f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
1734f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
174309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Langvoid Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
175f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
176f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
177e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mColorbuffers[colorAttachment]);
178aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill    GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
179aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill    mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
180f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com}
181f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
182309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Langvoid Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
1834f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
184e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mDepthbuffer);
185aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill    mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
1864f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
1874f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
188309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Langvoid Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
1894f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
190e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mStencilbuffer);
191aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill    mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
1924f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
1934f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
194309c92aa2af2ecadc9396c51b4c48b67d884e762Geoff Langvoid Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
19555ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang{
196aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill    FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
1976c7b4ada6bcb8ec0d929ff929b33f07c653d8e82Jamie Madill
198e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mDepthbuffer);
199e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    SafeDelete(mStencilbuffer);
200e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill
201e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    // ensure this is a legitimate depth+stencil format
202e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
20355ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang    {
204e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        mDepthbuffer = attachment;
20528bedaf892e4ca63aeae98a76b65744fe0191202Jamie Madill
20628bedaf892e4ca63aeae98a76b65744fe0191202Jamie Madill        // Make a new attachment object to ensure we do not double-delete
20728bedaf892e4ca63aeae98a76b65744fe0191202Jamie Madill        // See angle issue 686
208aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill        mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
20955ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang    }
21055ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang}
21155ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang
212e261b44af7631c31ddca8601490e7445af5a3341Jamie Madillvoid Framebuffer::detachTexture(GLuint textureId)
2134f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
214f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
2154f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    {
216e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
217e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill
218e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        if (attachment && attachment->isTextureWithId(textureId))
219f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        {
220e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            SafeDelete(mColorbuffers[colorAttachment]);
221f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        }
2224f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    }
223fbc09533f131522467c355cc4fcb1a8612edb7dedaniel@transgaming.com
224e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
225fbc09533f131522467c355cc4fcb1a8612edb7dedaniel@transgaming.com    {
226e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        SafeDelete(mDepthbuffer);
227fbc09533f131522467c355cc4fcb1a8612edb7dedaniel@transgaming.com    }
228fbc09533f131522467c355cc4fcb1a8612edb7dedaniel@transgaming.com
229e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
230fbc09533f131522467c355cc4fcb1a8612edb7dedaniel@transgaming.com    {
231e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        SafeDelete(mStencilbuffer);
232fbc09533f131522467c355cc4fcb1a8612edb7dedaniel@transgaming.com    }
2334f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
2344f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
235e261b44af7631c31ddca8601490e7445af5a3341Jamie Madillvoid Framebuffer::detachRenderbuffer(GLuint renderbufferId)
2364f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
237f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
2384f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    {
239e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
240e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill
241e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        if (attachment && attachment->isRenderbufferWithId(renderbufferId))
242f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        {
243e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            SafeDelete(mColorbuffers[colorAttachment]);
244f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        }
2454f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    }
2464f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
247e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
248339ae70162e96fe38b5c55a05645b634b0934c83daniel@transgaming.com    {
249e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        SafeDelete(mDepthbuffer);
250339ae70162e96fe38b5c55a05645b634b0934c83daniel@transgaming.com    }
251339ae70162e96fe38b5c55a05645b634b0934c83daniel@transgaming.com
252e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
2534cbc590fb59d7211ebb59b9bcfcc36f3880009d9daniel@transgaming.com    {
254e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        SafeDelete(mStencilbuffer);
2554cbc590fb59d7211ebb59b9bcfcc36f3880009d9daniel@transgaming.com    }
2564cbc590fb59d7211ebb59b9bcfcc36f3880009d9daniel@transgaming.com}
2574cbc590fb59d7211ebb59b9bcfcc36f3880009d9daniel@transgaming.com
2583c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
259f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
260f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
261e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return mColorbuffers[colorAttachment];
262f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com}
263f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
2643c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getDepthbuffer() const
2654f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
266e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return mDepthbuffer;
2674f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
2684f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
2693c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getStencilbuffer() const
2704f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
271e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return mStencilbuffer;
2724f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
2734f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
2743c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
275646559fe6566898f53f52f28f5f89d8f0d6b0eb8Geoff Lang{
276e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return (hasValidDepthStencil() ? mDepthbuffer : NULL);
277646559fe6566898f53f52f28f5f89d8f0d6b0eb8Geoff Lang}
278646559fe6566898f53f52f28f5f89d8f0d6b0eb8Geoff Lang
2793c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
280d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com{
281e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
282d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com
283d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com    if (!depthstencilbuffer)
284d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com    {
285e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        depthstencilbuffer = mStencilbuffer;
286d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com    }
287d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com
288d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com    return depthstencilbuffer;
289d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com}
290d2b4702a0424ddf29d4dac0e46c4bfc0e970c732daniel@transgaming.com
2913c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getReadColorbuffer() const
292f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
293f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    // Will require more logic if glReadBuffers is supported
294e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return mColorbuffers[0];
295f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com}
296f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
297f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.comGLenum Framebuffer::getReadColorbufferType() const
298f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com{
299f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com    // Will require more logic if glReadBuffers is supported
300e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
301f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com}
302f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com
3033c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Framebuffer::getFirstColorbuffer() const
304f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
305f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
306f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    {
307e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        if (mColorbuffers[colorAttachment])
308f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        {
309e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            return mColorbuffers[colorAttachment];
310f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        }
311f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    }
312f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
313f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    return NULL;
314f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com}
315f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
316e92a3546da271f33110714508529fef7306c4656Jamie MadillFramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
317f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
318e92a3546da271f33110714508529fef7306c4656Jamie Madill    if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
319e92a3546da271f33110714508529fef7306c4656Jamie Madill    {
320e92a3546da271f33110714508529fef7306c4656Jamie Madill        return getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
321e92a3546da271f33110714508529fef7306c4656Jamie Madill    }
322e92a3546da271f33110714508529fef7306c4656Jamie Madill    else
323e92a3546da271f33110714508529fef7306c4656Jamie Madill    {
324e92a3546da271f33110714508529fef7306c4656Jamie Madill        switch (attachment)
325e92a3546da271f33110714508529fef7306c4656Jamie Madill        {
326e92a3546da271f33110714508529fef7306c4656Jamie Madill          case GL_DEPTH_ATTACHMENT:
327e92a3546da271f33110714508529fef7306c4656Jamie Madill            return getDepthbuffer();
328e92a3546da271f33110714508529fef7306c4656Jamie Madill          case GL_STENCIL_ATTACHMENT:
329e92a3546da271f33110714508529fef7306c4656Jamie Madill            return getStencilbuffer();
330e92a3546da271f33110714508529fef7306c4656Jamie Madill          case GL_DEPTH_STENCIL_ATTACHMENT:
331e92a3546da271f33110714508529fef7306c4656Jamie Madill            return getDepthStencilBuffer();
332e92a3546da271f33110714508529fef7306c4656Jamie Madill          default:
333e92a3546da271f33110714508529fef7306c4656Jamie Madill            UNREACHABLE();
334e92a3546da271f33110714508529fef7306c4656Jamie Madill            return NULL;
335e92a3546da271f33110714508529fef7306c4656Jamie Madill        }
336e92a3546da271f33110714508529fef7306c4656Jamie Madill    }
33755ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang}
33855ba29c54fb10f88c6dcdd48c6704f2847c6b9caGeoff Lang
339f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.comGLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
340f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
341f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    return mDrawBufferStates[colorAttachment];
342f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com}
343f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
344f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.comvoid Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
345f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com{
346f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    mDrawBufferStates[colorAttachment] = drawBuffer;
347f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com}
348f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
349dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.combool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
350dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com{
351e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
352dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com}
353dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com
354dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.combool Framebuffer::hasEnabledColorAttachment() const
355dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com{
356dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
357dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com    {
358dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com        if (isEnabledColorAttachment(colorAttachment))
359dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com        {
360dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com            return true;
361dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com        }
362dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com    }
363dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com
364dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com    return false;
365dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com}
366dae240976148046cd86605b16a58c48433e8428cshannon.woods%transgaming.com@gtempaccount.com
3673b57b4fcbab340b8a43932ef5e2845fb0ec2bfe7shannon.woods%transgaming.com@gtempaccount.combool Framebuffer::hasStencil() const
368a27ff1eeaf40f6d509ad8ec978f27f9fd55c4315daniel@transgaming.com{
369e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    return (mStencilbuffer && mStencilbuffer->getStencilSize() > 0);
370a27ff1eeaf40f6d509ad8ec978f27f9fd55c4315daniel@transgaming.com}
371a27ff1eeaf40f6d509ad8ec978f27f9fd55c4315daniel@transgaming.com
37224ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.orgbool Framebuffer::usingExtendedDrawBuffers() const
37324ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org{
37424ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org    for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
37524ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org    {
37624ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org        if (isEnabledColorAttachment(colorAttachment))
37724ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org        {
37824ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org            return true;
37924ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org        }
38024ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org    }
38124ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org
38224ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org    return false;
38324ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org}
38424ac85003000f03bb0f87d1f27830a602caadd34shannonwoods@chromium.org
3853b57b4fcbab340b8a43932ef5e2845fb0ec2bfe7shannon.woods%transgaming.com@gtempaccount.comGLenum Framebuffer::completeness() const
3864f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
3874f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    int width = 0;
3884f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    int height = 0;
389f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    unsigned int colorbufferSize = 0;
3901f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com    int samples = -1;
3916b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    bool missingAttachment = true;
392f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
3934f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
394f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
3954f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    {
396bb94f341d22734ab581d718513de0ce30a03440fJamie Madill        const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
3971297d92b2dac331b0b6d49e4241b675840c2a87bdaniel@transgaming.com
398bb94f341d22734ab581d718513de0ce30a03440fJamie Madill        if (colorbuffer)
399bb94f341d22734ab581d718513de0ce30a03440fJamie Madill        {
400f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
4011297d92b2dac331b0b6d49e4241b675840c2a87bdaniel@transgaming.com            {
402f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
4031297d92b2dac331b0b6d49e4241b675840c2a87bdaniel@transgaming.com            }
404b6b2e67703fbe60394462e12415835739416e07adaniel@transgaming.com
405cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang            GLenum internalformat = colorbuffer->getInternalFormat();
406c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang            // TODO(geofflang): use context's texture caps
407c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang            const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
4085d601382b51c29d1670b58c01360416bd929842dGeoff Lang            const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
409bb94f341d22734ab581d718513de0ce30a03440fJamie Madill            if (colorbuffer->isTexture())
4106b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            {
4116cf8e1b906ebfcda10f0f1cc673df6688c81e0e0Geoff Lang                if (!formatCaps.renderable)
412f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                {
413f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                    return GL_FRAMEBUFFER_UNSUPPORTED;
414f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                }
415f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
4165d601382b51c29d1670b58c01360416bd929842dGeoff Lang                if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
417f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                {
418f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                    return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
419f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                }
420f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            }
421f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            else
422f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            {
4235d601382b51c29d1670b58c01360416bd929842dGeoff Lang                if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
424bb94f341d22734ab581d718513de0ce30a03440fJamie Madill                {
425bb94f341d22734ab581d718513de0ce30a03440fJamie Madill                    return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
426bb94f341d22734ab581d718513de0ce30a03440fJamie Madill                }
4276b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            }
4280186813531a7e8f47d584ca7fb54a73ed99d19bedaniel@transgaming.com
429f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            if (!missingAttachment)
430f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            {
431f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                // all color attachments must have the same width and height
432f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
433f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                {
434f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                    return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
435f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                }
436f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
437f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
438f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                // all color attachments have the same number of samples for the FBO to be complete.
439f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                if (colorbuffer->getSamples() != samples)
440f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                {
441f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                    return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
442f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                }
443f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
444c347152c01c50a1cc248c21d02387f687ad67aadshannon.woods%transgaming.com@gtempaccount.com                // in GLES 2.0, all color attachments attachments must have the same number of bitplanes
445c347152c01c50a1cc248c21d02387f687ad67aadshannon.woods%transgaming.com@gtempaccount.com                // in GLES 3.0, there is no such restriction
446f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org                if (clientVersion < 3)
447f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                {
4485d601382b51c29d1670b58c01360416bd929842dGeoff Lang                    if (formatInfo.pixelBytes != colorbufferSize)
449c347152c01c50a1cc248c21d02387f687ad67aadshannon.woods%transgaming.com@gtempaccount.com                    {
450c347152c01c50a1cc248c21d02387f687ad67aadshannon.woods%transgaming.com@gtempaccount.com                        return GL_FRAMEBUFFER_UNSUPPORTED;
451c347152c01c50a1cc248c21d02387f687ad67aadshannon.woods%transgaming.com@gtempaccount.com                    }
452f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                }
453f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
454f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
455f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
456f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                {
457e92a3546da271f33110714508529fef7306c4656Jamie Madill                    const FramebufferAttachment *previousAttachment = mColorbuffers[previousColorAttachment];
458e92a3546da271f33110714508529fef7306c4656Jamie Madill
459e92a3546da271f33110714508529fef7306c4656Jamie Madill                    if (previousAttachment &&
460e92a3546da271f33110714508529fef7306c4656Jamie Madill                        (colorbuffer->id() == previousAttachment->id() &&
461e92a3546da271f33110714508529fef7306c4656Jamie Madill                         colorbuffer->type() == previousAttachment->type()))
462f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                    {
463f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                        return GL_FRAMEBUFFER_UNSUPPORTED;
464f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                    }
465f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                }
466f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            }
467f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            else
468f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            {
469f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                width = colorbuffer->getWidth();
470f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                height = colorbuffer->getHeight();
471f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                samples = colorbuffer->getSamples();
4725d601382b51c29d1670b58c01360416bd929842dGeoff Lang                colorbufferSize = formatInfo.pixelBytes;
473f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com                missingAttachment = false;
474f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            }
475f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        }
4769ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    }
4779ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
478e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mDepthbuffer)
4799ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    {
480e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
4814f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        {
4829ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
4834f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        }
4844f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
485e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        GLenum internalformat = mDepthbuffer->getInternalFormat();
486c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        // TODO(geofflang): use context's texture caps
487c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
4885d601382b51c29d1670b58c01360416bd929842dGeoff Lang        const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
489bb94f341d22734ab581d718513de0ce30a03440fJamie Madill        if (mDepthbuffer->isTexture())
4909ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com        {
4916b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            // depth texture attachments require OES/ANGLE_depth_texture
492c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang            // TODO(geofflang): use context's extensions
493c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang            if (!mRenderer->getRendererExtensions().depthTextures)
4946b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            {
4956b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
4966b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            }
4976b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com
4986cf8e1b906ebfcda10f0f1cc673df6688c81e0e0Geoff Lang            if (!formatCaps.renderable)
499cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang            {
500cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang                return GL_FRAMEBUFFER_UNSUPPORTED;
501cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang            }
502cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang
5035d601382b51c29d1670b58c01360416bd929842dGeoff Lang            if (formatInfo.depthBits == 0)
5046b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            {
5056b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
5066b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            }
5076b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        }
5086b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        else
5096b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        {
5105d601382b51c29d1670b58c01360416bd929842dGeoff Lang            if (!formatCaps.renderable || formatInfo.depthBits == 0)
511bb94f341d22734ab581d718513de0ce30a03440fJamie Madill            {
512bb94f341d22734ab581d718513de0ce30a03440fJamie Madill                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
513bb94f341d22734ab581d718513de0ce30a03440fJamie Madill            }
5149ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com        }
5151f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com
5166b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        if (missingAttachment)
5171f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        {
518e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            width = mDepthbuffer->getWidth();
519e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            height = mDepthbuffer->getHeight();
520e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            samples = mDepthbuffer->getSamples();
5216b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            missingAttachment = false;
5226b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        }
523e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
5246b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        {
5256b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
5261f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        }
527e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        else if (samples != mDepthbuffer->getSamples())
5281f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        {
5291f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com            return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
5301f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        }
5319ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    }
5329ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
533e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mStencilbuffer)
5349ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    {
535e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
5364f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        {
5379ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
5384f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        }
5394f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
540e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        GLenum internalformat = mStencilbuffer->getInternalFormat();
541c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        // TODO(geofflang): use context's texture caps
542c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
5435d601382b51c29d1670b58c01360416bd929842dGeoff Lang        const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
544bb94f341d22734ab581d718513de0ce30a03440fJamie Madill        if (mStencilbuffer->isTexture())
5459ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com        {
5466b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            // texture stencil attachments come along as part
5476b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
548c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang            // TODO(geofflang): use context's extensions
549c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang            if (!mRenderer->getRendererExtensions().depthTextures)
5506b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            {
5516b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
5526b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            }
5536b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com
5546cf8e1b906ebfcda10f0f1cc673df6688c81e0e0Geoff Lang            if (!formatCaps.renderable)
555cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang            {
556cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang                return GL_FRAMEBUFFER_UNSUPPORTED;
557cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang            }
558cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang
5595d601382b51c29d1670b58c01360416bd929842dGeoff Lang            if (formatInfo.stencilBits == 0)
5606b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            {
5616b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
5626b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            }
5636b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        }
5646b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        else
5656b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        {
5665d601382b51c29d1670b58c01360416bd929842dGeoff Lang            if (!formatCaps.renderable || formatInfo.stencilBits == 0)
567bb94f341d22734ab581d718513de0ce30a03440fJamie Madill            {
568bb94f341d22734ab581d718513de0ce30a03440fJamie Madill                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
569bb94f341d22734ab581d718513de0ce30a03440fJamie Madill            }
5709ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com        }
5711f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com
5726b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        if (missingAttachment)
5731f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        {
574e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            width = mStencilbuffer->getWidth();
575e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            height = mStencilbuffer->getHeight();
576e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            samples = mStencilbuffer->getSamples();
5776b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            missingAttachment = false;
5786b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        }
579e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
5806b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        {
5816b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com            return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
5821f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        }
583e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill        else if (samples != mStencilbuffer->getSamples())
5841f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        {
5851f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com            return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
5861f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com        }
5879ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    }
5889ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
5896b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    // if we have both a depth and stencil buffer, they must refer to the same object
5906b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    // since we only support packed_depth_stencil and not separate depth and stencil
591e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
5929ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    {
5936b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        return GL_FRAMEBUFFER_UNSUPPORTED;
5946b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    }
5956b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com
5966b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    // we need to have at least one attachment to be complete
5976b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    if (missingAttachment)
5986b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com    {
5996b7c84cd1eaa94a0413aef02c56761f08b7dd26bdaniel@transgaming.com        return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
600cdacc8e27117f22035bb56150899e1e52bb542d6daniel@transgaming.com    }
601cdacc8e27117f22035bb56150899e1e52bb542d6daniel@transgaming.com
6024f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    return GL_FRAMEBUFFER_COMPLETE;
6034f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
6049ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
6052d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madillvoid Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
6062d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madill{
6072d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madill    GLuint maxDimension = caps.maxRenderbufferSize;
6082d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madill    invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
6092d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madill}
6102d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madill
6112d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madillvoid Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
6122d96b9ebeac93aae8b5ae425c9902ca8823fd415Jamie Madill                                GLint x, GLint y, GLsizei width, GLsizei height)
613400a44188a51008af0748e6910d992dfc20871f8Jamie Madill{
614400a44188a51008af0748e6910d992dfc20871f8Jamie Madill    ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
6156d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill    for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
616400a44188a51008af0748e6910d992dfc20871f8Jamie Madill    {
6176d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill        GLenum attachmentTarget = attachments[attachIndex];
618400a44188a51008af0748e6910d992dfc20871f8Jamie Madill
6196d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill        gl::FramebufferAttachment *attachment =
6206d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill            (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
6216d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill                                                                getAttachment(attachmentTarget);
622400a44188a51008af0748e6910d992dfc20871f8Jamie Madill
6236d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill        if (attachment)
6246d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill        {
6259f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill            rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
6266d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill            if (renderTarget)
627400a44188a51008af0748e6910d992dfc20871f8Jamie Madill            {
6286d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill                renderTarget->invalidate(x, y, width, height);
629400a44188a51008af0748e6910d992dfc20871f8Jamie Madill            }
630400a44188a51008af0748e6910d992dfc20871f8Jamie Madill        }
631400a44188a51008af0748e6910d992dfc20871f8Jamie Madill    }
632400a44188a51008af0748e6910d992dfc20871f8Jamie Madill}
633400a44188a51008af0748e6910d992dfc20871f8Jamie Madill
63416418b115610ebc2d40efc3c6e817b0584d8c6f7daniel@transgaming.comDefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
635aa2ab7d8c9112231b623ea3ebb85e3f28c26e526Shannon Woods    : Framebuffer(renderer, 0)
6369ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com{
637e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
638aef95dec1cb82857fbe0dd88ad92eb3451e482f2Jamie Madill    mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
6399ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
64004ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    GLenum depthStencilActualFormat = depthStencil->getActualFormat();
64104ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    const gl::InternalFormat &depthStencilFormatInfo = GetInternalFormatInfo(depthStencilActualFormat);
64228bedaf892e4ca63aeae98a76b65744fe0191202Jamie Madill
64304ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    if (depthStencilFormatInfo.depthBits != 0 || depthStencilFormatInfo.stencilBits != 0)
64404ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    {
64504ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
64604ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill
64704ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        // Make a new attachment objects to ensure we do not double-delete
64804ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        // See angle issue 686
64904ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        mDepthbuffer = (depthStencilFormatInfo.depthBits != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
65004ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        mStencilbuffer = (depthStencilFormatInfo.stencilBits != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
65104ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    }
65204ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    else
65304ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    {
65404ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        // This method transfers ownership, so delete the unused storage if we don't keep it.
65504ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill        SafeDelete(depthStencil);
65604ab0eb41f1bb02eb722ce662bd9e6f47cca83a3Jamie Madill    }
657f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
658f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    mDrawBufferStates[0] = GL_BACK;
659f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    mReadBufferState = GL_BACK;
6609ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com}
6619ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
6623b57b4fcbab340b8a43932ef5e2845fb0ec2bfe7shannon.woods%transgaming.com@gtempaccount.comint Framebuffer::getSamples() const
6631f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com{
6641f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com    if (completeness() == GL_FRAMEBUFFER_COMPLETE)
6651f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com    {
666f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        // for a complete framebuffer, all attachments must have the same sample count
667f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        // in this case return the first nonzero sample size
668f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
669f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        {
670e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            if (mColorbuffers[colorAttachment])
671f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            {
672e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill                return mColorbuffers[colorAttachment]->getSamples();
673f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com            }
674f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com        }
6751f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com    }
676f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
677f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    return 0;
6781f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com}
6791f135d86ab03ef260de7d653625f916644ddd747daniel@transgaming.com
680e261b44af7631c31ddca8601490e7445af5a3341Jamie Madillbool Framebuffer::hasValidDepthStencil() const
681e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill{
682e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    // A valid depth-stencil attachment has the same resource bound to both the
683e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    // depth and stencil attachment points.
684e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill    return (mDepthbuffer && mStencilbuffer &&
685e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            mDepthbuffer->type() == mStencilbuffer->type() &&
686e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill            mDepthbuffer->id() == mStencilbuffer->id());
687e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill}
688e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill
689ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie MadillColorbufferInfo Framebuffer::getColorbuffersForRender() const
690ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill{
691ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill    ColorbufferInfo colorbuffersForRender;
692ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill
693ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill    for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
694ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill    {
695ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        GLenum drawBufferState = mDrawBufferStates[colorAttachment];
696ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
697ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill
698ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        if (colorbuffer != NULL && drawBufferState != GL_NONE)
699ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        {
700ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill            ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
701ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill            colorbuffersForRender.push_back(colorbuffer);
702ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        }
7033f2e61dea6c447ed7b98483fa0ce9ccc3cb5cc3cJamie Madill#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
704ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        else
705ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        {
706ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill            colorbuffersForRender.push_back(NULL);
707ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill        }
7083f2e61dea6c447ed7b98483fa0ce9ccc3cb5cc3cJamie Madill#endif
709ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill    }
710ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill
711ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill    return colorbuffersForRender;
712ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill}
713ce20c7f143fcd724c2da0294c552bbe7594dd84dJamie Madill
7143b57b4fcbab340b8a43932ef5e2845fb0ec2bfe7shannon.woods%transgaming.com@gtempaccount.comGLenum DefaultFramebuffer::completeness() const
7159ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com{
7163e3da5833393098b525d24a03ef105e75666f13fshannon.woods@transgaming.com    // The default framebuffer *must* always be complete, though it may not be
7173e3da5833393098b525d24a03ef105e75666f13fshannon.woods@transgaming.com    // subject to the same rules as application FBOs. ie, it could have 0x0 size.
7189ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com    return GL_FRAMEBUFFER_COMPLETE;
7199ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com}
7209ecb9f9d504e71672a610183c34ae33ab276aef4daniel@transgaming.com
721e92a3546da271f33110714508529fef7306c4656Jamie MadillFramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) const
722e92a3546da271f33110714508529fef7306c4656Jamie Madill{
723e92a3546da271f33110714508529fef7306c4656Jamie Madill    switch (attachment)
724e92a3546da271f33110714508529fef7306c4656Jamie Madill    {
7256d70826335924f25877d8d5bdb1202a1315131a3Jamie Madill      case GL_COLOR:
726e92a3546da271f33110714508529fef7306c4656Jamie Madill      case GL_BACK:
727e92a3546da271f33110714508529fef7306c4656Jamie Madill        return getColorbuffer(0);
728e92a3546da271f33110714508529fef7306c4656Jamie Madill      case GL_DEPTH:
729e92a3546da271f33110714508529fef7306c4656Jamie Madill        return getDepthbuffer();
730e92a3546da271f33110714508529fef7306c4656Jamie Madill      case GL_STENCIL:
731e92a3546da271f33110714508529fef7306c4656Jamie Madill        return getStencilbuffer();
732e92a3546da271f33110714508529fef7306c4656Jamie Madill      case GL_DEPTH_STENCIL:
733e92a3546da271f33110714508529fef7306c4656Jamie Madill        return getDepthStencilBuffer();
734e92a3546da271f33110714508529fef7306c4656Jamie Madill      default:
735e92a3546da271f33110714508529fef7306c4656Jamie Madill        UNREACHABLE();
736e92a3546da271f33110714508529fef7306c4656Jamie Madill        return NULL;
737e92a3546da271f33110714508529fef7306c4656Jamie Madill    }
738e92a3546da271f33110714508529fef7306c4656Jamie Madill}
739e92a3546da271f33110714508529fef7306c4656Jamie Madill
7404f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
741