1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // ClearMultiviewGL:
7*8975f5c5SAndroid Build Coastguard Worker // A helper for clearing multiview side-by-side and layered framebuffers.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/ClearMultiviewGL.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FunctionsGL.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/StateManagerGL.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/TextureGL.h"
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Framebuffer.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker namespace rx
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker
ClearMultiviewGL(const FunctionsGL * functions,StateManagerGL * stateManager)20*8975f5c5SAndroid Build Coastguard Worker ClearMultiviewGL::ClearMultiviewGL(const FunctionsGL *functions, StateManagerGL *stateManager)
21*8975f5c5SAndroid Build Coastguard Worker : mFunctions(functions), mStateManager(stateManager), mFramebuffer(0u)
22*8975f5c5SAndroid Build Coastguard Worker {}
23*8975f5c5SAndroid Build Coastguard Worker
~ClearMultiviewGL()24*8975f5c5SAndroid Build Coastguard Worker ClearMultiviewGL::~ClearMultiviewGL()
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker if (mFramebuffer != 0u)
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker mFunctions->deleteFramebuffers(1, &mFramebuffer);
29*8975f5c5SAndroid Build Coastguard Worker }
30*8975f5c5SAndroid Build Coastguard Worker }
31*8975f5c5SAndroid Build Coastguard Worker
clearMultiviewFBO(const gl::FramebufferState & state,const gl::Rectangle & scissorBase,ClearCommandType clearCommandType,GLbitfield mask,GLenum buffer,GLint drawbuffer,const uint8_t * values,GLfloat depth,GLint stencil)32*8975f5c5SAndroid Build Coastguard Worker void ClearMultiviewGL::clearMultiviewFBO(const gl::FramebufferState &state,
33*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &scissorBase,
34*8975f5c5SAndroid Build Coastguard Worker ClearCommandType clearCommandType,
35*8975f5c5SAndroid Build Coastguard Worker GLbitfield mask,
36*8975f5c5SAndroid Build Coastguard Worker GLenum buffer,
37*8975f5c5SAndroid Build Coastguard Worker GLint drawbuffer,
38*8975f5c5SAndroid Build Coastguard Worker const uint8_t *values,
39*8975f5c5SAndroid Build Coastguard Worker GLfloat depth,
40*8975f5c5SAndroid Build Coastguard Worker GLint stencil)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *firstAttachment = state.getFirstNonNullAttachment();
43*8975f5c5SAndroid Build Coastguard Worker if (firstAttachment->isMultiview())
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker clearLayeredFBO(state, clearCommandType, mask, buffer, drawbuffer, values, depth, stencil);
46*8975f5c5SAndroid Build Coastguard Worker }
47*8975f5c5SAndroid Build Coastguard Worker }
48*8975f5c5SAndroid Build Coastguard Worker
clearLayeredFBO(const gl::FramebufferState & state,ClearCommandType clearCommandType,GLbitfield mask,GLenum buffer,GLint drawbuffer,const uint8_t * values,GLfloat depth,GLint stencil)49*8975f5c5SAndroid Build Coastguard Worker void ClearMultiviewGL::clearLayeredFBO(const gl::FramebufferState &state,
50*8975f5c5SAndroid Build Coastguard Worker ClearCommandType clearCommandType,
51*8975f5c5SAndroid Build Coastguard Worker GLbitfield mask,
52*8975f5c5SAndroid Build Coastguard Worker GLenum buffer,
53*8975f5c5SAndroid Build Coastguard Worker GLint drawbuffer,
54*8975f5c5SAndroid Build Coastguard Worker const uint8_t *values,
55*8975f5c5SAndroid Build Coastguard Worker GLfloat depth,
56*8975f5c5SAndroid Build Coastguard Worker GLint stencil)
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker initializeResources();
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
61*8975f5c5SAndroid Build Coastguard Worker
62*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *firstAttachment = state.getFirstNonNullAttachment();
63*8975f5c5SAndroid Build Coastguard Worker ASSERT(firstAttachment->isMultiview());
64*8975f5c5SAndroid Build Coastguard Worker
65*8975f5c5SAndroid Build Coastguard Worker const auto &drawBuffers = state.getDrawBufferStates();
66*8975f5c5SAndroid Build Coastguard Worker mFunctions->drawBuffers(static_cast<GLsizei>(drawBuffers.size()), drawBuffers.data());
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker // Attach the new attachments and clear.
69*8975f5c5SAndroid Build Coastguard Worker int numViews = firstAttachment->getNumViews();
70*8975f5c5SAndroid Build Coastguard Worker int baseViewIndex = firstAttachment->getBaseViewIndex();
71*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < numViews; ++i)
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker attachTextures(state, baseViewIndex + i);
74*8975f5c5SAndroid Build Coastguard Worker genericClear(clearCommandType, mask, buffer, drawbuffer, values, depth, stencil);
75*8975f5c5SAndroid Build Coastguard Worker }
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard Worker detachTextures(state);
78*8975f5c5SAndroid Build Coastguard Worker }
79*8975f5c5SAndroid Build Coastguard Worker
genericClear(ClearCommandType clearCommandType,GLbitfield mask,GLenum buffer,GLint drawbuffer,const uint8_t * values,GLfloat depth,GLint stencil)80*8975f5c5SAndroid Build Coastguard Worker void ClearMultiviewGL::genericClear(ClearCommandType clearCommandType,
81*8975f5c5SAndroid Build Coastguard Worker GLbitfield mask,
82*8975f5c5SAndroid Build Coastguard Worker GLenum buffer,
83*8975f5c5SAndroid Build Coastguard Worker GLint drawbuffer,
84*8975f5c5SAndroid Build Coastguard Worker const uint8_t *values,
85*8975f5c5SAndroid Build Coastguard Worker GLfloat depth,
86*8975f5c5SAndroid Build Coastguard Worker GLint stencil)
87*8975f5c5SAndroid Build Coastguard Worker {
88*8975f5c5SAndroid Build Coastguard Worker switch (clearCommandType)
89*8975f5c5SAndroid Build Coastguard Worker {
90*8975f5c5SAndroid Build Coastguard Worker case ClearCommandType::Clear:
91*8975f5c5SAndroid Build Coastguard Worker mFunctions->clear(mask);
92*8975f5c5SAndroid Build Coastguard Worker break;
93*8975f5c5SAndroid Build Coastguard Worker case ClearCommandType::ClearBufferfv:
94*8975f5c5SAndroid Build Coastguard Worker mFunctions->clearBufferfv(buffer, drawbuffer,
95*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<const GLfloat *>(values));
96*8975f5c5SAndroid Build Coastguard Worker break;
97*8975f5c5SAndroid Build Coastguard Worker case ClearCommandType::ClearBufferuiv:
98*8975f5c5SAndroid Build Coastguard Worker mFunctions->clearBufferuiv(buffer, drawbuffer,
99*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<const GLuint *>(values));
100*8975f5c5SAndroid Build Coastguard Worker break;
101*8975f5c5SAndroid Build Coastguard Worker case ClearCommandType::ClearBufferiv:
102*8975f5c5SAndroid Build Coastguard Worker mFunctions->clearBufferiv(buffer, drawbuffer, reinterpret_cast<const GLint *>(values));
103*8975f5c5SAndroid Build Coastguard Worker break;
104*8975f5c5SAndroid Build Coastguard Worker case ClearCommandType::ClearBufferfi:
105*8975f5c5SAndroid Build Coastguard Worker mFunctions->clearBufferfi(buffer, drawbuffer, depth, stencil);
106*8975f5c5SAndroid Build Coastguard Worker break;
107*8975f5c5SAndroid Build Coastguard Worker default:
108*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker
attachTextures(const gl::FramebufferState & state,int layer)112*8975f5c5SAndroid Build Coastguard Worker void ClearMultiviewGL::attachTextures(const gl::FramebufferState &state, int layer)
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker for (auto drawBufferId : state.getEnabledDrawBuffers())
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *attachment = state.getColorAttachment(drawBufferId);
117*8975f5c5SAndroid Build Coastguard Worker if (attachment == nullptr)
118*8975f5c5SAndroid Build Coastguard Worker {
119*8975f5c5SAndroid Build Coastguard Worker continue;
120*8975f5c5SAndroid Build Coastguard Worker }
121*8975f5c5SAndroid Build Coastguard Worker
122*8975f5c5SAndroid Build Coastguard Worker const auto &imageIndex = attachment->getTextureImageIndex();
123*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex.getType() == gl::TextureType::_2DArray);
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker GLenum colorAttachment =
126*8975f5c5SAndroid Build Coastguard Worker static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + static_cast<int>(drawBufferId));
127*8975f5c5SAndroid Build Coastguard Worker const TextureGL *textureGL = GetImplAs<TextureGL>(attachment->getTexture());
128*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, colorAttachment,
129*8975f5c5SAndroid Build Coastguard Worker textureGL->getTextureID(), imageIndex.getLevelIndex(),
130*8975f5c5SAndroid Build Coastguard Worker layer);
131*8975f5c5SAndroid Build Coastguard Worker }
132*8975f5c5SAndroid Build Coastguard Worker
133*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *depthStencilAttachment = state.getDepthStencilAttachment();
134*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *depthAttachment = state.getDepthAttachment();
135*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *stencilAttachment = state.getStencilAttachment();
136*8975f5c5SAndroid Build Coastguard Worker if (depthStencilAttachment != nullptr)
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker const auto &imageIndex = depthStencilAttachment->getTextureImageIndex();
139*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex.getType() == gl::TextureType::_2DArray);
140*8975f5c5SAndroid Build Coastguard Worker
141*8975f5c5SAndroid Build Coastguard Worker const TextureGL *textureGL = GetImplAs<TextureGL>(depthStencilAttachment->getTexture());
142*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
143*8975f5c5SAndroid Build Coastguard Worker textureGL->getTextureID(), imageIndex.getLevelIndex(),
144*8975f5c5SAndroid Build Coastguard Worker layer);
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker else if (depthAttachment != nullptr)
147*8975f5c5SAndroid Build Coastguard Worker {
148*8975f5c5SAndroid Build Coastguard Worker const auto &imageIndex = depthAttachment->getTextureImageIndex();
149*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex.getType() == gl::TextureType::_2DArray);
150*8975f5c5SAndroid Build Coastguard Worker
151*8975f5c5SAndroid Build Coastguard Worker const TextureGL *textureGL = GetImplAs<TextureGL>(depthAttachment->getTexture());
152*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
153*8975f5c5SAndroid Build Coastguard Worker textureGL->getTextureID(), imageIndex.getLevelIndex(),
154*8975f5c5SAndroid Build Coastguard Worker layer);
155*8975f5c5SAndroid Build Coastguard Worker }
156*8975f5c5SAndroid Build Coastguard Worker else if (stencilAttachment != nullptr)
157*8975f5c5SAndroid Build Coastguard Worker {
158*8975f5c5SAndroid Build Coastguard Worker const auto &imageIndex = stencilAttachment->getTextureImageIndex();
159*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex.getType() == gl::TextureType::_2DArray);
160*8975f5c5SAndroid Build Coastguard Worker
161*8975f5c5SAndroid Build Coastguard Worker const TextureGL *textureGL = GetImplAs<TextureGL>(stencilAttachment->getTexture());
162*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
163*8975f5c5SAndroid Build Coastguard Worker textureGL->getTextureID(), imageIndex.getLevelIndex(),
164*8975f5c5SAndroid Build Coastguard Worker layer);
165*8975f5c5SAndroid Build Coastguard Worker }
166*8975f5c5SAndroid Build Coastguard Worker }
167*8975f5c5SAndroid Build Coastguard Worker
detachTextures(const gl::FramebufferState & state)168*8975f5c5SAndroid Build Coastguard Worker void ClearMultiviewGL::detachTextures(const gl::FramebufferState &state)
169*8975f5c5SAndroid Build Coastguard Worker {
170*8975f5c5SAndroid Build Coastguard Worker for (auto drawBufferId : state.getEnabledDrawBuffers())
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *attachment = state.getColorAttachment(drawBufferId);
173*8975f5c5SAndroid Build Coastguard Worker if (attachment == nullptr)
174*8975f5c5SAndroid Build Coastguard Worker {
175*8975f5c5SAndroid Build Coastguard Worker continue;
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker
178*8975f5c5SAndroid Build Coastguard Worker GLenum colorAttachment =
179*8975f5c5SAndroid Build Coastguard Worker static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + static_cast<int>(drawBufferId));
180*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, colorAttachment, 0, 0, 0);
181*8975f5c5SAndroid Build Coastguard Worker }
182*8975f5c5SAndroid Build Coastguard Worker
183*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *depthStencilAttachment = state.getDepthStencilAttachment();
184*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *depthAttachment = state.getDepthAttachment();
185*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *stencilAttachment = state.getStencilAttachment();
186*8975f5c5SAndroid Build Coastguard Worker if (depthStencilAttachment != nullptr)
187*8975f5c5SAndroid Build Coastguard Worker {
188*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0,
189*8975f5c5SAndroid Build Coastguard Worker 0);
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker else if (depthAttachment != nullptr)
192*8975f5c5SAndroid Build Coastguard Worker {
193*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0, 0, 0);
194*8975f5c5SAndroid Build Coastguard Worker }
195*8975f5c5SAndroid Build Coastguard Worker else if (stencilAttachment != nullptr)
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 0, 0, 0);
198*8975f5c5SAndroid Build Coastguard Worker }
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker
initializeResources()201*8975f5c5SAndroid Build Coastguard Worker void ClearMultiviewGL::initializeResources()
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker if (mFramebuffer == 0u)
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker mFunctions->genFramebuffers(1, &mFramebuffer);
206*8975f5c5SAndroid Build Coastguard Worker }
207*8975f5c5SAndroid Build Coastguard Worker ASSERT(mFramebuffer != 0u);
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker
210*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
211