Code:
class procedure TGAPI.AnalyzeAndRegisterQuirks;
var
t: TGAPITextureFormat;
v: TImageFormat;
function TryGLTexFormat(mfmt: TGAPITextureFormat; gfmt, gtype: GLenum;
gact: GLint; vf: TImageFormat): boolean;
var
i: TImageFormat;
t: GLuint;
e: GLenum;
buf: pointer;
begin
try
case Mother^.GAPI.Mode of
{$ifndef glesonly}
gapi_GL21,
{$endif glesonly}
gapi_GLES2: begin
ImageFormatForTextureFormat[mfmt]:= ifUnknown; //aka zero
try
GetMem(buf, 16 * 32 * 32);//Self.NumTexelsToBytes(mfmt, 32 * 32));
GlGenTextures(1, @t);
glBindTexture(GL_TEXTURE_2D, t);
glTexImage2D (GL_TEXTURE_2D, 0, gact, 32, 32, 0, gfmt, gtype, buf);
e:= glGetError();
glDeleteTextures(1, @t);
finally
FreeMem(buf);
buf:= nil;
glGetError();
end;
if e = GL_NO_ERROR then begin
if Mother^.Debug.Verbose then AddLog(
' OK: %0 / %1 / %2 / %3',
[GetEnumName(typeinfo(TGAPITextureFormat), ord(mfmt)),
GlTextureFormatToString(gact),
GlTextureFormatToString(gfmt),
GlTextureFormatToString(gtype)
]);
with Mother^.GAPI.TexFormats^[mfmt] do begin
general:= gfmt;
_type:= gtype;
actual:= gact;
end;
TGAPI.ImageFormatForTextureFormat[mfmt]:= vf;
Result:= true;
end
else begin
if Mother^.Debug.Verbose then AddLog(
' %0 / %1 / %2 / %3: failed, %4.',
[GetEnumName(typeinfo(TGAPITextureFormat), ord(mfmt)),
GlTextureFormatToString(gact),
GlTextureFormatToString(gfmt),
GlTextureFormatToString(gtype),
GlErrorCodeToString(e)
]);
FillChar(Mother^.GAPI.TexFormats^[mfmt], sizeof(TMotherTexFormatDesc), 0);
Result:= false;
end;
end;
else
DieUnsupportedGLMode;
end;
except
Die(RuEn(
'Сбой при испытании сочетания текстурных форматов %0 / %1 / %2 / %3',
'Crashed trying texture formats combo %0 / %1 / %2 / %3'
), [GetEnumName(typeinfo(TGAPITextureFormat), ord(mfmt)),
GlTextureFormatToString(gact),
GlTextureFormatToString(gfmt),
GlTextureFormatToString(gtype)
]
);
end;
end;
function TryRenderbufferFormat(mfmt: TGAPITextureFormat; gfmt: GLenum): boolean;
var
t: GLuint;
e: GLenum;
begin
try
case Mother^.GAPI.Mode of
{$ifndef glesonly}
gapi_GL21,
{$endif glesonly}
gapi_GLES2: begin
glGenRenderbuffers(1, @t);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, t);
glRenderbufferStorage(GL_RENDERBUFFER_EXT, gfmt, 32, 32);
e:= glGetError();
glDeleteRenderbuffers(1, @t);
glGetError();
if e = GL_NO_ERROR then begin
if Mother^.Debug.Verbose then AddLog(
' OK: %0 / %1',
[GetEnumName(typeinfo(TGAPITextureFormat), ord(mfmt)),
GlTextureFormatToString(gfmt)
]);
Mother^.GAPI.RenderBufferFormats^[mfmt]:= gfmt;
Result:= true;
end
else begin
if Mother^.Debug.Verbose then AddLog(
' %0 / %1: failed, %2.',
[GetEnumName(typeinfo(TGAPITextureFormat), ord(mfmt)),
GlTextureFormatToString(gfmt),
GlErrorCodeToString(e)
]);
Mother^.GAPI.RenderBufferFormats^[mfmt]:= 0;
Result:= false;
end;
end;
else
DieUnsupportedGLMode;
end;
except
Die(RuEn(
'Сбой при испытании формата буфера отрисовки %0 / %1',
'Crashed trying render buffer format %0 / %1'
), [GetEnumName(typeinfo(TGAPITextureFormat), ord(mfmt)),
GlTextureFormatToString(gfmt)
]
);
end;
end;
begin
Config.GetSet(@Mother^.GAPI.Quirks, typeInfo(TGAPIQuirksEnum), 'videocard', 'quirks');
Config.GetSet(@Mother^.GAPI.QuirksTested, typeInfo(TGAPIQuirksEnum), 'videocard', 'tested_quirks');
try
case Mother^.GAPI.Mode of
{$ifndef glesonly}
gapi_GL21: begin
Assert(sizeof(TGAPITextureFormatSet) = 4, 'The size of TGAPITextureFormatSet is not 4 but ' + IntToStr(sizeof(TGAPITextureFormatSet)));
GetMem(Mother^.GAPI.TexFormats, 32 * sizeof(TMotherTexFormatDesc));
FillChar(Mother^.GAPI.TexFormats^, 32 * sizeof(TMotherTexFormatDesc), 0);
GetMem(Mother^.GAPI.RenderbufferFormats, 32 * sizeof(ptruint));
FillChar(Mother^.GAPI.RenderbufferFormats^, 32 * sizeof(ptruint), 0);
if Mother^.Debug.Verbose then AddLog(' Trying texture formats...');
TryGLTexFormat(texformat_RGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8, ifR8G8B8);
TryGLTexFormat(texformat_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8, ifA8R8G8B8);
TryGLTexFormat(texformat_L8, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8, ifGray8);
TryGLTexFormat(texformat_A8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8, ifGray8);
TryGLTexFormat(texformat_LA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8, ifA8Gray8);
TryGLTexFormat(texformat_L16, GL_LUMINANCE, GL_UNSIGNED_SHORT, GL_LUMINANCE16, ifGray16);
TryGLTexFormat(texformat_LA16, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT, GL_LUMINANCE16_ALPHA16, ifA16Gray16);
if not TryGLTexFormat(texformat_R5G6B5, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB5, ifA8R8G8B8)
then TryGLTexFormat(texformat_R5G6B5, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB5, ifR5G6B5);
if not TryGLTexFormat(texformat_R5G5B5A1, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB5, ifA8R8G8B8)
then TryGLTexFormat(texformat_R5G5B5A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5, ifA1R5G5B5);
if not TryGLTexFormat(texformat_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA4, ifA8R8G8B8)
then TryGLTexFormat(texformat_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, ifA4R4G4B4);
TryGLTexFormat(texformat_RGB16, GL_RGB, GL_UNSIGNED_SHORT, GL_RGB16, ifR16G16B16);
TryGLTexFormat(texformat_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, GL_RGBA16, ifA16R16G16B16);
TryGLTexFormat(texformat_R32F, GL_RED, GL_FLOAT, GL_LUMINANCE32F_ARB, ifR32F);
TryGLTexFormat(texformat_RGBA32F, GL_RGBA, GL_FLOAT, GL_RGBA32F_ARB, ifA32R32G32B32F);
TryGLTexFormat(texformat_R16F, GL_RED, GL_HALF_FLOAT_ARB, GL_LUMINANCE16F_ARB, ifR16F);
TryGLTexFormat(texformat_RGBA16F, GL_RGBA, GL_HALF_FLOAT_ARB, GL_RGBA16F_ARB, ifA16R16G16B16F);
// DDS format is NOT supported because it is patented.
// If the driver allows uploading RGBA8 to DXT, this becomes the driver
// manufacturer's problem.
// So while using DXT is supported, saving / loading of it is NOT.
// (even as Vampyre Imaging has DDS support, including mipmaps)
TryGLTexFormat(texformat_DXT1, GL_RGB, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, ifR8G8B8);
TryGLTexFormat(texformat_DXT1RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, ifA8R8G8B8);
TryGLTexFormat(texformat_DXT3, GL_RGBA, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, ifA8R8G8B8);
TryGLTexFormat(texformat_DXT5, GL_RGBA, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, ifA8R8G8B8);
if not TryGLTexFormat(texformat_Depth, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT, ifR32F)
then TryGLTexFormat(texformat_Depth, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, ifGray32);
if not TryGLTexFormat(texformat_Depth16, GL_DEPTH_COMPONENT, GL_HALF_FLOAT_ARB, GL_DEPTH_COMPONENT, ifR16F)
then TryGLTexFormat(texformat_Depth16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, ifR16F);
for t in TGAPITextureFormat do begin
v:= TGAPI.ImageFormatForTextureFormat[t];
if v <> ifUnknown
then TGAPI.TextureFormatsPerImageFormat[byte(v)]+= [t]; //add the enum to the set
end;
if Mother^.Debug.Verbose then AddLog(' Trying render buffer formats...');
TryRenderbufferFormat(texformat_RGBA4, GL_RGBA4);
TryRenderbufferFormat(texformat_R5G6B5, GL_RGB565);
TryRenderbufferFormat(texformat_R5G5B5A1, GL_RGB5_A1);
TryRenderbufferFormat(texformat_RGBA8, GL_RGBA8);
TryRenderbufferFormat(texformat_RGB8, GL_RGB8);
TryRenderbufferFormat(texformat_RGB16, GL_RGB16);
TryRenderbufferFormat(texformat_RGBA16, GL_RGBA16);
TryRenderbufferFormat(texformat_R16F, GL_LUMINANCE16F_ARB);
TryRenderbufferFormat(texformat_R32F, GL_LUMINANCE32F_ARB);
TryRenderbufferFormat(texformat_RGBA16F, GL_RGBA16F_ARB);
TryRenderbufferFormat(texformat_RGBA32F, GL_RGBA32F_ARB);
TryRenderbufferFormat(texformat_L8, GL_LUMINANCE8);
{
TryRenderbufferFormat();
TryRenderbufferFormat();
TryRenderbufferFormat();
TryRenderbufferFormat();
TryRenderbufferFormat();
}
if not TryRenderbufferFormat(texformat_Depth, GL_DEPTH_COMPONENT32)
then TryRenderbufferFormat(texformat_Depth, GL_DEPTH_COMPONENT24);
TryRenderbufferFormat(texformat_Depth16, GL_DEPTH_COMPONENT16);
if Mother^.GAPI.Mode in [gapi_GL21]
then TestOpenGlQuirkNo2;
CheckGLError(false);
end;
{$endif glesonly}
gapi_GLES2: begin
Assert(sizeof(TGAPITextureFormatSet) = 4, 'The size of TGAPITextureFormatSet is not 4 but ' + IntToStr(sizeof(TGAPITextureFormatSet)));
GetMem(Mother^.GAPI.TexFormats, 32 * sizeof(TMotherTexFormatDesc));
FillChar(Mother^.GAPI.TexFormats^, 32 * sizeof(TMotherTexFormatDesc), 0);
GetMem(Mother^.GAPI.RenderbufferFormats, 32 * sizeof(ptruint));
FillChar(Mother^.GAPI.RenderbufferFormats^, 32 * sizeof(ptruint), 0);
if Mother^.Debug.Verbose then AddLog(' Trying texture formats...');
TryGLTexFormat(texformat_RGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, ifR8G8B8);
TryGLTexFormat(texformat_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, ifA8R8G8B8);
TryGLTexFormat(texformat_L8, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, ifGray8);
TryGLTexFormat(texformat_LA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA, ifA8Gray8);
TryGLTexFormat(texformat_L16, GL_LUMINANCE, GL_UNSIGNED_SHORT, GL_LUMINANCE, ifGray16);
TryGLTexFormat(texformat_LA16, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT, GL_LUMINANCE_ALPHA, ifA16Gray16);
TryGLTexFormat(texformat_R5G6B5, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, ifR5G6B5);
TryGLTexFormat(texformat_R5G5B5A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_RGBA, ifA1R5G5B5);
TryGLTexFormat(texformat_R5G5B5A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA, ifA1R5G5B5);
TryGLTexFormat(texformat_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_RGBA, ifA4R4G4B4);
TryGLTexFormat(texformat_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA, ifA4R4G4B4);
TryGLTexFormat(texformat_R16F, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE, ifR16F);
TryGLTexFormat(texformat_RGBA16F, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA, ifA16R16G16B16F);
TryGLTexFormat(texformat_RGB16, GL_RGB, GL_UNSIGNED_SHORT, GL_RGB, ifR16G16B16);
TryGLTexFormat(texformat_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, GL_RGBA, ifA16R16G16B16);
// Well, ANGLE supports this. On top of Direct3d9...
TryGLTexFormat(texformat_R32F, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE, ifR32F);
TryGLTexFormat(texformat_RGBA32F, GL_RGBA, GL_FLOAT, GL_RGBA, ifA32R32G32B32F);
//These do *not* work in ANGLE:
if not TryGLTexFormat(texformat_Depth, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT, ifR32F)
then TryGLTexFormat(texformat_Depth, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, ifR32F);
if not TryGLTexFormat(texformat_Depth16, GL_DEPTH_COMPONENT, GL_HALF_FLOAT_OES, GL_DEPTH_COMPONENT, ifR16F)
then TryGLTexFormat(texformat_Depth16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, ifR16F);
for t in TGAPITextureFormat do begin
v:= TGAPI.ImageFormatForTextureFormat[t];
if v <> ifUnknown
then TGAPI.TextureFormatsPerImageFormat[byte(v)]+= [t]; //add the enum to the set
end;
if Mother^.Debug.Verbose then AddLog(' Trying render buffer formats...');
TryRenderbufferFormat(texformat_RGBA4, GL_RGBA4);
TryRenderbufferFormat(texformat_R5G6B5, GL_RGB565);
TryRenderbufferFormat(texformat_R5G5B5A1, GL_RGB5_A1);
TryRenderbufferFormat(texformat_RGBA8, GL_RGBA8);
TryRenderbufferFormat(texformat_RGB8, GL_RGB8);
TryRenderbufferFormat(texformat_RGB16, GL_RGB16);
TryRenderbufferFormat(texformat_RGBA16, GL_RGBA16);
TryRenderbufferFormat(texformat_R16F, GL_LUMINANCE16F_ARB);
TryRenderbufferFormat(texformat_R32F, GL_LUMINANCE32F_ARB);
TryRenderbufferFormat(texformat_RGBA16F, GL_RGBA16F_ARB);
TryRenderbufferFormat(texformat_RGBA32F, GL_RGBA32F_ARB);
TryRenderbufferFormat(texformat_L8, GL_LUMINANCE8);
if not TryRenderbufferFormat(texformat_Depth, GL_DEPTH_COMPONENT24_OES) //this one never works
then if not TryRenderbufferFormat(texformat_Depth, GL_DEPTH_COMPONENT32_OES)
then TryRenderbufferFormat(texformat_Depth, GL_DEPTH24_STENCIL8_OES);
TryRenderbufferFormat(texformat_Depth16, GL_DEPTH_COMPONENT16);
if Mother^.GAPI.Mode in [gapi_GL21]
then TestOpenGlQuirkNo2;
end;
else
DieUnsupportedGLMode;
end;
if Self.SupportedTexFormat(texformat_RGBA8) <> texformat_RGBA8
then Die(RuEn(
'Что-то не то с видеодрайвером, нет поддержки текстурного формата RGBA8!',
'There is something wrong with the video driver, no support for the RGBA8 texture format!'))
except
Die(RuEn(
'Сбой при анализе особенностей %0',
'Crashed trying to analyze %0 quirks'
), [self.Name(rc_Accusative)]);
end;
end;
Bookmarks