blob: f6c4a90bc986f9001a92c10b94c016cc43bfbf6f [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
10#include "test_utils/ANGLETest.h"
11
12using namespace angle;
13
Martin Radev9bc9a322017-07-21 14:28:17 +030014namespace
15{
16
17GLuint CreateTexture2D(GLenum internalFormat, GLenum format, GLenum type)
18{
19 GLuint tex;
20 glGenTextures(1, &tex);
21 glBindTexture(GL_TEXTURE_2D, tex);
22 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
23 return tex;
24}
25
26} // namespace
27
Martin Radeve5285d22017-07-14 16:23:53 +030028class FramebufferMultiviewTest : public ANGLETest
29{
30 protected:
Martin Radev137032d2017-07-13 10:11:12 +030031 FramebufferMultiviewTest() : mFramebuffer(0), mTexture2D(0), mTexture2DArray(0)
Martin Radeve5285d22017-07-14 16:23:53 +030032 {
33 setWindowWidth(128);
34 setWindowHeight(128);
35 setWebGLCompatibilityEnabled(true);
36 }
37
38 void SetUp() override
39 {
40 ANGLETest::SetUp();
41
42 glGenFramebuffers(1, &mFramebuffer);
43 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
44
Martin Radeve5285d22017-07-14 16:23:53 +030045 glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>(
46 eglGetProcAddress("glRequestExtensionANGLE"));
47 }
48
49 void TearDown() override
50 {
Martin Radev137032d2017-07-13 10:11:12 +030051 if (mTexture2D != 0)
Martin Radeve5285d22017-07-14 16:23:53 +030052 {
Martin Radev137032d2017-07-13 10:11:12 +030053 glDeleteTextures(1, &mTexture2D);
54 mTexture2D = 0;
55 }
56
57 if (mTexture2DArray != 0)
58 {
59 glDeleteTextures(1, &mTexture2DArray);
60 mTexture2DArray = 0;
Martin Radeve5285d22017-07-14 16:23:53 +030061 }
62
63 if (mFramebuffer != 0)
64 {
65 glDeleteFramebuffers(1, &mFramebuffer);
66 mFramebuffer = 0;
67 }
68
69 ANGLETest::TearDown();
70 }
71
Martin Radev137032d2017-07-13 10:11:12 +030072 void createTexture2DArray()
73 {
74 glGenTextures(1, &mTexture2DArray);
75 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture2DArray);
76 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA16F, 1, 1, 2);
77 ASSERT_GL_NO_ERROR();
78 }
79
80 // Requests the ANGLE_multiview extension and returns true if the operation succeeds.
81 bool requestMultiviewExtension()
82 {
83 if (extensionRequestable("GL_ANGLE_multiview"))
84 {
85 glRequestExtensionANGLE("GL_ANGLE_multiview");
86 }
87
88 if (!extensionEnabled("GL_ANGLE_multiview"))
89 {
90 std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
91 return false;
92 }
93 return true;
94 }
95
Martin Radeve5285d22017-07-14 16:23:53 +030096 GLuint mFramebuffer;
Martin Radev137032d2017-07-13 10:11:12 +030097 GLuint mTexture2D;
98 GLuint mTexture2DArray;
Martin Radeve5285d22017-07-14 16:23:53 +030099 PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
100};
101
102// Test that the framebuffer tokens introduced by ANGLE_multiview can be used query the framebuffer
103// state and that their corresponding default values are correctly set.
104TEST_P(FramebufferMultiviewTest, DefaultState)
105{
Martin Radev137032d2017-07-13 10:11:12 +0300106 if (!requestMultiviewExtension())
Martin Radeve5285d22017-07-14 16:23:53 +0300107 {
Martin Radeve5285d22017-07-14 16:23:53 +0300108 return;
109 }
110
Martin Radev9bc9a322017-07-21 14:28:17 +0300111 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
112 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300113 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
114
Martin Radeve5285d22017-07-14 16:23:53 +0300115 GLint numViews = -1;
116 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
117 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
118 &numViews);
119 EXPECT_GL_NO_ERROR();
120 EXPECT_EQ(1, numViews);
121
122 GLint baseViewIndex = -1;
123 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
124 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
125 &baseViewIndex);
126 EXPECT_GL_NO_ERROR();
127 EXPECT_EQ(0, baseViewIndex);
128
129 GLint multiviewLayout = GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE;
130 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
131 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
132 &multiviewLayout);
133 EXPECT_GL_NO_ERROR();
134 EXPECT_EQ(GL_NONE, multiviewLayout);
135
136 GLint viewportOffsets[2] = {-1, -1};
137 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
138 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
139 &viewportOffsets[0]);
140 EXPECT_GL_NO_ERROR();
141 EXPECT_EQ(0, viewportOffsets[0]);
142 EXPECT_EQ(0, viewportOffsets[1]);
143}
144
145// Test that without having the ANGLE_multiview extension, querying for the framebuffer state using
146// the ANGLE_multiview tokens results in an INVALID_ENUM error.
147TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
148{
Martin Radev9bc9a322017-07-21 14:28:17 +0300149 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
150 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300151 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
152
Martin Radeve5285d22017-07-14 16:23:53 +0300153 GLint numViews = -1;
154 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
155 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
156 &numViews);
157 EXPECT_GL_ERROR(GL_INVALID_ENUM);
158
159 GLint baseViewIndex = -1;
160 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
161 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
162 &baseViewIndex);
163 EXPECT_GL_ERROR(GL_INVALID_ENUM);
164
165 GLint multiviewLayout = GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE;
166 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
167 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
168 &multiviewLayout);
169 EXPECT_GL_ERROR(GL_INVALID_ENUM);
170
171 GLint viewportOffsets[2] = {-1, -1};
172 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
173 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
174 &viewportOffsets[0]);
175 EXPECT_GL_ERROR(GL_INVALID_ENUM);
176}
177
Martin Radev137032d2017-07-13 10:11:12 +0300178// Test that the correct errors are generated whenever glFramebufferTextureMultiviewSideBySideANGLE
179// is called with invalid arguments.
180TEST_P(FramebufferMultiviewTest, InvalidMultiviewSideBySideArguments)
181{
182 if (!requestMultiviewExtension())
183 {
184 return;
185 }
186
Martin Radev9bc9a322017-07-21 14:28:17 +0300187 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
188 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300189 // Negative offsets.
190 int viewportOffsets[2] = {-1};
191 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
192 0, 1, &viewportOffsets[0]);
193 EXPECT_GL_ERROR(GL_INVALID_VALUE);
194
195 // Negative number of views.
196 viewportOffsets[0] = 0;
197 viewportOffsets[1] = 0;
198 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
199 0, -1, &viewportOffsets[0]);
200 EXPECT_GL_ERROR(GL_INVALID_VALUE);
201}
202
203// Test that the correct errors are generated whenever glFramebufferTextureMultiviewLayeredANGLE is
204// called with invalid arguments.
205TEST_P(FramebufferMultiviewTest, InvalidMultiviewLayeredArguments)
206{
207 if (!requestMultiviewExtension())
208 {
209 return;
210 }
211
212 createTexture2DArray();
213 // Negative base view index.
214 glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
215 0, -1, 1);
216 EXPECT_GL_ERROR(GL_INVALID_VALUE);
217
218 // baseViewIndex + numViews is greater than MAX_TEXTURE_LAYERS.
219 GLint maxTextureLayers = 0;
220 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
221 ASSERT_GL_NO_ERROR();
222 glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
223 0, maxTextureLayers, 1);
224 EXPECT_GL_ERROR(GL_INVALID_VALUE);
225}
226
227// Test that an INVALID_OPERATION error is generated whenever the ANGLE_multiview extension is not
228// available.
229TEST_P(FramebufferMultiviewTest, ExtensionNotAvailableCheck)
230{
Martin Radev9bc9a322017-07-21 14:28:17 +0300231 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
232 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300233 int viewportOffsets[2] = {0};
234 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
235 0, 1, &viewportOffsets[0]);
236 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
237}
238
Martin Radev5dae57b2017-07-14 16:15:55 +0300239// Test that glFramebufferTextureMultiviewSideBySideANGLE modifies the internal multiview state.
240TEST_P(FramebufferMultiviewTest, ModifySideBySideState)
241{
242 if (!requestMultiviewExtension())
243 {
244 return;
245 }
246
247 const GLint viewportOffsets[4] = {0, 0, 1, 2};
Martin Radev9bc9a322017-07-21 14:28:17 +0300248 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
249 ASSERT_GL_NO_ERROR();
Martin Radev5dae57b2017-07-14 16:15:55 +0300250 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
251 0, 2, &viewportOffsets[0]);
252 ASSERT_GL_NO_ERROR();
253
254 GLint numViews = -1;
255 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
256 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
257 &numViews);
258 ASSERT_GL_NO_ERROR();
259 EXPECT_EQ(2, numViews);
260
261 GLint baseViewIndex = -1;
262 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
263 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
264 &baseViewIndex);
265 ASSERT_GL_NO_ERROR();
266 EXPECT_EQ(0, baseViewIndex);
267
268 GLint multiviewLayout = GL_NONE;
269 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
270 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
271 &multiviewLayout);
272 ASSERT_GL_NO_ERROR();
273 EXPECT_EQ(GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, multiviewLayout);
274
275 GLint internalViewportOffsets[4] = {-1};
276 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
277 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
278 &internalViewportOffsets[0]);
279 ASSERT_GL_NO_ERROR();
280 for (size_t i = 0u; i < 4u; ++i)
281 {
282 EXPECT_EQ(viewportOffsets[i], internalViewportOffsets[i]);
283 }
284}
285
Martin Radev9bc9a322017-07-21 14:28:17 +0300286// Test framebuffer completeness status of a side-by-side framebuffer with color and depth
287// attachments.
288TEST_P(FramebufferMultiviewTest, IncompleteViewTargetsSideBySide)
289{
290 if (!requestMultiviewExtension())
291 {
292 return;
293 }
294
295 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
296 ASSERT_GL_NO_ERROR();
297
298 GLuint otherTexture = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
299 ASSERT_GL_NO_ERROR();
300
301 GLuint depthTexture = CreateTexture2D(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
302 ASSERT_GL_NO_ERROR();
303
304 const GLint viewportOffsets[4] = {0, 0, 2, 0};
305 const GLint otherViewportOffsets[4] = {2, 0, 4, 0};
306
307 // Set the 0th attachment and keep it as it is till the end of the test. The 1st or depth
308 // attachment will me modified to change the framebuffer's status.
309 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
310 0, 2, &viewportOffsets[0]);
311 ASSERT_GL_NO_ERROR();
312
313 // Color attachment 1.
314 {
315 // Test framebuffer completeness when the number of views differ.
316 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
317 otherTexture, 0, 1, &viewportOffsets[0]);
318 ASSERT_GL_NO_ERROR();
319 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
320 glCheckFramebufferStatus(GL_FRAMEBUFFER));
321
322 // Test framebuffer completeness when the viewport offsets differ.
323 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
324 otherTexture, 0, 2, &otherViewportOffsets[0]);
325 ASSERT_GL_NO_ERROR();
326 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
327 glCheckFramebufferStatus(GL_FRAMEBUFFER));
328
329 // Test framebuffer completeness when attachment layouts differ.
330 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, otherTexture,
331 0);
332 ASSERT_GL_NO_ERROR();
333 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
334 glCheckFramebufferStatus(GL_FRAMEBUFFER));
335
336 // Test that framebuffer is complete when the number of views, viewport offsets and layouts
337 // are the same.
338 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
339 otherTexture, 0, 2, &viewportOffsets[0]);
340 ASSERT_GL_NO_ERROR();
341 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
342
343 // Reset attachment 1
344 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0, 0, 1,
345 &viewportOffsets[0]);
346 }
347
348 // Depth attachment.
349 {
350 // Test framebuffer completeness when the number of views differ.
351 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
352 depthTexture, 0, 1, &viewportOffsets[0]);
353 ASSERT_GL_NO_ERROR();
354 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
355 glCheckFramebufferStatus(GL_FRAMEBUFFER));
356
357 // Test framebuffer completeness when the viewport offsets differ.
358 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
359 depthTexture, 0, 2, &otherViewportOffsets[0]);
360 ASSERT_GL_NO_ERROR();
361 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
362 glCheckFramebufferStatus(GL_FRAMEBUFFER));
363
364 // Test framebuffer completeness when attachment layouts differ.
365 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
366 ASSERT_GL_NO_ERROR();
367 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
368 glCheckFramebufferStatus(GL_FRAMEBUFFER));
369
370 // Test that framebuffer is complete when the number of views, viewport offsets and layouts
371 // are the same.
372 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
373 depthTexture, 0, 2, &viewportOffsets[0]);
374 ASSERT_GL_NO_ERROR();
375 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
376 }
377
378 glDeleteTextures(1, &depthTexture);
379 glDeleteTextures(1, &otherTexture);
380}
381
Martin Radev04e2c3b2017-07-27 16:54:35 +0300382// Test that the active read framebuffer cannot be read from through glCopyTex* if it has multi-view
383// attachments.
384TEST_P(FramebufferMultiviewTest, InvalidCopyTex)
385{
386 if (!requestMultiviewExtension())
387 {
388 return;
389 }
390
391 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
392 ASSERT_GL_NO_ERROR();
393
394 const GLint viewportOffsets[2] = {0};
395 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
396 0, 1, &viewportOffsets[0]);
397 ASSERT_GL_NO_ERROR();
398
399 // Test glCopyTexImage2D and glCopyTexSubImage2D.
400 {
401 GLuint tex = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
402
403 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 1, 1, 0);
404 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
405
406 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
407 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
408
409 glDeleteTextures(1, &tex);
410 }
411
412 // Test glCopyTexSubImage3D.
413 {
414 GLuint tex = 0u;
415 glGenTextures(1, &tex);
416 glBindTexture(GL_TEXTURE_3D, tex);
417 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
418
419 glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1, 1);
420 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
421
422 glDeleteTextures(1, &tex);
423 }
424}
425
Martin Radeva3ed4572017-07-27 18:29:37 +0300426// Test that glBlitFramebuffer generates an invalid framebuffer operation when either the current
427// draw framebuffer, or current read framebuffer have multiview attachments.
428TEST_P(FramebufferMultiviewTest, InvalidBlit)
429{
430 if (!requestMultiviewExtension())
431 {
432 return;
433 }
434
435 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
436 ASSERT_GL_NO_ERROR();
437
438 const GLint viewportOffsets[2] = {0};
439 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
440 0, 1, &viewportOffsets[0]);
441 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
442 ASSERT_GL_NO_ERROR();
443
444 // Blit with the active read framebuffer having multiview attachments.
445 {
446 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
447 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
448 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
449 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
450 }
451
452 // Blit with the active draw framebuffer having multiview attachments.
453 {
454 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
455 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
456 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
457 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
458 }
459}
460
Martin Radev28031682017-07-28 14:47:56 +0300461// Test that glReadPixels generates an invalid framebuffer operation error if the current read
462// framebuffer has a multi-view layout.
463TEST_P(FramebufferMultiviewTest, InvalidReadPixels)
464{
465 if (!requestMultiviewExtension())
466 {
467 return;
468 }
469
470 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
471 ASSERT_GL_NO_ERROR();
472
473 const GLint viewportOffsets[2] = {0};
474 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
475 0, 1, &viewportOffsets[0]);
476 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
477 ASSERT_GL_NO_ERROR();
478
479 GLColor pixelColor;
480 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColor.R);
481 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
482}
483
Martin Radeve5285d22017-07-14 16:23:53 +0300484ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());