chromium/third_party/angle/src/tests/gl_tests/PixelLocalStorageTest.cpp

//
// 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();