From b69e94de10e116e3991745dd58b7aa2a648de43f Mon Sep 17 00:00:00 2001 From: jeske Date: Sat, 14 Mar 2026 23:00:14 -0600 Subject: [PATCH] GLES stencil support + packed depth/stencil fixes - support stencil buffer on GLES - extend the fix to GL and GLES3 - fix int that should be IntPtr in eglGetDisplay() - support packed stencil where it is available - Merge branch 'an_main' into GLES_stencil_init_bug --- src/Veldrid/OpenGL/EGL/EGLNative.cs | 3 ++- src/Veldrid/OpenGL/OpenGLExtensions.cs | 8 ++++++ src/Veldrid/OpenGL/OpenGLFormats.cs | 5 ++++ src/Veldrid/OpenGL/OpenGLGraphicsDevice.cs | 29 +++++++++++++++++++++- src/Veldrid/OpenGL/OpenGLTexture.cs | 20 +++++++++++++-- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/Veldrid/OpenGL/EGL/EGLNative.cs b/src/Veldrid/OpenGL/EGL/EGLNative.cs index 4c07f6851..30fc4c1ad 100644 --- a/src/Veldrid/OpenGL/EGL/EGLNative.cs +++ b/src/Veldrid/OpenGL/EGL/EGLNative.cs @@ -12,6 +12,7 @@ internal static unsafe class EglNative public const int EGL_BLUE_SIZE = 0x3022; public const int EGL_ALPHA_SIZE = 0x3021; public const int EGL_DEPTH_SIZE = 0x3025; + public const int EGL_STENCIL_SIZE = 0x3026; public const int EGL_SURFACE_TYPE = 0x3033; public const int EGL_WINDOW_BIT = 0x0004; public const int EGL_OPENGL_ES_BIT = 0x0001; @@ -45,7 +46,7 @@ internal static unsafe class EglNative public static extern IntPtr eglGetCurrentDisplay(); [DllImport(lib_name)] - public static extern IntPtr eglGetDisplay(int nativeDisplay); + public static extern IntPtr eglGetDisplay(IntPtr nativeDisplay); [DllImport(lib_name)] public static extern IntPtr eglGetCurrentSurface(int readdraw); diff --git a/src/Veldrid/OpenGL/OpenGLExtensions.cs b/src/Veldrid/OpenGL/OpenGLExtensions.cs index b9608bc09..3a8e23e61 100644 --- a/src/Veldrid/OpenGL/OpenGLExtensions.cs +++ b/src/Veldrid/OpenGL/OpenGLExtensions.cs @@ -33,6 +33,7 @@ internal class OpenGLExtensions : IReadOnlyCollection public readonly bool MultiDrawIndirect; public readonly bool StorageBuffers; public readonly bool AnisotropicFilter; + public readonly bool OesPackedDepthStencil; private readonly HashSet extensions; private readonly GraphicsBackend backend; private readonly int major; @@ -90,6 +91,13 @@ internal OpenGLExtensions(HashSet extensions, GraphicsBackend backend, i ArbUniformBufferObject = IsExtensionSupported("GL_ARB_uniform_buffer_object"); AnisotropicFilter = IsExtensionSupported("GL_EXT_texture_filter_anisotropic") || IsExtensionSupported("GL_ARB_texture_filter_anisotropic"); + + // D24_UNorm_S8_UInt (GL_DEPTH24_STENCIL8) is core in GL 3.0+ and GLES 3.0+. + // On desktop GL 2.x, GL_ARB_framebuffer_object provides it. + // On GLES 2.x, it requires the GL_OES_packed_depth_stencil extension. + OesPackedDepthStencil = GLVersion(3, 0) || GLESVersion(3, 0) + || IsExtensionSupported("GL_ARB_framebuffer_object") + || IsExtensionSupported("GL_OES_packed_depth_stencil"); } /// diff --git a/src/Veldrid/OpenGL/OpenGLFormats.cs b/src/Veldrid/OpenGL/OpenGLFormats.cs index 638f8aeb9..972b1f563 100644 --- a/src/Veldrid/OpenGL/OpenGLFormats.cs +++ b/src/Veldrid/OpenGL/OpenGLFormats.cs @@ -843,6 +843,11 @@ internal static bool IsFormatSupported(OpenGLExtensions extensions, PixelFormat case PixelFormat.R10G10B10A2UNorm: return backend == GraphicsBackend.OpenGL; + case PixelFormat.D24UNormS8UInt: + return extensions.GLVersion(3, 0) || extensions.GLESVersion(3, 0) + || extensions.IsExtensionSupported("GL_OES_packed_depth_stencil") + || extensions.IsExtensionSupported("GL_ARB_framebuffer_object"); + default: return true; } diff --git a/src/Veldrid/OpenGL/OpenGLGraphicsDevice.cs b/src/Veldrid/OpenGL/OpenGLGraphicsDevice.cs index 26637cc8d..23086861c 100644 --- a/src/Veldrid/OpenGL/OpenGLGraphicsDevice.cs +++ b/src/Veldrid/OpenGL/OpenGLGraphicsDevice.cs @@ -311,6 +311,29 @@ private static int getDepthBits(PixelFormat value) case PixelFormat.R32Float: return 32; + case PixelFormat.D24UNormS8UInt: + return 24; + + case PixelFormat.D32FloatS8UInt: + return 32; + + default: + throw new VeldridException($"Unsupported depth format: {value}"); + } + } + + private static int getStencilBits(PixelFormat value) + { + switch (value) + { + case PixelFormat.D24UNormS8UInt: + case PixelFormat.D32FloatS8UInt: + return 8; + + case PixelFormat.R16UNorm: + case PixelFormat.R32Float: + return 0; + default: throw new VeldridException($"Unsupported depth format: {value}"); } @@ -750,7 +773,7 @@ private void initializeANativeWindow( IntPtr aNativeWindow, SwapchainDescription swapchainDescription) { - IntPtr display = eglGetDisplay(0); + IntPtr display = eglGetDisplay(IntPtr.Zero); if (display == IntPtr.Zero) throw new VeldridException($"Failed to get the default Android EGLDisplay: {eglGetError()}"); int major, minor; @@ -766,6 +789,10 @@ private void initializeANativeWindow( swapchainDescription.DepthFormat != null ? getDepthBits(swapchainDescription.DepthFormat.Value) : 0, + EGL_STENCIL_SIZE, + swapchainDescription.DepthFormat != null + ? getStencilBits(swapchainDescription.DepthFormat.Value) + : 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_NONE diff --git a/src/Veldrid/OpenGL/OpenGLTexture.cs b/src/Veldrid/OpenGL/OpenGLTexture.cs index 491e118da..61b61bca2 100644 --- a/src/Veldrid/OpenGL/OpenGLTexture.cs +++ b/src/Veldrid/OpenGL/OpenGLTexture.cs @@ -65,7 +65,15 @@ public OpenGLTexture(OpenGLGraphicsDevice gd, ref TextureDescription description Width = description.Width; Height = description.Height; Depth = description.Depth; - Format = description.Format; + + if (description.Format == PixelFormat.D24UNormS8UInt && !gd.Extensions.OesPackedDepthStencil) { + Console.WriteLine( + "[Veldrid] GL_OES_packed_depth_stencil not available — downgrading D24_UNorm_S8_UInt to D32_Float_S8_UInt"); + Format = PixelFormat.D32FloatS8UInt; + } + else { + Format = description.Format; + } MipLevels = description.MipLevels; ArrayLayers = description.ArrayLayers; Usage = description.Usage; @@ -115,7 +123,15 @@ public OpenGLTexture(OpenGLGraphicsDevice gd, uint nativeTexture, ref TextureDes Width = description.Width; Height = description.Height; Depth = description.Depth; - Format = description.Format; + + if (description.Format == PixelFormat.D24UNormS8UInt && !gd.Extensions.OesPackedDepthStencil) { + Console.WriteLine( + "[Veldrid] GL_OES_packed_depth_stencil not available — downgrading D24_UNorm_S8_UInt to D32_Float_S8_UInt"); + Format = PixelFormat.D32FloatS8UInt; + } + else { + Format = description.Format; + } MipLevels = description.MipLevels; ArrayLayers = description.ArrayLayers; Usage = description.Usage;