blob: aa2f7aacc43aff6a25fd153beb1a3b9ed14cc8b2 [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
17GLuint CreateSimplePassthroughProgram(int numViews)
18{
19 const std::string vsSource =
20 "#version 300 es\n"
Mingyu Hu7d64c482019-03-12 14:27:40 -070021 "#extension GL_OVR_multiview2 : require\n"
Olli Etuahof26b27e2018-08-17 11:01:19 +030022 "layout(num_views = " +
23 ToString(numViews) +
24 ") in;\n"
25 "layout(location=0) in vec2 vPosition;\n"
26 "void main()\n"
27 "{\n"
28 " gl_PointSize = 1.;\n"
29 " gl_Position = vec4(vPosition.xy, 0.0, 1.0);\n"
30 "}\n";
31
Jamie Madill35cd7332018-12-02 12:03:33 -050032 constexpr char kFS[] =
Olli Etuahof26b27e2018-08-17 11:01:19 +030033 "#version 300 es\n"
Mingyu Hu7d64c482019-03-12 14:27:40 -070034 "#extension GL_OVR_multiview2 : require\n"
Olli Etuahof26b27e2018-08-17 11:01:19 +030035 "precision mediump float;\n"
36 "out vec4 col;\n"
37 "void main()\n"
38 "{\n"
39 " col = vec4(0,1,0,1);\n"
40 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -050041 return CompileProgram(vsSource.c_str(), kFS);
Olli Etuahof26b27e2018-08-17 11:01:19 +030042}
43
Mingyu Hu7d64c482019-03-12 14:27:40 -070044void CreateMultiviewBackingTextures(int samples,
Olli Etuahoa7b35c32018-08-21 16:32:24 +030045 int viewWidth,
46 int height,
47 int numLayers,
48 std::vector<GLuint> colorTextures,
49 GLuint depthTexture,
50 GLuint depthStencilTexture)
51{
52 // The same zero data is used to initialize both color and depth/stencil textures.
53 std::vector<GLubyte> textureData;
54 textureData.resize(viewWidth * height * numLayers * 4, 0u);
55
Olli Etuaho2c8f0842018-09-12 14:44:55 +030056 // We can't upload data to multisample textures, so we clear them using a temporary framebuffer
57 // instead. The current framebuffer binding is stored so we can restore it once we're done with
58 // using the temporary framebuffers.
59 GLint restoreDrawFramebuffer;
60 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &restoreDrawFramebuffer);
61
Olli Etuahoa7b35c32018-08-21 16:32:24 +030062 // Create color and depth textures.
Mingyu Hu7d64c482019-03-12 14:27:40 -070063 GLenum texTarget = (samples > 0) ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES : GL_TEXTURE_2D_ARRAY;
64 for (auto colorTexture : colorTextures)
Olli Etuahoa7b35c32018-08-21 16:32:24 +030065 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070066 glBindTexture(texTarget, colorTexture);
67 if (samples > 0)
Olli Etuahoa7b35c32018-08-21 16:32:24 +030068 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070069 glTexStorage3DMultisampleOES(texTarget, samples, GL_RGBA8, viewWidth, height, numLayers,
70 false);
Olli Etuahoa7b35c32018-08-21 16:32:24 +030071
Mingyu Hu7d64c482019-03-12 14:27:40 -070072 GLFramebuffer tempFbo;
73 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
74 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
75 for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
Olli Etuahoa7b35c32018-08-21 16:32:24 +030076 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070077 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture,
78 0, layerIndex);
79 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuahoa7b35c32018-08-21 16:32:24 +030080 }
Olli Etuahoa7b35c32018-08-21 16:32:24 +030081 }
Mingyu Hu7d64c482019-03-12 14:27:40 -070082 else
Olli Etuaho2c8f0842018-09-12 14:44:55 +030083 {
Mingyu Hu7d64c482019-03-12 14:27:40 -070084 glTexImage3D(texTarget, 0, GL_RGBA8, viewWidth, height, numLayers, 0, GL_RGBA,
85 GL_UNSIGNED_BYTE, textureData.data());
86 glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
87 glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Olli Etuaho2c8f0842018-09-12 14:44:55 +030088 }
Olli Etuahoa7b35c32018-08-21 16:32:24 +030089 }
Mingyu Hu7d64c482019-03-12 14:27:40 -070090
91 if (depthTexture != 0)
92 {
93 glBindTexture(texTarget, depthTexture);
94 if (samples > 0)
95 {
96 glTexStorage3DMultisampleOES(texTarget, samples, GL_DEPTH_COMPONENT32F, viewWidth,
97 height, numLayers, false);
98
99 GLFramebuffer tempFbo;
100 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
101 glClearDepthf(0.0f);
102 for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
103 {
104 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0,
105 layerIndex);
106 glClear(GL_DEPTH_BUFFER_BIT);
107 }
108 }
109 else
110 {
111 glTexImage3D(texTarget, 0, GL_DEPTH_COMPONENT32F, viewWidth, height, numLayers, 0,
112 GL_DEPTH_COMPONENT, GL_FLOAT, textureData.data());
113 }
114 }
115 if (depthStencilTexture != 0)
116 {
117 glBindTexture(texTarget, depthStencilTexture);
118 if (samples > 0)
119 {
120 glTexStorage3DMultisampleOES(texTarget, samples, GL_DEPTH24_STENCIL8, viewWidth, height,
121 numLayers, false);
122
123 GLFramebuffer tempFbo;
124 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
125 glClearDepthf(0.0f);
126 glClearStencil(0);
127 for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
128 {
129 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
130 depthTexture, 0, layerIndex);
131 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
132 }
133 }
134 else
135 {
136 glTexImage3D(texTarget, 0, GL_DEPTH24_STENCIL8, viewWidth, height, numLayers, 0,
137 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, textureData.data());
138 }
139 }
140 glBindTexture(texTarget, 0);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300141 ASSERT_GL_NO_ERROR();
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300142
143 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFramebuffer);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300144}
145
Mingyu Hu7d64c482019-03-12 14:27:40 -0700146void CreateMultiviewBackingTextures(int samples,
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300147 int viewWidth,
148 int height,
149 int numLayers,
150 GLuint colorTexture,
151 GLuint depthTexture,
152 GLuint depthStencilTexture)
153{
Jamie Madillba319ba2018-12-29 10:29:33 -0500154 ASSERT_TRUE(colorTexture != 0u);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300155 std::vector<GLuint> colorTextures(1, colorTexture);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700156 CreateMultiviewBackingTextures(samples, viewWidth, height, numLayers, colorTextures,
157 depthTexture, depthStencilTexture);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300158}
159
160void AttachMultiviewTextures(GLenum target,
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300161 int viewWidth,
162 int numViews,
163 int baseViewIndex,
164 std::vector<GLuint> colorTextures,
165 GLuint depthTexture,
166 GLuint depthStencilTexture)
167{
Jamie Madillba319ba2018-12-29 10:29:33 -0500168 ASSERT_TRUE(depthTexture == 0u || depthStencilTexture == 0u);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700169 for (size_t i = 0; i < colorTextures.size(); ++i)
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300170 {
Mingyu Hu7d64c482019-03-12 14:27:40 -0700171 GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
172 glFramebufferTextureMultiviewOVR(target, attachment, colorTextures[i], 0, baseViewIndex,
173 numViews);
174 }
175 if (depthTexture)
176 {
177 glFramebufferTextureMultiviewOVR(target, GL_DEPTH_ATTACHMENT, depthTexture, 0,
178 baseViewIndex, numViews);
179 }
180 if (depthStencilTexture)
181 {
182 glFramebufferTextureMultiviewOVR(target, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture,
183 0, baseViewIndex, numViews);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300184 }
185}
186
187void AttachMultiviewTextures(GLenum target,
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300188 int viewWidth,
189 int numViews,
190 int baseViewIndex,
191 GLuint colorTexture,
192 GLuint depthTexture,
193 GLuint depthStencilTexture)
194{
Jamie Madillba319ba2018-12-29 10:29:33 -0500195 ASSERT_TRUE(colorTexture != 0u);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300196 std::vector<GLuint> colorTextures(1, colorTexture);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700197 AttachMultiviewTextures(target, viewWidth, numViews, baseViewIndex, colorTextures, depthTexture,
198 depthStencilTexture);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300199}
200
Olli Etuahof26b27e2018-08-17 11:01:19 +0300201std::ostream &operator<<(std::ostream &os, const MultiviewImplementationParams &params)
202{
203 const PlatformParameters &base = static_cast<const PlatformParameters &>(params);
204 os << base;
205 if (params.mForceUseGeometryShaderOnD3D)
206 {
207 os << "_force_geom_shader";
208 }
209 else
210 {
211 os << "_vertex_shader";
212 }
213 return os;
214}
215
216MultiviewImplementationParams VertexShaderOpenGL(GLint majorVersion, GLint minorVersion)
217{
218 return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::OPENGL());
219}
220
221MultiviewImplementationParams VertexShaderD3D11(GLint majorVersion, GLint minorVersion)
222{
223 return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::D3D11());
224}
225
226MultiviewImplementationParams GeomShaderD3D11(GLint majorVersion, GLint minorVersion)
227{
228 return MultiviewImplementationParams(majorVersion, minorVersion, true, egl_platform::D3D11());
229}
230
231void MultiviewTest::overrideWorkaroundsD3D(WorkaroundsD3D *workarounds)
232{
233 workarounds->selectViewInGeometryShader = GetParam().mForceUseGeometryShaderOnD3D;
234}
235
236} // namespace angle