Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenGL textures problem #72

Open
pyroakm opened this issue Sep 27, 2015 · 9 comments
Open

OpenGL textures problem #72

pyroakm opened this issue Sep 27, 2015 · 9 comments

Comments

@pyroakm
Copy link

pyroakm commented Sep 27, 2015

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
Copy link

Could you post the code that triggers the bug please?

@pyroakm
Copy link
Author

pyroakm commented Sep 28, 2015

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
Copy link

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
Copy link
Author

pyroakm commented Sep 29, 2015

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
Copy link

Have you tried the code on another platform?

@pyroakm
Copy link
Author

pyroakm commented Sep 29, 2015

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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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
Copy link
Author

pyroakm commented Sep 29, 2015

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

@HarveyHunt
Copy link

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
Copy link
Author

pyroakm commented Sep 29, 2015

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

pcercuei pushed a commit to OpenDingux/linux that referenced this issue Jan 22, 2019
Hammering the "bank enable" (PBKEN) bit on and off between
every command crashes the Nomadik NHK15 with this message:

Scanning device for bad blocks
Unhandled fault: external abort on non-linefetch (0x008) at 0xcc95e000
pgd = (ptrval)
[cc95e000] *pgd=0b808811, *pte=40000653, *ppte=40000552
Internal error: : 8 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Not tainted 4.20.0-rc2+ MIPS#72
Hardware name: Nomadik STn8815
PC is at fsmc_exec_op+0x194/0x204
(...)

After a discussion we (me and Boris Brezillon) start to suspect
that this bit does not immediately control the chip select line
at all, it rather enables access to the bank and the hardware
will drive the CS autonomously. If there is a NAND chip connected,
we should keep this enabled.

As fsmc_nand_setup() sets this bit, we can simply remove the
offending code.

Fixes: 550b9fc ("mtd: rawnand: fsmc: Stop implementing ->select_chip()")
Signed-off-by: Linus Walleij <[email protected]>
Acked-by: Miquel Raynal <[email protected]>
Signed-off-by: Boris Brezillon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants