glTexImage3D crash, Windows XP, Nvidia 8800GTX

  • Follow


I'm trying to create a 3D LUT using a 3D texture on a modern GPU with 
the latest drivers. I'm using GLEW.

I'm creating a 64x64x64x3 16 LUT and and when I try to download the 
data, my program crashes with an unhandled exception:

Unhandled exception at 0x0702f72e in application.exe: 0xC0000005: Access 
violation reading location 0x088b11f8.

Here is my setup code:

::glBindTexture(GL_TEXTURE_3D, lutTexId);
::glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
::glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
::glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
::glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// crashes here
::glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16,
	64, 64, 64,
	0,
	GL_RGB, GL_UNSIGNED_SHORT, clut);

If I pass NULL for clut, it works, but then will crash if I call 
glTexSubImage3D.

This setup code is based on example code I've found in several places 
around the net.

Any ideas?

0
Reply Paul 5/13/2008 10:08:12 PM

On May 14, 12:08 am, Paul Miller <p...@fxtech.com> wrote:
>
> Any ideas?

This sort of weird crash normally means you corrupted memory
somewhere before the call to glTexSubImage3D().


--
<\___/>
/ O O \
\_____/  FTB.     Remove my socks for email address.
0
Reply fungus 5/14/2008 12:21:40 AM


"Paul Miller" <paul@fxtech.com> wrote in message 
news:PioWj.1755$3n2.122@fe04.usenetserver.com...

> I'm creating a 64x64x64x3 16 LUT
<and>
> ::glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16,
> 64, 64, 64,
> 0,
> GL_RGB, GL_UNSIGNED_SHORT, clut);
>
> If I pass NULL for clut, it works, but then will crash if I call 
> glTexSubImage3D.

You are telling glTexImage3D that 'clut' is a pointer to data
that has 3 color channels, each channel a 16-bit integer.
So 'clut' better point to a 64x64x64 array of RGB colors
where R is 16-bit, G is 16-bit, and B is 16-bit.  I suspect
that 'clut' is pointing to a smaller array, and the access
violation is trying to read memory you don't "own".

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/14/2008 2:58:56 AM

Dave Eberly wrote:
> "Paul Miller" <paul@fxtech.com> wrote in message 
> news:PioWj.1755$3n2.122@fe04.usenetserver.com...
> 
>> I'm creating a 64x64x64x3 16 LUT
> <and>
>> ::glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16,
>> 64, 64, 64,
>> 0,
>> GL_RGB, GL_UNSIGNED_SHORT, clut);
>>
>> If I pass NULL for clut, it works, but then will crash if I call 
>> glTexSubImage3D.
> 
> You are telling glTexImage3D that 'clut' is a pointer to data
> that has 3 color channels, each channel a 16-bit integer.
> So 'clut' better point to a 64x64x64 array of RGB colors
> where R is 16-bit, G is 16-bit, and B is 16-bit.  I suspect
> that 'clut' is pointing to a smaller array, and the access
> violation is trying to read memory you don't "own".

Sorry - should have posted the clut code as well:

struct LUTPixel
{
	GLushort r;
	GLushort g;
	GLushort b;
};

static const int kLutSize = 64;
std::vector<LUTPixel> clutVec(kLutSize * kLutSize * kLutSize);

// initialize lut here

const void *clut = &clutVec[0];

So yeah, clut does point to what it's supposed to.

Even if the compiler is padding out LUTPixel to 64 bits, there should be 
plenty of room in clutVec to avoid a memory access exception.

0
Reply Paul 5/14/2008 3:16:28 AM

"Paul Miller" <paul@fxtech.com> wrote in message 
news:PPsWj.193$lW2.159@fe80.usenetserver.com...
> Sorry - should have posted the clut code as well:
>
> struct LUTPixel
> {
> GLushort r;
> GLushort g;
> GLushort b;
> };
>
> static const int kLutSize = 64;
> std::vector<LUTPixel> clutVec(kLutSize * kLutSize * kLutSize);
>
> // initialize lut here
>
> const void *clut = &clutVec[0];
>
> So yeah, clut does point to what it's supposed to.
>
> Even if the compiler is padding out LUTPixel to 64 bits, there should be 
> plenty of room in clutVec to avoid a memory access exception.

Yes, it appears you have enough space, but even if the texture
creation were to succeed, the outcome is wrong.  OpenGL expects
that the data is contiguous.  There will be padding of LUTPixel, even
on a 32-bit system.  Check the value of sizeof(LUTPixel), it will not be 6,
but probably is 8.

Also, have you called glGetError after the glTexImage3D call?

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/14/2008 3:38:06 PM

Dave Eberly wrote:
> "Paul Miller" <paul@fxtech.com> wrote in message 
> news:PPsWj.193$lW2.159@fe80.usenetserver.com...
>> Sorry - should have posted the clut code as well:
>>
>> struct LUTPixel
>> {
>> GLushort r;
>> GLushort g;
>> GLushort b;
>> };
>>
>> static const int kLutSize = 64;
>> std::vector<LUTPixel> clutVec(kLutSize * kLutSize * kLutSize);
>>
>> // initialize lut here
>>
>> const void *clut = &clutVec[0];
>>
>> So yeah, clut does point to what it's supposed to.
>>
>> Even if the compiler is padding out LUTPixel to 64 bits, there should be 
>> plenty of room in clutVec to avoid a memory access exception.
> 
> Yes, it appears you have enough space, but even if the texture
> creation were to succeed, the outcome is wrong.  OpenGL expects
> that the data is contiguous.  There will be padding of LUTPixel, even
> on a 32-bit system.  Check the value of sizeof(LUTPixel), it will not be 6,
> but probably is 8.

Yes, true. I'll restructure my setup to avoid the padding.

> Also, have you called glGetError after the glTexImage3D call?

I can't - glTexImage3D crashes!

I think you're on to something though - but I just can't figure out what.

For fun, I had tried it with a smaller, empty, 3D table on the heap, 
16x16x16, and got the same crash.

0
Reply Paul 5/14/2008 5:49:07 PM

On May 14, 7:49 pm, Paul Miller <p...@fxtech.com> wrote:
>
> For fun, I had tried it with a smaller, empty, 3D table on the heap,
> 16x16x16, and got the same crash.

Try writing a minimal OpenGL program to use 3D textures.

I'm betting it won't crash...  :-)


--
<\___/>
/ O O \
\_____/  FTB.     Remove my socks for email address.

0
Reply fungus 5/15/2008 12:02:33 AM

"Paul Miller" <paul@fxtech.com> wrote in message 
news:TBFWj.899$rj3.88@fe09.usenetserver.com...
>> Also, have you called glGetError after the glTexImage3D call?
>
> I can't - glTexImage3D crashes!

Duh...   Try calling glGetError *before* the glTexImage3D call.  Perhaps
something went wrong earlier.

> I think you're on to something though - but I just can't figure out what.
>
> For fun, I had tried it with a smaller, empty, 3D table on the heap, 
> 16x16x16, and got the same crash.

Try the experiment using 8-bits-per-channel colors.  Maybe your drivers/card
do not support 3D textures with "fat" formats (16-bit, 32-bit per channel).

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/15/2008 6:14:29 AM



#pragma push(pack, 2)
struct LUTPixel
{
GLushort r;
GLushort g;
GLushort b;
};
#pragma pop(pack)
maybe?



0
Reply Gernot 5/15/2008 8:23:23 AM

Paul Miller a �crit :
> I'm trying to create a 3D LUT using a 3D texture on a modern GPU with 
> the latest drivers. I'm using GLEW.
> 

Sorry for my "basic" post, but did you check if your card manages 3D 
texture? Using glew, it's just (after glewInit()):

bool IsTexture3DAvailable(void)
{
	if (!GLEW_EXT_texture3D) return false;
	return true;
}

I know that you have a recent 8800, but if you take a look at my 
previous post, on may, the 4th, called "OpenGL version problem", there 
are problems with (even recent) nvidia cards with OpenGL. You can find 
ways to fix this up there:
http://forums.nvidia.com/index.php?act=ST&f=33&t=39191

Hope this can help.

David
0
Reply singin_dav 5/15/2008 9:17:59 AM

singin_dav wrote:
> Paul Miller a �crit :
>> I'm trying to create a 3D LUT using a 3D texture on a modern GPU with 
>> the latest drivers. I'm using GLEW.
>>
> 
> Sorry for my "basic" post, but did you check if your card manages 3D 
> texture? Using glew, it's just (after glewInit()):
> 
> bool IsTexture3DAvailable(void)
> {
>     if (!GLEW_EXT_texture3D) return false;
>     return true;
> }
> 
> I know that you have a recent 8800, but if you take a look at my 
> previous post, on may, the 4th, called "OpenGL version problem", there 
> are problems with (even recent) nvidia cards with OpenGL. You can find 
> ways to fix this up there:
> http://forums.nvidia.com/index.php?act=ST&f=33&t=39191
> 
> Hope this can help.

Yep - definitely "supported" - at least, it shows up in the extension list.

0
Reply Paul 5/15/2008 1:07:50 PM

Dave Eberly wrote:
> "Paul Miller" <paul@fxtech.com> wrote in message 
> news:TBFWj.899$rj3.88@fe09.usenetserver.com...
>>> Also, have you called glGetError after the glTexImage3D call?
>> I can't - glTexImage3D crashes!
> 
> Duh...   Try calling glGetError *before* the glTexImage3D call.  Perhaps
> something went wrong earlier.
> 
>> I think you're on to something though - but I just can't figure out what.
>>
>> For fun, I had tried it with a smaller, empty, 3D table on the heap, 
>> 16x16x16, and got the same crash.
> 
> Try the experiment using 8-bits-per-channel colors.  Maybe your drivers/card
> do not support 3D textures with "fat" formats (16-bit, 32-bit per channel).

Found it!!!

I had called glPixelStorei(GL_UNPACK_ROW_LENGTH, ...) elsewhere in my 
code for a different texture, and forgot to reset it back to the default 
value for my LUT download.

0
Reply Paul 5/15/2008 2:58:03 PM

I tried the following and it succeeded on my Windows Vista machine with
an NVIDIA GeForce 7600 GT.  I am using the 163.69 Forceware drivers
from NVIDIA for Windows Vista.  The Gl* functions are my wrappers that
call glGetError after the OpenGL call.  No errors reported and no crash.

    std::vector<unsigned short> clutVec(3 * 64 * 64 * 64);
    const void *clut = &clutVec[0];
    unsigned int lutTexId;
    GlGenTextures(1, &lutTexId);
    GlBindTexture(GL_TEXTURE_3D, lutTexId);
    GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
    GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    GlTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16,
     64, 64, 64,
     0,
     GL_RGB, GL_UNSIGNED_SHORT, clut);

Maybe a bug in the drivers you have installed?  Hard to say without seeing
your entire program.  As 'fungus' mentioned, you might have trashed out
the memory used by clutVec during initialization of it.  Or some other
memory overwrite might have trashed out the stack.

In addition to the experiment I mentioned where you try 8-bit colors, try
this example but with GL_NEAREST for filtering.

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/15/2008 3:08:13 PM

Dave Eberly wrote:
> I tried the following and it succeeded on my Windows Vista machine with
> an NVIDIA GeForce 7600 GT.  I am using the 163.69 Forceware drivers
> from NVIDIA for Windows Vista.  The Gl* functions are my wrappers that
> call glGetError after the OpenGL call.  No errors reported and no crash.
> 
>     std::vector<unsigned short> clutVec(3 * 64 * 64 * 64);
>     const void *clut = &clutVec[0];
>     unsigned int lutTexId;
>     GlGenTextures(1, &lutTexId);
>     GlBindTexture(GL_TEXTURE_3D, lutTexId);
>     GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
>     GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
>     GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
>     GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
>     GlTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
>     GlTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16,
>      64, 64, 64,
>      0,
>      GL_RGB, GL_UNSIGNED_SHORT, clut);
> 
> Maybe a bug in the drivers you have installed?  Hard to say without seeing
> your entire program.  As 'fungus' mentioned, you might have trashed out
> the memory used by clutVec during initialization of it.  Or some other
> memory overwrite might have trashed out the stack.
> 
> In addition to the experiment I mentioned where you try 8-bit colors, try
> this example but with GL_NEAREST for filtering.

Hey Dave - thanks for checking. See my previous post - turned out to be 
a lingering glPixelStore() from a 2D texture. :-(

0
Reply Paul 5/15/2008 4:02:30 PM

"Paul Miller" <paul@fxtech.com> wrote in message 
news:V7ZWj.6920$lQ5.2657@fe58.usenetserver.com...
> Hey Dave - thanks for checking. See my previous post - turned out to be a 
> lingering glPixelStore() from a 2D texture. :-(

Your post came between my editing and then posting.

I would report this to NVIDIA as a bug.  The glTexImage3D should not crash,
instead generating some type of OpenGL error that you can query with
glGetError.

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/15/2008 4:44:58 PM

On May 15, 11:44=A0am, "Dave Eberly" <dNOSPAMebe...@usemydomain.com>
wrote:

> > Hey Dave - thanks for checking. See my previous post - turned out to be =
a
> > lingering glPixelStore() from a 2D texture. :-(
>
> Your post came between my editing and then posting.
>
> I would report this to NVIDIA as a bug. =A0The glTexImage3D should not cra=
sh,
> instead generating some type of OpenGL error that you can query with
> glGetError.

How can NVIDIA know that the memory pointed to is invalid?

- Chris
0
Reply crjjrc 5/16/2008 2:46:45 PM

"crjjrc" <crjjrc@gmail.com> wrote in message 
news:241552d0-2893-4c2f-890f-4cd3546af63c@k37g2000hsf.googlegroups.com...

> How can NVIDIA know that the memory pointed to is invalid?

The OP indicated that he had set some state with glPixelStore*.  If
glTexImage3D fails because it does not like that current state, the driver
ought to be able to test for this state and report "invalid operation" or
some such.

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/16/2008 6:27:53 PM

Dave Eberly wrote:
> "crjjrc" <crjjrc@gmail.com> wrote in message 
> news:241552d0-2893-4c2f-890f-4cd3546af63c@k37g2000hsf.googlegroups.com...
> 
>> How can NVIDIA know that the memory pointed to is invalid?
> 
> The OP indicated that he had set some state with glPixelStore*.  If
> glTexImage3D fails because it does not like that current state, the driver
> ought to be able to test for this state and report "invalid operation" or
> some such.

Agreed. The previously-set row length (as passed to glPixelStore) was 
far larger than the new width/height/depth of the 3D texture. I admit 
this is probably an edge case, but it's easily tested by the driver.

0
Reply Paul 5/16/2008 6:32:36 PM

Hello,

Paul Miller wrote:
> Dave Eberly wrote:
>> "crjjrc" <crjjrc@gmail.com> wrote in message 
>> news:241552d0-2893-4c2f-890f-4cd3546af63c@k37g2000hsf.googlegroups.com...
>> 
>>> How can NVIDIA know that the memory pointed to is invalid?
>> 
>> The OP indicated that he had set some state with glPixelStore*.  If
>> glTexImage3D fails because it does not like that current state, the driver
>> ought to be able to test for this state and report "invalid operation" or
>> some such.
>
> Agreed. The previously-set row length (as passed to glPixelStore) was 
> far larger than the new width/height/depth of the 3D texture. I admit 
> this is probably an edge case, but it's easily tested by the driver.

But using a larger row length than the texture width is not a bug.
Suppose you have a large 8096x8096 image in memory, and want to specify
a 512x512 part of it as a texture. You can just set GL_UNPACK_ROW_LENGTH 
to 8192 in this case. 

Regards
Marcel

-- 
Marcel Heinz | <marcel.heinz@informatik.tu-chemnitz.de> | PGP-KeyID: E78E9442
 
"Perfection is attained not when there is nothing more to add,
 but when there is nothing more to remove."  -- Antoine de Saint-Exup�ry
0
Reply Marcel 5/16/2008 8:17:18 PM

Hello,

Paul Miller wrote:
> Dave Eberly wrote:
>> "crjjrc" <crjjrc@gmail.com> wrote in message 
>> news:241552d0-2893-4c2f-890f-4cd3546af63c@k37g2000hsf.googlegroups.com...
>> 
>>> How can NVIDIA know that the memory pointed to is invalid?
>> 
>> The OP indicated that he had set some state with glPixelStore*.  If
>> glTexImage3D fails because it does not like that current state, the driver
>> ought to be able to test for this state and report "invalid operation" or
>> some such.
>
> Agreed. The previously-set row length (as passed to glPixelStore) was 
> far larger than the new width/height/depth of the 3D texture. I admit 
> this is probably an edge case, but it's easily tested by the driver.

But using a larger row length than the texture width is not a bug.
Suppose you have a large 8192x8192 image in memory, and want to specify
a 512x512 part of it as a texture. You can just set GL_UNPACK_ROW_LENGTH 
to 8192 in this case. 

Regards
Marcel

-- 
Marcel Heinz | <marcel.heinz@informatik.tu-chemnitz.de> | PGP-KeyID: E78E9442
 
"Perfection is attained not when there is nothing more to add,
 but when there is nothing more to remove."  -- Antoine de Saint-Exup�ry
0
Reply Marcel 5/16/2008 8:25:24 PM

"Marcel Heinz" <marcel.heinz@informatik.tu-chemnitz.de> wrote in message 
news:g0kqjg$q85$2@anderson.hrz.tu-chemnitz.de...
> But using a larger row length than the texture width is not a bug.
> Suppose you have a large 8192x8192 image in memory, and want to specify
> a 512x512 part of it as a texture. You can just set GL_UNPACK_ROW_LENGTH
> to 8192 in this case.

My point was that a crash in a call to an OpenGL function is unacceptable
behavior.  The alternative of failing the function call gracefully is 
better.

--
Dave Eberly
http://www.geometrictools.com


0
Reply Dave 5/16/2008 9:25:52 PM

Hi,

Dave Eberly wrote:
> "Marcel Heinz" <marcel.heinz@informatik.tu-chemnitz.de> wrote in message 
> news:g0kqjg$q85$2@anderson.hrz.tu-chemnitz.de...
>> But using a larger row length than the texture width is not a bug.
>> Suppose you have a large 8192x8192 image in memory, and want to specify
>> a 512x512 part of it as a texture. You can just set GL_UNPACK_ROW_LENGTH
>> to 8192 in this case.
>
> My point was that a crash in a call to an OpenGL function is unacceptable
> behavior.  The alternative of failing the function call gracefully is 
> better.

My point is that a crash is inavoidable in such situations. OpenGL can't know
how you use your memory, it just can use the pointers and unpack state you
provide. How should it decide if these values are "evil" before it
accesses the memory?

-- 
Marcel Heinz | <marcel.heinz@informatik.tu-chemnitz.de> | PGP-KeyID: E78E9442
 
"Perfection is attained not when there is nothing more to add,
 but when there is nothing more to remove."  -- Antoine de Saint-Exup�ry
0
Reply Marcel 5/16/2008 9:37:56 PM

Marcel Heinz wrote:
> Hello,
> 
> Paul Miller wrote:
>> Dave Eberly wrote:
>>> "crjjrc" <crjjrc@gmail.com> wrote in message 
>>> news:241552d0-2893-4c2f-890f-4cd3546af63c@k37g2000hsf.googlegroups.com...
>>>
>>>> How can NVIDIA know that the memory pointed to is invalid?
>>> The OP indicated that he had set some state with glPixelStore*.  If
>>> glTexImage3D fails because it does not like that current state, the driver
>>> ought to be able to test for this state and report "invalid operation" or
>>> some such.
>> Agreed. The previously-set row length (as passed to glPixelStore) was 
>> far larger than the new width/height/depth of the 3D texture. I admit 
>> this is probably an edge case, but it's easily tested by the driver.
> 
> But using a larger row length than the texture width is not a bug.
> Suppose you have a large 8096x8096 image in memory, and want to specify
> a 512x512 part of it as a texture. You can just set GL_UNPACK_ROW_LENGTH 
> to 8192 in this case. 

Ah, yes, this is true. Nevermind! It was definitely a bug in my code. 
I've since modified my texture class to reset the PixelStore values I 
change back to their defaults after setting up each texture.

0
Reply Paul 5/16/2008 9:56:57 PM

22 Replies
268 Views

(page loaded in 0.172 seconds)


Reply: