[prev in list] [next in list] [prev in thread] [next in thread] 

List:       dri-devel
Subject:    [Bug 4327]  New: texture mapping bug on unichrome
From:       bugzilla-daemon () freedesktop ! org
Date:       2005-08-31 23:45:33
Message-ID: 20050831234533.34CAF9E774 () gabe ! freedesktop ! org
[Download RAW message or body]

Please do not reply to this email: if you want to comment on the bug, go to    
       
the URL shown below and enter yourcomments there.     
   
https://bugs.freedesktop.org/show_bug.cgi?id=4327          
     
           Summary: texture mapping bug on unichrome
           Product: DRI
           Version: XOrg CVS
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: libdri
        AssignedTo: dri-devel@lists.sourceforge.net
        ReportedBy: flynnt@acm.org


I'm seeing a really weird texture mapping bug on unichrome.  My app displays
really large images by specifying a reasonable sized texture (a tile, size
256x256 or 512x512) and calling glTexSubImage2D() to update that texture with a
portion of the larger image.  The app then draws a textured quad for that
portion of the screen.  This is repeated for all the tiles that make up the image.

What I'm seeing appears to be a couple scanlines from one tiles swapped with a
couple scanlines from another tile.  In addition, there seems to be a small
triangle of the swapped image in the lower left of each tile.

I last updated my cvs trees for X, drm, and Mesa August 30th, 2005.
I'm building for linux-dri-x86.
I don't see this issue with swrast, nvidia, or ati drivers.

The following is a small sample that reproduces the error:

#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>

Display *dpy;
Window win;
GLboolean doubleBuffer = GL_TRUE;

static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};

int tiledim = 0;
int tilesize = 0;
unsigned char *image = NULL;
int numtiles = 3;
GLint texid = 0;

static GLfloat verts[4][2] = {
                                { 0.0f, 0.0f },
                                { 1.0f, 0.0f },
                                { 1.0f, 1.0f },
                                { 0.0f, 1.0f },
                              };

static GLfloat texcoords[4][2] = {
                                { 0.0f, 0.0f },
                                { 1.0f, 0.0f },
                                { 1.0f, 1.0f },
                                { 0.0f, 1.0f },
                              };

void init(void)
{
    unsigned char *dst = NULL;
    int i = 0;

    // get tile size
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tiledim);

    tilesize = tiledim * tiledim * 4;

    // create image buffer
    image = (unsigned char *) malloc(numtiles * tilesize);
    dst = image;
    memset(image, 0, numtiles * tilesize);

    // fill in red tile
    for(i = 0; i < tiledim * tiledim; i++)
    {
        *dst++ = 255; // r
        *dst++ = 0;   // g
        *dst++ = 0;   // b
        *dst++ = 255; // a
    }

    // fill in green tile
    for(i = 0; i < tiledim * tiledim; i++)
    {
        *dst++ = 0;   // r
        *dst++ = 255; // g
        *dst++ = 0;   // b
        *dst++ = 255; // a
    }

    // fill in blue tile
    for(i = 0; i < tiledim * tiledim; i++)
    {
        *dst++ = 0;   // r
        *dst++ = 0;   // g
        *dst++ = 255; // b
        *dst++ = 255; // a
    }

    // create gl texture
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &texid);
    glBindTexture(GL_TEXTURE_2D, texid);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tiledim, tiledim, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);

    // setup verts
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, verts);
    glTexCoordPointer(2, GL_FLOAT, 0, texcoords);

    // setup frustum
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.5, 1.5, -1.5, 1.5, 1, 10000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void draw(void)
{
    unsigned char *subimage = NULL;
    int i = 0;

    glLoadIdentity();
    glTranslatef(-2.5, 0.0, -1.0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for(i = 0; i < numtiles; i++)
    {
        subimage = image + (i * tilesize);
        glTranslatef(1.0, 0.0, 0.0);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tiledim, tiledim, GL_RGBA,
GL_UNSIGNED_BYTE, subimage);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }

    glXSwapBuffers(dpy, win);
}

int main(int argc, char *argv[])
{
    XVisualInfo    *vi;
    Colormap        cmap;
    XSetWindowAttributes swa;
    GLXContext      cx;
    int         dummy;
    int asdf = 1; 
    XEvent event;
    KeySym keysym;
    XComposeStatus compose;

    /*** (1) open a connection to the X server ***/

    dpy = XOpenDisplay(NULL);
    if (dpy == NULL)
    {
        printf("could not open display\n");
        return 1;
    }

    /*** (2) make sure OpenGL's GLX extension supported ***/

    if(!glXQueryExtension(dpy, &dummy, &dummy))
    {
        printf("X server has no OpenGL GLX extension\n");
        return 1;
    }

    /*** (3) find an appropriate visual ***/

    /* find an OpenGL-capable RGB visual with depth buffer */
    vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
    if (vi == NULL)
    {
        printf("couldn't get dblBuf\n");
        vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
        if (vi == NULL)
        {
            printf("no RGB visual with depth buffer\n");
            return 1;
        }
        doubleBuffer = GL_FALSE;
    }
    //printf("got visual id 0x%x\n", vi->visualid);

    if(vi->class != TrueColor)
    {
        printf("TrueColor visual required for this program\n");
    }

    /*** (4) create an OpenGL rendering context  ***/

    /* create an OpenGL rendering context */
    cx = glXCreateContext(dpy, vi, None, GL_TRUE);
    if (cx == NULL)
    {
        printf("could not create rendering context\n");
        return 1;
    }
    /*** (5) create an X window with the selected visual ***/

    /* create an X colormap since probably not using default visual */
    cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
    swa.colormap = cmap;
    swa.border_pixel = 0;
    swa.override_redirect = False;
    swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask;
    win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 640, 480, 0,
vi->depth, InputOutput, vi->visual, CWOverrideRedirect | CWBorderPixel |
CWColormap | CWEventMask, &swa);

    /*** (6) bind the rendering context to the window ***/

    glXMakeCurrent(dpy, win, cx);

    /*** (7) request the X window to be displayed on the screen ***/

    XSelectInput(dpy, win, ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | StructureNotifyMask);

    Cursor no_ptr;
    Pixmap bm_no;
    XColor black, xdummy;
    Colormap colormap;
    static char no_data[] = { 0,0,0,0,0,0,0,0 };

    /* make sure the window is in the upper-left */
    XMoveWindow(dpy, win, 0, 0);

    /*
     * Some code to hide the cursor.  This just creates an empty 8x8 pixmap
     * and defines the cursor to be that pixmap.
     */
    colormap = DefaultColormap(dpy, DefaultScreen(dpy));
    XAllocNamedColor(dpy, colormap, "black", &black, &xdummy);
    bm_no = XCreateBitmapFromData(dpy, win, no_data, 8, 8);
    no_ptr = XCreatePixmapCursor(dpy, bm_no, bm_no, &black, &black, 0, 0);

    XDefineCursor(dpy, win, no_ptr);
    XFreeCursor(dpy, no_ptr);


    XMapWindow(dpy, win);
    XFlush(dpy);

    init();

    asdf = 1; 

    while(asdf)
    {
      if(XPending(dpy))
      {
            if(XCheckWindowEvent(dpy, win, KeyPressMask | KeyReleaseMask |
ExposureMask | ButtonPressMask | StructureNotifyMask, &event)) /* loop to
compress events */
            {
                switch (event.type)
                {
                    case KeyPress:
                        XLookupString((XKeyEvent *)&event, NULL, 0x00, &keysym,
&compose);
                        if(keysym == XK_Escape)
                        {
                           asdf = 0; 
                        }
                        break;
                }
            }
        }
        draw();
    }

    return 0;
}          
     
     
--           
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email         
     
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.


-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic