Prechádzať zdrojové kódy

Merge pull request #1241 from floooh/issue1234/android-gles31

Support compute shaders on Android and Linux+GLES3.
Andre Weissflog 5 mesiacov pred
rodič
commit
a9b62e4c78
7 zmenil súbory, kde vykonal 85 pridanie a 79 odobranie
  1. 24 0
      CHANGELOG.md
  2. 35 21
      sokol_app.h
  3. 23 10
      sokol_gfx.h
  4. 0 3
      tests/CMakeLists.txt
  5. 2 42
      tests/CMakePresets.json
  6. 0 2
      tests/test_android.sh
  7. 1 1
      tests/test_common.sh

+ 24 - 0
CHANGELOG.md

@@ -1,5 +1,29 @@
 ## Updates
 
+### 05-Apr-2025
+
+Compute shaders are now supported on platforms that support GLES3.1
+(e.g. Android and desktop Linux, but not WebGL2 or iOS):
+
+- sokol_app.h:
+    - `sapp_desc.gl_major/minor_version` is now taken into account for GLES context
+      creation on platforms that support more recent GLES3 contexts than GLES3.0
+      (Android and desktop Linux)
+    - the functions `sapp_gl_get_major_version()` and `sapp_gl_get_minor_version()`
+      now return the requested GL context version also in 'GLES3 mode'
+    - a new function `sapp_gl_is_gles()` has been added which returns true in 'GLES3 mode'
+    - on Android and desktop-Linux in GLES3 mode, a GLES3.1 context will now be
+      created by default
+- sokol_gfx.h:
+    - the SOKOL_GLES3 code path now dynamically queries the GLES3 context version
+      to check for storage-buffer and compute-shader support (e.g. >= GLES3.1)
+
+Note that to get compute shader support on GLES3.1 capable platforms you'll also
+need to pass in matching GLSL shaders, e.g. with sokol-shdc, use the `glsl310es`
+output shader language instead of `glsl300es`.
+
+For details see PR https://github.com/floooh/sokol/pull/1241
+
 ### 04-Apr-2025
 
 - sokol_imgui.h: a small compatibility hack for the 'traditional' [cimgui.h](https://github.com/cimgui/cimgui).

+ 35 - 21
sokol_app.h

@@ -334,8 +334,9 @@
 
         int sapp_gl_get_major_version(void)
         int sapp_gl_get_minor_version(void)
-            Returns the major and minor version of the GL context
-            (only for SOKOL_GLCORE, all other backends return zero here, including SOKOL_GLES3)
+        bool sapp_gl_is_gles(void)
+            Returns the major and minor version of the GL context and
+            whether the GL context is a GLES context
 
         const void* sapp_android_get_native_activity(void);
             On Android, get the native activity ANativeActivity pointer, otherwise
@@ -1818,7 +1819,7 @@ typedef struct sapp_desc {
     sapp_logger logger;                 // logging callback override (default: NO LOGGING!)
 
     // backend-specific options
-    int gl_major_version;               // override GL major and minor version (the default GL version is 4.1 on macOS, 4.3 elsewhere)
+    int gl_major_version;               // override GL/GLES major and minor version (defaults: GL4.1 (macOS) or GL4.3, GLES3.1 (Android) or GLES3.0
     int gl_minor_version;
     bool win32_console_utf8;            // if true, set the output console codepage to UTF-8
     bool win32_console_create;          // if true, attach stdout/stderr to a new console window
@@ -2010,10 +2011,12 @@ SOKOL_APP_API_DECL const void* sapp_wgpu_get_depth_stencil_view(void);
 
 /* GL: get framebuffer object */
 SOKOL_APP_API_DECL uint32_t sapp_gl_get_framebuffer(void);
-/* GL: get major version (only valid for desktop GL) */
+/* GL: get major version */
 SOKOL_APP_API_DECL int sapp_gl_get_major_version(void);
-/* GL: get minor version (only valid for desktop GL) */
+/* GL: get minor version */
 SOKOL_APP_API_DECL int sapp_gl_get_minor_version(void);
+/* GL: return true if the context is GLES */
+SOKOL_APP_API_DECL bool sapp_gl_is_gles(void);
 
 /* X11: get Window */
 SOKOL_APP_API_DECL const void* sapp_x11_get_window(void);
@@ -3216,17 +3219,21 @@ _SOKOL_PRIVATE sapp_desc _sapp_desc_defaults(const sapp_desc* desc) {
     sapp_desc res = *desc;
     res.sample_count = _sapp_def(res.sample_count, 1);
     res.swap_interval = _sapp_def(res.swap_interval, 1);
-    // NOTE: can't patch the default for gl_major_version and gl_minor_version
-    // independently, because a desired version 4.0 would be patched to 4.2
-    // (or expressed differently: zero is a valid value for gl_minor_version
-    // and can't be used to indicate 'default')
     if (0 == res.gl_major_version) {
-        #if defined(_SAPP_APPLE)
-            res.gl_major_version = 4;
-            res.gl_minor_version = 1;
-        #else
+        #if defined(SOKOL_GLCORE)
             res.gl_major_version = 4;
-            res.gl_minor_version = 3;
+            #if defined(_SAPP_APPLE)
+                res.gl_minor_version = 1;
+            #else
+                res.gl_minor_version = 3;
+            #endif
+        #elif defined(SOKOL_GLES3)
+            res.gl_major_version = 3;
+            #if defined(_SAPP_ANDROID) || defined(_SAPP_LINUX)
+                res.gl_minor_version = 1;
+            #else
+                res.gl_minor_version = 0;
+            #endif
         #endif
     }
     res.html5_canvas_selector = _sapp_def(res.html5_canvas_selector, "#canvas");
@@ -8332,7 +8339,8 @@ _SOKOL_PRIVATE bool _sapp_android_init_egl(void) {
     }
 
     EGLint ctx_attributes[] = {
-        EGL_CONTEXT_CLIENT_VERSION, 3,
+        EGL_CONTEXT_MAJOR_VERSION, _sapp.desc.gl_major_version,
+        EGL_CONTEXT_MINOR_VERSION, _sapp.desc.gl_minor_version,
         EGL_NONE,
     };
     EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctx_attributes);
@@ -11648,12 +11656,10 @@ _SOKOL_PRIVATE void _sapp_egl_init(void) {
     }
 
     EGLint ctx_attrs[] = {
+        EGL_CONTEXT_MAJOR_VERSION, _sapp.desc.gl_major_version,
+        EGL_CONTEXT_MINOR_VERSION, _sapp.desc.gl_minor_version,
         #if defined(SOKOL_GLCORE)
-            EGL_CONTEXT_MAJOR_VERSION, _sapp.desc.gl_major_version,
-            EGL_CONTEXT_MINOR_VERSION, _sapp.desc.gl_minor_version,
             EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
-        #elif defined(SOKOL_GLES3)
-            EGL_CONTEXT_CLIENT_VERSION, 3,
         #endif
         EGL_NONE,
     };
@@ -12374,7 +12380,7 @@ SOKOL_API_IMPL uint32_t sapp_gl_get_framebuffer(void) {
 
 SOKOL_API_IMPL int sapp_gl_get_major_version(void) {
     SOKOL_ASSERT(_sapp.valid);
-    #if defined(SOKOL_GLCORE)
+    #if defined(_SAPP_ANY_GL)
         return _sapp.desc.gl_major_version;
     #else
         return 0;
@@ -12383,13 +12389,21 @@ SOKOL_API_IMPL int sapp_gl_get_major_version(void) {
 
 SOKOL_API_IMPL int sapp_gl_get_minor_version(void) {
     SOKOL_ASSERT(_sapp.valid);
-    #if defined(SOKOL_GLCORE)
+    #if defined(_SAPP_ANY_GL)
         return _sapp.desc.gl_minor_version;
     #else
         return 0;
     #endif
 }
 
+SOKOL_API_IMPL bool sapp_gl_is_gles(void) {
+    #if defined(SOKOL_GLES3)
+        return true;
+    #else
+        return false;
+    #endif
+}
+
 SOKOL_API_IMPL const void* sapp_x11_get_window(void) {
     #if defined(_SAPP_LINUX)
         return (void*)_sapp.x11.window;

+ 23 - 10
sokol_gfx.h

@@ -711,8 +711,9 @@
 
         - macOS and iOS with Metal
         - Windows with D3D11 and OpenGL
-        - Linux with OpenGL
-        - web with WebGPU
+        - Linux with OpenGL or GLES3.1+
+        - Web with WebGPU
+        - Android with GLES3.1+
 
     ...this means compute shaders can't be used on the following platform/backend
     combos (the same restrictions apply to using storage buffers without compute
@@ -720,8 +721,7 @@
 
         - macOS with GL
         - iOS with GLES3
-        - Android
-        - web with WebGL2
+        - Web with WebGL2
 
     A compute pass is started with:
 
@@ -1185,8 +1185,7 @@
     Storage buffers are *NOT* supported on the following platform/backend combos:
 
     - macOS+GL (because storage buffers require GL 4.3, while macOS only goes up to GL 4.1)
-    - all GLES3 platforms (WebGL2, iOS, Android - with the option that support on
-      Android may be added at a later point)
+    - platforms which only support a GLES3.0 context (WebGL2 and iOS)
 
     To use storage buffers, the following steps are required:
 
@@ -4979,17 +4978,20 @@ inline int sg_append_buffer(sg_buffer buf_id, const sg_range& data) { return sg_
                 #include <OpenGLES/ES3/gl.h>
                 #include <OpenGLES/ES3/glext.h>
             #endif
-        #elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+        #elif defined(__EMSCRIPTEN__)
             #if defined(SOKOL_GLES3)
                 #include <GLES3/gl3.h>
             #endif
+        #elif defined(__ANDROID__)
+            #define _SOKOL_GL_HAS_COMPUTE (1)
+            #include <GLES3/gl31.h>
         #elif defined(__linux__) || defined(__unix__)
+            #define _SOKOL_GL_HAS_COMPUTE (1)
             #if defined(SOKOL_GLCORE)
                 #define GL_GLEXT_PROTOTYPES
                 #include <GL/gl.h>
-                #define _SOKOL_GL_HAS_COMPUTE (1)
             #else
-                #include <GLES3/gl3.h>
+                #include <GLES3/gl31.h>
                 #include <GLES3/gl3ext.h>
             #endif
         #endif
@@ -8346,11 +8348,16 @@ _SOKOL_PRIVATE void _sg_gl_init_caps_glcore(void) {
 _SOKOL_PRIVATE void _sg_gl_init_caps_gles3(void) {
     _sg.backend = SG_BACKEND_GLES3;
 
+    GLint major_version = 0;
+    GLint minor_version = 0;
+    glGetIntegerv(GL_MAJOR_VERSION, &major_version);
+    glGetIntegerv(GL_MINOR_VERSION, &minor_version);
+    const int version = major_version * 100 + minor_version * 10;
     _sg.features.origin_top_left = false;
     _sg.features.image_clamp_to_border = false;
     _sg.features.mrt_independent_blend_state = false;
     _sg.features.mrt_independent_write_mask = false;
-    _sg.features.compute = false;
+    _sg.features.compute = version >= 310;
     _sg.features.msaa_image_bindings = false;
 
     bool has_s3tc = false;  // BC1..BC3
@@ -9998,6 +10005,9 @@ _SOKOL_PRIVATE void _sg_gl_apply_pipeline(_sg_pipeline_t* pip) {
 
 #if defined _SOKOL_GL_HAS_COMPUTE
 _SOKOL_PRIVATE void _sg_gl_handle_memory_barriers(const _sg_shader_t* shd, const _sg_bindings_t* bnd) {
+    if (!_sg.features.compute) {
+        return;
+    }
     // NOTE: currently only storage buffers can be GPU-written, and storage
     // buffers cannot be bound as vertex- or index-buffers.
     bool needs_barrier = false;
@@ -10221,6 +10231,9 @@ _SOKOL_PRIVATE void _sg_gl_draw(int base_element, int num_elements, int num_inst
 
 _SOKOL_PRIVATE void _sg_gl_dispatch(int num_groups_x, int num_groups_y, int num_groups_z) {
     #if defined(_SOKOL_GL_HAS_COMPUTE)
+    if (!_sg.features.compute) {
+        return;
+    }
     glDispatchCompute((GLuint)num_groups_x, (GLuint)num_groups_y, (GLuint)num_groups_z);
     #else
     (void)num_groups_x; (void)num_groups_y; (void)num_groups_z;

+ 0 - 3
tests/CMakeLists.txt

@@ -125,9 +125,6 @@ macro(configure_common target)
     if (SOKOL_FORCE_EGL)
         target_compile_definitions(${target} PRIVATE SOKOL_FORCE_EGL)
     endif()
-    if (SOKOL_FORCE_SLES)
-        target_compile_definitions(${target} PRIVATE SAUDIO_ANDROID_SLES)
-    endif()
     target_compile_definitions(${target} PRIVATE ${SOKOL_BACKEND})
     target_link_options(${target} PRIVATE ${link_flags})
     target_link_libraries(${target} PRIVATE ${system_libs})

+ 2 - 42
tests/CMakePresets.json

@@ -418,7 +418,7 @@
             "cacheVariables": {
                 "SOKOL_BACKEND": "SOKOL_GLES3",
                 "ANDROID_ABI": "armeabi-v7a",
-                "ANDROID_PLATFORM": "android-28",
+                "ANDROID_PLATFORM": "android-30",
                 "CMAKE_BUILD_TYPE": "Debug"
             }
         },
@@ -430,42 +430,10 @@
             "cacheVariables": {
                 "SOKOL_BACKEND": "SOKOL_GLES3",
                 "ANDROID_ABI": "armeabi-v7a",
-                "ANDROID_PLATFORM": "android-28",
+                "ANDROID_PLATFORM": "android-30",
                 "CMAKE_BUILD_TYPE": "Release"
             }
         },
-        {
-            "name": "android_sles_debug",
-            "generator": "Ninja",
-            "binaryDir": "build/android_sles_debug",
-            "toolchainFile": "build/android_sdk/ndk-bundle/build/cmake/android.toolchain.cmake",
-            "cacheVariables": {
-                "SOKOL_BACKEND": "SOKOL_GLES3",
-                "ANDROID_ABI": "armeabi-v7a",
-                "ANDROID_PLATFORM": "android-28",
-                "CMAKE_BUILD_TYPE": "Debug",
-                "SOKOL_FORCE_SLES": {
-                    "type": "BOOL",
-                    "value": "ON"
-                }
-            }
-        },
-        {
-            "name": "android_sles_release",
-            "generator": "Ninja",
-            "binaryDir": "build/android_sles_release",
-            "toolchainFile": "build/android_sdk/ndk-bundle/build/cmake/android.toolchain.cmake",
-            "cacheVariables": {
-                "SOKOL_BACKEND": "SOKOL_GLES3",
-                "ANDROID_ABI": "armeabi-v7a",
-                "ANDROID_PLATFORM": "android-28",
-                "CMAKE_BUILD_TYPE": "Release",
-                "SOKOL_FORCE_SLES": {
-                    "type": "BOOL",
-                    "value": "ON"
-                }
-            }
-        },
         {
             "name": "win_gl",
             "binaryDir": "build/win_gl",
@@ -680,14 +648,6 @@
             "name": "android_release",
             "configurePreset": "android_release"
         },
-        {
-            "name": "android_sles_debug",
-            "configurePreset": "android_sles_debug"
-        },
-        {
-            "name": "android_sles_release",
-            "configurePreset": "android_sles_release"
-        },
         {
             "name": "win_gl_debug",
             "configurePreset": "win_gl",

+ 0 - 2
tests/test_android.sh

@@ -4,5 +4,3 @@ source test_common.sh
 setup_android
 build android_debug android_debug
 build android_release android_release
-build android_sles_debug android_sles_debug
-build android_sles_release android_sles_release

+ 1 - 1
tests/test_common.sh

@@ -17,7 +17,7 @@ setup_android() {
         wget --no-verbose https://dl.google.com/android/repository/$sdk_file
         unzip -q $sdk_file
         cd tools/bin
-        yes | ./sdkmanager "platforms;android-28" >/dev/null
+        yes | ./sdkmanager "platforms;android-30" >/dev/null
         yes | ./sdkmanager "build-tools;29.0.3" >/dev/null
         yes | ./sdkmanager "platform-tools" >/dev/null
         yes | ./sdkmanager "ndk-bundle" >/dev/null