blob: 35712dcc5c079149807a9a54caec316da0865e2e [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
Corentin Wallez86f8dd72015-08-12 12:37:48 -070038FramebufferGL::FramebufferGL(GLuint id,
39 const gl::Framebuffer::Data &data,
40 const FunctionsGL *functions,
41 StateManagerGL *stateManager)
42 : FramebufferImpl(data),
43 mFunctions(functions),
44 mStateManager(stateManager),
45 mFramebufferID(id),
46 mIsDefault(true)
47{
48}
49
Geoff Langf9a6f082015-01-22 13:32:49 -050050FramebufferGL::~FramebufferGL()
Geoff Lang4ad17092015-03-10 16:47:44 -040051{
Geoff Lang1eb708e2015-05-04 14:58:23 -040052 mStateManager->deleteFramebuffer(mFramebufferID);
53 mFramebufferID = 0;
Geoff Lang4ad17092015-03-10 16:47:44 -040054}
55
56static void BindFramebufferAttachment(const FunctionsGL *functions, GLenum attachmentPoint,
57 const gl::FramebufferAttachment *attachment)
58{
59 if (attachment)
60 {
61 if (attachment->type() == GL_TEXTURE)
62 {
Jamie Madill5160ec12015-04-14 08:13:48 -040063 const gl::Texture *texture = attachment->getTexture();
Geoff Lang4ad17092015-03-10 16:47:44 -040064 const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
65
66 if (texture->getTarget() == GL_TEXTURE_2D)
67 {
68 functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D,
69 textureGL->getTextureID(), attachment->mipLevel());
70 }
71 else if (texture->getTarget() == GL_TEXTURE_CUBE_MAP)
72 {
73 functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, attachment->cubeMapFace(),
74 textureGL->getTextureID(), attachment->mipLevel());
75 }
76 else if (texture->getTarget() == GL_TEXTURE_2D_ARRAY || texture->getTarget() == GL_TEXTURE_3D)
77 {
78 functions->framebufferTextureLayer(GL_FRAMEBUFFER, attachmentPoint, textureGL->getTextureID(),
79 attachment->mipLevel(), attachment->layer());
80 }
81 else
82 {
83 UNREACHABLE();
84 }
85 }
86 else if (attachment->type() == GL_RENDERBUFFER)
87 {
Jamie Madill5160ec12015-04-14 08:13:48 -040088 const gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
Geoff Langcd69f1c2015-03-18 14:33:23 -040089 const RenderbufferGL *renderbufferGL = GetImplAs<RenderbufferGL>(renderbuffer);
Geoff Lang4ad17092015-03-10 16:47:44 -040090
Geoff Langcd69f1c2015-03-18 14:33:23 -040091 functions->framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER,
92 renderbufferGL->getRenderbufferID());
Geoff Lang4ad17092015-03-10 16:47:44 -040093 }
94 else
95 {
96 UNREACHABLE();
97 }
98 }
99 else
100 {
101 // Unbind this attachment
102 functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, 0, 0);
103 }
104}
Geoff Langf9a6f082015-01-22 13:32:49 -0500105
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400106void FramebufferGL::onUpdateColorAttachment(size_t index)
Geoff Langf9a6f082015-01-22 13:32:49 -0500107{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700108 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400109 {
110 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700111 BindFramebufferAttachment(mFunctions, GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400112 mData.getColorAttachment(static_cast<unsigned int>(index)));
Geoff Lang4ad17092015-03-10 16:47:44 -0400113 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500114}
115
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400116void FramebufferGL::onUpdateDepthAttachment()
Geoff Langf9a6f082015-01-22 13:32:49 -0500117{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700118 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400119 {
120 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400121 BindFramebufferAttachment(mFunctions,
122 GL_DEPTH_ATTACHMENT,
123 mData.getDepthAttachment());
Geoff Lang4ad17092015-03-10 16:47:44 -0400124 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500125}
126
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400127void FramebufferGL::onUpdateStencilAttachment()
Geoff Langf9a6f082015-01-22 13:32:49 -0500128{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700129 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400130 {
131 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400132 BindFramebufferAttachment(mFunctions,
133 GL_STENCIL_ATTACHMENT,
134 mData.getStencilAttachment());
Geoff Lang4ad17092015-03-10 16:47:44 -0400135 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500136}
137
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400138void FramebufferGL::onUpdateDepthStencilAttachment()
Geoff Langf9a6f082015-01-22 13:32:49 -0500139{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700140 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400141 {
142 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Jamie Madill7d75e2b2015-04-30 09:42:18 -0400143 BindFramebufferAttachment(mFunctions,
144 GL_DEPTH_STENCIL_ATTACHMENT,
145 mData.getDepthStencilAttachment());
Geoff Lang4ad17092015-03-10 16:47:44 -0400146 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500147}
148
149void FramebufferGL::setDrawBuffers(size_t count, const GLenum *buffers)
150{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700151 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400152 {
153 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700154 mFunctions->drawBuffers(static_cast<GLsizei>(count), buffers);
Geoff Lang4ad17092015-03-10 16:47:44 -0400155 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500156}
157
158void FramebufferGL::setReadBuffer(GLenum buffer)
159{
Corentin Wallez6ab01b92015-08-03 10:16:36 -0700160 if (!mIsDefault)
Geoff Lang4ad17092015-03-10 16:47:44 -0400161 {
162 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
163 mFunctions->readBuffer(buffer);
164 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500165}
166
Austin Kinross08332632015-05-05 13:35:47 -0700167gl::Error FramebufferGL::discard(size_t count, const GLenum *attachments)
168{
169 UNIMPLEMENTED();
170 return gl::Error(GL_INVALID_OPERATION);
171}
172
Geoff Langf9a6f082015-01-22 13:32:49 -0500173gl::Error FramebufferGL::invalidate(size_t count, const GLenum *attachments)
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->invalidateFramebuffer)
177 {
178 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700179 mFunctions->invalidateFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count), attachments);
Geoff Lang64a72442015-04-01 14:43:11 -0400180 }
181
Geoff Lang4ad17092015-03-10 16:47:44 -0400182 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500183}
184
185gl::Error FramebufferGL::invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area)
186{
Geoff Lang64a72442015-04-01 14:43:11 -0400187 // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available.
188 if (mFunctions->invalidateSubFramebuffer)
189 {
190 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700191 mFunctions->invalidateSubFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count),
192 attachments, area.x, area.y, area.width, area.height);
Geoff Lang64a72442015-04-01 14:43:11 -0400193 }
194
Geoff Lang4ad17092015-03-10 16:47:44 -0400195 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500196}
197
Jamie Madilld1f5ef22015-04-01 14:17:06 -0400198gl::Error FramebufferGL::clear(const gl::Data &data, GLbitfield mask)
Geoff Langf9a6f082015-01-22 13:32:49 -0500199{
Geoff Lang4ad17092015-03-10 16:47:44 -0400200 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
201 mFunctions->clear(mask);
202
203 return gl::Error(GL_NO_ERROR);
204}
205
Geoff Langf9a6f082015-01-22 13:32:49 -0500206gl::Error FramebufferGL::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
207{
Geoff Lang4ad17092015-03-10 16:47:44 -0400208 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
209 mFunctions->clearBufferfv(buffer, drawbuffer, values);
210
211 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500212}
213
214gl::Error FramebufferGL::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
215{
Geoff Lang4ad17092015-03-10 16:47:44 -0400216 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
217 mFunctions->clearBufferuiv(buffer, drawbuffer, values);
218
219 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500220}
221
222gl::Error FramebufferGL::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
223{
Geoff Lang4ad17092015-03-10 16:47:44 -0400224 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
225 mFunctions->clearBufferiv(buffer, drawbuffer, values);
226
227 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500228}
229
230gl::Error FramebufferGL::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
231{
Geoff Lang4ad17092015-03-10 16:47:44 -0400232 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
233 mFunctions->clearBufferfi(buffer, drawbuffer, depth, stencil);
234
235 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500236}
237
238GLenum FramebufferGL::getImplementationColorReadFormat() const
239{
Geoff Lang4ad17092015-03-10 16:47:44 -0400240 const gl::FramebufferAttachment *readAttachment = getData().getReadAttachment();
241 GLenum internalFormat = readAttachment->getInternalFormat();
242 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
243 return internalFormatInfo.format;
Geoff Langf9a6f082015-01-22 13:32:49 -0500244}
245
246GLenum FramebufferGL::getImplementationColorReadType() const
247{
Geoff Lang4ad17092015-03-10 16:47:44 -0400248 const gl::FramebufferAttachment *readAttachment = getData().getReadAttachment();
249 GLenum internalFormat = readAttachment->getInternalFormat();
250 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
251 return internalFormatInfo.type;
Geoff Langf9a6f082015-01-22 13:32:49 -0500252}
253
254gl::Error FramebufferGL::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const
255{
Geoff Langda34d002015-09-04 11:08:59 -0400256 // TODO: don't sync the pixel pack state here once the dirty bits contain the pixel pack buffer
257 // binding
Jamie Madill87de3622015-03-16 10:41:44 -0400258 const gl::PixelPackState &packState = state.getPackState();
Geoff Langda34d002015-09-04 11:08:59 -0400259 mStateManager->setPixelPackState(packState);
Jamie Madill87de3622015-03-16 10:41:44 -0400260
Geoff Lang4ad17092015-03-10 16:47:44 -0400261 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
262 mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels);
263
264 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500265}
266
267gl::Error FramebufferGL::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
268 GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
269{
Geoff Lang4ad17092015-03-10 16:47:44 -0400270 const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer);
271
272 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
273 mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID);
274
275 mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x + sourceArea.width, sourceArea.y + sourceArea.height,
276 destArea.x, destArea.y, destArea.x + destArea.width, destArea.y + destArea.height,
277 mask, filter);
278
279 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500280}
281
282GLenum FramebufferGL::checkStatus() const
283{
Geoff Lang4ad17092015-03-10 16:47:44 -0400284 mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
285 return mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER);
286}
287
288GLuint FramebufferGL::getFramebufferID() const
289{
290 return mFramebufferID;
Geoff Langf9a6f082015-01-22 13:32:49 -0500291}
292
293}