Bug 108977

Summary: Reading back an EGL Pbuffer using the OpenGL API returns garbled output
Product: Mesa Reporter: Matthieu Bouron <matthieu.bouron>
Component: EGLAssignee: Tapani Pälli <lemody>
Status: RESOLVED MOVED QA Contact: mesa-dev
Severity: normal    
Priority: medium    
Version: 18.2   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: EGL pbuffer test

Description Matthieu Bouron 2018-12-08 10:05:17 UTC
Created attachment 142750 [details]
EGL pbuffer test

Hello,

I am currently facing an issue while reading back EGL Pbuffers using glReadPixels() with the OpenGL API as the output is garbled. It properly works with the OpenGL ES API though.

I can reproduce the issue on different machines running Arch Linux with mesa 18.2.5 on X using the following GPU: Intel HD 5500, Intel Iris 580 Pro, AMD RX 580.

I am not able to reproduce the issue on an NVDIA GTX 1070 running the proprietary driver.

I have attached a sample code that reproduces the issue:

On OpenGL:
gcc `pkg-config --libs egl gl` -Wall egl-pbuffer.c -o egl-pbuffer &&./egl-pbuffer
0xff69fc07 0xff69fc07 0xff69fc07 0xff69fc07 
0xff69fc07 0xff11a1e4 0xff000000 0xff000000 
0xff69fc07 0xff000000 0xff7fc700 0xff000000 
0xff69fc07 0xff000000 0xff000000 0xff3a4e3b 

On OpenGLES (adding the -es parameter to ./egl-pbuffer):
gcc `pkg-config --libs egl gl` -Wall egl-pbuffer.c -o egl-pbuffer &&./egl-pbuffer -es
0xff0000ff 0xff0000ff 0xff0000ff 0xff0000ff 
0xff0000ff 0xff0000ff 0xff0000ff 0xff0000ff 
0xff0000ff 0xff0000ff 0xff0000ff 0xff0000ff 
0xff0000ff 0xff0000ff 0xff0000ff 0xff0000ff
Comment 1 Matthieu Bouron 2018-12-08 10:16:04 UTC
Comment on attachment 142750 [details]
EGL pbuffer test

>#include <stdio.h>
>#include <stdint.h>
>#include <stdlib.h>
>#include <string.h>
>#include <EGL/egl.h>
>
>#include <GL/gl.h>
>
>#define WIDTH 4
>#define HEIGHT 4
>
>int main(int argc, char *argv[])
>{
>    int gles = argc > 1 ? !strcmp(argv[1], "-es") : 0;
>
>    EGLDisplay egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
>    if (!egl_dpy)
>        return -1;
>
>    EGLint major, minor;
>    int ret = eglInitialize(egl_dpy, &major, &minor);
>    if (!ret)
>        return -1;
>
>    const EGLint attribs[] = {
>        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
>        EGL_RENDERABLE_TYPE, gles ? EGL_OPENGL_ES_BIT : EGL_OPENGL_BIT,
>        EGL_BLUE_SIZE, 8,
>        EGL_GREEN_SIZE, 8,
>        EGL_RED_SIZE, 8,
>        EGL_NONE
>    };
>    EGLint nb_configs;
>    EGLConfig egl_cfg;
>    ret = eglChooseConfig(egl_dpy, attribs, &egl_cfg, 1, &nb_configs);
>    if (!ret)
>        return -1;
>
>    eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
>
>    EGLContext egl_ctx = eglCreateContext(egl_dpy, egl_cfg, EGL_NO_CONTEXT, NULL);
>    if (!egl_ctx)
>        return -1;
>
>    const EGLint pbuffer_attribs[] = {
>        EGL_WIDTH, WIDTH,
>        EGL_HEIGHT, HEIGHT,
>        EGL_NONE,
>    };
>    EGLSurface egl_surface = eglCreatePbufferSurface(egl_dpy, egl_cfg, pbuffer_attribs);
>    if (!egl_surface)
>        return -1;
>
>    ret = eglMakeCurrent(egl_dpy, egl_surface, egl_surface, egl_ctx);
>    if (!ret)
>        return -1;
>
>    uint8_t *data = calloc(1, 4 * WIDTH * HEIGHT);
>    if (!data)
>        return -1;
>
>    glClearColor(1.0, 0.0, 0.0, 1.0);
>    glClear(GL_COLOR_BUFFER_BIT);
>    glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, data);
>
>    for(int y = 0; y < HEIGHT; y++) {
>        for(int x = 0; x < WIDTH; x++) {
>            int *color = (int *)data + x*y;

Should be int *color = (int *)data + y*WIDTH + x;

>            printf("0x%8x ", *color);
>        }
>        printf("\n");
>    }
>    free(data);
>
>    eglTerminate(egl_dpy);
>    return 0;
>}
Comment 2 Tapani Pälli 2018-12-10 09:05:26 UTC
FWIW I couldn't reproduce this with Haswell or Skylake machines (using mesa 19.0.0-devel).
Comment 3 Matthieu Bouron 2018-12-10 10:00:09 UTC
Using Mesa 18.2.6, the frame is black instead of garbled (0xff000000 instead of 0xff0000ff for all pixels).
Comment 4 Tapani Pälli 2018-12-10 12:41:51 UTC
Hmm yep, I'm able to reproduce this after all.
Comment 5 Tapani Pälli 2018-12-11 11:41:24 UTC
I've checked for possible regressions in dEQP-EGL suite (that has a lot of clear surface related tests), it seems all of those are passing but I assume they all use gles1, gles2 or gles3.x so this is something specific to OpenGL. Will continue investigation.
Comment 6 GitLab Migration User 2019-09-18 18:07:38 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/164.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.