blob: aa4c00b4cfa1293ad6ba76fd7fa93e9aa40c2463 [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
265 GLFramebuffer fbo;
266 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
267
268 GLTexture tex;
269 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
270 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
271
Mingyu Hu7d64c482019-03-12 14:27:40 -0700272 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 1);
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300273 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
274 ASSERT_GL_NO_ERROR();
275
276 // Test glCopyTexImage2D and glCopyTexSubImage2D.
277 {
278 GLTexture tex2;
279 glBindTexture(GL_TEXTURE_2D, tex2);
280 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
281
282 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
283 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
284 glClear(GL_COLOR_BUFFER_BIT);
285
286 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 1, 1, 0);
287 ASSERT_GL_NO_ERROR();
288
289 // Test texture contents.
290 glBindFramebuffer(GL_FRAMEBUFFER, 0);
291 draw2DTexturedQuad(0.0f, 1.0f, true);
292 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
293
294 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
295 glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
296 glClear(GL_COLOR_BUFFER_BIT);
297
298 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
299 ASSERT_GL_NO_ERROR();
300
301 glBindFramebuffer(GL_FRAMEBUFFER, 0);
302 draw2DTexturedQuad(0.0f, 1.0f, true);
303 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
304 }
305
306 // Test glCopyTexSubImage3D.
307 {
308 GLTexture tex2;
309 glBindTexture(GL_TEXTURE_3D, tex2);
310 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
311
312 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
313 glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
314 glClear(GL_COLOR_BUFFER_BIT);
315 glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1, 1);
316 ASSERT_GL_NO_ERROR();
317
318 glBindFramebuffer(GL_FRAMEBUFFER, 0);
319 draw3DTexturedQuad(0.0f, 1.0f, true, 0.0f);
320 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
321 }
322}
323
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300324// Test that glBlitFramebuffer succeeds if the current read framebuffer has just one layered view.
325TEST_P(FramebufferMultiviewTest, Blit)
326{
327 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
328
329 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
330 glClear(GL_COLOR_BUFFER_BIT);
331
332 GLFramebuffer fbo;
333 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
334
335 GLTexture tex;
336 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
337 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
338
Mingyu Hu7d64c482019-03-12 14:27:40 -0700339 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 1);
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300340 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
341 ASSERT_GL_NO_ERROR();
342
343 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
344 glClear(GL_COLOR_BUFFER_BIT);
345
346 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
347 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
348 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
349 ASSERT_GL_NO_ERROR();
350
351 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
352 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
353}
354
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300355// Test that glReadPixels succeeds from a layered multiview framebuffer with just one view.
356TEST_P(FramebufferMultiviewTest, ReadPixels)
357{
358 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
359
360 GLFramebuffer fbo;
361 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
362
363 GLTexture tex;
364 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
365 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
366
Mingyu Hu7d64c482019-03-12 14:27:40 -0700367 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 1);
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300368 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
369 ASSERT_GL_NO_ERROR();
370
371 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
372 glClear(GL_COLOR_BUFFER_BIT);
373
374 GLColor pixelColor;
375 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColor.R);
376 ASSERT_GL_NO_ERROR();
377 EXPECT_COLOR_NEAR(GLColor::green, pixelColor, 2);
378}
379
Mingyu Hu7d64c482019-03-12 14:27:40 -0700380// Test that glFramebufferTextureMultiviewOVR modifies the internal multiview state.
Martin Radev82ef7742017-08-08 17:44:58 +0300381TEST_P(FramebufferMultiviewTest, ModifyLayeredState)
382{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300383 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev82ef7742017-08-08 17:44:58 +0300384
385 GLFramebuffer multiviewFBO;
386 glBindFramebuffer(GL_FRAMEBUFFER, multiviewFBO);
387
388 GLTexture tex;
389 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
390 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
391 ASSERT_GL_NO_ERROR();
392
Mingyu Hu7d64c482019-03-12 14:27:40 -0700393 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1, 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300394 ASSERT_GL_NO_ERROR();
395
396 GLint numViews = -1;
397 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700398 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300399 &numViews);
400 ASSERT_GL_NO_ERROR();
401 EXPECT_EQ(2, numViews);
402
403 GLint baseViewIndex = -1;
404 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
Mingyu Hu7d64c482019-03-12 14:27:40 -0700405 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300406 &baseViewIndex);
407 ASSERT_GL_NO_ERROR();
408 EXPECT_EQ(1, baseViewIndex);
Martin Radev82ef7742017-08-08 17:44:58 +0300409}
410
411// Test framebuffer completeness status of a layered framebuffer with color attachments.
412TEST_P(FramebufferMultiviewTest, IncompleteViewTargetsLayered)
413{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300414 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev82ef7742017-08-08 17:44:58 +0300415
416 GLFramebuffer fbo;
417 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
418
419 GLTexture tex;
420 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
421 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
422
423 // Set the 0th attachment and keep it as it is till the end of the test. The 1st color
424 // attachment will be modified to change the framebuffer's status.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700425 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300426 ASSERT_GL_NO_ERROR();
427
428 GLTexture otherTexLayered;
429 glBindTexture(GL_TEXTURE_2D_ARRAY, otherTexLayered);
430 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
431
432 // Test framebuffer completeness when the base view index differs.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700433 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 1,
434 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300435 ASSERT_GL_NO_ERROR();
Mingyu Hu7d64c482019-03-12 14:27:40 -0700436 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300437 glCheckFramebufferStatus(GL_FRAMEBUFFER));
438
Martin Radev5e424fa2017-08-09 16:25:36 +0300439 // Test framebuffer completeness when the 1st attachment has a non-multiview layout.
Martin Radev82ef7742017-08-08 17:44:58 +0300440 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 0);
441 ASSERT_GL_NO_ERROR();
Mingyu Hu7d64c482019-03-12 14:27:40 -0700442 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
Martin Radev82ef7742017-08-08 17:44:58 +0300443 glCheckFramebufferStatus(GL_FRAMEBUFFER));
444
445 // Test that framebuffer is complete when the number of views, base view index and layouts are
446 // the same.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700447 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 0,
448 2);
Martin Radev82ef7742017-08-08 17:44:58 +0300449 ASSERT_GL_NO_ERROR();
450 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
451}
452
Martin Radev5e424fa2017-08-09 16:25:36 +0300453// Test that glClear clears the contents of the color buffer for only the attached layers to a
454// layered FBO.
455TEST_P(FramebufferMultiviewLayeredClearTest, ColorBufferClear)
456{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300457 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300458
459 initializeFBOs(1, 1, 4, 1, 2, 1, false, false);
460
461 // Bind and specify viewport/scissor dimensions for each view.
462 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
463
464 glClearColor(0, 1, 0, 1);
465 glClear(GL_COLOR_BUFFER_BIT);
466
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300467 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300468 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
469 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300470 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300471}
472
473// Test that glClearBufferfv can be used to clear individual color buffers of a layered FBO.
474TEST_P(FramebufferMultiviewLayeredClearTest, ClearIndividualColorBuffer)
475{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300476 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300477
478 initializeFBOs(1, 1, 4, 1, 2, 2, false, false);
479
480 for (int i = 0; i < 2; ++i)
481 {
482 for (int layer = 0; layer < 4; ++layer)
483 {
484 GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300485 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(layer, colorAttachment));
Martin Radev5e424fa2017-08-09 16:25:36 +0300486 }
487 }
488
489 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
490
491 float clearValues0[4] = {0.f, 0.f, 1.f, 1.f};
492 glClearBufferfv(GL_COLOR, 0, clearValues0);
493
494 float clearValues1[4] = {0.f, 1.f, 0.f, 1.f};
495 glClearBufferfv(GL_COLOR, 1, clearValues1);
496
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300497 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300498 EXPECT_EQ(GLColor::blue, getLayerColor(1, GL_COLOR_ATTACHMENT0));
499 EXPECT_EQ(GLColor::blue, getLayerColor(2, GL_COLOR_ATTACHMENT0));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300500 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300501
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300502 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300503 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1));
504 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300505 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300506}
507
508// Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers
509// to a layered FBO.
510TEST_P(FramebufferMultiviewLayeredClearTest, ClearBufferfi)
511{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300512 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300513
514 // Create program to draw a quad.
Jamie Madill35cd7332018-12-02 12:03:33 -0500515 constexpr char kVS[] =
Martin Radev5e424fa2017-08-09 16:25:36 +0300516 "#version 300 es\n"
517 "in vec3 vPos;\n"
518 "void main(){\n"
519 " gl_Position = vec4(vPos, 1.);\n"
520 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500521 constexpr char kFS[] =
Martin Radev5e424fa2017-08-09 16:25:36 +0300522 "#version 300 es\n"
523 "precision mediump float;\n"
524 "uniform vec3 uCol;\n"
525 "out vec4 col;\n"
526 "void main(){\n"
527 " col = vec4(uCol,1.);\n"
528 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500529 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev5e424fa2017-08-09 16:25:36 +0300530 glUseProgram(program);
531 GLuint mColorUniformLoc = glGetUniformLocation(program, "uCol");
532
533 initializeFBOs(1, 1, 4, 1, 2, 1, true, false);
534 glEnable(GL_STENCIL_TEST);
535 glDisable(GL_DEPTH_TEST);
536
537 // Set clear values.
538 glClearColor(1, 0, 0, 1);
539 glClearStencil(0xFF);
540
541 // Clear the color and stencil buffers of each layer.
542 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
543 {
544 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
545 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
546 }
547
548 // Switch to multiview framebuffer and clear portions of the texture.
549 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
550 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
551
552 // Draw a fullscreen quad, but adjust the stencil function so that only the cleared regions pass
553 // the test.
554 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
555 glStencilFunc(GL_EQUAL, 0x00, 0xFF);
556 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
557 {
558 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
559 glUniform3f(mColorUniformLoc, 0.0f, 1.0f, 0.0f);
560 drawQuad(program, "vPos", 0.0f, 1.0f, true);
561 }
562 EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0));
563 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
564 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0));
565 EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0));
566}
567
568// Test that glClear does not clear the content of a detached texture.
569TEST_P(FramebufferMultiviewLayeredClearTest, UnmodifiedDetachedTexture)
570{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300571 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300572
573 initializeFBOs(1, 1, 4, 1, 2, 2, false, false);
574
575 // Clear all attachments.
576 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
577 glClearColor(0, 1, 0, 1);
578 glClear(GL_COLOR_BUFFER_BIT);
579
580 for (int i = 0; i < 2; ++i)
581 {
582 GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300583 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, colorAttachment));
Martin Radev5e424fa2017-08-09 16:25:36 +0300584 EXPECT_EQ(GLColor::green, getLayerColor(1, colorAttachment));
585 EXPECT_EQ(GLColor::green, getLayerColor(2, colorAttachment));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300586 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, colorAttachment));
Martin Radev5e424fa2017-08-09 16:25:36 +0300587 }
588
589 // Detach and clear again.
590 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700591 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0, 0, 1, 2);
Martin Radev5e424fa2017-08-09 16:25:36 +0300592 glClearColor(1, 1, 0, 1);
593 glClear(GL_COLOR_BUFFER_BIT);
594
595 // Check that color attachment 0 is modified.
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300596 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300597 EXPECT_EQ(GLColor::yellow, getLayerColor(1, GL_COLOR_ATTACHMENT0));
598 EXPECT_EQ(GLColor::yellow, getLayerColor(2, GL_COLOR_ATTACHMENT0));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300599 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300600
601 // Check that color attachment 1 is unmodified.
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300602 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300603 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1));
604 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1));
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300605 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT1));
Martin Radev5e424fa2017-08-09 16:25:36 +0300606}
607
608// Test that glClear clears only the contents within the scissor rectangle of the attached layers.
609TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClear)
610{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300611 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev5e424fa2017-08-09 16:25:36 +0300612
613 initializeFBOs(2, 1, 4, 1, 2, 1, false, false);
614
615 // Bind and specify viewport/scissor dimensions for each view.
616 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
617
618 glEnable(GL_SCISSOR_TEST);
619 glScissor(1, 0, 1, 1);
620 glClearColor(0, 1, 0, 1);
621 glClear(GL_COLOR_BUFFER_BIT);
622
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300623 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0));
624 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0, 1, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300625
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300626 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300627 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0, 1, 0));
628
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300629 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300630 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0, 1, 0));
631
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300632 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 0));
633 EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0, 1, 0));
Martin Radev5e424fa2017-08-09 16:25:36 +0300634}
635
Martin Radev18b75ba2017-08-15 15:50:40 +0300636// Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers
637// to a layered FBO.
638TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClearBufferfi)
639{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300640 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev18b75ba2017-08-15 15:50:40 +0300641
642 // Create program to draw a quad.
Jamie Madill35cd7332018-12-02 12:03:33 -0500643 constexpr char kVS[] =
Martin Radev18b75ba2017-08-15 15:50:40 +0300644 "#version 300 es\n"
645 "in vec3 vPos;\n"
646 "void main(){\n"
647 " gl_Position = vec4(vPos, 1.);\n"
648 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500649 constexpr char kFS[] =
Martin Radev18b75ba2017-08-15 15:50:40 +0300650 "#version 300 es\n"
651 "precision mediump float;\n"
652 "uniform vec3 uCol;\n"
653 "out vec4 col;\n"
654 "void main(){\n"
655 " col = vec4(uCol,1.);\n"
656 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -0500657 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev18b75ba2017-08-15 15:50:40 +0300658 glUseProgram(program);
659 GLuint mColorUniformLoc = glGetUniformLocation(program, "uCol");
660
661 initializeFBOs(1, 2, 4, 1, 2, 1, true, false);
662 glEnable(GL_STENCIL_TEST);
663 glDisable(GL_DEPTH_TEST);
664
665 // Set clear values.
666 glClearColor(1, 0, 0, 1);
667 glClearStencil(0xFF);
668
669 // Clear the color and stencil buffers of each layer.
670 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
671 {
672 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
673 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
674 }
675
676 // Switch to multiview framebuffer and clear portions of the texture.
677 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
678 glEnable(GL_SCISSOR_TEST);
679 glScissor(0, 0, 1, 1);
680 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
681 glDisable(GL_SCISSOR_TEST);
682
683 // Draw a fullscreen quad, but adjust the stencil function so that only the cleared regions pass
684 // the test.
685 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
686 glStencilFunc(GL_EQUAL, 0x00, 0xFF);
Olli Etuahoa7b35c32018-08-21 16:32:24 +0300687 glUniform3f(mColorUniformLoc, 0.0f, 1.0f, 0.0f);
Martin Radev18b75ba2017-08-15 15:50:40 +0300688 for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
689 {
690 glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
Martin Radev18b75ba2017-08-15 15:50:40 +0300691 drawQuad(program, "vPos", 0.0f, 1.0f, true);
692 }
693 EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0));
694 EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 1));
695 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 0));
696 EXPECT_EQ(GLColor::red, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 1));
697 EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 0));
698 EXPECT_EQ(GLColor::red, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 1));
699 EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 0));
700 EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 1));
701}
702
Martin Radev14b21262017-08-25 13:54:37 +0300703// Test that detaching an attachment does not generate an error whenever the multi-view related
704// arguments are invalid.
705TEST_P(FramebufferMultiviewTest, InvalidMultiviewArgumentsOnDetach)
706{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300707 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev14b21262017-08-25 13:54:37 +0300708
709 GLFramebuffer fbo;
710 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
711
712 // Invalid base view index.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700713 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, -1, 1);
Martin Radev14b21262017-08-25 13:54:37 +0300714 EXPECT_GL_NO_ERROR();
715
716 // Invalid number of views.
Mingyu Hu7d64c482019-03-12 14:27:40 -0700717 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0, 0);
Martin Radev14b21262017-08-25 13:54:37 +0300718 EXPECT_GL_NO_ERROR();
719}
720
Martin Radev61e710b2017-09-05 11:59:52 +0300721// Test that glClear clears the contents of the color buffer whenever all layers of a 2D texture
722// array are attached. The test is added because a special fast code path is used for this case.
723TEST_P(FramebufferMultiviewLayeredClearTest, ColorBufferClearAllLayersAttached)
724{
Olli Etuaho8acb1b62018-07-30 16:20:54 +0300725 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
Martin Radev61e710b2017-09-05 11:59:52 +0300726
727 initializeFBOs(1, 1, 2, 0, 2, 1, false, false);
728
729 glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
730 glClearColor(0, 1, 0, 1);
731 glClear(GL_COLOR_BUFFER_BIT);
732
733 EXPECT_EQ(GLColor::green, getLayerColor(0, GL_COLOR_ATTACHMENT0));
734 EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
735}
736
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300737// Test that attaching a multisampled texture array is not possible if all the required extensions
738// are not enabled.
739TEST_P(FramebufferMultiviewTest, NegativeMultisampledFramebufferTest)
740{
741 ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
742
Jamie Madillb8149072019-04-30 16:14:44 -0400743 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_OES_texture_storage_multisample_2d_array"));
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300744
Mingyu Hu7d64c482019-03-12 14:27:40 -0700745 // We don't enable OVR_multiview2_multisample
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300746
747 GLTexture multisampleTexture;
748 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, multisampleTexture);
749
750 GLFramebuffer fbo;
751 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
Mingyu Hu7d64c482019-03-12 14:27:40 -0700752 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, multisampleTexture, 0, 0,
753 2);
Olli Etuaho2c8f0842018-09-12 14:44:55 +0300754 // From the extension spec: "An INVALID_OPERATION error is generated if texture is not zero, and
755 // does not name an existing texture object of type TEXTURE_2D_ARRAY."
756 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
757}
758
Mingyu Huebab6702019-04-19 14:36:45 -0700759ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest,
760 VertexShaderOpenGL(3, 0, ExtensionName::multiview),
761 GeomShaderD3D11(3, 0, ExtensionName::multiview),
762 VertexShaderOpenGL(3, 0, ExtensionName::multiview2),
763 GeomShaderD3D11(3, 0, ExtensionName::multiview2));
Olli Etuahof26b27e2018-08-17 11:01:19 +0300764ANGLE_INSTANTIATE_TEST(FramebufferMultiviewLayeredClearTest,
Mingyu Huebab6702019-04-19 14:36:45 -0700765 VertexShaderOpenGL(3, 0, ExtensionName::multiview),
766 GeomShaderD3D11(3, 0, ExtensionName::multiview),
767 VertexShaderOpenGL(3, 0, ExtensionName::multiview2),
768 GeomShaderD3D11(3, 0, ExtensionName::multiview2));