Public Group

# OpenGL AMD ATI atioglxx.dll access violation (Bug???)

## Recommended Posts

Hello!

I was trying to load some textures and I was getting this access violation atioglxx.dll access violation

stb image which i'm using to load the png file into the memory, was not reporting any errors.

I found this on the internet explaining that it is a bug from AMD.
I fixed that problem by changing the image file which i was using. The image that was causing this issue was generated by this online converter from gif to pngs.

Does anyone know more about it?

Thank you.

Edited by babaliaris

##### Share on other sites

If you get a crash inside a dll with a name like "nv something gl something dll" or "amd something gl something dll", then yeah, that's inside your GL driver.

99% of the time, it's your bug that's caused the crash, not theirs. For example, if you've passed a pointer to a buffer into the driver (e.g. to tell it to copy some pixel data out of that buffer), but the pointer isn't actually valid to read from, then the driver will crash when it tries to read from it. The crash occurs in the driver, but the bug is in your code (passing invalid pointers to the driver).

Seeing this is to do with texture loading, I would guess that you've somehow asked the driver to read more pixel than actually exist within your memory allocation.

##### Share on other sites
1 hour ago, Hodgman said:

If you get a crash inside a dll with a name like "nv something gl something dll" or "amd something gl something dll", then yeah, that's inside your GL driver.

99% of the time, it's your bug that's caused the crash, not theirs. For example, if you've passed a pointer to a buffer into the driver (e.g. to tell it to copy some pixel data out of that buffer), but the pointer isn't actually valid to read from, then the driver will crash when it tries to read from it. The crash occurs in the driver, but the bug is in your code (passing invalid pointers to the driver).

Seeing this is to do with texture loading, I would guess that you've somehow asked the driver to read more pixel than actually exist within your memory allocation.

Texture::Texture(std::string path, bool trans, int unit)
{

//Reverse the pixels.

unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 0);

if (data)
{

//Generate the texture and bind it.
GLCall(glGenTextures(1, &m_id));
GLCall(glActiveTexture(GL_TEXTURE0 + unit));
GLCall(glBindTexture(GL_TEXTURE_2D, m_id));

//Not Transparent texture.
if (!trans)
{
GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
}

//Transparent texture.
else
{
GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
}

//Texture Filters.
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));

//Generate mipmaps.
GLCall(glGenerateMipmap(GL_TEXTURE_2D));
}

else

//Unbind the texture.
GLCall(glBindTexture(GL_TEXTURE_2D, 0));

//Free the image data.
stbi_image_free(data);
}

The thing is that never happened before using the above code. Can it be the fault of the image file? Maybe some corrupted bytes?

Quote

Seeing this is to do with texture loading, I would guess that you've somehow asked the driver to read more pixel than actually exist within your memory allocation.

Now that you mentioned that, GlTexImage2D() takes the data pointer, the width and the height of the image. How does this function know how many bytes to read from the data buffer? Can it calculate it using the width and the height?

Edited by babaliaris

##### Share on other sites
19 minutes ago, babaliaris said:

Now that you mentioned that, GlTexImage2D() takes the data pointer, the width and the height of the image. How does this function know how many bytes﻿ to read from the data buffer? Can it calculate﻿ it using the width and the height﻿﻿﻿?﻿

Yes, the width, height and format (RGB is 3 byes, RGBA is 4 bytes).

Your code might be incorrect if you load a greyscale image -- it would load one byte per pixel, and then GL would try to read 3 or 4 bytes per pixel.

The final parameter of stbi_load (0 in your code) tells it how many channels that you want the loaded data to have -- you should probably be using something like "trans ? 4 : 3" instead of "0" there.

##### Share on other sites
4 minutes ago, Hodgman said:

Yes, the width, height and format (RGB is 3 byes, RGBA is 4 bytes).

Your code might be incorrect if you load a greyscale image -- it would load one byte per pixel, and then GL would try to read 3 or 4 bytes per pixel.

The final parameter of stbi_load (0 in your code) tells it how many channels that you want the loaded data to have -- you should probably be using something like "trans ? 4 : 3" instead of "0" there.

Obviously I don't know anything about image formats and what a channel is. Do you know a good place to learn more about that?

Quote

Your code might be incorrect if you load a greyscale image -- it would load one byte per pixel, and then GL would try to read 3 or 4 bytes per pixel.

Does this relates to what you said about the channels (stb_load last parameter).

Edited by babaliaris

##### Share on other sites
11 hours ago, Hodgman said:

Yes, the width, height and format (RGB is 3 byes, RGBA is 4 bytes).

So the size of an image file is widthXheightXnumber_of_channels ? (because a channel is one byte)

Edited by babaliaris

##### Share on other sites

@Hodgman Thank you so much! You literally just made clear to me how digital images work and how the driver is reading them.

The problem was indeed in the channels. By debugging I found that the PNG file which I was loading had only 3 channels and I was saying the driver 4. I was assuming that a PNG always has 4 channels no matter what, now I know this is not true.  My tans variable was initialised based the extension of the file. PNG trans = true, false otherwise. So If trans then the driver was reading using 4 channels no matter what, else using 3 channels.

Now I know what to do with the channel variable that load_image is assigning for me to use 😛

Edited by babaliaris

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 15
• 21
• 21
• 11
• 9