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