// // Copyright 2017 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // Multiview draw tests: // Test issuing multiview Draw* commands. // #include "platform/autogen/FeaturesD3D_autogen.h" #include "test_utils/MultiviewTest.h" #include "test_utils/gl_raii.h" usingnamespaceangle; namespace { std::vector<Vector2> ConvertPixelCoordinatesToClipSpace(const std::vector<Vector2I> &pixels, int width, int height) { … } } // namespace struct MultiviewRenderTestParams final : public MultiviewImplementationParams { … }; std::ostream &operator<<(std::ostream &os, const MultiviewRenderTestParams ¶ms) { … } class MultiviewFramebufferTestBase : public MultiviewTestBase, public ::testing::TestWithParam<MultiviewRenderTestParams> { … }; class MultiviewRenderTest : public MultiviewFramebufferTestBase { … }; std::string DualViewVS(ExtensionName multiviewExtension) { … } std::string DualViewFS(ExtensionName multiviewExtension) { … } class MultiviewRenderDualViewTest : public MultiviewRenderTest { … }; class MultiviewRenderDualViewTestNoWebGL : public MultiviewRenderDualViewTest { … }; // Base class for tests that care mostly about draw call validity and not rendering results. class MultiviewDrawValidationTest : public MultiviewTest { … }; class MultiviewOcclusionQueryTest : public MultiviewRenderTest { … }; class MultiviewProgramGenerationTest : public MultiviewTest { … }; class MultiviewRenderPrimitiveTest : public MultiviewRenderTest { … }; class MultiviewLayeredRenderTest : public MultiviewFramebufferTestBase { … }; // The test verifies that glDraw*Indirect works for any number of views. TEST_P(MultiviewDrawValidationTest, IndirectDraw) { … } // The test verifies that glDraw*: // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer and // program differs. // 2) does not generate any error if the number of views is the same. TEST_P(MultiviewDrawValidationTest, NumViewsMismatch) { … } // The test verifies that glDraw* generates an INVALID_OPERATION error if the program does not use // the multiview extension, but the active draw framebuffer has more than one view. TEST_P(MultiviewDrawValidationTest, NumViewsMismatchForNonMultiviewProgram) { … } // The test verifies that glDraw*: // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer is // greater than 1 and there is an active not paused transform feedback object. // 2) does not generate any error if the number of views in the draw framebuffer is 1. TEST_P(MultiviewDrawValidationTest, ActiveTransformFeedback) { … } // The test verifies that glDraw*: // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer is // greater than 1 and there is an active query for target GL_TIME_ELAPSED_EXT. // 2) does not generate any error if the number of views in the draw framebuffer is 1. TEST_P(MultiviewDrawValidationTest, ActiveTimeElapsedQuery) { … } // The test checks that glDrawArrays can be used to render into two views. TEST_P(MultiviewRenderDualViewTest, DrawArrays) { … } // The test checks that glDrawArrays can be used to render into two views, after the program // executable has been installed and the program relinked (with a failing link, and using a // different number of views). TEST_P(MultiviewRenderDualViewTestNoWebGL, DrawArraysAfterFailedRelink) { … } // The test checks that glDrawElements can be used to render into two views. TEST_P(MultiviewRenderDualViewTest, DrawElements) { … } // The test checks that glDrawRangeElements can be used to render into two views. TEST_P(MultiviewRenderDualViewTest, DrawRangeElements) { … } // The test checks that glDrawArrays can be used to render into four views. TEST_P(MultiviewRenderTest, DrawArraysFourViews) { … } // The test checks that glDrawArraysInstanced can be used to render into two views. TEST_P(MultiviewRenderTest, DrawArraysInstanced) { … } // The test verifies that the attribute divisor is correctly adjusted when drawing with a multi-view // program. The test draws 4 instances of a quad each of which covers a single pixel. The x and y // offset of each quad are passed as separate attributes which are indexed based on the // corresponding attribute divisors. A divisor of 1 is used for the y offset to have all quads // drawn vertically next to each other. A divisor of 3 is used for the x offset to have the last // quad offsetted by one pixel to the right. Note that the number of views is divisible by 1, but // not by 3. TEST_P(MultiviewRenderTest, AttribDivisor) { … } // Test that different sequences of vertexAttribDivisor, useProgram and bindVertexArray in a // multi-view context propagate the correct divisor to the driver. TEST_P(MultiviewRenderTest, DivisorOrderOfOperation) { … } // Test that no fragments pass the occlusion query for a multi-view vertex shader which always // transforms geometry to be outside of the clip region. TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryNothingVisible) { … } // Test that there are fragments passing the occlusion query if only view 0 can produce // output. TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryOnlyLeftVisible) { … } // Test that there are fragments passing the occlusion query if only view 1 can produce // output. TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryOnlyRightVisible) { … } // Test that a simple multi-view program which doesn't use gl_ViewID_OVR in neither VS nor FS // compiles and links without an error. TEST_P(MultiviewProgramGenerationTest, SimpleProgram) { … } // Test that a simple multi-view program which uses gl_ViewID_OVR only in VS compiles and links // without an error. TEST_P(MultiviewProgramGenerationTest, UseViewIDInVertexShader) { … } // Test that a simple multi-view program which uses gl_ViewID_OVR only in FS compiles and links // without an error. TEST_P(MultiviewProgramGenerationTest, UseViewIDInFragmentShader) { … } // The test checks that GL_POINTS is correctly rendered. TEST_P(MultiviewRenderPrimitiveTest, Points) { … } // The test checks that GL_LINES is correctly rendered. // The behavior of this test is not guaranteed by the spec: // OpenGL ES 3.0.5 (November 3, 2016), Section 3.5.1 Basic Line Segment Rasterization: // "The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in // either x or y window coordinates from a corresponding fragment produced by the diamond-exit // rule." TEST_P(MultiviewRenderPrimitiveTest, Lines) { … } // The test checks that GL_LINE_STRIP is correctly rendered. // The behavior of this test is not guaranteed by the spec: // OpenGL ES 3.0.5 (November 3, 2016), Section 3.5.1 Basic Line Segment Rasterization: // "The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in // either x or y window coordinates from a corresponding fragment produced by the diamond-exit // rule." TEST_P(MultiviewRenderPrimitiveTest, LineStrip) { … } // The test checks that GL_LINE_LOOP is correctly rendered. // The behavior of this test is not guaranteed by the spec: // OpenGL ES 3.0.5 (November 3, 2016), Section 3.5.1 Basic Line Segment Rasterization: // "The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in // either x or y window coordinates from a corresponding fragment produced by the diamond-exit // rule." TEST_P(MultiviewRenderPrimitiveTest, LineLoop) { … } // The test checks that GL_TRIANGLE_STRIP is correctly rendered. TEST_P(MultiviewRenderPrimitiveTest, TriangleStrip) { … } // The test checks that GL_TRIANGLE_FAN is correctly rendered. TEST_P(MultiviewRenderPrimitiveTest, TriangleFan) { … } // Verify that re-linking a program adjusts the attribute divisor. // The test uses instacing to draw for each view a strips of two red quads and two blue quads next // to each other. The quads' position and color depend on the corresponding attribute divisors. TEST_P(MultiviewRenderTest, ProgramRelinkUpdatesAttribDivisor) { … } // Test that useProgram applies the number of views in computing the final value of the attribute // divisor. TEST_P(MultiviewRenderTest, DivisorUpdatedOnProgramChange) { … } // The test checks that gl_ViewID_OVR is correctly propagated to the fragment shader. TEST_P(MultiviewRenderTest, SelectColorBasedOnViewIDOVR) { … } // The test checks that the inactive layers of a 2D texture array are not written to by a // multi-view program. TEST_P(MultiviewLayeredRenderTest, RenderToSubrangeOfLayers) { … } // The D3D11 renderer uses a GS whenever the varyings are flat interpolated which can cause // potential bugs if the view is selected in the VS. The test contains a program in which the // gl_InstanceID is passed as a flat varying to the fragment shader where it is used to discard the // fragment if its value is negative. The gl_InstanceID should never be negative and that branch is // never taken. One quad is drawn and the color is selected based on the ViewID - red for view 0 and // green for view 1. TEST_P(MultiviewRenderTest, FlatInterpolation) { … } // This test assigns gl_ViewID_OVR to a flat int varying and then sets the color based on that // varying in the fragment shader. TEST_P(MultiviewRenderTest, FlatInterpolation2) { … } // Test that shader caching maintains the num_views value used in GL_OVR_multiview between shader // compilations. TEST_P(MultiviewRenderTest, ShaderCacheVertexWithOVRMultiview) { … } MultiviewRenderTestParams VertexShaderOpenGL(ExtensionName multiviewExtension) { … } MultiviewRenderTestParams VertexShaderVulkan(ExtensionName multiviewExtension) { … } MultiviewRenderTestParams GeomShaderD3D11(ExtensionName multiviewExtension) { … } MultiviewRenderTestParams VertexShaderD3D11(ExtensionName multiviewExtension) { … } MultiviewRenderTestParams MultisampledVertexShaderOpenGL(ExtensionName multiviewExtension) { … } MultiviewRenderTestParams MultisampledVertexShaderVulkan(ExtensionName multiviewExtension) { … } MultiviewRenderTestParams MultisampledVertexShaderD3D11(ExtensionName multiviewExtension) { … } #define ALL_VERTEX_SHADER_CONFIGS(minor) … #define ALL_SINGLESAMPLE_CONFIGS() … #define ALL_MULTISAMPLE_CONFIGS() … GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…);