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 ¶ms)
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