MIPS / CI20_linux

Linux kernel source tree with MIPS Creator CI20 (JZ4780 based) board patches/development for upstreaming
Other
54 stars 24 forks source link

OpenGL textures problem #72

Open pyroakm opened 8 years ago

pyroakm commented 8 years ago

Hello.

I found some issue with OpenGL driver, then dynamicly updating texture using glTexImage2d() or glTexSubImage2d(). I've tested this with Debian 8 beta.

Here are my OpenGL calls:

glBindTexture(); //Bind a texture ID. glTexImage2d(); //Upload first texture. glDrawArrays(); //Bug here, the second texture is displayed here instead of first. glTexImage2d(); //Upload second texture. glDrawArrays(); //Second texture is correctly displayed here.

HarveyHunt commented 8 years ago

Could you post the code that triggers the bug please?

pyroakm commented 8 years ago

Here are more detailled code:

glBindTexture(GL_TEXTURE_2D,textureid); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glDisable(GL_DITHER); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glDisable(GL_BLEND); glViewport(0,0,640,480); glScissor(0,0,640,480);

glEnable(GL_TEXTURE_2D); glDisable(GL_ALPHA_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glOrtho(0.f,640.f,480.f,0.f,-1.f,1.f);

glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(3,GL_FLOAT,sizeof(tvertex),(gx_void )tmpvertex); glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(tvertex),(gx_void )&tmpvertex->r); glTexCoordPointer(2,GL_FLOAT,sizeof(tvertex),(gx_void *)&tmpvertex->u);

pvertex=tmpvertex; pvertex[0].z=0.f; pvertex[0].a=255; pvertex[0].r=255; pvertex[0].g=255; pvertex[0].b=255; pvertex[1].z=0.f; pvertex[1].a=255; pvertex[1].r=255; pvertex[1].g=255; pvertex[1].b=255; pvertex[2].z=0.f; pvertex[2].a=255; pvertex[2].r=255; pvertex[2].g=255; pvertex[2].b=255; pvertex[3].z=0.f; pvertex[3].a=255; pvertex[3].r=255; pvertex[3].g=255; pvertex[3].b=255;

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,0,GL_BGRA,GL_UNSIGNED_BYTE,picturebuffer1); pvertex[0].x=0.f; pvertex[0].y=0.f; pvertex[1].x=256.f; pvertex[1].y=0.f; pvertex[2].x=0.f; pvertex[2].y=256.f; pvertex[3].x=256.f; pvertex[3].y=256.f; pvertex[0].u=0.f; pvertex[0].v=0.f; pvertex[1].u=1.f; pvertex[1].v=0.f; pvertex[2].u=0.f; pvertex[2].v=1.f; pvertex[3].u=1.f; pvertex[3].v=1.f; glDrawArrays(GL_TRIANGLE_STRIP,0,4); /* Display picturebuffer2 content instead of picturebuffer1 */

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,0,GL_BGRA,GL_UNSIGNED_BYTE,picturebuffer2); pvertex[0].x=256.f; pvertex[0].y=0.f; pvertex[1].x=512.f; pvertex[1].y=0.f; pvertex[2].x=256.f; pvertex[2].y=256.f; pvertex[3].x=512.f; pvertex[3].y=256.f; pvertex[0].u=0.f; pvertex[0].v=0.f; pvertex[1].u=1.f; pvertex[1].v=0.f; pvertex[2].u=0.f; pvertex[2].v=1.f; pvertex[3].u=1.f; pvertex[3].v=1.f; glDrawArrays(GL_TRIANGLE_STRIP,0,4);

glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glEnable(GL_DITHER);

glXSwapBuffers(display,window);

HarveyHunt commented 8 years ago

Is is any of this code called in a loop?

You've only called glBindTexture() once, I think you're supposed to call it each time you want to deal with a new texture. You're also missing a call to glActiveTexture(), to select the texture unit.

It's strange that you're seeing the second texture before you have uploaded it to the graphics card.

pyroakm commented 8 years ago

This is a part of a code used to display a picture on screen. The picture is segmented into several 256x256 blocks. I had done some modifications recently, maybe my fault, I'm checking my code.

HarveyHunt commented 8 years ago

Have you tried the code on another platform?

pyroakm commented 8 years ago

Yes, it display correctly on other platforms. I've done a complete example, with screenshots. Compile with command: gcc opengltest.cpp -lGL -lX11 -o opengltest_mips

include

include

include

include

include <X11/Xlib.h>

include <X11/Xutil.h>

include <GL/gl.h>

include <GL/glx.h>

int main(int argc, char* argv[]) { Display *display = XOpenDisplay(NULL);

if (!display) { printf("Failed to open X display\n"); exit(1); }

// Get a matching FB config static int visual_attribs[] = { GLX_DOUBLEBUFFER , True, GLX_RGBA, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, None };

printf( "Getting matching framebuffer configs\n" ); int fbcount; GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount); if (!fbc) { printf( "Failed to retrieve a framebuffer config\n" ); exit(1); } printf( "Found %d matching FB configs.\n", fbcount );

// Pick the FB config/visual with the most samples per pixel printf( "Getting XVisualInfos\n" ); int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;

int i; for (i=0; i<fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] ); if ( vi ) { int samp_buf, samples; glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples );

  printf( "  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
          " SAMPLES = %d\n", 
          i, vi -> visualid, samp_buf, samples );

  if ( best_fbc < 0 || samp_buf && samples > best_num_samp )
    best_fbc = i, best_num_samp = samples;
  if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
    worst_fbc = i, worst_num_samp = samples;
}
XFree( vi );

}

GLXFBConfig bestFbc = fbc[ best_fbc ];

// Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree( fbc );

// Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc ); printf( "Chosen visual ID = 0x%x\n", vi->visualid );

printf( "Creating colormap\n" ); XSetWindowAttributes swa; Colormap cmap; swa.colormap = cmap = XCreateColormap( display, RootWindow( display, vi->screen ), vi->visual, AllocNone ); swa.background_pixmap = None ; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask;

printf( "Creating window\n" ); Window win = XCreateWindow( display, RootWindow( display, vi->screen ), 0, 0, 640, 480, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); if ( !win ) { printf( "Failed to create window.\n" ); exit(1); }

// Done with the visual info data XFree( vi );

XStoreName( display, win, "GL 3.0 Window" );

printf( "Mapping window\n" ); XMapWindow( display, win );

// Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( display, DefaultScreen( display ) );

GLXContext ctx = 0;

ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );

// Sync to ensure any errors generated are processed. XSync( display, False );

if ( !ctx ) { printf( "Failed to create an OpenGL context\n" ); exit(1); }

// Verifying that context is a direct context if ( ! glXIsDirect ( display, ctx ) ) { printf( "Indirect GLX rendering context obtained\n" ); } else { printf( "Direct GLX rendering context obtained\n" ); }

printf( "Making context current\n" ); glXMakeCurrent( display, win, ctx );

/* End of initialisation, now this code show the texture problem / / ------------------------------------------------------------- */

unsigned int _buffer[256_256*4]; struct tvertex { float x,y,z; unsigned char r,g,b,a; float u,v; }; tvertex pvertex[4]; unsigned int textureid; glGenTextures(1,&textureid);

for(;;) { glBindTexture(GL_TEXTURE_2D,textureid); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glDisable(GL_DITHER);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glViewport(0,0,640,480);
glScissor(0,0,640,480);

glEnable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0.f,640.f,480.f,0.f,-1.f,1.f);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(3,GL_FLOAT,sizeof(tvertex),(void *)pvertex);
glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(tvertex),(void *)&pvertex->r);
glTexCoordPointer(2,GL_FLOAT,sizeof(tvertex),(void *)&pvertex->u);

pvertex[0].z=0.f;
pvertex[0].a=255;
pvertex[0].r=255;
pvertex[0].g=255;
pvertex[0].b=255;
pvertex[1].z=0.f;
pvertex[1].a=255;
pvertex[1].r=255;
pvertex[1].g=255;
pvertex[1].b=255;
pvertex[2].z=0.f;
pvertex[2].a=255;
pvertex[2].r=255;
pvertex[2].g=255;
pvertex[2].b=255;
pvertex[3].z=0.f;
pvertex[3].a=255;
pvertex[3].r=255;
pvertex[3].g=255;
pvertex[3].b=255;

memset(buffer,0xff,256*256*4);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,0,GL_BGRA,GL_UNSIGNED_BYTE,(void *)buffer);
pvertex[0].x=0.f;
pvertex[0].y=0.f;
pvertex[1].x=256.f;
pvertex[1].y=0.f;
pvertex[2].x=0.f;
pvertex[2].y=256.f;
pvertex[3].x=256.f;
pvertex[3].y=256.f;
pvertex[0].u=0.f;
pvertex[0].v=0.f;
pvertex[1].u=1.f;
pvertex[1].v=0.f;
pvertex[2].u=0.f;
pvertex[2].v=1.f;
pvertex[3].u=1.f;
pvertex[3].v=1.f;
glDrawArrays(GL_TRIANGLE_STRIP,0,4);

memset(buffer,0x88,256*256*4);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,128,256,GL_BGRA,GL_UNSIGNED_BYTE,(void *)buffer);
pvertex[0].x=256.f;
pvertex[0].y=0.f;
pvertex[1].x=512.f;
pvertex[1].y=0.f;
pvertex[2].x=256.f;
pvertex[2].y=256.f;
pvertex[3].x=512.f;
pvertex[3].y=256.f;
pvertex[0].u=0.f;
pvertex[0].v=0.f;
pvertex[1].u=1.f;
pvertex[1].v=0.f;
pvertex[2].u=0.f;
pvertex[2].v=1.f;
pvertex[3].u=1.f;
pvertex[3].v=1.f;
glDrawArrays(GL_TRIANGLE_STRIP,0,4);

glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_DITHER);

glXSwapBuffers ( display, win );

sleep( 1 );

}

glXMakeCurrent( display, 0, 0 ); glXDestroyContext( display, ctx );

XDestroyWindow( display, win ); XFreeColormap( display, cmap ); XCloseDisplay( display );

return 0; }

correct_x64 incorrect_mips

pyroakm commented 8 years ago

I've archived the example here: http://www.arkham-development.com/download/texturebug.7z

HarveyHunt commented 8 years ago

I tried out the binary that you gave me and I can reproduce the problem on my Ci20 running the latest Debian 8 beta. I also installed libgl1-mesa-dev and used that to compile your source - I can reproduce the problem that way as well. It's worth mentioning that you should use the OpenGL specific types when using the OpenGL API, to ensure portability (e.g. int -> GLint).

Could you give me some more information about the system please? Are you running Debian 7, or the new Debian 8 beta? Did you install the mesa development libraries and link against them?

pyroakm commented 8 years ago

I use Debian 8 beta, and yes I've installed libgl1-mesa-dev to compile it.