• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(EGLenum clientType,GLint majorVersion,GLint minorVersion,EGLint profileMask,ExtensionName multiviewExtension)234 MultiviewImplementationParams VertexShaderOpenGL(EGLenum clientType,
235                                                  GLint majorVersion,
236                                                  GLint minorVersion,
237                                                  EGLint profileMask,
238                                                  ExtensionName multiviewExtension)
239 {
240     return MultiviewImplementationParams(clientType, majorVersion, minorVersion, profileMask,
241                                          egl_platform::OPENGL(), multiviewExtension);
242 }
243 
VertexShaderVulkan(EGLenum clientType,GLint majorVersion,GLint minorVersion,EGLint profileMask,ExtensionName multiviewExtension)244 MultiviewImplementationParams VertexShaderVulkan(EGLenum clientType,
245                                                  GLint majorVersion,
246                                                  GLint minorVersion,
247                                                  EGLint profileMask,
248                                                  ExtensionName multiviewExtension)
249 {
250     return MultiviewImplementationParams(clientType, majorVersion, minorVersion, profileMask,
251                                          egl_platform::VULKAN(), multiviewExtension);
252 }
253 
VertexShaderD3D11(EGLenum clientType,GLint majorVersion,GLint minorVersion,EGLint profileMask,ExtensionName multiviewExtension)254 MultiviewImplementationParams VertexShaderD3D11(EGLenum clientType,
255                                                 GLint majorVersion,
256                                                 GLint minorVersion,
257                                                 EGLint profileMask,
258                                                 ExtensionName multiviewExtension)
259 {
260     return MultiviewImplementationParams(clientType, majorVersion, minorVersion, profileMask,
261                                          egl_platform::D3D11(), multiviewExtension);
262 }
263 
GeomShaderD3D11(EGLenum clientType,GLint majorVersion,GLint minorVersion,EGLint profileMask,ExtensionName multiviewExtension)264 MultiviewImplementationParams GeomShaderD3D11(EGLenum clientType,
265                                               GLint majorVersion,
266                                               GLint minorVersion,
267                                               EGLint profileMask,
268                                               ExtensionName multiviewExtension)
269 {
270     return MultiviewImplementationParams(
271         clientType, majorVersion, minorVersion, profileMask,
272         egl_platform::D3D11().enable(Feature::SelectViewInGeometryShader), multiviewExtension);
273 }
274 
275 }  // namespace angle
276