xref: /aosp_15_r20/external/angle/src/tests/test_utils/MultiviewTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2018 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 // MultiviewTest:
7 //   Implementation of helpers for multiview testing.
8 //
9 
10 #include "test_utils/MultiviewTest.h"
11 #include "platform/autogen/FeaturesD3D_autogen.h"
12 #include "test_utils/gl_raii.h"
13 
14 namespace angle
15 {
16 
CreateSimplePassthroughProgram(int numViews,ExtensionName multiviewExtension)17 GLuint CreateSimplePassthroughProgram(int numViews, ExtensionName multiviewExtension)
18 {
19     std::string ext;
20     switch (multiviewExtension)
21     {
22         case multiview:
23             ext = "GL_OVR_multiview";
24             break;
25         case multiview2:
26             ext = "GL_OVR_multiview2";
27             break;
28         default:
29             // Unknown extension.
30             break;
31     }
32 
33     const std::string vsSource =
34         "#version 300 es\n"
35         "#extension " +
36         ext +
37         " : require\n"
38         "layout(num_views = " +
39         ToString(numViews) +
40         ") in;\n"
41         "layout(location=0) in vec2 vPosition;\n"
42         "void main()\n"
43         "{\n"
44         "   gl_PointSize = 1.;\n"
45         "   gl_Position = vec4(vPosition.xy, 0.0, 1.0);\n"
46         "}\n";
47 
48     const std::string fsSource =
49         "#version 300 es\n"
50         "#extension " +
51         ext +
52         " : require\n"
53         "precision mediump float;\n"
54         "out vec4 col;\n"
55         "void main()\n"
56         "{\n"
57         "   col = vec4(0,1,0,1);\n"
58         "}\n";
59     return CompileProgram(vsSource.c_str(), fsSource.c_str());
60 }
61 
CreateMultiviewBackingTextures(int samples,int viewWidth,int height,int numLayers,std::vector<GLuint> colorTextures,GLuint depthTexture,GLuint depthStencilTexture)62 void CreateMultiviewBackingTextures(int samples,
63                                     int viewWidth,
64                                     int height,
65                                     int numLayers,
66                                     std::vector<GLuint> colorTextures,
67                                     GLuint depthTexture,
68                                     GLuint depthStencilTexture)
69 {
70     // The same zero data is used to initialize both color and depth/stencil textures.
71     std::vector<GLubyte> textureData;
72     textureData.resize(viewWidth * height * numLayers * 4, 0u);
73 
74     // We can't upload data to multisample textures, so we clear them using a temporary framebuffer
75     // instead. The current framebuffer binding is stored so we can restore it once we're done with
76     // using the temporary framebuffers.
77     GLint restoreDrawFramebuffer;
78     glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &restoreDrawFramebuffer);
79 
80     // Create color and depth textures.
81     GLenum texTarget = (samples > 0) ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES : GL_TEXTURE_2D_ARRAY;
82     for (auto colorTexture : colorTextures)
83     {
84         glBindTexture(texTarget, colorTexture);
85         if (samples > 0)
86         {
87             glTexStorage3DMultisampleOES(texTarget, samples, GL_RGBA8, viewWidth, height, numLayers,
88                                          false);
89 
90             GLFramebuffer tempFbo;
91             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
92             glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
93             for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
94             {
95                 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture,
96                                           0, layerIndex);
97                 glClear(GL_COLOR_BUFFER_BIT);
98             }
99         }
100         else
101         {
102             glTexImage3D(texTarget, 0, GL_RGBA8, viewWidth, height, numLayers, 0, GL_RGBA,
103                          GL_UNSIGNED_BYTE, textureData.data());
104             glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
105             glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
106         }
107     }
108 
109     if (depthTexture != 0)
110     {
111         glBindTexture(texTarget, depthTexture);
112         if (samples > 0)
113         {
114             glTexStorage3DMultisampleOES(texTarget, samples, GL_DEPTH_COMPONENT32F, viewWidth,
115                                          height, numLayers, false);
116 
117             GLFramebuffer tempFbo;
118             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
119             glClearDepthf(0.0f);
120             for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
121             {
122                 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0,
123                                           layerIndex);
124                 glClear(GL_DEPTH_BUFFER_BIT);
125             }
126         }
127         else
128         {
129             glTexImage3D(texTarget, 0, GL_DEPTH_COMPONENT32F, viewWidth, height, numLayers, 0,
130                          GL_DEPTH_COMPONENT, GL_FLOAT, textureData.data());
131         }
132     }
133     if (depthStencilTexture != 0)
134     {
135         glBindTexture(texTarget, depthStencilTexture);
136         if (samples > 0)
137         {
138             glTexStorage3DMultisampleOES(texTarget, samples, GL_DEPTH24_STENCIL8, viewWidth, height,
139                                          numLayers, false);
140 
141             GLFramebuffer tempFbo;
142             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
143             glClearDepthf(0.0f);
144             glClearStencil(0);
145             for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
146             {
147                 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
148                                           depthTexture, 0, layerIndex);
149                 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
150             }
151         }
152         else
153         {
154             glTexImage3D(texTarget, 0, GL_DEPTH24_STENCIL8, viewWidth, height, numLayers, 0,
155                          GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, textureData.data());
156         }
157     }
158     glBindTexture(texTarget, 0);
159     ASSERT_GL_NO_ERROR();
160 
161     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFramebuffer);
162 }
163 
CreateMultiviewBackingTextures(int samples,int viewWidth,int height,int numLayers,GLuint colorTexture,GLuint depthTexture,GLuint depthStencilTexture)164 void CreateMultiviewBackingTextures(int samples,
165                                     int viewWidth,
166                                     int height,
167                                     int numLayers,
168                                     GLuint colorTexture,
169                                     GLuint depthTexture,
170                                     GLuint depthStencilTexture)
171 {
172     ASSERT_TRUE(colorTexture != 0u);
173     std::vector<GLuint> colorTextures(1, colorTexture);
174     CreateMultiviewBackingTextures(samples, viewWidth, height, numLayers, colorTextures,
175                                    depthTexture, depthStencilTexture);
176 }
177 
AttachMultiviewTextures(GLenum target,int viewWidth,int numViews,int baseViewIndex,std::vector<GLuint> colorTextures,GLuint depthTexture,GLuint depthStencilTexture)178 void AttachMultiviewTextures(GLenum target,
179                              int viewWidth,
180                              int numViews,
181                              int baseViewIndex,
182                              std::vector<GLuint> colorTextures,
183                              GLuint depthTexture,
184                              GLuint depthStencilTexture)
185 {
186     ASSERT_TRUE(depthTexture == 0u || depthStencilTexture == 0u);
187     for (size_t i = 0; i < colorTextures.size(); ++i)
188     {
189         GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
190         glFramebufferTextureMultiviewOVR(target, attachment, colorTextures[i], 0, baseViewIndex,
191                                          numViews);
192     }
193     if (depthTexture)
194     {
195         glFramebufferTextureMultiviewOVR(target, GL_DEPTH_ATTACHMENT, depthTexture, 0,
196                                          baseViewIndex, numViews);
197     }
198     if (depthStencilTexture)
199     {
200         glFramebufferTextureMultiviewOVR(target, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture,
201                                          0, baseViewIndex, numViews);
202     }
203 }
204 
AttachMultiviewTextures(GLenum target,int viewWidth,int numViews,int baseViewIndex,GLuint colorTexture,GLuint depthTexture,GLuint depthStencilTexture)205 void AttachMultiviewTextures(GLenum target,
206                              int viewWidth,
207                              int numViews,
208                              int baseViewIndex,
209                              GLuint colorTexture,
210                              GLuint depthTexture,
211                              GLuint depthStencilTexture)
212 {
213     ASSERT_TRUE(colorTexture != 0u);
214     std::vector<GLuint> colorTextures(1, colorTexture);
215     AttachMultiviewTextures(target, viewWidth, numViews, baseViewIndex, colorTextures, depthTexture,
216                             depthStencilTexture);
217 }
218 
operator <<(std::ostream & os,const MultiviewImplementationParams & params)219 std::ostream &operator<<(std::ostream &os, const MultiviewImplementationParams &params)
220 {
221     const PlatformParameters &base = static_cast<const PlatformParameters &>(params);
222     os << base << "_";
223     if (params.mMultiviewExtension)
224     {
225         os << "_multiview";
226     }
227     else
228     {
229         os << "_multiview2";
230     }
231     return os;
232 }
233 
VertexShaderOpenGL(GLint majorVersion,GLint minorVersion,ExtensionName multiviewExtension)234 MultiviewImplementationParams VertexShaderOpenGL(GLint majorVersion,
235                                                  GLint minorVersion,
236                                                  ExtensionName multiviewExtension)
237 {
238     return MultiviewImplementationParams(majorVersion, minorVersion, egl_platform::OPENGL(),
239                                          multiviewExtension);
240 }
241 
VertexShaderVulkan(GLint majorVersion,GLint minorVersion,ExtensionName multiviewExtension)242 MultiviewImplementationParams VertexShaderVulkan(GLint majorVersion,
243                                                  GLint minorVersion,
244                                                  ExtensionName multiviewExtension)
245 {
246     return MultiviewImplementationParams(majorVersion, minorVersion, egl_platform::VULKAN(),
247                                          multiviewExtension);
248 }
249 
VertexShaderD3D11(GLint majorVersion,GLint minorVersion,ExtensionName multiviewExtension)250 MultiviewImplementationParams VertexShaderD3D11(GLint majorVersion,
251                                                 GLint minorVersion,
252                                                 ExtensionName multiviewExtension)
253 {
254     return MultiviewImplementationParams(majorVersion, minorVersion, egl_platform::D3D11(),
255                                          multiviewExtension);
256 }
257 
GeomShaderD3D11(GLint majorVersion,GLint minorVersion,ExtensionName multiviewExtension)258 MultiviewImplementationParams GeomShaderD3D11(GLint majorVersion,
259                                               GLint minorVersion,
260                                               ExtensionName multiviewExtension)
261 {
262     return MultiviewImplementationParams(
263         majorVersion, minorVersion,
264         egl_platform::D3D11().enable(Feature::SelectViewInGeometryShader), multiviewExtension);
265 }
266 
267 }  // namespace angle
268