// // Copyright 2022 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. // #include <regex> #include <sstream> #include <string> #include "test_utils/ANGLETest.h" #include "test_utils/gl_raii.h" usingnamespaceangle; #define ASSERT_GL_INTEGER(pname, expected) … #define EXPECT_GL_INTEGER(pname, expected) … #define EXPECT_PLS_INTEGER(plane, pname, expected) … #define EXPECT_GL_SINGLE_ERROR(err) … #define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(plane, rgba) … #define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(plane, rgba) … #define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(plane, rgba) … #define EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(framebuffer, attachment, value) … constexpr static int W = …, H = …; constexpr static std::array<float, 4> FULLSCREEN = …; // For building the <loadops> parameter of glBeginPixelLocalStorageANGLE. template <typename T> struct Array { … }; template <typename T> static Array<T> MakeArray(const std::initializer_list<T> &list) { … } static Array<GLenum> GLenumArray(const std::initializer_list<GLenum> &list) { … } static Array<GLfloat> ClearF(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { … } static Array<GLint> ClearI(GLint r, GLint g, GLint b, GLint a) { … } static Array<GLuint> ClearUI(GLuint r, GLuint g, GLuint b, GLuint a) { … } class PLSTestTexture { … }; struct Box { … }; enum class UseBarriers : bool { … }; class PLSProgram { … }; class ShaderInfoLog { … }; class PixelLocalStorageTest : public ANGLETest<> { … }; // Verify conformant implementation-dependent PLS limits. TEST_P(PixelLocalStorageTest, ImplementationDependentLimits) { … } // Verify that rgba8, rgba8i, and rgba8ui pixel local storage behaves as specified. TEST_P(PixelLocalStorageTest, RGBA8) { … } // Verify that r32f and r32ui pixel local storage behaves as specified. TEST_P(PixelLocalStorageTest, R32) { … } // Check proper functioning of the clear value state. TEST_P(PixelLocalStorageTest, ClearValues_rgba8) { … } // Check clear values for r32f and r32ui PLS format. TEST_P(PixelLocalStorageTest, ClearValues_r32) { … } // Check proper support of GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_LOAD_ANGLE, and GL_LOAD_OP_CLEAR_ANGLE // loadOps. Also verify that it works do draw with GL_MAX_LOCAL_STORAGE_PLANES_ANGLE planes. TEST_P(PixelLocalStorageTest, LoadOps) { … } // This next series of tests checks that GL utilities for rejecting fragments prevent stores to PLS: // // * stencil test // * depth test // * viewport // // Some utilities are not legal in ANGLE_shader_pixel_local_storage: // // * gl_SampleMask is disallowed by the spec // * discard, after potential calls to pixelLocalLoadANGLE/Store, is disallowed by the spec // * pixelLocalLoadANGLE/Store after a return from main is disallowed by the spec // // To run the tests, bind a FragmentRejectTestFBO and draw {FRAG_REJECT_TEST_BOX}: // // * {0, 0, FRAG_REJECT_TEST_WIDTH, FRAG_REJECT_TEST_HEIGHT} should be green // * Fragments outside should have been rejected, leaving the pixels black // struct FragmentRejectTestFBO : GLFramebuffer { … }; constexpr static int FRAG_REJECT_TEST_WIDTH = …; constexpr static int FRAG_REJECT_TEST_HEIGHT = …; constexpr static Box FRAG_REJECT_TEST_BOX(FULLSCREEN, { … }, // draw color { … }); // reject pixels outside aux1 // Check that the stencil test prevents stores to PLS. TEST_P(PixelLocalStorageTest, FragmentReject_stencil) { … } // Check that the depth test prevents stores to PLS. TEST_P(PixelLocalStorageTest, FragmentReject_depth) { … } // Check that restricting the viewport also restricts stores to PLS. TEST_P(PixelLocalStorageTest, FragmentReject_viewport) { … } // Check that results are only nondeterministic within predictable constraints, and that no data is // random or leaked from other contexts when we forget to insert a barrier. TEST_P(PixelLocalStorageTest, ForgetBarrier) { … } // Check loading and storing from memoryless local storage planes. TEST_P(PixelLocalStorageTest, MemorylessStorage) { … } // Check that it works to render with the maximum supported data payload: // // GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE // TEST_P(PixelLocalStorageTest, MaxCombinedDrawBuffersAndPLSPlanes) { … } // Verifies that program caching works for programs that use pixel local storage. TEST_P(PixelLocalStorageTest, ProgramCache) { … } // Check that pls is preserved when a shader does not call pixelLocalStoreANGLE(). (Whether that's // because a conditional branch failed or because the shader didn't write to it at all.) // // * The framebuffer fetch implementation needs to make sure every active plane's output variable // gets written during every invocation, or else its value will become undefined. // // * The native pixel local storage implementation needs to declare a variable for every active // plane, even if it is unused in a particular shader invocation. // // Also check that a pixelLocalLoadANGLE() of an r32f texture returns (r, 0, 0, 1). TEST_P(PixelLocalStorageTest, LoadOnly) { … } // Check that stores and loads in a single shader invocation are coherent. TEST_P(PixelLocalStorageTest, LoadAfterStore) { … } // Check that PLS handles can be passed as function arguments. TEST_P(PixelLocalStorageTest, FunctionArguments) { … } // Check that if the "_coherent" extension is advertised, PLS operations are ordered and coherent. TEST_P(PixelLocalStorageTest, Coherency) { … } // Check that binding mipmap levels to PLS is supported. TEST_P(PixelLocalStorageTest, MipMapLevels) { … } // Check that all supported texture types work at various levels and layers. TEST_P(PixelLocalStorageTest, TextureLevelsAndLayers) { … } void PixelLocalStorageTest::doStateRestorationTest() { … } // Check that application-facing ES3 state is not perturbed by pixel local storage. TEST_P(PixelLocalStorageTest, StateRestoration) { … } void PixelLocalStorageTest::doDrawStateTest() { … } // Check that draw state does not affect PLS loads and stores, particularly for // EXT_shader_pixel_local_storage, where they are implemented as fullscreen draws. TEST_P(PixelLocalStorageTest, DrawStateReset) { … } // Check that blend and color mask state do not affect pixel local storage, and that PLS does not // affect blend or color mask on the application's draw buffers. TEST_P(PixelLocalStorageTest, BlendAndColorMask) { … } // Check that PLS and EXT_shader_framebuffer_fetch can be used together. TEST_P(PixelLocalStorageTest, ParallelFramebufferFetch) { … } // Check that PLS gets properly cleaned up when its framebuffer and textures are never deleted. TEST_P(PixelLocalStorageTest, LeakFramebufferAndTexture) { … } // Check that sampler, texture, and PLS bindings all work when they are used in the same shader. TEST_P(PixelLocalStorageTest, PLSWithSamplers) { … } // Check the PLS interruption mechanism. TEST_P(PixelLocalStorageTest, Interrupt) { … } // Check that deleting attachments and PLS bindings on the current draw framebuffer implicitly // deactivates pixel local storage. TEST_P(PixelLocalStorageTest, DeleteAttachments_draw_framebuffer) { … } // Check that deleting attachments and PLS bindings on the current read framebuffer does *not* // deactivate pixel local storage. TEST_P(PixelLocalStorageTest, DeleteAttachments_read_framebuffer) { … } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); #define PLATFORM(API, BACKEND) … #define PLS_INSTANTIATE_RENDERING_TEST_AND(TEST, API, ...) … #define PLS_INSTANTIATE_RENDERING_TEST_ES3(TEST) … #define PLS_INSTANTIATE_RENDERING_TEST_ES31(TEST) … PLS_INSTANTIATE_RENDERING_TEST_ES3(…); class PixelLocalStorageTestES31 : public PixelLocalStorageTest { … }; // Check that early_fragment_tests are not triggered when PLS uniforms are not declared. TEST_P(PixelLocalStorageTestES31, EarlyFragmentTests) { … } // Check that application-facing ES31 state is not perturbed by pixel local storage. TEST_P(PixelLocalStorageTestES31, StateRestoration) { … } // Check that draw state does not affect PLS loads and stores, particularly for // EXT_shader_pixel_local_storage, where they are implemented as fullscreen draws. TEST_P(PixelLocalStorageTestES31, DrawStateReset) { … } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); PLS_INSTANTIATE_RENDERING_TEST_ES31(…); class PixelLocalStorageRequestableExtensionTest : public ANGLETest<> { … }; static void do_implicitly_enabled_extensions_test(const char *plsExtensionToRequest) { … } // Check that ANGLE_shader_pixel_local_storage implicitly enables its dependency extensions. TEST_P(PixelLocalStorageRequestableExtensionTest, ImplicitlyEnabledExtensions) { … } // Check that ANGLE_shader_pixel_local_storage_coherent implicitly enables its // dependency extensions. TEST_P(PixelLocalStorageRequestableExtensionTest, ImplicitlyEnabledExtensionsCoherent) { … } // Check that the dependency extensions of ANGLE_shader_pixel_local_storage do not enable it. TEST_P(PixelLocalStorageRequestableExtensionTest, ANGLEShaderPixelLocalStorageNotImplicitlyEnabled) { … } PLS_INSTANTIATE_RENDERING_TEST_ES3(…); class PixelLocalStorageValidationTest : public ANGLETest<> { … }; class ScopedEnable { … }; #define EXPECT_GL_SINGLE_ERROR_MSG(msg) … // Check that PLS state has the correct initial values. TEST_P(PixelLocalStorageValidationTest, InitialValues) { … } // Check that glFramebufferMemorylessPixelLocalStorageANGLE validates as specified. TEST_P(PixelLocalStorageValidationTest, FramebufferMemorylessPixelLocalStorageANGLE) { … } // Check that glFramebufferTexturePixelLocalStorageANGLE validates as specified. TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE) { … } // Check that FramebufferPixelLocalClearValue{f,i,ui}vANGLE validate as specified. TEST_P(PixelLocalStorageValidationTest, glFramebufferPixelLocalClearValuesANGLE) { … } #define EXPECT_BANNED(cmd, msg) … #define EXPECT_BANNED_DEFAULT_MSG(cmd) … static std::vector<char> FormatBannedCapMsg(GLenum cap) { … } #define EXPECT_ALLOWED_CAP(cap) … #define EXPECT_BANNED_CAP(cap) … #define EXPECT_BANNED_CAP_INDEXED(cap) … // Check that glBeginPixelLocalStorageANGLE validates non-PLS context state as specified. TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_context_state) { … } // Check that transform feedback is banned when PLS is active. TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_transform_feedback) { … } // Check that EXT_blend_func_extended is banned when PLS is active. TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_blend_func_extended) { … } // Check that KHR_blend_equation_advanced is banned when PLS is active. TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_blend_equation_advanced) { … } // Check that glBeginPixelLocalStorageANGLE validates the draw framebuffer's state as specified. TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_framebuffer_state) { … } // Check that glBeginPixelLocalStorageANGLE validates its loadops as specified. TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_loadops) { … } // Check that glBeginPixelLocalStorageANGLE validates the pixel local storage planes as specified. TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_pls_planes) { … } // TODO(anglebug.com/40096838): Block feedback loops // Check glBeginPixelLocalStorageANGLE validates feedback loops as specified. // TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_feedback_loops) // { // // INVALID_OPERATION is generated if a single texture image is bound to more than one pixel // // local storage plane. // // // INVALID_OPERATION is generated if a single texture image is simultaneously bound to a // // pixel local storage plane and attached to the draw framebuffer. // // ASSERT_GL_NO_ERROR(); // } // Check that glEndPixelLocalStorageANGLE and glPixelLocalStorageBarrierANGLE validate as specified. TEST_P(PixelLocalStorageValidationTest, EndAndBarrierANGLE) { … } // Check that FramebufferPixelLocalStorageInterruptANGLE validates as specified. TEST_P(PixelLocalStorageValidationTest, InterruptMechanism) { … } // Check that glGetFramebufferPixelLocalStorageParameter(f|i|ui)(Robust)?ANGLE validate as // specified. TEST_P(PixelLocalStorageValidationTest, GetFramebufferPixelLocalStorageParametersANGLE) { … } // Check command-specific errors that go into effect when PLS is active, as well as commands // specifically called out by EXT_shader_pixel_local_storage for flushing tiled memory. TEST_P(PixelLocalStorageValidationTest, BannedCommands) { … } // Check that PLS gets properly cleaned up when its framebuffer and textures are never deleted. TEST_P(PixelLocalStorageValidationTest, LeakFramebufferAndTexture) { … } // Check that PLS gets properly cleaned up when the context is lost. TEST_P(PixelLocalStorageValidationTest, LoseContext) { … } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); class PixelLocalStorageCompilerTest : public ANGLETest<> { … }; // Check that PLS #extension support is properly implemented. TEST_P(PixelLocalStorageCompilerTest, Extension) { … } // Check proper validation of PLS handle declarations. TEST_P(PixelLocalStorageCompilerTest, Declarations) { … } // Check proper validation of PLS layout qualifiers. TEST_P(PixelLocalStorageCompilerTest, LayoutQualifiers) { … } // Check proper validation of the discard statement when pixel local storage is(n't) declared. TEST_P(PixelLocalStorageCompilerTest, Discard) { … } // Check proper validation of the return statement when pixel local storage is(n't) declared. TEST_P(PixelLocalStorageCompilerTest, Return) { … } // Check that gl_FragDepth(EXT) and gl_SampleMask are not assignable when PLS is declared. TEST_P(PixelLocalStorageCompilerTest, FragmentTestVariables) { … } // Check that the "blend_support" layout qualifiers defined in KHR_blend_equation_advanced are // illegal when PLS is declared. TEST_P(PixelLocalStorageCompilerTest, BlendFuncExtended_illegal_with_PLS) { … } // Check that the "blend_support" layout qualifiers defined in KHR_blend_equation_advanced are // illegal when PLS is declared. TEST_P(PixelLocalStorageCompilerTest, BlendEquationAdvanced_illegal_with_PLS) { … } // Check proper validation of PLS function arguments. TEST_P(PixelLocalStorageCompilerTest, FunctionArguments) { … } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…); class PixelLocalStorageTestPreES3 : public ANGLETest<> { … }; // Check that GL_ANGLE_shader_pixel_local_storage is not advertised before ES 3.1. // // TODO(anglebug.com/40096838): we can relax the min supported version once the implementation // details are inside ANGLE. TEST_P(PixelLocalStorageTestPreES3, UnsupportedClientVersion) { … } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(…); ANGLE_INSTANTIATE_TEST(…);