blob: 197ae25c825312dac7f89493da82d02990fca39f [file] [log] [blame]
Martin Radeve5285d22017-07-14 16:23:53 +03001//
2// Copyright 2017 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// Framebuffer multiview tests:
7// The tests modify and examine the multiview state.
8//
9
Olli Etuahof26b27e2018-08-17 11:01:19 +030010#include "test_utils/MultiviewTest.h"
Martin Radev0f7714e2017-08-07 15:13:42 +030011#include "test_utils/gl_raii.h"
Martin Radeve5285d22017-07-14 16:23:53 +030012
13using namespace angle;
14
Martin Radev5c00d0d2017-08-07 10:06:59 +030015namespace
16{
17std::vector<GLenum> GetDrawBufferRange(size_t numColorAttachments)
18{
19 std::vector<GLenum> drawBuffers(numColorAttachments);
20 const size_t kBase = static_cast<size_t>(GL_COLOR_ATTACHMENT0);
21 for (size_t i = 0u; i < drawBuffers.size(); ++i)
22 {
23 drawBuffers[i] = static_cast<GLenum>(kBase + i);
24 }
25 return drawBuffers;
26}
27} // namespace
28
Olli Etuahof26b27e2018-08-17 11:01:19 +030029// Base class for tests that care mostly about draw call validity and not rendering results.
30class FramebufferMultiviewTest : public MultiviewTest
Martin Radeve5285d22017-07-14 16:23:53 +030031{
32 protected:
Olli Etuahof26b27e2018-08-17 11:01:19 +030033 FramebufferMultiviewTest() : MultiviewTest() {}
Martin Radeve5285d22017-07-14 16:23:53 +030034};
35
Martin Radev5e424fa2017-08-09 16:25:36 +030036class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest
37{
38 protected:
Olli Etuaho7a4f6b82018-08-17 11:38:11 +030039 FramebufferMultiviewLayeredClearTest() : mMultiviewFBO(0), mDepthTex(0), mDepthStencilTex(0) {}
40
Jamie Madill5cbaa3f2019-05-07 15:49:22 -040041 void testTearDown() override
Olli Etuaho7a4f6b82018-08-17 11:38:11 +030042 {
43 if (mMultiviewFBO != 0)
44 {
45 glDeleteFramebuffers(1, &mMultiviewFBO);
46 mMultiviewFBO = 0u;
47 }
48 if (!mNonMultiviewFBO.empty())
49 {
Shahbaz Youssefic4097442018-08-22 12:14:52 -040050 GLsizei textureCount = static_cast<GLsizei>(mNonMultiviewFBO.size());
51 glDeleteTextures(textureCount, mNonMultiviewFBO.data());
Olli Etuaho7a4f6b82018-08-17 11:38:11 +030052 mNonMultiviewFBO.clear();
53 }
54 if (!mColorTex.empty())
55 {
Shahbaz Youssefic4097442018-08-22 12:14:52 -040056 GLsizei textureCount = static_cast<GLsizei>(mColorTex.size());
57 glDeleteTextures(textureCount, mColorTex.data());
Olli Etuaho7a4f6b82018-08-17 11:38:11 +030058 mColorTex.clear();
59 }
60 if (mDepthStencilTex != 0u)
61 {
62 glDeleteTextures(1, &mDepthStencilTex);
63 mDepthStencilTex = 0u;
64 }
65 if (mDepthTex != 0u)
66 {
67 glDeleteTextures(1, &mDepthTex);
68 mDepthTex = 0u;
69 }
Jamie Madill5cbaa3f2019-05-07 15:49:22 -040070 MultiviewTest::testTearDown();
Olli Etuaho7a4f6b82018-08-17 11:38:11 +030071 }
Martin Radev5e424fa2017-08-09 16:25:36 +030072
73 void initializeFBOs(int width,
74 int height,
75 int numLayers,
76 int baseViewIndex,
77 int numViews,
78 int numColorAttachments,
79 bool stencil,
80 bool depth)
81 {
Jamie Madillba319ba2018-12-29 10:29:33 -050082 ASSERT_TRUE(mColorTex.empty());
83 ASSERT_EQ(0u, mDepthStencilTex);
84 ASSERT_EQ(0u, mDepthTex);
85 ASSERT_LE(baseViewIndex + numViews, numLayers);
Martin Radev5e424fa2017-08-09 16:25:36 +030086
87 // Generate textures.
88 mColorTex.resize(numColorAttachments);
Shahbaz Youssefic4097442018-08-22 12:14:52 -040089 GLsizei textureCount = static_cast<GLsizei>(mColorTex.size());
90 glGenTextures(textureCount, mColorTex.data());
Olli Etuaho7a4f6b82018-08-17 11:38:11 +030091 if (stencil)
92 {
93 glGenTextures(1, &mDepthStencilTex);
94 }
95 else if (depth)
96 {
97 glGenTextures(1, &mDepthTex);
98 }
99
Mingyu Hu7d64c482019-03-12 14:27:40 -0700100 CreateMultiviewBackingTextures(0, width, height, numLayers, mColorTex, mDepthTex,
101 mDepthStencilTex);
Martin Radev5e424fa2017-08-09 16:25:36 +0300102
Olli Etuaho7a4f6b82018-08-17 11:38:11 +0300103 glGenFramebuffers(1, &mMultiviewFBO);
104
Martin Radev5e424fa2017-08-09 16:25:36 +0300105 // Generate multiview FBO and attach textures.
106 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700107 AttachMultiviewTextures(GL_FRAMEBUFFER, width, numViews, baseViewIndex, mColorTex,
108 mDepthTex, mDepthStencilTex);
Martin Radev5e424fa2017-08-09 16:25:36 +0300109
110 const auto &drawBuffers = GetDrawBufferRange(numColorAttachments);
111 glDrawBuffers(numColorAttachments, drawBuffers.data());
112
113 // Generate non-multiview FBOs and attach textures.
114 mNonMultiviewFBO.resize(numLayers);
Shahbaz Youssefic4097442018-08-22 12:14:52 -0400115 GLsizei framebufferCount = static_cast<GLsizei>(mNonMultiviewFBO.size());
116 glGenFramebuffers(framebufferCount, mNonMultiviewFBO.data());
Martin Radev5e424fa2017-08-09 16:25:36 +0300117 for (int i = 0; i < numLayers; ++i)
118 {
119 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
120 for (int j = 0; j < numColorAttachments; ++j)
121 {
122 glFramebufferTextureLayer(GL_FRAMEBUFFER,
123 static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + j),
124 mColorTex[j], 0, i);
125 }
126 if (stencil)
127 {
Olli Etuaho7a4f6b82018-08-17 11:38:11 +0300128 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
129 mDepthStencilTex, 0, i);
Martin Radev5e424fa2017-08-09 16:25:36 +0300130 }
131 else if (depth)
132 {
133 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTex, 0, i);
134 }
135 glDrawBuffers(numColorAttachments, drawBuffers.data());
Martin Radev5e424fa2017-08-09 16:25:36 +0300136 }
137
138 ASSERT_GL_NO_ERROR();
139 }
140
141 GLColor getLayerColor(size_t layer, GLenum attachment, GLint x, GLint y)
142 {
Jamie Madillba319ba2018-12-29 10:29:33 -0500143 EXPECT_LT(layer, mNonMultiviewFBO.size());
Martin Radev5e424fa2017-08-09 16:25:36 +0300144 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[layer]);
145 glReadBuffer(attachment);
146 return angle::ReadColor(x, y);
147 }
148
149 GLColor getLayerColor(size_t layer, GLenum attachment)
150 {
151 return getLayerColor(layer, attachment, 0, 0);
152 }
153
Olli Etuaho7a4f6b82018-08-17 11:38:11 +0300154 GLuint mMultiviewFBO;
155 std::vector<GLuint> mNonMultiviewFBO;
156
157 private:
158 std::vector<GLuint> mColorTex;
159 GLuint mDepthTex;
160 GLuint mDepthStencilTex;
Martin Radev5e424fa2017-08-09 16:25:36 +0300161};
162
Mingyu Hu7d64c482019-03-12 14:27:40 -0700163// Test that the framebuffer tokens introduced by OVR_multiview2 can be used to query the
Martin Radev5e424fa2017-08-09 16:25:36 +0300164// framebuffer state and that their corresponding default values are correctly set.
Martin Radeve5285d22017-07-14 16:23:53 +0300165TEST_P(FramebufferMultiviewTest, DefaultState)
166{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300167 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radeve5285d22017-07-14 16:23:53 +0300168
Martin Radev0f7714e2017-08-07 15:13:42 +0300169 GLFramebuffer fbo;
170 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
171
172 GLTexture tex;
173 glBindTexture(GL_TEXTURE_2D, tex);
174 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
175 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
Martin Radev137032d2017-07-13 10:11:12 +0300176
Martin Radeve5285d22017-07-14 16:23:53 +0300177 GLint numViews = -1;
178 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700179 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR,
Martin Radeve5285d22017-07-14 16:23:53 +0300180 &numViews);
Martin Radev0f7714e2017-08-07 15:13:42 +0300181 ASSERT_GL_NO_ERROR();
Martin Radeve5285d22017-07-14 16:23:53 +0300182 EXPECT_EQ(1, numViews);
183
184 GLint baseViewIndex = -1;
185 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700186 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR,
Martin Radeve5285d22017-07-14 16:23:53 +0300187 &baseViewIndex);
Martin Radev0f7714e2017-08-07 15:13:42 +0300188 ASSERT_GL_NO_ERROR();
Martin Radeve5285d22017-07-14 16:23:53 +0300189 EXPECT_EQ(0, baseViewIndex);
Martin Radeve5285d22017-07-14 16:23:53 +0300190}
191
Mingyu Hu7d64c482019-03-12 14:27:40 -0700192// Test that without having the OVR_multiview2 extension, querying for the framebuffer state using
193// the OVR_multiview2 tokens results in an INVALID_ENUM error.
Martin Radeve5285d22017-07-14 16:23:53 +0300194TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
195{
Martin Radev0f7714e2017-08-07 15:13:42 +0300196 GLFramebuffer fbo;
197 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
198
199 GLTexture tex;
200 glBindTexture(GL_TEXTURE_2D, tex);
201 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
202 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
Martin Radev137032d2017-07-13 10:11:12 +0300203
Martin Radeve5285d22017-07-14 16:23:53 +0300204 GLint numViews = -1;
205 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700206 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR,
Martin Radeve5285d22017-07-14 16:23:53 +0300207 &numViews);
208 EXPECT_GL_ERROR(GL_INVALID_ENUM);
209
210 GLint baseViewIndex = -1;
211 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700212 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR,
Martin Radeve5285d22017-07-14 16:23:53 +0300213 &baseViewIndex);
214 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Martin Radeve5285d22017-07-14 16:23:53 +0300215}
216
Mingyu Hu7d64c482019-03-12 14:27:40 -0700217// Test that the correct errors are generated whenever glFramebufferTextureMultiviewOVR is
Martin Radev137032d2017-07-13 10:11:12 +0300218// called with invalid arguments.
219TEST_P(FramebufferMultiviewTest, InvalidMultiviewLayeredArguments)
220{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300221 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev137032d2017-07-13 10:11:12 +0300222
Martin Radev0f7714e2017-08-07 15:13:42 +0300223 GLFramebuffer fbo;
224 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
225
226 GLTexture tex;
227 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
228 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
229 ASSERT_GL_NO_ERROR();
230
Martin Radev137032d2017-07-13 10:11:12 +0300231 // Negative base view index.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700232 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, -1, 1);
Martin Radev137032d2017-07-13 10:11:12 +0300233 EXPECT_GL_ERROR(GL_INVALID_VALUE);
234
235 // baseViewIndex + numViews is greater than MAX_TEXTURE_LAYERS.
236 GLint maxTextureLayers = 0;
237 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700238 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, maxTextureLayers,
239 1);
Martin Radev137032d2017-07-13 10:11:12 +0300240 EXPECT_GL_ERROR(GL_INVALID_VALUE);
241}
242
Mingyu Hu7d64c482019-03-12 14:27:40 -0700243// Test that an INVALID_OPERATION error is generated whenever the OVR_multiview2 extension is not
Martin Radev137032d2017-07-13 10:11:12 +0300244// available.
245TEST_P(FramebufferMultiviewTest, ExtensionNotAvailableCheck)
246{
Martin Radev0f7714e2017-08-07 15:13:42 +0300247 GLFramebuffer fbo;
248 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
249
250 GLTexture tex;
251 glBindTexture(GL_TEXTURE_2D, tex);
252 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
253
Martin Radev9bc9a322017-07-21 14:28:17 +0300254 ASSERT_GL_NO_ERROR();
Mingyu Hu7d64c482019-03-12 14:27:40 -0700255 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1, 1);
Martin Radev137032d2017-07-13 10:11:12 +0300256 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
257}
258
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300259// Test that the active read framebuffer can be read with glCopyTex* if it only has one layered
260// view.
261TEST_P(FramebufferMultiviewTest, CopyTex)
262{
263 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
264
Geoff Lang2a19c592019-08-23 14:10:24 -0400265 // glCopyTexImage2D generates GL_INVALID_FRAMEBUFFER_OPERATION. http://anglebug.com/3857
266 ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL());
267
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300268 GLFramebuffer fbo;
269 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
270
271 GLTexture tex;
272 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
273 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
274
Mingyu Hu7d64c482019-03-12 14:27:40 -0700275 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 1);
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300276 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
277 ASSERT_GL_NO_ERROR();
278
279 // Test glCopyTexImage2D and glCopyTexSubImage2D.
280 {
281 GLTexture tex2;
282 glBindTexture(GL_TEXTURE_2D, tex2);
283 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
284
285 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
286 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
287 glClear(GL_COLOR_BUFFER_BIT);
288
289 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 1, 1, 0);
290 ASSERT_GL_NO_ERROR();
291
292 // Test texture contents.
293 glBindFramebuffer(GL_FRAMEBUFFER, 0);
294 draw2DTexturedQuad(0.0f, 1.0f, true);
295 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
296
297 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
298 glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
299 glClear(GL_COLOR_BUFFER_BIT);
300
301 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
302 ASSERT_GL_NO_ERROR();
303
304 glBindFramebuffer(GL_FRAMEBUFFER, 0);
305 draw2DTexturedQuad(0.0f, 1.0f, true);
306 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
307 }
308
309 // Test glCopyTexSubImage3D.
310 {
311 GLTexture tex2;
312 glBindTexture(GL_TEXTURE_3D, tex2);
313 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
314
315 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
316 glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
317 glClear(GL_COLOR_BUFFER_BIT);
318 glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1, 1);
319 ASSERT_GL_NO_ERROR();
320
321 glBindFramebuffer(GL_FRAMEBUFFER, 0);
322 draw3DTexturedQuad(0.0f, 1.0f, true, 0.0f);
323 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
324 }
325}
326
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300327// Test that glBlitFramebuffer succeeds if the current read framebuffer has just one layered view.
328TEST_P(FramebufferMultiviewTest, Blit)
329{
330 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
331
332 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
333 glClear(GL_COLOR_BUFFER_BIT);
334
335 GLFramebuffer fbo;
336 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337
338 GLTexture tex;
339 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
340 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
341
Mingyu Hu7d64c482019-03-12 14:27:40 -0700342 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 1);
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300343 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
344 ASSERT_GL_NO_ERROR();
345
346 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
347 glClear(GL_COLOR_BUFFER_BIT);
348
349 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
350 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
351 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
352 ASSERT_GL_NO_ERROR();
353
354 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
355 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
356}
357
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300358// Test that glReadPixels succeeds from a layered multiview framebuffer with just one view.
359TEST_P(FramebufferMultiviewTest, ReadPixels)
360{
361 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
362
363 GLFramebuffer fbo;
364 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
365
366 GLTexture tex;
367 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
368 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
369
Mingyu Hu7d64c482019-03-12 14:27:40 -0700370 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 1);
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300371 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
372 ASSERT_GL_NO_ERROR();
373
374 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
375 glClear(GL_COLOR_BUFFER_BIT);
376
377 GLColor pixelColor;
378 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColor.R);
379 ASSERT_GL_NO_ERROR();
380 EXPECT_COLOR_NEAR(GLColor::green, pixelColor, 2);
381}
382
Mingyu Hu7d64c482019-03-12 14:27:40 -0700383// Test that glFramebufferTextureMultiviewOVR modifies the internal multiview state.
Martin Radev82ef7742017-08-08 17:44:58 +0300384TEST_P(FramebufferMultiviewTest, ModifyLayeredState)
385{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300386 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev82ef7742017-08-08 17:44:58 +0300387
388 GLFramebuffer multiviewFBO;
389 glBindFramebuffer(GL_FRAMEBUFFER, multiviewFBO);
390
391 GLTexture tex;
392 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
393 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
394 ASSERT_GL_NO_ERROR();
395
Mingyu Hu7d64c482019-03-12 14:27:40 -0700396 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1, 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300397 ASSERT_GL_NO_ERROR();
398
399 GLint numViews = -1;
400 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700401 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300402 &numViews);
403 ASSERT_GL_NO_ERROR();
404 EXPECT_EQ(2, numViews);
405
406 GLint baseViewIndex = -1;
407 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700408 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300409 &baseViewIndex);
410 ASSERT_GL_NO_ERROR();
411 EXPECT_EQ(1, baseViewIndex);
Martin Radev82ef7742017-08-08 17:44:58 +0300412}
413
414// Test framebuffer completeness status of a layered framebuffer with color attachments.
415TEST_P(FramebufferMultiviewTest, IncompleteViewTargetsLayered)
416{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300417 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev82ef7742017-08-08 17:44:58 +0300418
419 GLFramebuffer fbo;
420 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
421
422 GLTexture tex;
423 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
424 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
425
426 // Set the 0th attachment and keep it as it is till the end of the test. The 1st color
427 // attachment will be modified to change the framebuffer's status.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700428 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300429 ASSERT_GL_NO_ERROR();
430
431 GLTexture otherTexLayered;
432 glBindTexture(GL_TEXTURE_2D_ARRAY, otherTexLayered);
433 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
434
435 // Test framebuffer completeness when the base view index differs.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700436 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 1,
437 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300438 ASSERT_GL_NO_ERROR();
Mingyu Hu7d64c482019-03-12 14:27:40 -0700439 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300440 glCheckFramebufferStatus(GL_FRAMEBUFFER));
441
Martin Radev5e424fa2017-08-09 16:25:36 +0300442 // Test framebuffer completeness when the 1st attachment has a non-multiview layout.
Martin Radev82ef7742017-08-08 17:44:58 +0300443 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 0);
444 ASSERT_GL_NO_ERROR();
Mingyu Hu7d64c482019-03-12 14:27:40 -0700445 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300446 glCheckFramebufferStatus(GL_FRAMEBUFFER));
447
448 // Test that framebuffer is complete when the number of views, base view index and layouts are
449 // the same.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700450 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 0,
451 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300452 ASSERT_GL_NO_ERROR();
453 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
454}
455
Martin Radev5e424fa2017-08-09 16:25:36 +0300456// Test that glClear clears the contents of the color buffer for only the attached layers to a
457// layered FBO.
458TEST_P(FramebufferMultiviewLayeredClearTest, ColorBufferClear)
459{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300460 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300461
462 initializeFBOs(1, 1, 4, 1, 2, 1, false, false);
463
464 // Bind and specify viewport/scissor dimensions for each view.
465 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
466
467 glClearColor(0, 1, 0, 1);
468 glClear(GL_COLOR_BUFFER_BIT);
469
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300470 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300471 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
472 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300473 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300474}
475
476// Test that glClearBufferfv can be used to clear individual color buffers of a layered FBO.
477TEST_P(FramebufferMultiviewLayeredClearTest, ClearIndividualColorBuffer)
478{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300479 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300480
481 initializeFBOs(1, 1, 4, 1, 2, 2, false, false);
482
483 for (int i = 0; i < 2; ++i)
484 {
485 for (int layer = 0; layer < 4; ++layer)
486 {
487 GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300488 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(layer, colorAttachment));
Martin Radev5e424fa2017-08-09 16:25:36 +0300489 }
490 }
491
492 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
493
494 float clearValues0[4] = {0.f, 0.f, 1.f, 1.f};
495 glClearBufferfv(GL_COLOR, 0, clearValues0);
496
497 float clearValues1[4] = {0.f, 1.f, 0.f, 1.f};
498 glClearBufferfv(GL_COLOR, 1, clearValues1);
499
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300500 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300501 EXPECT_EQ(GLColor::blue, getLayerColor(1, GL_COLOR_ATTACHMENT0));
502 EXPECT_EQ(GLColor::blue, getLayerColor(2, GL_COLOR_ATTACHMENT0));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300503 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300504
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300505 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300506 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1));
507 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300508 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300509}
510
511// Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers
512// to a layered FBO.
513TEST_P(FramebufferMultiviewLayeredClearTest, ClearBufferfi)
514{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300515 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300516
517 // Create program to draw a quad.
Jamie Madill35cd7332018-12-02 12:03:33 -0500518 constexpr char kVS[] =
Martin Radev5e424fa2017-08-09 16:25:36 +0300519 "#version 300 es\n"
520 "in vec3 vPos;\n"
521 "void main(){\n"
522 " gl_Position = vec4(vPos, 1.);\n"
523 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500524 constexpr char kFS[] =
Martin Radev5e424fa2017-08-09 16:25:36 +0300525 "#version 300 es\n"
526 "precision mediump float;\n"
527 "uniform vec3 uCol;\n"
528 "out vec4 col;\n"
529 "void main(){\n"
530 " col = vec4(uCol,1.);\n"
531 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500532 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev5e424fa2017-08-09 16:25:36 +0300533 glUseProgram(program);
534 GLuint mColorUniformLoc = glGetUniformLocation(program, "uCol");
535
536 initializeFBOs(1, 1, 4, 1, 2, 1, true, false);
537 glEnable(GL_STENCIL_TEST);
538 glDisable(GL_DEPTH_TEST);
539
540 // Set clear values.
541 glClearColor(1, 0, 0, 1);
542 glClearStencil(0xFF);
543
544 // Clear the color and stencil buffers of each layer.
545 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
546 {
547 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
548 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
549 }
550
551 // Switch to multiview framebuffer and clear portions of the texture.
552 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
553 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
554
555 // Draw a fullscreen quad, but adjust the stencil function so that only the cleared regions pass
556 // the test.
557 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
558 glStencilFunc(GL_EQUAL, 0x00, 0xFF);
559 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
560 {
561 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
562 glUniform3f(mColorUniformLoc, 0.0f, 1.0f, 0.0f);
563 drawQuad(program, "vPos", 0.0f, 1.0f, true);
564 }
565 EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0));
566 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
567 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0));
568 EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0));
569}
570
571// Test that glClear does not clear the content of a detached texture.
572TEST_P(FramebufferMultiviewLayeredClearTest, UnmodifiedDetachedTexture)
573{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300574 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300575
576 initializeFBOs(1, 1, 4, 1, 2, 2, false, false);
577
578 // Clear all attachments.
579 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
580 glClearColor(0, 1, 0, 1);
581 glClear(GL_COLOR_BUFFER_BIT);
582
583 for (int i = 0; i < 2; ++i)
584 {
585 GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300586 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, colorAttachment));
Martin Radev5e424fa2017-08-09 16:25:36 +0300587 EXPECT_EQ(GLColor::green, getLayerColor(1, colorAttachment));
588 EXPECT_EQ(GLColor::green, getLayerColor(2, colorAttachment));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300589 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, colorAttachment));
Martin Radev5e424fa2017-08-09 16:25:36 +0300590 }
591
592 // Detach and clear again.
593 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700594 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0, 0, 1, 2);
Martin Radev5e424fa2017-08-09 16:25:36 +0300595 glClearColor(1, 1, 0, 1);
596 glClear(GL_COLOR_BUFFER_BIT);
597
598 // Check that color attachment 0 is modified.
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300599 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300600 EXPECT_EQ(GLColor::yellow, getLayerColor(1, GL_COLOR_ATTACHMENT0));
601 EXPECT_EQ(GLColor::yellow, getLayerColor(2, GL_COLOR_ATTACHMENT0));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300602 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300603
604 // Check that color attachment 1 is unmodified.
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300605 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300606 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1));
607 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300608 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300609}
610
611// Test that glClear clears only the contents within the scissor rectangle of the attached layers.
612TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClear)
613{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300614 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300615
616 initializeFBOs(2, 1, 4, 1, 2, 1, false, false);
617
618 // Bind and specify viewport/scissor dimensions for each view.
619 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
620
621 glEnable(GL_SCISSOR_TEST);
622 glScissor(1, 0, 1, 1);
623 glClearColor(0, 1, 0, 1);
624 glClear(GL_COLOR_BUFFER_BIT);
625
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300626 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0));
627 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0, 1, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300628
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300629 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300630 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0, 1, 0));
631
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300632 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300633 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0, 1, 0));
634
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300635 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 0));
636 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0, 1, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300637}
638
Martin Radev18b75ba2017-08-15 15:50:40 +0300639// Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers
640// to a layered FBO.
641TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClearBufferfi)
642{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300643 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev18b75ba2017-08-15 15:50:40 +0300644
645 // Create program to draw a quad.
Jamie Madill35cd7332018-12-02 12:03:33 -0500646 constexpr char kVS[] =
Martin Radev18b75ba2017-08-15 15:50:40 +0300647 "#version 300 es\n"
648 "in vec3 vPos;\n"
649 "void main(){\n"
650 " gl_Position = vec4(vPos, 1.);\n"
651 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500652 constexpr char kFS[] =
Martin Radev18b75ba2017-08-15 15:50:40 +0300653 "#version 300 es\n"
654 "precision mediump float;\n"
655 "uniform vec3 uCol;\n"
656 "out vec4 col;\n"
657 "void main(){\n"
658 " col = vec4(uCol,1.);\n"
659 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500660 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev18b75ba2017-08-15 15:50:40 +0300661 glUseProgram(program);
662 GLuint mColorUniformLoc = glGetUniformLocation(program, "uCol");
663
664 initializeFBOs(1, 2, 4, 1, 2, 1, true, false);
665 glEnable(GL_STENCIL_TEST);
666 glDisable(GL_DEPTH_TEST);
667
668 // Set clear values.
669 glClearColor(1, 0, 0, 1);
670 glClearStencil(0xFF);
671
672 // Clear the color and stencil buffers of each layer.
673 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
674 {
675 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
676 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
677 }
678
679 // Switch to multiview framebuffer and clear portions of the texture.
680 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
681 glEnable(GL_SCISSOR_TEST);
682 glScissor(0, 0, 1, 1);
683 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
684 glDisable(GL_SCISSOR_TEST);
685
686 // Draw a fullscreen quad, but adjust the stencil function so that only the cleared regions pass
687 // the test.
688 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
689 glStencilFunc(GL_EQUAL, 0x00, 0xFF);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300690 glUniform3f(mColorUniformLoc, 0.0f, 1.0f, 0.0f);
Martin Radev18b75ba2017-08-15 15:50:40 +0300691 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
692 {
693 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
Martin Radev18b75ba2017-08-15 15:50:40 +0300694 drawQuad(program, "vPos", 0.0f, 1.0f, true);
695 }
696 EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0));
697 EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 1));
698 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 0));
699 EXPECT_EQ(GLColor::red, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 1));
700 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 0));
701 EXPECT_EQ(GLColor::red, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 1));
702 EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 0));
703 EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 1));
704}
705
Martin Radev14b21262017-08-25 13:54:37 +0300706// Test that detaching an attachment does not generate an error whenever the multi-view related
707// arguments are invalid.
708TEST_P(FramebufferMultiviewTest, InvalidMultiviewArgumentsOnDetach)
709{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300710 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev14b21262017-08-25 13:54:37 +0300711
712 GLFramebuffer fbo;
713 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
714
715 // Invalid base view index.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700716 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, -1, 1);
Martin Radev14b21262017-08-25 13:54:37 +0300717 EXPECT_GL_NO_ERROR();
718
719 // Invalid number of views.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700720 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0, 0);
Martin Radev14b21262017-08-25 13:54:37 +0300721 EXPECT_GL_NO_ERROR();
722}
723
Martin Radev61e710b2017-09-05 11:59:52 +0300724// Test that glClear clears the contents of the color buffer whenever all layers of a 2D texture
725// array are attached. The test is added because a special fast code path is used for this case.
726TEST_P(FramebufferMultiviewLayeredClearTest, ColorBufferClearAllLayersAttached)
727{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300728 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev61e710b2017-09-05 11:59:52 +0300729
730 initializeFBOs(1, 1, 2, 0, 2, 1, false, false);
731
732 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
733 glClearColor(0, 1, 0, 1);
734 glClear(GL_COLOR_BUFFER_BIT);
735
736 EXPECT_EQ(GLColor::green, getLayerColor(0, GL_COLOR_ATTACHMENT0));
737 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
738}
739
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300740// Test that attaching a multisampled texture array is not possible if all the required extensions
741// are not enabled.
742TEST_P(FramebufferMultiviewTest, NegativeMultisampledFramebufferTest)
743{
744 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
745
Jamie Madillb8149072019-04-30 16:14:44 -0400746 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_OES_texture_storage_multisample_2d_array"));
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300747
Mingyu Hu7d64c482019-03-12 14:27:40 -0700748 // We don't enable OVR_multiview2_multisample
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300749
750 GLTexture multisampleTexture;
751 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, multisampleTexture);
752
753 GLFramebuffer fbo;
754 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700755 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, multisampleTexture, 0, 0,
756 2);
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300757 // From the extension spec: "An INVALID_OPERATION error is generated if texture is not zero, and
758 // does not name an existing texture object of type TEXTURE_2D_ARRAY."
759 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
760}
761
Mingyu Huebab6702019-04-19 14:36:45 -0700762ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest,
763 VertexShaderOpenGL(3, 0, ExtensionName::multiview),
764 GeomShaderD3D11(3, 0, ExtensionName::multiview),
765 VertexShaderOpenGL(3, 0, ExtensionName::multiview2),
766 GeomShaderD3D11(3, 0, ExtensionName::multiview2));
Olli Etuahof26b27e2018-08-17 11:01:19 +0300767ANGLE_INSTANTIATE_TEST(FramebufferMultiviewLayeredClearTest,
Mingyu Huebab6702019-04-19 14:36:45 -0700768 VertexShaderOpenGL(3, 0, ExtensionName::multiview),
769 GeomShaderD3D11(3, 0, ExtensionName::multiview),
770 VertexShaderOpenGL(3, 0, ExtensionName::multiview2),
771 GeomShaderD3D11(3, 0, ExtensionName::multiview2));