in renderdoc/driver/gl/gl_common.cpp [1872:2322]
ResourceFormat MakeResourceFormat(GLenum target, GLenum fmt)
{
ResourceFormat ret;
ret.type = ResourceFormatType::Regular;
if(fmt == eGL_NONE)
{
ret.type = ResourceFormatType::Undefined;
return ret;
}
// special handling for formats that don't query neatly
if(fmt == eGL_LUMINANCE8_EXT || fmt == eGL_INTENSITY8_EXT || fmt == eGL_LUMINANCE)
{
ret.compByteWidth = 1;
ret.compCount = 1;
ret.compType = CompType::UNorm;
return ret;
}
else if(fmt == eGL_ALPHA || fmt == eGL_ALPHA8_EXT)
{
ret.compByteWidth = 1;
ret.compCount = 1;
ret.compType = CompType::UNorm;
ret.type = ResourceFormatType::A8;
return ret;
}
else if(fmt == eGL_LUMINANCE8_ALPHA8_EXT || fmt == eGL_LUMINANCE_ALPHA)
{
ret.compByteWidth = 1;
ret.compCount = 2;
ret.compType = CompType::UNorm;
return ret;
}
else if(fmt == eGL_RGBA2)
{
// pretend it's RGBA8 and hope for the best
ret.compByteWidth = 1;
ret.compCount = 4;
ret.compType = CompType::UNorm;
return ret;
}
if(IsCompressedFormat(fmt))
{
switch(fmt)
{
// BC1
case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: ret.compCount = 3; break;
case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: ret.compCount = 4; break;
// BC2
case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: ret.compCount = 4; break;
// BC3
case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: ret.compCount = 4; break;
// BC4
case eGL_COMPRESSED_RED_RGTC1:
case eGL_COMPRESSED_SIGNED_RED_RGTC1: ret.compCount = 1; break;
// BC5
case eGL_COMPRESSED_RG_RGTC2:
case eGL_COMPRESSED_SIGNED_RG_RGTC2: ret.compCount = 2; break;
// BC6
case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: ret.compCount = 3; break;
// BC7
case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: ret.compCount = 4; break;
case eGL_COMPRESSED_RGBA8_ETC2_EAC:
case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: ret.compCount = 4; break;
case eGL_COMPRESSED_R11_EAC:
case eGL_COMPRESSED_SIGNED_R11_EAC: ret.compCount = 1; break;
case eGL_COMPRESSED_RG11_EAC:
case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.compCount = 2; break;
case eGL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
case eGL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: ret.compCount = 3; break;
case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: ret.compCount = 4; break;
case eGL_ETC1_RGB8_OES:
case eGL_COMPRESSED_RGB8_ETC2:
case eGL_COMPRESSED_SRGB8_ETC2: ret.compCount = 3; break;
case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: ret.compCount = 4; break;
case eGL_COMPRESSED_RGBA_ASTC_4x4_KHR:
case eGL_COMPRESSED_RGBA_ASTC_5x4_KHR:
case eGL_COMPRESSED_RGBA_ASTC_5x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_6x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_6x6_KHR:
case eGL_COMPRESSED_RGBA_ASTC_8x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_8x6_KHR:
case eGL_COMPRESSED_RGBA_ASTC_8x8_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x6_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x8_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x10_KHR:
case eGL_COMPRESSED_RGBA_ASTC_12x10_KHR:
case eGL_COMPRESSED_RGBA_ASTC_12x12_KHR:
case eGL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
case eGL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
case eGL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
case eGL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
case eGL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
case eGL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
case eGL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
case eGL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
case eGL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
case eGL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: ret.compCount = 4; break;
default: break;
}
ret.compType = CompType::UNorm;
switch(fmt)
{
case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
case eGL_COMPRESSED_SRGB8_ETC2:
case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: ret.compType = CompType::UNormSRGB; break;
default: break;
}
switch(fmt)
{
case eGL_COMPRESSED_SIGNED_RED_RGTC1:
case eGL_COMPRESSED_SIGNED_RG_RGTC2:
case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
case eGL_COMPRESSED_SIGNED_R11_EAC:
case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.compType = CompType::SNorm; break;
default: break;
}
ret.type = ResourceFormatType::Undefined;
switch(fmt)
{
// BC1
case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: ret.type = ResourceFormatType::BC1; break;
// BC2
case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: ret.type = ResourceFormatType::BC2; break;
// BC3
case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: ret.type = ResourceFormatType::BC3; break;
// BC4
case eGL_COMPRESSED_RED_RGTC1:
case eGL_COMPRESSED_SIGNED_RED_RGTC1: ret.type = ResourceFormatType::BC4; break;
// BC5
case eGL_COMPRESSED_RG_RGTC2:
case eGL_COMPRESSED_SIGNED_RG_RGTC2: ret.type = ResourceFormatType::BC5; break;
// BC6
case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: ret.type = ResourceFormatType::BC6; break;
// BC7
case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: ret.type = ResourceFormatType::BC7; break;
// ETC1
case eGL_ETC1_RGB8_OES: // handle it as ETC2
// ETC2
case eGL_COMPRESSED_RGB8_ETC2:
case eGL_COMPRESSED_SRGB8_ETC2:
case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
ret.type = ResourceFormatType::ETC2;
break;
// EAC
case eGL_COMPRESSED_RGBA8_ETC2_EAC:
case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case eGL_COMPRESSED_R11_EAC:
case eGL_COMPRESSED_SIGNED_R11_EAC:
case eGL_COMPRESSED_RG11_EAC:
case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.type = ResourceFormatType::EAC; break;
// ASTC
case eGL_COMPRESSED_RGBA_ASTC_4x4_KHR:
case eGL_COMPRESSED_RGBA_ASTC_5x4_KHR:
case eGL_COMPRESSED_RGBA_ASTC_5x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_6x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_6x6_KHR:
case eGL_COMPRESSED_RGBA_ASTC_8x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_8x6_KHR:
case eGL_COMPRESSED_RGBA_ASTC_8x8_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x5_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x6_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x8_KHR:
case eGL_COMPRESSED_RGBA_ASTC_10x10_KHR:
case eGL_COMPRESSED_RGBA_ASTC_12x10_KHR:
case eGL_COMPRESSED_RGBA_ASTC_12x12_KHR:
case eGL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
case eGL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
case eGL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
case eGL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
case eGL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
case eGL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
case eGL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
case eGL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
case eGL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
case eGL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: ret.type = ResourceFormatType::ASTC; break;
// PVRTC
case eGL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
case eGL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: ret.type = ResourceFormatType::PVRTC; break;
default: RDCERR("Unexpected compressed format %#x", fmt); break;
}
return ret;
}
// handle certain non compressed but special formats
switch(fmt)
{
case eGL_R11F_G11F_B10F:
ret.type = ResourceFormatType::R11G11B10;
ret.compType = CompType::Float;
ret.compCount = 3;
break;
case eGL_RGB565:
ret.type = ResourceFormatType::R5G6B5;
ret.compType = CompType::UNorm;
ret.compCount = 3;
ret.SetBGRAOrder(true);
break;
case eGL_RGB5_A1:
ret.type = ResourceFormatType::R5G5B5A1;
ret.compType = CompType::UNorm;
ret.compCount = 4;
ret.SetBGRAOrder(true);
break;
case eGL_RGB9_E5:
ret.type = ResourceFormatType::R9G9B9E5;
ret.compType = CompType::Float;
ret.compCount = 3;
break;
case eGL_RGBA4:
ret.type = ResourceFormatType::R4G4B4A4;
ret.compType = CompType::UNorm;
ret.compCount = 4;
ret.SetBGRAOrder(true);
break;
case eGL_RGB10_A2:
case eGL_RGB10_A2UI:
ret.type = ResourceFormatType::R10G10B10A2;
ret.compType = fmt == eGL_RGB10_A2 ? CompType::UNorm : CompType::UInt;
ret.compCount = 4;
break;
default: break;
}
if(ret.Special())
return ret;
ret.compByteWidth = 1;
ret.compCount = 4;
ret.compType = CompType::Float;
GLint data[8];
GLenum *edata = (GLenum *)data;
GLint iscol = 0, isdepth = 0, isstencil = 0;
GL.glGetInternalformativ(target, fmt, eGL_COLOR_COMPONENTS, 1, &iscol);
GL.glGetInternalformativ(target, fmt, eGL_DEPTH_COMPONENTS, 1, &isdepth);
GL.glGetInternalformativ(target, fmt, eGL_STENCIL_COMPONENTS, 1, &isstencil);
if(iscol == GL_TRUE)
{
if(fmt == eGL_BGRA8_EXT || fmt == eGL_BGRA)
ret.SetBGRAOrder(true);
// colour format
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_SIZE, 1, &data[0]);
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_SIZE, 1, &data[1]);
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_SIZE, 1, &data[2]);
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_SIZE, 1, &data[3]);
ret.compCount = 0;
for(int i = 0; i < 4; i++)
if(data[i] > 0)
ret.compCount++;
for(int i = ret.compCount; i < 4; i++)
data[i] = data[0];
if(data[0] == data[1] && data[1] == data[2] && data[2] == data[3])
{
ret.compByteWidth = (uint8_t)(data[0] / 8);
// wasn't a byte format (8, 16, 32)
if(int32_t(ret.compByteWidth) * 8 != data[0])
{
ret.type = ResourceFormatType::Undefined;
RDCERR("Unexpected/unhandled non-uniform format: '%s'", ToStr(fmt).c_str());
}
}
else
{
ret.type = ResourceFormatType::Undefined;
RDCERR("Unexpected/unhandled non-uniform format: '%s'", ToStr(fmt).c_str());
}
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_TYPE, 1, &data[0]);
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_TYPE, 1, &data[1]);
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_TYPE, 1, &data[2]);
GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_TYPE, 1, &data[3]);
for(int i = ret.compCount; i < 4; i++)
data[i] = data[0];
if(data[0] == data[1] && data[1] == data[2] && data[2] == data[3])
{
switch(edata[0])
{
case eGL_UNSIGNED_INT: ret.compType = CompType::UInt; break;
case eGL_UNSIGNED_BYTE:
case eGL_UNSIGNED_NORMALIZED: ret.compType = CompType::UNorm; break;
case eGL_SIGNED_NORMALIZED: ret.compType = CompType::SNorm; break;
case eGL_FLOAT: ret.compType = CompType::Float; break;
case eGL_INT: ret.compType = CompType::SInt; break;
default:
{
RDCERR("Unexpected texture type");
if(ret.compByteWidth == 1)
ret.compType = CompType::UNorm;
else
ret.compType = CompType::Float;
}
}
}
else
{
ret.type = ResourceFormatType::Undefined;
RDCERR("Unexpected/unhandled non-uniform format: '%s'", ToStr(fmt).c_str());
}
GL.glGetInternalformativ(target, fmt, eGL_COLOR_ENCODING, 1, &data[0]);
if(edata[0] == eGL_SRGB || fmt == eGL_SR8_EXT || fmt == eGL_SRG8_EXT)
ret.compType = CompType::UNormSRGB;
}
else if(isdepth == GL_TRUE || isstencil == GL_TRUE)
{
// depth format
ret.compType = CompType::Depth;
switch(fmt)
{
case eGL_DEPTH_COMPONENT16:
ret.compByteWidth = 2;
ret.compCount = 1;
break;
case eGL_DEPTH_COMPONENT24:
ret.compByteWidth = 3;
ret.compCount = 1;
break;
case eGL_DEPTH_COMPONENT:
case eGL_DEPTH_COMPONENT32:
case eGL_DEPTH_COMPONENT32F:
ret.compByteWidth = 4;
ret.compCount = 1;
break;
case eGL_DEPTH24_STENCIL8:
ret.compByteWidth = 0;
ret.compCount = 2;
ret.type = ResourceFormatType::D24S8;
break;
case eGL_DEPTH_STENCIL:
case eGL_DEPTH32F_STENCIL8:
ret.compByteWidth = 0;
ret.compCount = 2;
ret.type = ResourceFormatType::D32S8;
break;
case eGL_STENCIL_INDEX:
case eGL_STENCIL_INDEX8:
ret.compByteWidth = 1;
ret.compCount = 1;
ret.type = ResourceFormatType::S8;
break;
default: RDCERR("Unexpected depth or stencil format '%s'", ToStr(fmt).c_str());
}
}
else
{
// not colour or depth!
RDCERR("Unexpected texture type, not colour or depth: '%s'", ToStr(fmt).c_str());
}
return ret;
}