I am having issues with glGetTexImage. I am using it to retrieve pixels from render targets, and as far as I have been able to test it out, every pixel format works properly except for GL_R16F. This is the code:
GLenum pixelType = OGL4Types::AsOGL4PixelFormat(this->pixelFormat);
GLint components, type;
glGetInternalformativ(GL_TEXTURE_2D, pixelType, GL_GET_TEXTURE_IMAGE_FORMAT, 4, &components);
glGetInternalformativ(GL_TEXTURE_2D, pixelType, GL_GET_TEXTURE_IMAGE_TYPE, 4, &type);
GLint mipWidth;
GLint mipHeight;
glGetTexLevelParameteriv(GL_TEXTURE_2D, mipLevel, GL_TEXTURE_WIDTH, &mipWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, mipLevel, GL_TEXTURE_HEIGHT, &mipHeight);
GLint size;
size = PixelFormat::ToSize(this->pixelFormat);
// for some reason, the GL driver produces an additional pixel if the format is R16F
if (this->pixelFormat == PixelFormat::R16F)
{
mipWidth += 1;
mipHeight += 1;
}
// the row pitch must be the size of one pixel times the number of pixels in width
outMapInfo.mipWidth = mipWidth;
outMapInfo.mipHeight = mipHeight;
outMapInfo.rowPitch = size * mipWidth;
outMapInfo.depthPitch = 0;
this->mappedData = Memory::Alloc(Memory::ObjectArrayHeap, mipWidth * mipHeight * size);
glGetTexImage(this->target, mipLevel, components, type, this->mappedData);
The statement where I check if the format is R16F, and if so, add 1 extra pixel in both dimensions is required for glGetTexImage to not crash. Some of the other formats I have tested (and they work) are:
RGBA8
R32F
RGBA16F
RG16F
SRGBA8
R8
BC2
BC1
And the results occur on both the 7970 and my R9 Nano with GL driver version 6.14.10.13416.
Has anyone else encountered this issue?
Solved! Go to Solution.
What is the size of your texture?
> The statement where I check if the format is R16F, and if so, add 1 extra pixel in both dimensions is required for glGetTexImage to not crash.
I am not sure what you mean by crash but I believe you see a buffer write out of bounds.
What is your GL_PACK_ALIGNMENT?
The problem could be answered in this stackoverflow post: https://stackoverflow.com/a/26048033
Basically, if you did not change GL_PACK_ALIGNMENT it is set to 4 bytes whereas R16F is only 2 byte aligned.
For an odd number of pixels per scanline (width) this means the end of the scanline is unaligned and needs additional padding which you are doing via adding one pixel.
In theory it should be sufficient to add 1 to width when it is odd to fix the problem.
What is the size of your texture?
> The statement where I check if the format is R16F, and if so, add 1 extra pixel in both dimensions is required for glGetTexImage to not crash.
I am not sure what you mean by crash but I believe you see a buffer write out of bounds.
What is your GL_PACK_ALIGNMENT?
The problem could be answered in this stackoverflow post: https://stackoverflow.com/a/26048033
Basically, if you did not change GL_PACK_ALIGNMENT it is set to 4 bytes whereas R16F is only 2 byte aligned.
For an odd number of pixels per scanline (width) this means the end of the scanline is unaligned and needs additional padding which you are doing via adding one pixel.
In theory it should be sufficient to add 1 to width when it is odd to fix the problem.
Thank you!
Sorry for being vague with the error, but you were right by assuming it was a buffer write which was out of bounds that caused it. Just calculating a valid alignment (or setting it to 1) solved the issue.