mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 15:36:33 +00:00
Handle case where an implementation can't readback 'native' format/type
* Sometimes a GLES implementation can refuse to copy back the 'native' format/type, most commonly if you want to read back from a GL_RGB texture it might require you to readback GL_RGBA. * We handle this by just reading back the requested format in this case, and then copying only RGB tightly into the output buffer.
This commit is contained in:
@@ -1870,7 +1870,76 @@ void APIENTRY _glGetTexImage(GLenum target, GLint level, GLenum format, GLenum t
|
||||
|
||||
byte *dst = (byte *)pixels + d * sliceSize;
|
||||
GLenum readFormat = fixBGRA ? eGL_RGBA : format;
|
||||
GL.glReadPixels(0, 0, width, height, readFormat, type, (void *)dst);
|
||||
|
||||
GLenum implFormat = eGL_NONE, implType = eGL_NONE;
|
||||
|
||||
GL.glGetIntegerv(eGL_IMPLEMENTATION_COLOR_READ_FORMAT, (GLint *)&implFormat);
|
||||
GL.glGetIntegerv(eGL_IMPLEMENTATION_COLOR_READ_TYPE, (GLint *)&implType);
|
||||
|
||||
// spec says this must be supported
|
||||
bool validReadback = (readFormat == eGL_RGBA && type == eGL_UNSIGNED_BYTE);
|
||||
|
||||
// the implementation is allowed to support one other format/type pair, it can vary by texture.
|
||||
// Normally this will be the 'natural' readback format/type pair that we are trying
|
||||
validReadback |= (readFormat == implFormat && type == implType);
|
||||
|
||||
if(validReadback)
|
||||
{
|
||||
GL.glReadPixels(0, 0, width, height, readFormat, type, (void *)dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
// unfortunately the readback is not supported directly, we'll need to fudge it.
|
||||
RDCDEBUG("Reading as %s/%s but impl supported pair is %s/%s", ToStr(readFormat).c_str(),
|
||||
ToStr(type).c_str(), ToStr(implFormat).c_str(), ToStr(implType).c_str());
|
||||
|
||||
if(readFormat == implFormat && (type == eGL_HALF_FLOAT_OES || type == eGL_HALF_FLOAT) &&
|
||||
(implType == eGL_HALF_FLOAT_OES || implType == eGL_HALF_FLOAT))
|
||||
{
|
||||
// if the format itself is supported and we just have a mismatch between eGL_HALF_FLOAT_OES
|
||||
// and eGL_HALF_FLOAT (different enum values), we can just use the implementation's pair
|
||||
// as-is.
|
||||
|
||||
GL.glReadPixels(0, 0, width, height, readFormat, implType, (void *)dst);
|
||||
}
|
||||
else if(readFormat == eGL_RGB && implFormat == eGL_RGBA && type == implType)
|
||||
{
|
||||
// if the only difference is that the implementation wants to read RGBA for an RGB format
|
||||
// (could be understandable if the native storage is RGBA anyway for RGB textures) then we
|
||||
// can readback into a temporary buffer and strip the alpha.
|
||||
|
||||
size_t size = GetByteSize(width, height, 1, implFormat, type);
|
||||
byte *readback = new byte[size];
|
||||
GL.glReadPixels(0, 0, width, height, implFormat, implType, readback);
|
||||
|
||||
// how big is a component (1/2/4 bytes)
|
||||
size_t compSize = GetByteSize(1, 1, 1, eGL_RED, type);
|
||||
|
||||
byte *src = readback;
|
||||
|
||||
// for each pixel
|
||||
for(GLint i = 0; i < width * height; i++)
|
||||
{
|
||||
// copy RGB
|
||||
memcpy(dst, src, compSize * 3);
|
||||
|
||||
// advance dst by RGB
|
||||
dst += compSize * 3;
|
||||
|
||||
// advance src by RGBA
|
||||
src += compSize * 4;
|
||||
}
|
||||
|
||||
delete[] readback;
|
||||
|
||||
fixBGRA = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unhandled readback failure");
|
||||
memset(dst, 0, sliceSize);
|
||||
}
|
||||
}
|
||||
|
||||
if(fixBGRA)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user