Advertisement

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

Started by December 11, 2018 11:26 PM
6 comments, last by babaliaris 6 years, 2 months ago

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.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

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.

Advertisement
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.
	stbi_set_flip_vertically_on_load(1);

	//Try to load the image.
	unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 0);

	//Image loaded successfully.
	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));
	}


	//Loading Failed.
	else
		throw VampEngine::EngineError("The was an error loading image: " + path);



	//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?

 

GlTexImage2D Doc

 


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

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.

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).


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

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)


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Advertisement

@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 ? 


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

This topic is closed to new replies.

Advertisement