Skip to content

Commit

Permalink
rework again how we manage different versions of GL
Browse files Browse the repository at this point in the history
try to be more explicit about which configurations are supported,
and use the same pattern everywhere for checking the gl version at
either compile and runtime.
  • Loading branch information
pixelflinger committed Mar 1, 2023
1 parent 21995e4 commit 9ee41b9
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 140 deletions.
4 changes: 2 additions & 2 deletions filament/backend/src/opengl/GLUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ constexpr inline GLenum getBufferBindingType(BufferObjectBinding bindingType) no
case BufferObjectBinding::UNIFORM:
return GL_UNIFORM_BUFFER;
case BufferObjectBinding::SHADER_STORAGE:
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
return GL_SHADER_STORAGE_BUFFER;
#else
utils::panic(__func__, __FILE__, __LINE__, "SHADER_STORAGE not supported");
Expand Down Expand Up @@ -423,7 +423,7 @@ constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
case TextureFormat::RGBA32I: return GL_RGBA32I;

// compressed formats
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_4_3) || defined(GL_ARB_ES3_compatibility)
#if defined(GL_ES_VERSION_3_0) || defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_ARB_ES3_compatibility)
case TextureFormat::EAC_R11: return GL_COMPRESSED_R11_EAC;
case TextureFormat::EAC_R11_SIGNED: return GL_COMPRESSED_SIGNED_R11_EAC;
case TextureFormat::EAC_RG11: return GL_COMPRESSED_RG11_EAC;
Expand Down
109 changes: 53 additions & 56 deletions filament/backend/src/opengl/OpenGLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ using namespace utils;
namespace filament::backend {

bool OpenGLContext::queryOpenGLVersion(GLint* major, GLint* minor) noexcept {
if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GLES) {
char const* version = (char const*)glGetString(GL_VERSION);
// This works on all versions of GLES
int const n = version ? sscanf(version, "OpenGL ES %d.%d", major, minor) : 0;
return n == 2;
} else if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL) {
// OpenGL version
glGetIntegerv(GL_MAJOR_VERSION, major);
glGetIntegerv(GL_MINOR_VERSION, minor);
return (glGetError() == GL_NO_ERROR);
}
#ifdef BACKEND_OPENGL_VERSION_GLES
char const* version = (char const*)glGetString(GL_VERSION);
// This works on all versions of GLES
int const n = version ? sscanf(version, "OpenGL ES %d.%d", major, minor) : 0;
return n == 2;
#else
// OpenGL version
glGetIntegerv(GL_MAJOR_VERSION, major);
glGetIntegerv(GL_MINOR_VERSION, minor);
return (glGetError() == GL_NO_ERROR);
#endif
}

OpenGLContext::OpenGLContext() noexcept {
Expand Down Expand Up @@ -73,50 +73,47 @@ OpenGLContext::OpenGLContext() noexcept {
constexpr GLint MAX_VERTEX_SAMPLER_COUNT = caps3.MAX_VERTEX_SAMPLER_COUNT;
constexpr GLint MAX_FRAGMENT_SAMPLER_COUNT = caps3.MAX_FRAGMENT_SAMPLER_COUNT;

if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GLES) {
#if defined(GL_ES_VERSION_2_0)
initExtensionsGLES();
#endif
if (state.major == 3) {
assert_invariant(gets.max_texture_image_units >= 16);
assert_invariant(gets.max_combined_texture_image_units >= 32);
if (state.minor >= 1) {
features.multisample_texture = true;
// figure out our feature level
if (ext.EXT_texture_cube_map_array) {
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_2;
if (gets.max_texture_image_units >= MAX_FRAGMENT_SAMPLER_COUNT &&
gets.max_combined_texture_image_units >=
(MAX_FRAGMENT_SAMPLER_COUNT + MAX_VERTEX_SAMPLER_COUNT)) {
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_3;
}
}
}
}
} else if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL) {
#if defined(GL_VERSION_4_1)
initExtensionsGL();
#endif
if (state.major == 4) {
assert_invariant(state.minor >= 1);
mShaderModel = ShaderModel::DESKTOP;
if (state.minor >= 3) {
// cubemap arrays are available as of OpenGL 4.0
#ifdef BACKEND_OPENGL_VERSION_GLES
initExtensionsGLES();
if (state.major == 3) {
assert_invariant(gets.max_texture_image_units >= 16);
assert_invariant(gets.max_combined_texture_image_units >= 32);
if (state.minor >= 1) {
features.multisample_texture = true;
// figure out our feature level
if (ext.EXT_texture_cube_map_array) {
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_2;
// figure out our feature level
if (gets.max_texture_image_units >= MAX_FRAGMENT_SAMPLER_COUNT &&
gets.max_combined_texture_image_units >=
(MAX_FRAGMENT_SAMPLER_COUNT + MAX_VERTEX_SAMPLER_COUNT)) {
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_3;
}
}
features.multisample_texture = true;
}
// feedback loops are allowed on GL desktop as long as writes are disabled
bugs.allow_read_only_ancillary_feedback_loop = true;
assert_invariant(gets.max_texture_image_units >= 16);
assert_invariant(gets.max_combined_texture_image_units >= 32);
}
#else
initExtensionsGL();
if (state.major == 4) {
assert_invariant(state.minor >= 1);
mShaderModel = ShaderModel::DESKTOP;
if (state.minor >= 3) {
// cubemap arrays are available as of OpenGL 4.0
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_2;
// figure out our feature level
if (gets.max_texture_image_units >= MAX_FRAGMENT_SAMPLER_COUNT &&
gets.max_combined_texture_image_units >=
(MAX_FRAGMENT_SAMPLER_COUNT + MAX_VERTEX_SAMPLER_COUNT)) {
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_3;
}
}
features.multisample_texture = true;
}
// feedback loops are allowed on GL desktop as long as writes are disabled
bugs.allow_read_only_ancillary_feedback_loop = true;
assert_invariant(gets.max_texture_image_units >= 16);
assert_invariant(gets.max_combined_texture_image_units >= 32);
#endif

#ifdef GL_EXT_texture_filter_anisotropic
if (ext.EXT_texture_filter_anisotropic) {
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gets.max_anisotropy);
Expand Down Expand Up @@ -337,7 +334,7 @@ void OpenGLContext::setDefaultState() noexcept {

// Point sprite size and seamless cubemap filtering are disabled by default in desktop GL.
// In OpenGL ES, these flags do not exist because they are always on.
#if BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL
#ifdef BACKEND_OPENGL_VERSION_GL
glEnable(GL_PROGRAM_POINT_SIZE);
enable(GL_PROGRAM_POINT_SIZE);
#endif
Expand All @@ -352,15 +349,15 @@ void OpenGLContext::setDefaultState() noexcept {
#endif

if (ext.EXT_clip_control) {
#if defined(GL_VERSION_4_5)
#if defined(BACKEND_OPENGL_VERSION_GL)
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
#elif defined(GL_EXT_clip_control)
glClipControlEXT(GL_LOWER_LEFT_EXT, GL_ZERO_TO_ONE_EXT);
#endif
}
}

#if defined(GL_ES_VERSION_2_0)
#ifdef BACKEND_OPENGL_VERSION_GLES

void OpenGLContext::initExtensionsGLES() noexcept {
const char * const extensions = (const char*)glGetString(GL_EXTENSIONS);
Expand Down Expand Up @@ -405,9 +402,9 @@ void OpenGLContext::initExtensionsGLES() noexcept {
}
}

#endif // defined(GL_ES_VERSION_2_0)
#endif // BACKEND_OPENGL_VERSION_GLES

#if defined(GL_VERSION_4_1)
#ifdef BACKEND_OPENGL_VERSION_GL

void OpenGLContext::initExtensionsGL() noexcept {
GLUtils::unordered_string_set exts;
Expand Down Expand Up @@ -454,7 +451,7 @@ void OpenGLContext::initExtensionsGL() noexcept {
ext.WEBGL_compressed_texture_s3tc_srgb = false;
}

#endif // defined(GL_VERSION_4_1)
#endif // BACKEND_OPENGL_VERSION_GL

void OpenGLContext::bindBuffer(GLenum target, GLuint buffer) noexcept {
if (target == GL_ELEMENT_ARRAY_BUFFER) {
Expand Down Expand Up @@ -636,7 +633,7 @@ void OpenGLContext::resetState() noexcept {
GLenum const bufferTargets[] = {
GL_UNIFORM_BUFFER,
GL_TRANSFORM_FEEDBACK_BUFFER,
#if !defined(__EMSCRIPTEN__) && (defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1))
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
GL_SHADER_STORAGE_BUFFER,
#endif
GL_ARRAY_BUFFER,
Expand Down Expand Up @@ -667,14 +664,14 @@ void OpenGLContext::resetState() noexcept {
{ GL_TEXTURE_2D_ARRAY, true },
{ GL_TEXTURE_CUBE_MAP, true },
{ GL_TEXTURE_3D, true },
#if !defined(__EMSCRIPTEN__)
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
{ GL_TEXTURE_2D_MULTISAMPLE, true },
#endif
#if !defined(__EMSCRIPTEN__)
#if defined(GL_OES_EGL_image_external)
{ GL_TEXTURE_EXTERNAL_OES, ext.OES_EGL_image_external_essl3 },
#endif
#if defined(GL_VERSION_4_1) || defined(GL_EXT_texture_cube_map_array)
#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_texture_cube_map_array)
{ GL_TEXTURE_CUBE_MAP_ARRAY, ext.EXT_texture_cube_map_array },
#endif
#endif
Expand Down
28 changes: 23 additions & 5 deletions filament/backend/src/opengl/OpenGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@ class OpenGLContext {

OpenGLContext() noexcept;

constexpr bool isAtLeastGL(int major, int minor) const noexcept {
#ifdef BACKEND_OPENGL_VERSION_GL
return state.major > major || (state.major == major && state.minor >= minor);
#else
(void)major, (void)minor;
return false;
#endif
}

constexpr bool isAtLeastGLES(int major, int minor) const noexcept {
#ifdef BACKEND_OPENGL_VERSION_GLES
return state.major > major || (state.major == major && state.minor >= minor);
#else
(void)major, (void)minor;
return false;
#endif
}

constexpr static inline size_t getIndexForTextureTarget(GLuint target) noexcept;
constexpr inline size_t getIndexForCap(GLenum cap) noexcept;
constexpr static inline size_t getIndexForBufferTarget(GLenum target) noexcept;
Expand Down Expand Up @@ -412,10 +430,10 @@ class OpenGLContext {
RenderPrimitive mDefaultVAO;

// this is chosen to minimize code size
#if defined(GL_ES_VERSION_2_0)
#if defined(BACKEND_OPENGL_VERSION_GLES)
void initExtensionsGLES() noexcept;
#endif
#if defined(GL_VERSION_4_1)
#if defined(BACKEND_OPENGL_VERSION_GL)
void initExtensionsGL() noexcept;
#endif

Expand All @@ -442,7 +460,7 @@ constexpr size_t OpenGLContext::getIndexForTextureTarget(GLuint target) noexcept
case GL_TEXTURE_2D: return 0;
case GL_TEXTURE_2D_ARRAY: return 1;
case GL_TEXTURE_CUBE_MAP: return 2;
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
case GL_TEXTURE_2D_MULTISAMPLE: return 3;
#endif
case GL_TEXTURE_EXTERNAL_OES: return 4;
Expand All @@ -468,7 +486,7 @@ constexpr size_t OpenGLContext::getIndexForCap(GLenum cap) noexcept { //NOLINT
#ifdef GL_ARB_seamless_cube_map
case GL_TEXTURE_CUBE_MAP_SEAMLESS: index = 9; break;
#endif
#if BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL
#ifdef BACKEND_OPENGL_VERSION_GL
case GL_PROGRAM_POINT_SIZE: index = 10; break;
#endif
default: break;
Expand All @@ -483,7 +501,7 @@ constexpr size_t OpenGLContext::getIndexForBufferTarget(GLenum target) noexcept
// The indexed buffers MUST be first in this list (those usable with bindBufferRange)
case GL_UNIFORM_BUFFER: index = 0; break;
case GL_TRANSFORM_FEEDBACK_BUFFER: index = 1; break;
#if defined(GL_VERSION_4_1) || defined(GL_ES_VERSION_3_1)
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
case GL_SHADER_STORAGE_BUFFER: index = 2; break;
#endif
case GL_ARRAY_BUFFER: index = 3; break;
Expand Down
Loading

0 comments on commit 9ee41b9

Please sign in to comment.