blob: 25d419defab02cf226deabe8798523bedc59fce8 [file] [log] [blame]
Olli Etuahof26b27e2018-08-17 11:01:19 +03001//
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/WorkaroundsD3D.h"
Olli Etuaho2c8f0842018-09-12 14:44:55 +030012#include "test_utils/gl_raii.h"
Olli Etuahof26b27e2018-08-17 11:01:19 +030013
14namespace angle
15{
16
Mingyu Huebab6702019-04-19 14:36:45 -070017GLuint CreateSimplePassthroughProgram(int numViews, ExtensionName multiviewExtension)
Olli Etuahof26b27e2018-08-17 11:01:19 +030018{
Mingyu Huebab6702019-04-19 14:36:45 -070019 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
Olli Etuahof26b27e2018-08-17 11:01:19 +030033 const std::string vsSource =
34 "#version 300 es\n"
Mingyu Huebab6702019-04-19 14:36:45 -070035 "#extension " +
36 ext +
37 " : require\n"
Olli Etuahof26b27e2018-08-17 11:01:19 +030038 "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
Mingyu Huebab6702019-04-19 14:36:45 -070048 const std::string fsSource =
Olli Etuahof26b27e2018-08-17 11:01:19 +030049 "#version 300 es\n"
Mingyu Huebab6702019-04-19 14:36:45 -070050 "#extension " +
51 ext +
52 " : require\n"
Olli Etuahof26b27e2018-08-17 11:01:19 +030053 "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";
Mingyu Huebab6702019-04-19 14:36:45 -070059 return CompileProgram(vsSource.c_str(), fsSource.c_str());
Olli Etuahof26b27e2018-08-17 11:01:19 +030060}
61
Mingyu Hu7d64c482019-03-12 14:27:40 -070062void CreateMultiviewBackingTextures(int samples,
Olli Etuahoa7b35c32018-08-21 16:32:24 +030063 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
Olli Etuaho2c8f0842018-09-12 14:44:55 +030074 // 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
Olli Etuahoa7b35c32018-08-21 16:32:24 +030080 // Create color and depth textures.
Mingyu Hu7d64c482019-03-12 14:27:40 -070081 GLenum texTarget = (samples > 0) ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES : GL_TEXTURE_2D_ARRAY;
82 for (auto colorTexture : colorTextures)
Olli Etuahoa7b35c32018-08-21 16:32:24 +030083 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070084 glBindTexture(texTarget, colorTexture);
85 if (samples > 0)
Olli Etuahoa7b35c32018-08-21 16:32:24 +030086 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070087 glTexStorage3DMultisampleOES(texTarget, samples, GL_RGBA8, viewWidth, height, numLayers,
88 false);
Olli Etuahoa7b35c32018-08-21 16:32:24 +030089
Mingyu Hu7d64c482019-03-12 14:27:40 -070090 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)
Olli Etuahoa7b35c32018-08-21 16:32:24 +030094 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070095 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture,
96 0, layerIndex);
97 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuahoa7b35c32018-08-21 16:32:24 +030098 }
Olli Etuahoa7b35c32018-08-21 16:32:24 +030099 }
Mingyu Hu7d64c482019-03-12 14:27:40 -0700100 else
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300101 {
Mingyu Hu7d64c482019-03-12 14:27:40 -0700102 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);
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300106 }
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300107 }
Mingyu Hu7d64c482019-03-12 14:27:40 -0700108
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);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300159 ASSERT_GL_NO_ERROR();
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300160
161 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFramebuffer);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300162}
163
Mingyu Hu7d64c482019-03-12 14:27:40 -0700164void CreateMultiviewBackingTextures(int samples,
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300165 int viewWidth,
166 int height,
167 int numLayers,
168 GLuint colorTexture,
169 GLuint depthTexture,
170 GLuint depthStencilTexture)
171{
Jamie Madillba319ba2018-12-29 10:29:33 -0500172 ASSERT_TRUE(colorTexture != 0u);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300173 std::vector<GLuint> colorTextures(1, colorTexture);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700174 CreateMultiviewBackingTextures(samples, viewWidth, height, numLayers, colorTextures,
175 depthTexture, depthStencilTexture);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300176}
177
178void AttachMultiviewTextures(GLenum target,
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300179 int viewWidth,
180 int numViews,
181 int baseViewIndex,
182 std::vector<GLuint> colorTextures,
183 GLuint depthTexture,
184 GLuint depthStencilTexture)
185{
Jamie Madillba319ba2018-12-29 10:29:33 -0500186 ASSERT_TRUE(depthTexture == 0u || depthStencilTexture == 0u);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700187 for (size_t i = 0; i < colorTextures.size(); ++i)
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300188 {
Mingyu Hu7d64c482019-03-12 14:27:40 -0700189 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);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300202 }
203}
204
205void AttachMultiviewTextures(GLenum target,
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300206 int viewWidth,
207 int numViews,
208 int baseViewIndex,
209 GLuint colorTexture,
210 GLuint depthTexture,
211 GLuint depthStencilTexture)
212{
Jamie Madillba319ba2018-12-29 10:29:33 -0500213 ASSERT_TRUE(colorTexture != 0u);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300214 std::vector<GLuint> colorTextures(1, colorTexture);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700215 AttachMultiviewTextures(target, viewWidth, numViews, baseViewIndex, colorTextures, depthTexture,
216 depthStencilTexture);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300217}
218
Olli Etuahof26b27e2018-08-17 11:01:19 +0300219std::ostream &operator<<(std::ostream &os, const MultiviewImplementationParams &params)
220{
221 const PlatformParameters &base = static_cast<const PlatformParameters &>(params);
222 os << base;
223 if (params.mForceUseGeometryShaderOnD3D)
224 {
225 os << "_force_geom_shader";
226 }
227 else
228 {
229 os << "_vertex_shader";
230 }
Mingyu Huebab6702019-04-19 14:36:45 -0700231 if (params.mMultiviewExtension)
232 {
233 os << "_multiview";
234 }
235 else
236 {
237 os << "_multiview2";
238 }
Olli Etuahof26b27e2018-08-17 11:01:19 +0300239 return os;
240}
241
Mingyu Huebab6702019-04-19 14:36:45 -0700242MultiviewImplementationParams VertexShaderOpenGL(GLint majorVersion,
243 GLint minorVersion,
244 ExtensionName multiviewExtension)
Olli Etuahof26b27e2018-08-17 11:01:19 +0300245{
Mingyu Huebab6702019-04-19 14:36:45 -0700246 return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::OPENGL(),
247 multiviewExtension);
Olli Etuahof26b27e2018-08-17 11:01:19 +0300248}
249
Mingyu Huebab6702019-04-19 14:36:45 -0700250MultiviewImplementationParams VertexShaderD3D11(GLint majorVersion,
251 GLint minorVersion,
252 ExtensionName multiviewExtension)
Olli Etuahof26b27e2018-08-17 11:01:19 +0300253{
Mingyu Huebab6702019-04-19 14:36:45 -0700254 return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::D3D11(),
255 multiviewExtension);
Olli Etuahof26b27e2018-08-17 11:01:19 +0300256}
257
Mingyu Huebab6702019-04-19 14:36:45 -0700258MultiviewImplementationParams GeomShaderD3D11(GLint majorVersion,
259 GLint minorVersion,
260 ExtensionName multiviewExtension)
Olli Etuahof26b27e2018-08-17 11:01:19 +0300261{
Mingyu Huebab6702019-04-19 14:36:45 -0700262 return MultiviewImplementationParams(majorVersion, minorVersion, true, egl_platform::D3D11(),
263 multiviewExtension);
Olli Etuahof26b27e2018-08-17 11:01:19 +0300264}
265
266void MultiviewTest::overrideWorkaroundsD3D(WorkaroundsD3D *workarounds)
267{
268 workarounds->selectViewInGeometryShader = GetParam().mForceUseGeometryShaderOnD3D;
269}
270
271} // namespace angle