xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/ClearMultiviewGL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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