[Piglit] [PATCH] egl: Add test for EGL_KHR_create_context_no_error

Grigori Goronzy greg at chown.ath.cx
Thu Aug 3 18:24:12 UTC 2017


Hey Emil,

On 2017-08-02 18:01, Emil Velikov wrote:
> Hi Grigori,
> 
>> +++ b/tests/all.py
>> @@ -4608,6 +4608,8 @@ with profile.test_list.group_manager(
>>        run_concurrent=False)
>>      g(['egl-create-context-valid-flag-debug-gl', 'gl'], 'valid debug 
>> flag GL',
>>        run_concurrent=False)
>> +    g(['egl-create-context-no-error'], 'KHR_no_error enable',
>> +      run_concurrent=False)
>> 
> I'm assuming that you've copied the run_concurrent=False piece from 
> another?
> AFAICT there is nothing specific in the test (or in
> egl-create-context-valid-flag-debug IIRC) that requires it.
> 

Yes, that's true. A bit of cargo culting I guess. I'll change it.

>> +static void
>> +fold_results(enum piglit_result *a, enum piglit_result b)
>> +{
>> +    if (*a == PIGLIT_FAIL || b == PIGLIT_FAIL)
>> +        *a = PIGLIT_FAIL;
>> +    else if (*a == PIGLIT_PASS || b == PIGLIT_PASS)
>> +        *a = PIGLIT_PASS;
>> +    else
>> +        *a = PIGLIT_SKIP;
> I haven't seen this kind of construct in piglit before.
> One option is to let the (sub)test report the status (with
> piglit_report_subtest_result).
> While the test overall returns a bool, with true for the PIGLIT_SKIP 
> case.
> 

I actually derived this from some other test (don't remember which one). 
piglit_report_subtest_result sounds like a better choice, I didn't know 
about it. Thanks for pointing it out.

>> +}
>> +
>> +static void
>> +check_extension(EGLint mask)
>> +{
>> +    if (!EGL_KHR_create_context_setup(mask))
>> +        piglit_report_result(PIGLIT_SKIP);
>> +
>> +    piglit_require_egl_extension(egl_dpy, 
>> "EGL_KHR_create_context_no_error");
>> +
> Extension requires EGL 1.4 instead of EGL_KHR_create_context or
> EGL_KHR_surfaceless_context.
> Although there's no obvious helpers, so I guess this will do for now.
> 

Maybe I should add a helper, I'll look if this is easily possible.

>> +    EGL_KHR_create_context_teardown();
>> +}
>> +
>> +static enum piglit_result
>> +check_no_error(EGLenum api, bool no_error, bool debug, bool robust)
> 
> I don't know if we need the no_error here. The test should check if
> things work correctly when it's set.
> Everything else falls outside the scope of the extension.
> 

I added testing with no-error==false because there were some issues with 
the EGL implementation of the no-error extension, which then switched on 
no-error mode if any context flag was set. Some other tests *might* also 
catch such issues, but here's the obvious place. Anyway, that's the 
motivation for doing these "control tests". What do you think?

>> +{
>> +       static bool is_dispatch_init = false;
>> +    enum piglit_result pass = PIGLIT_SKIP;
>> +    EGLContext ctx;
>> +    EGLint attribs[11];
>> +    size_t ai = 0;
>> +    GLint context_flags = 0;
>> +    EGLint mask = (api == EGL_OPENGL_API) ? EGL_OPENGL_BIT : 
>> EGL_OPENGL_ES2_BIT;
>> +
>> +    printf("info: %s no_error=%s debug=%s robustness=%s\n",
>> +           (api == EGL_OPENGL_API) ? "OpenGL" : "OpenGL ES",
>> +           BOOLSTR(no_error), BOOLSTR(debug), BOOLSTR(robust));
>> +
>> +    if (!EGL_KHR_create_context_setup(mask))
>> +        goto out;
>> +
>> +    if (eglBindAPI(api) != EGL_TRUE)
>> +        goto out;
>> +
>> +    if (api == EGL_OPENGL_ES_API) {
>> +        attribs[ai++] = EGL_CONTEXT_CLIENT_VERSION;
>> +        attribs[ai++] = 2;
>> +    }
> EGL_CONTEXT_CLIENT_VERSION and EGL_CONTEXT_MAJOR_VERSION_KHR are 
> aliases.
> So I'd drop this hunk.
> 

Ok.

>> +    if (debug || robust) {
> I think that one could pass EGL_CONTEXT_FLAGS_KHR 0 to
> eglCreateContext and things should still work.
> 
>> +        EGLint flags = 0;
>> +        flags |= debug ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0;
>> +        flags |= robust ? EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR : 
>> 0;
> Just pass "flags" into the function?
> This way the attribs[] list become a nice const EGLint attribsp[] = { 
> ... }.
> 

Yep, that's easier.

>> +        attribs[ai++] = EGL_CONTEXT_FLAGS_KHR;
>> +        attribs[ai++] = flags;
>> +    }
>> +    /* Always use OpenGL 2.0 or OpenGL ES 2.0 to keep this test 
>> reasonably
>> +     * simple; there are enough variants as-is.
> Another hint - GL_KHR_no_error requires OpenGL{,ES} 2.0
> 

OK, I'll add a check to validate that the implementation doesn't accept 
no-error for GL/ES 1.x.

>> +        goto out;
>> +    }
>> +
>> +    if (eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
>> +                       ctx) != EGL_TRUE) {
>> +        printf("error: failed to make context current\n");
>> +        pass = PIGLIT_FAIL;
>> +        goto out;
>> +    }
>> +
>> +    if (!is_dispatch_init) {
>> +        /* We must postpone initialization of piglit-dispatch until
>> +         * a context is current.
>> +         */
>> +        piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
>> +        is_dispatch_init = true;
>> +    }
>> +
>> +    /* The EGL_KHR_create_context_no_error extension unfortunately 
>> allows
>> +     * "no-op" implementations. That is, the EGL extension can be 
>> supported
>> +     * without any support on the GL side of things. This means we 
>> can't
>> +     * fail if KHR_no_error turns out to be not enabled at this 
>> point.
>> +     */
>> +    if (no_error) {
> Always true, with above suggestion.
> 
>> +        /* Verify that the KHR_no_error extension is available in the
>> +         * extension list.
>> +         */
>> +        if (!piglit_is_extension_supported("GL_KHR_no_error")) {
>> +            printf("error: context does not report GL_KHR_no_error "
>> +                   "availability\n");
>> +            pass = PIGLIT_SKIP;
>> +            goto out;
>> +        }
>> +
>> +        /* Verify that constant flags report KHR_no_error to be 
>> enabled.
>> +         * Unfortunately, OpenGL ES does not support the necessary 
>> flag until
>> +         * OpenGL ES 3.2, so the check is skipped for ES. We just 
>> have to
>> +         * assume that it is supported when the extension appears to 
>> be
>> +         * available in the context, according to extension list.
>> +         */
>> +        if (api == EGL_OPENGL_API) {
> Requesting GLES2 v2.0 can (should) give you highest compatible version.
> So we could be using ES 3.2 after all.
> 
> Thus the above can become
>  if (api == EGL_OPENGL_API ||
>      api == EGL_OPENGL_ES2_BIT /* added for posterity */ &&
> piglit_get_gl_version() >= 32) {
> 

Interesting, I didn't know about it. That might make the check more 
reliable on modern implementations, which is good.

> With the earlier suggestions in place the function becomes
> 
> bool pass = true;
> 
> check_extension(EGL_OPENGL_BIT);
> check_extension(EGL_OPENGL_ES2_BIT);
> 
> pass = check_no_error(EGL_OPENGL_API, 0) && pass;
> pass = check_no_error(EGL_OPENGL_API, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) 
> && pass;
> pass = check_no_error(EGL_OPENGL_API,
> EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) && pass;
> pass = check_no_error(EGL_OPENGL_API, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 
> |
> 
> EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) && pass;
> 
> pass = check_no_error(EGL_OPENGL_ES_API, 0) && pass;
> pass = check_no_error(EGL_OPENGL_ES_API,
> EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) && pass;
> 
> piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
> 

Looks good.

Thanks for your feedback!

Grigori


More information about the Piglit mailing list