blob: ae2a6173399efba42b6ae904e4aa03c72fca7419 [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// FramebufferGL.cpp: Implements the class methods for FramebufferGL.
8
9#include "libANGLE/renderer/gl/FramebufferGL.h"
10
11#include "common/debug.h"
Jamie Madilld1f5ef22015-04-01 14:17:06 -040012#include "libANGLE/Data.h"
Jamie Madill87de3622015-03-16 10:41:44 -040013#include "libANGLE/State.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040014#include "libANGLE/FramebufferAttachment.h"
15#include "libANGLE/angletypes.h"
16#include "libANGLE/formatutils.h"
17#include "libANGLE/renderer/gl/FunctionsGL.h"
Jacek Cabanfa60f692015-04-27 18:23:44 +020018#include "libANGLE/renderer/gl/RenderbufferGL.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040019#include "libANGLE/renderer/gl/StateManagerGL.h"
20#include "libANGLE/renderer/gl/TextureGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050021
22namespace rx
23{
24
Geoff Lang4ad17092015-03-10 16:47:44 -040025FramebufferGL::FramebufferGL(const gl::Framebuffer::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager, bool isDefault)
26 : FramebufferImpl(data),
27 mFunctions(functions),
28 mStateManager(stateManager),
Corentin Wallez6ab01b92015-08-03 10:16:36 -070029 mFramebufferID(0),
30 mIsDefault(isDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -040031{
Corentin Wallez6ab01b92015-08-03 10:16:36 -070032 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -040033 {
34 mFunctions->genFramebuffers(1, &mFramebufferID);
35 }
36}
Geoff Langf9a6f082015-01-22 13:32:49 -050037
38FramebufferGL::~FramebufferGL()
Geoff Lang4ad17092015-03-10 16:47:44 -040039{
Geoff Lang1eb708e2015-05-04 14:58:23 -040040 mStateManager->deleteFramebuffer(mFramebufferID);
41 mFramebufferID = 0;
Geoff Lang4ad17092015-03-10 16:47:44 -040042}
43
44static void BindFramebufferAttachment(const FunctionsGL *functions, GLenum attachmentPoint,
45 const gl::FramebufferAttachment *attachment)
46{
47 if (attachment)
48 {
49 if (attachment->type() == GL_TEXTURE)
50 {
Jamie Madill5160ec12015-04-14 08:13:48 -040051 const gl::Texture *texture = attachment->getTexture();
Geoff Lang4ad17092015-03-10 16:47:44 -040052 const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
53
54 if (texture->getTarget() == GL_TEXTURE_2D)
55 {
56 functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D,
57 textureGL->getTextureID(), attachment->mipLevel());
58 }
59 else if (texture->getTarget() == GL_TEXTURE_CUBE_MAP)
60 {
61 functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, attachment->cubeMapFace(),
62 textureGL->getTextureID(), attachment->mipLevel());
63 }
64 else if (texture->getTarget() == GL_TEXTURE_2D_ARRAY || texture->getTarget() == GL_TEXTURE_3D)
65 {
66 functions->framebufferTextureLayer(GL_FRAMEBUFFER, attachmentPoint, textureGL->getTextureID(),
67 attachment->mipLevel(), attachment->layer());
68 }
69 else
70 {
71 UNREACHABLE();
72 }
73 }
74 else if (attachment->type() == GL_RENDERBUFFER)
75 {
Jamie Madill5160ec12015-04-14 08:13:48 -040076 const gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
Geoff Langcd69f1c2015-03-18 14:33:23 -040077 const RenderbufferGL *renderbufferGL = GetImplAs<RenderbufferGL>(renderbuffer);
Geoff Lang4ad17092015-03-10 16:47:44 -040078
Geoff Langcd69f1c2015-03-18 14:33:23 -040079 functions->framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER,
80 renderbufferGL->getRenderbufferID());
Geoff Lang4ad17092015-03-10 16:47:44 -040081 }
82 else
83 {
84 UNREACHABLE();
85 }
86 }
87 else
88 {
89 // Unbind this attachment
90 functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, 0, 0);
91 }
92}
Geoff Langf9a6f082015-01-22 13:32:49 -050093
Jamie Madill7d75e2b2015-04-30 09:42:18 -040094void FramebufferGL::onUpdateColorAttachment(size_t index)
Geoff Langf9a6f082015-01-22 13:32:49 -050095{
Corentin Wallez6ab01b92015-08-03 10:16:36 -070096 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -040097 {
98 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -070099 BindFramebufferAttachment(mFunctions, GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400100 mData.getColorAttachment(static_cast<unsigned int>(index)));
Geoff Lang4ad17092015-03-10 16:47:44 -0400101 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500102}
103
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400104void FramebufferGL::onUpdateDepthAttachment()
Geoff Langf9a6f082015-01-22 13:32:49 -0500105{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700106 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400107 {
108 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400109 BindFramebufferAttachment(mFunctions,
110 GL_DEPTH_ATTACHMENT,
111 mData.getDepthAttachment());
Geoff Lang4ad17092015-03-10 16:47:44 -0400112 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500113}
114
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400115void FramebufferGL::onUpdateStencilAttachment()
Geoff Langf9a6f082015-01-22 13:32:49 -0500116{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700117 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400118 {
119 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400120 BindFramebufferAttachment(mFunctions,
121 GL_STENCIL_ATTACHMENT,
122 mData.getStencilAttachment());
Geoff Lang4ad17092015-03-10 16:47:44 -0400123 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500124}
125
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400126void FramebufferGL::onUpdateDepthStencilAttachment()
Geoff Langf9a6f082015-01-22 13:32:49 -0500127{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700128 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400129 {
130 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400131 BindFramebufferAttachment(mFunctions,
132 GL_DEPTH_STENCIL_ATTACHMENT,
133 mData.getDepthStencilAttachment());
Geoff Lang4ad17092015-03-10 16:47:44 -0400134 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500135}
136
137void FramebufferGL::setDrawBuffers(size_t count, const GLenum *buffers)
138{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700139 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400140 {
141 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700142 mFunctions->drawBuffers(static_cast<GLsizei>(count), buffers);
Geoff Lang4ad17092015-03-10 16:47:44 -0400143 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500144}
145
146void FramebufferGL::setReadBuffer(GLenum buffer)
147{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700148 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400149 {
150 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
151 mFunctions->readBuffer(buffer);
152 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500153}
154
Austin Kinross08332632015-05-05 13:35:47 -0700155gl::Error FramebufferGL::discard(size_t count, const GLenum *attachments)
156{
157 UNIMPLEMENTED();
158 return gl::Error(GL_INVALID_OPERATION);
159}
160
Geoff Langf9a6f082015-01-22 13:32:49 -0500161gl::Error FramebufferGL::invalidate(size_t count, const GLenum *attachments)
162{
Geoff Lang64a72442015-04-01 14:43:11 -0400163 // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available.
164 if (mFunctions->invalidateFramebuffer)
165 {
166 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700167 mFunctions->invalidateFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count), attachments);
Geoff Lang64a72442015-04-01 14:43:11 -0400168 }
169
Geoff Lang4ad17092015-03-10 16:47:44 -0400170 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500171}
172
173gl::Error FramebufferGL::invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area)
174{
Geoff Lang64a72442015-04-01 14:43:11 -0400175 // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available.
176 if (mFunctions->invalidateSubFramebuffer)
177 {
178 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700179 mFunctions->invalidateSubFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count),
180 attachments, area.x, area.y, area.width, area.height);
Geoff Lang64a72442015-04-01 14:43:11 -0400181 }
182
Geoff Lang4ad17092015-03-10 16:47:44 -0400183 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500184}
185
Jamie Madilld1f5ef22015-04-01 14:17:06 -0400186gl::Error FramebufferGL::clear(const gl::Data &data, GLbitfield mask)
Geoff Langf9a6f082015-01-22 13:32:49 -0500187{
Geoff Lang4ad17092015-03-10 16:47:44 -0400188 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
189 mFunctions->clear(mask);
190
191 return gl::Error(GL_NO_ERROR);
192}
193
Geoff Langf9a6f082015-01-22 13:32:49 -0500194gl::Error FramebufferGL::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
195{
Geoff Lang4ad17092015-03-10 16:47:44 -0400196 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
197 mFunctions->clearBufferfv(buffer, drawbuffer, values);
198
199 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500200}
201
202gl::Error FramebufferGL::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
203{
Geoff Lang4ad17092015-03-10 16:47:44 -0400204 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
205 mFunctions->clearBufferuiv(buffer, drawbuffer, values);
206
207 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500208}
209
210gl::Error FramebufferGL::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
211{
Geoff Lang4ad17092015-03-10 16:47:44 -0400212 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
213 mFunctions->clearBufferiv(buffer, drawbuffer, values);
214
215 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500216}
217
218gl::Error FramebufferGL::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
219{
Geoff Lang4ad17092015-03-10 16:47:44 -0400220 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
221 mFunctions->clearBufferfi(buffer, drawbuffer, depth, stencil);
222
223 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500224}
225
226GLenum FramebufferGL::getImplementationColorReadFormat() const
227{
Geoff Lang4ad17092015-03-10 16:47:44 -0400228 const gl::FramebufferAttachment *readAttachment = getData().getReadAttachment();
229 GLenum internalFormat = readAttachment->getInternalFormat();
230 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
231 return internalFormatInfo.format;
Geoff Langf9a6f082015-01-22 13:32:49 -0500232}
233
234GLenum FramebufferGL::getImplementationColorReadType() const
235{
Geoff Lang4ad17092015-03-10 16:47:44 -0400236 const gl::FramebufferAttachment *readAttachment = getData().getReadAttachment();
237 GLenum internalFormat = readAttachment->getInternalFormat();
238 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
239 return internalFormatInfo.type;
Geoff Langf9a6f082015-01-22 13:32:49 -0500240}
241
242gl::Error FramebufferGL::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const
243{
Geoff Langda34d002015-09-04 11:08:59 -0400244 // TODO: don't sync the pixel pack state here once the dirty bits contain the pixel pack buffer
245 // binding
Jamie Madill87de3622015-03-16 10:41:44 -0400246 const gl::PixelPackState &packState = state.getPackState();
Geoff Langda34d002015-09-04 11:08:59 -0400247 mStateManager->setPixelPackState(packState);
Jamie Madill87de3622015-03-16 10:41:44 -0400248
Geoff Lang4ad17092015-03-10 16:47:44 -0400249 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
250 mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels);
251
252 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500253}
254
255gl::Error FramebufferGL::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
256 GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
257{
Geoff Lang4ad17092015-03-10 16:47:44 -0400258 const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer);
259
260 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
261 mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID);
262
263 mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x + sourceArea.width, sourceArea.y + sourceArea.height,
264 destArea.x, destArea.y, destArea.x + destArea.width, destArea.y + destArea.height,
265 mask, filter);
266
267 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500268}
269
270GLenum FramebufferGL::checkStatus() const
271{
Geoff Lang4ad17092015-03-10 16:47:44 -0400272 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
273 return mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER);
274}
275
276GLuint FramebufferGL::getFramebufferID() const
277{
278 return mFramebufferID;
Geoff Langf9a6f082015-01-22 13:32:49 -0500279}
280
281}