Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
  3.  * It is copyright by its individual contributors, as recorded in the
  4.  * project's Git history.  See COPYING.txt at the top level for license
  5.  * terms and a link to the Git history.
  6.  */
  7.  
  8. /* OpenGL extensions:
  9.  * We use global function pointer for any extension function we want to use.
  10.  */
  11.  
  12. #include <string.h>
  13. #include <SDL.h>
  14.  
  15. #include "ogl_extensions.h"
  16. #include "console.h"
  17.  
  18. #include "dxxsconf.h"
  19. #include "dsx-ns.h"
  20. #include <array>
  21.  
  22. namespace dcx {
  23.  
  24. /* GL_ARB_sync */
  25. bool ogl_have_ARB_sync = false;
  26. PFNGLFENCESYNCPROC glFenceSyncFunc = NULL;
  27. PFNGLDELETESYNCPROC glDeleteSyncFunc = NULL;
  28. PFNGLCLIENTWAITSYNCPROC glClientWaitSyncFunc = NULL;
  29.  
  30. /* GL_EXT_texture_filter_anisotropic */
  31. GLfloat ogl_maxanisotropy = 0.0f;
  32.  
  33. static std::array<long, 2> parse_version_str(const char *v)
  34. {
  35.         std::array<long, 2> version;
  36.         version[0]=1;
  37.         version[1]=0;
  38.         if (v) {
  39.                 char *ptr;
  40.                 if (v[0] == 'O') {
  41.                         // OpenGL ES uses the format "OpenGL ES-xx major.minor"
  42.                         const auto &prefix_gles = "OpenGL ES-";
  43.                         if (!strncmp(v, prefix_gles, sizeof(prefix_gles)-1)) {
  44.                                 // skip the prefix
  45.                                 v += sizeof(prefix_gles)-1;
  46.                                 // skip the profile marker
  47.                                 if (v[0] && v[1]) {
  48.                                         v +=2;
  49.                                 }
  50.                         }
  51.                 }
  52.                 version[0]=strtol(v,&ptr,10);
  53.                 if (ptr[0])
  54.                         version[1]=strtol(ptr+1,NULL,10);
  55.         }
  56.         return version;
  57. }
  58.  
  59. static bool is_ext_supported(const char *extensions, const char *name)
  60. {
  61.         if (extensions && name) {
  62.                 const char *found=strstr(extensions, name);
  63.                 if (found) {
  64.                         // check that the name is actually complete */
  65.                         char c = found[strlen(name)];
  66.                         if (c == ' ' || c == 0)
  67.                                 return true;
  68.                 }
  69.         }
  70.         return false;
  71. }
  72.  
  73. enum support_mode {
  74.         NO_SUPPORT=0,
  75.         SUPPORT_CORE=1,
  76.         SUPPORT_EXT=2
  77. };
  78.  
  79. static support_mode is_supported(const char *extensions, const std::array<long, 2> &version, const char *name, long major, long minor, long major_es, long minor_es)
  80. {
  81. #if DXX_USE_OGLES
  82.         static_cast<void>(major);
  83.         static_cast<void>(minor);
  84.         if ( (major_es > 0) && ((version[0] > major_es) || (version[0] == major_es && version[1] >= minor_es)) )
  85.                 return SUPPORT_CORE;
  86. #else
  87.         static_cast<void>(major_es);
  88.         static_cast<void>(minor_es);
  89.         if ( (major > 0) && ((version[0] > major) || (version[0] == major && version[1] >= minor)) )
  90.                 return SUPPORT_CORE;
  91. #endif
  92.  
  93.         if (is_ext_supported(extensions, name))
  94.                 return SUPPORT_EXT;
  95.         return NO_SUPPORT;
  96. }
  97.  
  98. void ogl_extensions_init()
  99. {
  100.         const auto version_str = reinterpret_cast<const char *>(glGetString(GL_VERSION));
  101.         if (!version_str) {
  102.                 con_puts(CON_URGENT, "DXX-Rebirth: no valid OpenGL context when querying GL extensions!");
  103.                 return;
  104.         }
  105.         const auto version = parse_version_str(version_str);
  106.         const auto extension_str = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
  107.  
  108. #if DXX_USE_OGLES
  109. #define DXX_OGL_STRING  " ES"
  110. #else
  111. #define DXX_OGL_STRING  ""
  112. #endif
  113.         con_printf(CON_VERBOSE, "DXX-Rebirth: OpenGL" DXX_OGL_STRING ": version %ld.%ld (%s)", version[0], version[1], version_str);
  114. #undef DXX_OGL_STRING
  115.  
  116.         /* GL_EXT_texture_filter_anisotropic */
  117.         if (is_supported(extension_str, version, "GL_EXT_texture_filter_anisotropic", -1, -1, -1, -1)) {
  118.                 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &ogl_maxanisotropy);
  119.                 con_printf(CON_VERBOSE, "DXX-Rebirth: OpenGL: GL_EXT_texture_filter_anisotropic available, max anisotropy: %f", ogl_maxanisotropy);
  120.         } else {
  121.                 ogl_maxanisotropy=0.0f;
  122.                 con_puts(CON_VERBOSE, "DXX-Rebirth: OpenGL: GL_EXT_texture_filter_anisotropic not available");
  123.         }
  124.  
  125.         /* GL_ARB_sync */
  126.         if (is_supported(extension_str, version, "GL_ARB_sync", 3, 2, 3, 0)) {
  127.                 glFenceSyncFunc = reinterpret_cast<PFNGLFENCESYNCPROC>(SDL_GL_GetProcAddress("glFenceSync"));
  128.                 glDeleteSyncFunc = reinterpret_cast<PFNGLDELETESYNCPROC>(SDL_GL_GetProcAddress("glDeleteSync"));
  129.                 glClientWaitSyncFunc = reinterpret_cast<PFNGLCLIENTWAITSYNCPROC>(SDL_GL_GetProcAddress("glClientWaitSync"));
  130.  
  131.         }
  132.         const char *s;
  133.         if (glFenceSyncFunc && glDeleteSyncFunc && glClientWaitSyncFunc) {
  134.                 ogl_have_ARB_sync=true;
  135.                 s = "DXX-Rebirth: OpenGL: GL_ARB_sync available";
  136.         } else {
  137.                 s = "DXX-Rebirth: OpenGL: GL_ARB_sync not available";
  138.         }
  139.         con_puts(CON_VERBOSE, s);
  140. }
  141.  
  142. }
  143.