PDA

View Full Version : Binding pbuffer with different pixel format(Linux)



FangQ
02-16-2009, 10:09 AM
hi

I am completely new to OpenGL programming. What I am trying to achieve is to get multiple output support under Linux for BrookGPU (a GPGPU language). So, I hacked into the source code and found the problem is located ina function called "bindPBuffer".

The related code can be browsed at the following URL (there are two bindPBuffer, the 1st is for windows, the second is for Linux):

http://brook.svn.sourceforge.net/viewvc/...838&view=markup (http://brook.svn.sourceforge.net/viewvc/brook/trunk/runtime/gpu/ogl/oglwindow.cpp?revision=1838&view=markup)

Obviously, the original code disabled this feature. I removed the "if (numOutputs > 1) {...}" bit and recompiled the code, I found when the output format is different from float4, which is the default format defined in initPBuffer(), the program will crash with


X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 143 (GLX)
Minor opcode of failed request: 5 (X_GLXMakeCurrent)
Serial number of failed request: 51
Current serial number in output stream: 51

Following some examples, I modified the code a little bit (attached at the end), but when I re-ran my program, it crashed right after the successful return from bindPBuffer:


GL: glGetError returned GL_INVALID_VALUE on line 654 of oglkernel.cpp

does anyone have experience how to do pbuffer rebinding under Linux? I would be very grateful if you can share some of your experience or point out the problems in my modification.

thanks a lot.



bool
OGLWindow::bindPbuffer(unsigned int width,
unsigned int height,
unsigned int numOutputs,
unsigned int numComponents) {

/* Sadly, Linux doesn't seem to like rebinding a
** context to a different format pbuffer.
*/

if (width > PBUFFER_WIDTH ||
height > PBUFFER_HEIGHT) {
fprintf (stderr, "Pbuffer not big enough\n");
fprintf (stderr, "User requested %d x %d\n",
width, height);
exit(1);
}

static const int pbAttribList[] =
{
GLX_PRESERVED_CONTENTS, GL_TRUE,
GLX_PBUFFER_WIDTH, 2048,
GLX_PBUFFER_HEIGHT, 2048,
0
};

// if the requested pixel format is identical to the current, skip

if (currentPbufferComponents == numComponents)
return 0;

assert (numComponents > 0 &&
numComponents <= 4);

// now, rebind the pixel format

glXDestroyPbuffer(pDisplay, glxPbuffer);

glxPbuffer = glXCreatePbuffer(pDisplay,
glxConfig[numComponents-1][0],
piAttribList[numComponents-1]);

if (glxPbuffer == 0) {
fprintf (stderr, "Error: Could not create float%d pbuffer.\n",
numComponents);
}

// create a new context (is this necessary?)
glxContext = glXCreateNewContext(pDisplay,
glxConfig[numComponents-1][0],
GLX_RGBA_TYPE,
0, GL_TRUE);
if (!glxContext) {
fprintf(stderr, "bindPbuffer: glXCreateContextWithConfig() failed\n");
exit (1);
}

if (!glXMakeCurrent(pDisplay, glxPbuffer, glxContext)) {
fprintf (stderr, "bindPbuffer: glXMakeCurrent Failed\n");
exit(1);
}

glFinish();

currentPbufferComponents = numComponents;

return 0;
}

V-man
02-18-2009, 08:59 AM
I haven't used p-buffers in a few years so I don't remember all the intracacies.
The best thing to do is move over to FBO which has become the new standard for about 6 years.
http://www.opengl.org/wiki/GL_EXT_framebuffer_object

FangQ
02-18-2009, 02:45 PM
thanks, I just realized yesterday, there was a branch of BrookGPU with the latest code, in this branch, the bindPBuffer was upgraded to bindFBO, which is what you recommended.

http://brook.svn.sourceforge.net/viewvc/...885&view=markup (http://brook.svn.sourceforge.net/viewvc/brook/branches/Niall%27s%20Update/runtime/gpu/ogl/oglwindow.cpp?revision=1885&view=markup)