src/third_party/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp
// Test that running multiple simultaneous queries from multiple EGL contexts returns the correct
// result for each query.  Helps expose bugs in ANGLE's virtual contexts.
Test that running multiple simultaneous queries from multiple EGL contexts returns the correct
result for each query.  Helps expose bugs in ANGLE's virtual contexts.
Test that running multiple simultaneous queries from multiple EGL contexts returns the correct result for each query . Helps expose bugs in ANGLE ' s virtual contexts .
TEST_P(OcclusionQueriesTest, MultiContext)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
    ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());
    ANGLE_SKIP_TEST_IF(GetParam() == ES2_D3D9() || GetParam() == ES2_D3D11() ||
                       GetParam() == ES3_D3D11() || GetParam() == ES2_VULKAN());
    ANGLE_SKIP_TEST_IF(IsVulkan());
    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    EGLWindow *window = getEGLWindow();
    EGLDisplay display = window->getDisplay();
    EGLConfig config   = window->getConfig();
    EGLSurface surface = window->getSurface();
    EGLint contextAttributes[] = {
        EGL_CONTEXT_MAJOR_VERSION_KHR,
        GetParam().majorVersion,
        EGL_CONTEXT_MINOR_VERSION_KHR,
        GetParam().minorVersion,
        EGL_NONE,
    };
    const size_t passCount = 5;
    struct ContextInfo
    {
        EGLContext context;
        GLuint program;
        GLuint query;
        bool visiblePasses[passCount];
        bool shouldPass;
    };
    ContextInfo contexts[] = {
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, true, false, true, false},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {true, true, false, true, true},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, true, true, true, true},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {true, false, false, true, false},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
    };
    for (auto &context : contexts)
    {
        context.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
        ASSERT_NE(context.context, EGL_NO_CONTEXT);
        eglMakeCurrent(display, surface, surface, context.context);
        context.program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        ASSERT_NE(context.program, 0u);
        glDepthMask(GL_FALSE);
        glEnable(GL_DEPTH_TEST);
        glGenQueriesEXT(1, &context.query);
        glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, context.query);
        ASSERT_GL_NO_ERROR();
    }
    for (size_t pass = 0; pass < passCount; pass++)
    {
        for (const auto &context : contexts)
        {
            eglMakeCurrent(display, surface, surface, context.context);
            float depth = context.visiblePasses[pass] ? mRNG.randomFloatBetween(0.0f, 0.4f)
                                                      : mRNG.randomFloatBetween(0.6f, 1.0f);
            drawQuad(context.program, essl1_shaders::PositionAttrib(), depth);
            EXPECT_GL_NO_ERROR();
        }
    }
    for (const auto &context : contexts)
    {
        eglMakeCurrent(display, surface, surface, context.context);
        glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
        GLuint result = GL_TRUE;
        glGetQueryObjectuivEXT(context.query, GL_QUERY_RESULT_EXT, &result);
        EXPECT_GL_NO_ERROR();
        GLuint expectation = context.shouldPass ? GL_TRUE : GL_FALSE;
        EXPECT_EQ(expectation, result);
    }
    eglMakeCurrent(display, surface, surface, window->getContext());
    for (auto &context : contexts)
    {
        eglDestroyContext(display, context.context);
        context.context = EGL_NO_CONTEXT;
    }
}
TEST_P ( OcclusionQueriesTest , MultiContext ) { ANGLE_SKIP_TEST_IF ( getClientMajorVersion ( ) < 3 && ! IsGLExtensionEnabled ( " " ) ) ; ANGLE_SKIP_TEST_IF ( IsWindows ( ) && IsNVIDIA ( ) && IsVulkan ( ) ) ; ANGLE_SKIP_TEST_IF ( GetParam ( ) == ES2_D3D9 ( ) || GetParam ( ) == ES2_D3D11 ( ) || GetParam ( ) == ES3_D3D11 ( ) || GetParam ( ) == ES2_VULKAN ( ) ) ; ANGLE_SKIP_TEST_IF ( IsVulkan ( ) ) ; glDepthMask ( GL_TRUE ) ; glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ) ; glEnable ( GL_DEPTH_TEST ) ; drawQuad ( mProgram , essl1_shaders :: PositionAttrib ( ) , 0.5f ) ; EGLWindow * window = getEGLWindow ( ) ; EGLDisplay display = window -> getDisplay ( ) ; EGLConfig config = window -> getConfig ( ) ; EGLSurface surface = window -> getSurface ( ) ; EGLint contextAttributes [ ] = { EGL_CONTEXT_MAJOR_VERSION_KHR , GetParam ( ) . majorVersion , EGL_CONTEXT_MINOR_VERSION_KHR , GetParam ( ) . minorVersion , EGL_NONE , } ; const size_t passCount = 5 ; struct ContextInfo { EGLContext context ; GLuint program ; GLuint query ; bool visiblePasses [ passCount ] ; bool shouldPass ; } ; ContextInfo contexts [ ] = { { EGL_NO_CONTEXT , 0 , 0 , { false , false , false , false , false } , false , } , { EGL_NO_CONTEXT , 0 , 0 , { false , true , false , true , false } , true , } , { EGL_NO_CONTEXT , 0 , 0 , { false , false , false , false , false } , false , } , { EGL_NO_CONTEXT , 0 , 0 , { true , true , false , true , true } , true , } , { EGL_NO_CONTEXT , 0 , 0 , { false , true , true , true , true } , true , } , { EGL_NO_CONTEXT , 0 , 0 , { true , false , false , true , false } , true , } , { EGL_NO_CONTEXT , 0 , 0 , { false , false , false , false , false } , false , } , { EGL_NO_CONTEXT , 0 , 0 , { false , false , false , false , false } , false , } , } ; for ( auto & context : contexts ) { context . context = eglCreateContext ( display , config , EGL_NO_CONTEXT , contextAttributes ) ; ASSERT_NE ( context . context , EGL_NO_CONTEXT ) ; eglMakeCurrent ( display , surface , surface , context . context ) ; context . program = CompileProgram ( essl1_shaders :: vs :: Simple ( ) , essl1_shaders :: fs :: Red ( ) ) ; ASSERT_NE ( context . program , 0u ) ; glDepthMask ( GL_FALSE ) ; glEnable ( GL_DEPTH_TEST ) ; glGenQueriesEXT ( 1 , & context . query ) ; glBeginQueryEXT ( GL_ANY_SAMPLES_PASSED_EXT , context . query ) ; ASSERT_GL_NO_ERROR ( ) ; } for ( size_t pass = 0 ; pass < passCount ; pass ++ ) { for ( const auto & context : contexts ) { eglMakeCurrent ( display , surface , surface , context . context ) ; float depth = context . visiblePasses [ pass ] ? mRNG . randomFloatBetween ( 0.0f , 0.4f ) : mRNG . randomFloatBetween ( 0.6f , 1.0f ) ; drawQuad ( context . program , essl1_shaders :: PositionAttrib ( ) , depth ) ; EXPECT_GL_NO_ERROR ( ) ; } } for ( const auto & context : contexts ) { eglMakeCurrent ( display , surface , surface , context . context ) ; glEndQueryEXT ( GL_ANY_SAMPLES_PASSED_EXT ) ; GLuint result = GL_TRUE ; glGetQueryObjectuivEXT ( context . query , GL_QUERY_RESULT_EXT , & result ) ; EXPECT_GL_NO_ERROR ( ) ; GLuint expectation = context . shouldPass ? GL_TRUE : GL_FALSE ; EXPECT_EQ ( expectation , result ) ; } eglMakeCurrent ( display , surface , surface , window -> getContext ( ) ) ; for ( auto & context : contexts ) { eglDestroyContext ( display , context . context ) ; context . context = EGL_NO_CONTEXT ; } }
Test that running multiple simultaneous queries from multiple EGL contexts returns the correct
result for each query.
Test that running multiple simultaneous queries from multiple EGL contexts returns the correct result for each query .
// TODO(cwallez@chromium.org): Suppression for http://anglebug.com/3080 // Test skipped because the D3D backends cannot support simultaneous queries on multiple // contexts yet.  Same with the Vulkan backend. // http://anglebug.com/4092 // draw a quad at depth 0.5