PDA

View Full Version : glTexImage2D() access violation



darkforest
04-07-2009, 09:08 AM
This is part of my texture loading routine:



GLuint id = -1;

//id always > 0 &amp;&amp; < 20
glGenTextures(1, &amp;id );
glBindTexture( GL_TEXTURE_2D, id );

//er always 0
GLenum er = glGetError();

//p always non NULL
const float* p = new float[4*256*256];

glTexImage2D( GL_TEXTURE_2D, 0,
GL_RGBA32F_ARB, 256,256, 0,
GL_RGBA, GL_FLOAT, p );
delete[] p;


It works. But later in my program I create multiple threads, bind the ogl context to one of them, and much more. After which calling the same code above I get access violation at glTexImage2D().

After much experimentation, if the second time I create p with approximately at least as large as this:

const float* p = new float[4*4*256*256 - 50000];

I do not get access violation.

Both times glGetError() returns 0; p is not NULL; and the texture id is valid, which I call glDeleteTextures() when no longer used.

I do not exclude memory leaks/corruptions. But since p is a successfully created new buffer, where in glTexImage2D() can the access violation be occurring?

If the prob is due to hglrc context, wouldn't I receive a error for glGetError()?

Thanks

ruysch
04-08-2009, 02:30 AM
How do you allocate the textures?

How do you upload data to the textures?

Do you have similar behavior when running in a single thread?

yooyo
04-08-2009, 04:04 AM
Above code looks fine.. Is this real world usage or you are allocating buffer in one thread and pass pointer to gl thread?
In that case you have shared resource (memory buffer) and you must take care of keeping buffer valid as long as it needs.

darkforest
04-08-2009, 03:56 PM
Thanks for looking. Below I made a function that emulates texture loading and inserted it at many places to see where it fails.

My program switches between two renderers. The first is single threaded via the main thread; the second is multi-threaded. My app flow is roughly:

-Main thread creates hdc and hglrc and calls wglMakeCurrent() and proceeds to single threaded rendering.
-Later by switching to multi-threaded renderer, main thread creates four rendering threads A,B,C,D.
-Main thread calls wglMakeCurrent(NULL,NULL) to release contexts. It no longer calls ogl functions.
-Thread A grabs the contexts by calling wglMakeCurrent(hdc, hglrc). Now only thread A calls ogl functions.
-Later I want to switch back to main thread single threaded rendering. Hence thread A releases them with wglMakeCurrent(NULL,NULL)
-After which main thread regrabs the contexts by calling wglMakeCurrent(hdc, hglrc).
-The testTexImage2D() call after this (by the main thread) fails with the access violation.

Any testTexImage2D() before this do not fail, no matter called by which thread. It is worth noting if in some calls of testTexImage2D() where wglMakeCurrent() doesn't return 1 because another thread still has the hdc, hglrc, testTexImage2D() does not fail, though glGetError() returns 1282 as expected.

I am reasonably sure the particular wglMakeCurrent() called when switching renderers returns success (1).

I use the same VS2008 on both my desktop and laptop; both encounter this, though the laptop only crashes with first/second chance exception without a meaningful stack trace, and has no idea the failing code is glTexImage2D().

Regards



void testTexImage2D( HDC hdc, HGLRC hglrc )
{
BOOL result = wglMakeCurrent(hdc, hglrc );

{
//Special test
GLuint texId;
glGenTextures(1, &amp;texId );
glBindTexture( GL_TEXTURE_2D, texId );

GLenum er = glGetError();
//const float* p = (const float*) img.getLevel(0);
//const float* p = new float[16*256*256-50000];
const float* p = new float[4*256*256];
#define GL_RGBA32F_ARB 0x8814
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, 256,256, 0, GL_RGBA, GL_FLOAT, p );
delete[] p;

glDeleteTextures(1, &amp;texId );
}
}