blob: d65705abadf644a6afc65fc1d263b06b65ffc595 [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
Martin Radevb0761932017-07-25 17:42:25 +030017GLuint CreateTexture2D(GLenum internalFormat,
18 GLenum format,
19 GLenum type,
20 GLsizei width,
21 GLsizei height)
Martin Radev9bc9a322017-07-21 14:28:17 +030022{
23 GLuint tex;
24 glGenTextures(1, &tex);
25 glBindTexture(GL_TEXTURE_2D, tex);
Martin Radevb0761932017-07-25 17:42:25 +030026 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, nullptr);
Martin Radev9bc9a322017-07-21 14:28:17 +030027 return tex;
28}
29
Martin Radevb0761932017-07-25 17:42:25 +030030GLuint CreateTexture2D(GLenum internalFormat, GLenum format, GLenum type)
31{
32 return CreateTexture2D(internalFormat, format, type, 1, 1);
33}
34
Martin Radev9bc9a322017-07-21 14:28:17 +030035} // namespace
36
Martin Radeve5285d22017-07-14 16:23:53 +030037class FramebufferMultiviewTest : public ANGLETest
38{
39 protected:
Martin Radev137032d2017-07-13 10:11:12 +030040 FramebufferMultiviewTest() : mFramebuffer(0), mTexture2D(0), mTexture2DArray(0)
Martin Radeve5285d22017-07-14 16:23:53 +030041 {
42 setWindowWidth(128);
43 setWindowHeight(128);
44 setWebGLCompatibilityEnabled(true);
45 }
46
47 void SetUp() override
48 {
49 ANGLETest::SetUp();
50
51 glGenFramebuffers(1, &mFramebuffer);
52 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
53
Martin Radeve5285d22017-07-14 16:23:53 +030054 glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>(
55 eglGetProcAddress("glRequestExtensionANGLE"));
56 }
57
58 void TearDown() override
59 {
Martin Radev137032d2017-07-13 10:11:12 +030060 if (mTexture2D != 0)
Martin Radeve5285d22017-07-14 16:23:53 +030061 {
Martin Radev137032d2017-07-13 10:11:12 +030062 glDeleteTextures(1, &mTexture2D);
63 mTexture2D = 0;
64 }
65
66 if (mTexture2DArray != 0)
67 {
68 glDeleteTextures(1, &mTexture2DArray);
69 mTexture2DArray = 0;
Martin Radeve5285d22017-07-14 16:23:53 +030070 }
71
72 if (mFramebuffer != 0)
73 {
74 glDeleteFramebuffers(1, &mFramebuffer);
75 mFramebuffer = 0;
76 }
77
78 ANGLETest::TearDown();
79 }
80
Martin Radev137032d2017-07-13 10:11:12 +030081 void createTexture2DArray()
82 {
83 glGenTextures(1, &mTexture2DArray);
84 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture2DArray);
85 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA16F, 1, 1, 2);
86 ASSERT_GL_NO_ERROR();
87 }
88
89 // Requests the ANGLE_multiview extension and returns true if the operation succeeds.
90 bool requestMultiviewExtension()
91 {
92 if (extensionRequestable("GL_ANGLE_multiview"))
93 {
94 glRequestExtensionANGLE("GL_ANGLE_multiview");
95 }
96
97 if (!extensionEnabled("GL_ANGLE_multiview"))
98 {
99 std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
100 return false;
101 }
102 return true;
103 }
104
Martin Radeve5285d22017-07-14 16:23:53 +0300105 GLuint mFramebuffer;
Martin Radev137032d2017-07-13 10:11:12 +0300106 GLuint mTexture2D;
107 GLuint mTexture2DArray;
Martin Radeve5285d22017-07-14 16:23:53 +0300108 PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
109};
110
111// Test that the framebuffer tokens introduced by ANGLE_multiview can be used query the framebuffer
112// state and that their corresponding default values are correctly set.
113TEST_P(FramebufferMultiviewTest, DefaultState)
114{
Martin Radev137032d2017-07-13 10:11:12 +0300115 if (!requestMultiviewExtension())
Martin Radeve5285d22017-07-14 16:23:53 +0300116 {
Martin Radeve5285d22017-07-14 16:23:53 +0300117 return;
118 }
119
Martin Radev9bc9a322017-07-21 14:28:17 +0300120 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
121 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300122 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
123
Martin Radeve5285d22017-07-14 16:23:53 +0300124 GLint numViews = -1;
125 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
126 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
127 &numViews);
128 EXPECT_GL_NO_ERROR();
129 EXPECT_EQ(1, numViews);
130
131 GLint baseViewIndex = -1;
132 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
133 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
134 &baseViewIndex);
135 EXPECT_GL_NO_ERROR();
136 EXPECT_EQ(0, baseViewIndex);
137
138 GLint multiviewLayout = GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE;
139 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
140 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
141 &multiviewLayout);
142 EXPECT_GL_NO_ERROR();
143 EXPECT_EQ(GL_NONE, multiviewLayout);
144
145 GLint viewportOffsets[2] = {-1, -1};
146 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
147 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
148 &viewportOffsets[0]);
149 EXPECT_GL_NO_ERROR();
150 EXPECT_EQ(0, viewportOffsets[0]);
151 EXPECT_EQ(0, viewportOffsets[1]);
152}
153
154// Test that without having the ANGLE_multiview extension, querying for the framebuffer state using
155// the ANGLE_multiview tokens results in an INVALID_ENUM error.
156TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
157{
Martin Radev9bc9a322017-07-21 14:28:17 +0300158 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
159 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300160 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
161
Martin Radeve5285d22017-07-14 16:23:53 +0300162 GLint numViews = -1;
163 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
164 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
165 &numViews);
166 EXPECT_GL_ERROR(GL_INVALID_ENUM);
167
168 GLint baseViewIndex = -1;
169 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
170 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
171 &baseViewIndex);
172 EXPECT_GL_ERROR(GL_INVALID_ENUM);
173
174 GLint multiviewLayout = GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE;
175 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
176 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
177 &multiviewLayout);
178 EXPECT_GL_ERROR(GL_INVALID_ENUM);
179
180 GLint viewportOffsets[2] = {-1, -1};
181 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
182 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
183 &viewportOffsets[0]);
184 EXPECT_GL_ERROR(GL_INVALID_ENUM);
185}
186
Martin Radev137032d2017-07-13 10:11:12 +0300187// Test that the correct errors are generated whenever glFramebufferTextureMultiviewSideBySideANGLE
188// is called with invalid arguments.
189TEST_P(FramebufferMultiviewTest, InvalidMultiviewSideBySideArguments)
190{
191 if (!requestMultiviewExtension())
192 {
193 return;
194 }
195
Martin Radev9bc9a322017-07-21 14:28:17 +0300196 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
197 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300198 // Negative offsets.
199 int viewportOffsets[2] = {-1};
200 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
201 0, 1, &viewportOffsets[0]);
202 EXPECT_GL_ERROR(GL_INVALID_VALUE);
203
204 // Negative number of views.
205 viewportOffsets[0] = 0;
206 viewportOffsets[1] = 0;
207 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
208 0, -1, &viewportOffsets[0]);
209 EXPECT_GL_ERROR(GL_INVALID_VALUE);
210}
211
212// Test that the correct errors are generated whenever glFramebufferTextureMultiviewLayeredANGLE is
213// called with invalid arguments.
214TEST_P(FramebufferMultiviewTest, InvalidMultiviewLayeredArguments)
215{
216 if (!requestMultiviewExtension())
217 {
218 return;
219 }
220
221 createTexture2DArray();
222 // Negative base view index.
223 glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
224 0, -1, 1);
225 EXPECT_GL_ERROR(GL_INVALID_VALUE);
226
227 // baseViewIndex + numViews is greater than MAX_TEXTURE_LAYERS.
228 GLint maxTextureLayers = 0;
229 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
230 ASSERT_GL_NO_ERROR();
231 glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
232 0, maxTextureLayers, 1);
233 EXPECT_GL_ERROR(GL_INVALID_VALUE);
234}
235
236// Test that an INVALID_OPERATION error is generated whenever the ANGLE_multiview extension is not
237// available.
238TEST_P(FramebufferMultiviewTest, ExtensionNotAvailableCheck)
239{
Martin Radev9bc9a322017-07-21 14:28:17 +0300240 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
241 ASSERT_GL_NO_ERROR();
Martin Radev137032d2017-07-13 10:11:12 +0300242 int viewportOffsets[2] = {0};
243 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
244 0, 1, &viewportOffsets[0]);
245 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
246}
247
Martin Radev5dae57b2017-07-14 16:15:55 +0300248// Test that glFramebufferTextureMultiviewSideBySideANGLE modifies the internal multiview state.
249TEST_P(FramebufferMultiviewTest, ModifySideBySideState)
250{
251 if (!requestMultiviewExtension())
252 {
253 return;
254 }
255
256 const GLint viewportOffsets[4] = {0, 0, 1, 2};
Martin Radev9bc9a322017-07-21 14:28:17 +0300257 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
258 ASSERT_GL_NO_ERROR();
Martin Radev5dae57b2017-07-14 16:15:55 +0300259 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
260 0, 2, &viewportOffsets[0]);
261 ASSERT_GL_NO_ERROR();
262
263 GLint numViews = -1;
264 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
265 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
266 &numViews);
267 ASSERT_GL_NO_ERROR();
268 EXPECT_EQ(2, numViews);
269
270 GLint baseViewIndex = -1;
271 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
272 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
273 &baseViewIndex);
274 ASSERT_GL_NO_ERROR();
275 EXPECT_EQ(0, baseViewIndex);
276
277 GLint multiviewLayout = GL_NONE;
278 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
279 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
280 &multiviewLayout);
281 ASSERT_GL_NO_ERROR();
282 EXPECT_EQ(GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, multiviewLayout);
283
284 GLint internalViewportOffsets[4] = {-1};
285 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
286 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
287 &internalViewportOffsets[0]);
288 ASSERT_GL_NO_ERROR();
289 for (size_t i = 0u; i < 4u; ++i)
290 {
291 EXPECT_EQ(viewportOffsets[i], internalViewportOffsets[i]);
292 }
293}
294
Martin Radev9bc9a322017-07-21 14:28:17 +0300295// Test framebuffer completeness status of a side-by-side framebuffer with color and depth
296// attachments.
297TEST_P(FramebufferMultiviewTest, IncompleteViewTargetsSideBySide)
298{
299 if (!requestMultiviewExtension())
300 {
301 return;
302 }
303
304 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
305 ASSERT_GL_NO_ERROR();
306
307 GLuint otherTexture = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
308 ASSERT_GL_NO_ERROR();
309
310 GLuint depthTexture = CreateTexture2D(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
311 ASSERT_GL_NO_ERROR();
312
313 const GLint viewportOffsets[4] = {0, 0, 2, 0};
314 const GLint otherViewportOffsets[4] = {2, 0, 4, 0};
315
316 // Set the 0th attachment and keep it as it is till the end of the test. The 1st or depth
317 // attachment will me modified to change the framebuffer's status.
318 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
319 0, 2, &viewportOffsets[0]);
320 ASSERT_GL_NO_ERROR();
321
322 // Color attachment 1.
323 {
324 // Test framebuffer completeness when the number of views differ.
325 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
326 otherTexture, 0, 1, &viewportOffsets[0]);
327 ASSERT_GL_NO_ERROR();
328 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
329 glCheckFramebufferStatus(GL_FRAMEBUFFER));
330
331 // Test framebuffer completeness when the viewport offsets differ.
332 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
333 otherTexture, 0, 2, &otherViewportOffsets[0]);
334 ASSERT_GL_NO_ERROR();
335 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
336 glCheckFramebufferStatus(GL_FRAMEBUFFER));
337
338 // Test framebuffer completeness when attachment layouts differ.
339 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, otherTexture,
340 0);
341 ASSERT_GL_NO_ERROR();
342 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
343 glCheckFramebufferStatus(GL_FRAMEBUFFER));
344
345 // Test that framebuffer is complete when the number of views, viewport offsets and layouts
346 // are the same.
347 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
348 otherTexture, 0, 2, &viewportOffsets[0]);
349 ASSERT_GL_NO_ERROR();
350 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
351
352 // Reset attachment 1
353 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0, 0, 1,
354 &viewportOffsets[0]);
355 }
356
357 // Depth attachment.
358 {
359 // Test framebuffer completeness when the number of views differ.
360 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
361 depthTexture, 0, 1, &viewportOffsets[0]);
362 ASSERT_GL_NO_ERROR();
363 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
364 glCheckFramebufferStatus(GL_FRAMEBUFFER));
365
366 // Test framebuffer completeness when the viewport offsets differ.
367 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
368 depthTexture, 0, 2, &otherViewportOffsets[0]);
369 ASSERT_GL_NO_ERROR();
370 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
371 glCheckFramebufferStatus(GL_FRAMEBUFFER));
372
373 // Test framebuffer completeness when attachment layouts differ.
374 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
375 ASSERT_GL_NO_ERROR();
376 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
377 glCheckFramebufferStatus(GL_FRAMEBUFFER));
378
379 // Test that framebuffer is complete when the number of views, viewport offsets and layouts
380 // are the same.
381 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
382 depthTexture, 0, 2, &viewportOffsets[0]);
383 ASSERT_GL_NO_ERROR();
384 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
385 }
386
387 glDeleteTextures(1, &depthTexture);
388 glDeleteTextures(1, &otherTexture);
389}
390
Martin Radev04e2c3b2017-07-27 16:54:35 +0300391// Test that the active read framebuffer cannot be read from through glCopyTex* if it has multi-view
392// attachments.
393TEST_P(FramebufferMultiviewTest, InvalidCopyTex)
394{
395 if (!requestMultiviewExtension())
396 {
397 return;
398 }
399
400 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
401 ASSERT_GL_NO_ERROR();
402
403 const GLint viewportOffsets[2] = {0};
404 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
405 0, 1, &viewportOffsets[0]);
406 ASSERT_GL_NO_ERROR();
407
408 // Test glCopyTexImage2D and glCopyTexSubImage2D.
409 {
410 GLuint tex = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
411
412 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 1, 1, 0);
413 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
414
415 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
416 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
417
418 glDeleteTextures(1, &tex);
419 }
420
421 // Test glCopyTexSubImage3D.
422 {
423 GLuint tex = 0u;
424 glGenTextures(1, &tex);
425 glBindTexture(GL_TEXTURE_3D, tex);
426 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
427
428 glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1, 1);
429 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
430
431 glDeleteTextures(1, &tex);
432 }
433}
434
Martin Radeva3ed4572017-07-27 18:29:37 +0300435// Test that glBlitFramebuffer generates an invalid framebuffer operation when either the current
436// draw framebuffer, or current read framebuffer have multiview attachments.
437TEST_P(FramebufferMultiviewTest, InvalidBlit)
438{
439 if (!requestMultiviewExtension())
440 {
441 return;
442 }
443
444 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
445 ASSERT_GL_NO_ERROR();
446
447 const GLint viewportOffsets[2] = {0};
448 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
449 0, 1, &viewportOffsets[0]);
450 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
451 ASSERT_GL_NO_ERROR();
452
453 // Blit with the active read framebuffer having multiview attachments.
454 {
455 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
456 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
457 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
458 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
459 }
460
461 // Blit with the active draw framebuffer having multiview attachments.
462 {
463 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
464 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
465 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
466 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
467 }
468}
469
Martin Radev28031682017-07-28 14:47:56 +0300470// Test that glReadPixels generates an invalid framebuffer operation error if the current read
471// framebuffer has a multi-view layout.
472TEST_P(FramebufferMultiviewTest, InvalidReadPixels)
473{
474 if (!requestMultiviewExtension())
475 {
476 return;
477 }
478
479 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
480 ASSERT_GL_NO_ERROR();
481
482 const GLint viewportOffsets[2] = {0};
483 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
484 0, 1, &viewportOffsets[0]);
485 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
486 ASSERT_GL_NO_ERROR();
487
488 GLColor pixelColor;
489 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColor.R);
490 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
491}
492
Martin Radevb0761932017-07-25 17:42:25 +0300493// Test that glClear clears only the contents of each view.
494TEST_P(FramebufferMultiviewTest, SideBySideClear)
495{
496 if (!requestMultiviewExtension())
497 {
498 return;
499 }
500
501 mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4, 2);
502 const GLint viewportOffsets[4] = {1, 0, 3, 0};
503 glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
504 0, 2, &viewportOffsets[0]);
505
506 // Create and bind a normal framebuffer to access the 2D texture.
507 GLuint fbo;
508 glGenFramebuffers(1, &fbo);
509 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
510 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
511
512 // Clear the contents of the texture.
513 glClearColor(0, 0, 0, 0);
514 glClear(GL_COLOR_BUFFER_BIT);
515
516 // Bind and specify viewport/scissor dimensions for each view.
517 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
518 glViewport(0, 0, 1, 2);
519 glScissor(0, 0, 1, 2);
520
521 glClearColor(1, 0, 0, 0);
522 glClear(GL_COLOR_BUFFER_BIT);
523
524 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
525
526 // column 0
527 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
528 EXPECT_PIXEL_EQ(0, 1, 0, 0, 0, 0);
529
530 // column 1
531 EXPECT_PIXEL_EQ(1, 0, 255, 0, 0, 0);
532 EXPECT_PIXEL_EQ(1, 1, 255, 0, 0, 0);
533
534 // column 2
535 EXPECT_PIXEL_EQ(2, 0, 0, 0, 0, 0);
536 EXPECT_PIXEL_EQ(2, 1, 0, 0, 0, 0);
537
538 // column 3
539 EXPECT_PIXEL_EQ(3, 0, 255, 0, 0, 0);
540 EXPECT_PIXEL_EQ(3, 1, 255, 0, 0, 0);
541
542 glDeleteFramebuffers(1, &fbo);
543}
544
Martin Radeve5285d22017-07-14 16:23:53 +0300545ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());