From 447b1b09e3e141003d0170cb5c51e3e32f1ddb00 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 26 Aug 2015 00:09:32 -0500 Subject: [PATCH] Support OpenGL ES 3.2. OpenGL ES 3.2 adds a few things we care about supporting in core. In particular: - GL_{ARB,EXT,OES}_draw_elements_base_vertex - KHR_Debug - Sample Shading - GL_{ARB,EXT,OES,NV}_copy_image - Geometry shaders - Geometry shader instancing (If they support GL_{EXT,OES}_geometry_point_size) Nvidia was the first to release an OpenGL ES 3.2 driver which I uesd to test this on. This also enables GS Instancing on GLES 3.1 hardware if it supports all of the required extensions. --- .../OGL/GLExtensions/ARB_sample_shading.h | 2 +- .../OGL/GLExtensions/GLExtensions.cpp | 76 ++++++++++++++----- .../VideoBackends/OGL/ProgramShaderCache.cpp | 13 +++- Source/Core/VideoBackends/OGL/Render.cpp | 23 +++++- Source/Core/VideoBackends/OGL/Render.h | 2 + 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/GLExtensions/ARB_sample_shading.h b/Source/Core/VideoBackends/OGL/GLExtensions/ARB_sample_shading.h index 9572ecc0c8..21ec073fc0 100644 --- a/Source/Core/VideoBackends/OGL/GLExtensions/ARB_sample_shading.h +++ b/Source/Core/VideoBackends/OGL/GLExtensions/ARB_sample_shading.h @@ -4,5 +4,5 @@ #include "VideoBackends/OGL/GLExtensions/gl_common.h" -extern PFNGLMINSAMPLESHADINGARBPROC glMinSampleShadingARB; +extern PFNGLMINSAMPLESHADINGARBPROC glMinSampleShading; diff --git a/Source/Core/VideoBackends/OGL/GLExtensions/GLExtensions.cpp b/Source/Core/VideoBackends/OGL/GLExtensions/GLExtensions.cpp index 75988b09c6..08b7bad5c3 100644 --- a/Source/Core/VideoBackends/OGL/GLExtensions/GLExtensions.cpp +++ b/Source/Core/VideoBackends/OGL/GLExtensions/GLExtensions.cpp @@ -752,7 +752,7 @@ PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glDrawRangeElementsBaseVertex; PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertex; // ARB_sample_shading -PFNGLMINSAMPLESHADINGARBPROC glMinSampleShadingARB; +PFNGLMINSAMPLESHADINGARBPROC glMinSampleShading; // ARB_debug_output PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; @@ -1229,7 +1229,7 @@ const GLFunc gl_function_array[] = GLFUNC_SUFFIX(glMultiDrawElementsBaseVertex, EXT, "GL_EXT_draw_elements_base_vertex GL_EXT_multi_draw_arrays !GL_OES_draw_elements_base_vertex !GL_ARB_draw_elements_base_vertex"), // ARB_sample_shading - GLFUNC_REQUIRES(glMinSampleShadingARB, "GL_ARB_sample_shading"), + GLFUNC_SUFFIX(glMinSampleShading, ARB, "GL_ARB_sample_shading"), // ARB_debug_output GLFUNC_REQUIRES(glDebugMessageCallbackARB, "GL_ARB_debug_output"), @@ -1285,13 +1285,27 @@ const GLFunc gl_function_array[] = GLFUNC_REQUIRES(glCopyImageSubData, "GL_ARB_copy_image"), // NV_copy_image - GLFUNC_SUFFIX(glCopyImageSubData, NV, "GL_NV_copy_image !GL_ARB_copy_image"), + GLFUNC_SUFFIX(glCopyImageSubData, NV, "GL_NV_copy_image !GL_ARB_copy_image !VERSION_GLES_3_2"), // OES_copy_image - GLFUNC_SUFFIX(glCopyImageSubData, OES, "GL_OES_copy_image"), + GLFUNC_SUFFIX(glCopyImageSubData, OES, "GL_OES_copy_image !VERSION_GLES_3_2"), // EXT_copy_image - GLFUNC_SUFFIX(glCopyImageSubData, EXT, "GL_EXT_copy_image !GL_OES_copy_image"), + GLFUNC_SUFFIX(glCopyImageSubData, EXT, "GL_EXT_copy_image !GL_OES_copy_image !VERSION_GLES_3_2"), + + // GLES 3.2 + GLFUNC_REQUIRES(glMinSampleShading, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glDebugMessageCallback, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glDebugMessageControl, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glDebugMessageInsert, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glGetDebugMessageLog, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glGetObjectLabel, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glGetObjectPtrLabel, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glObjectLabel, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glObjectPtrLabel, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glPopDebugGroup, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glPushDebugGroup, "VERSION_GLES_3_2"), + GLFUNC_REQUIRES(glCopyImageSubData, "VERSION_GLES_3_2"), // gl_1_1 // OpenGL 1.1 is at the end due to a bug in Android's EGL stack. @@ -1641,6 +1655,7 @@ namespace GLExtensions static bool _isES3; static bool _isES; static u32 _GLVersion; + static u32 _GLESVersion; static std::unordered_map m_extension_list; // Private initialization functions @@ -1663,21 +1678,39 @@ namespace GLExtensions if (_isES3) { // XXX: Add all extensions that a base ES3 implementation supports - std::string gles3exts[] = { - "GL_ARB_uniform_buffer_object", - "GL_ARB_sampler_objects", - "GL_ARB_map_buffer_range", - "GL_ARB_vertex_array_object", - "GL_ARB_framebuffer_object", - "GL_ARB_occlusion_query", - "GL_ARB_get_program_binary", - "GL_ARB_sync", - "GL_ARB_ES2_compatibility", - "VERSION_GLES3", - "VERSION_3_0", - }; - for (auto it : gles3exts) - m_extension_list[it] = true; + switch (_GLESVersion) + { + default: + case 320: + { + std::string gles320exts[] = { + "GL_ARB_draw_elements_base_vertex", + "VERSION_GLES_3_2", + }; + for (auto it : gles320exts) + m_extension_list[it] = true; + } + case 310: + case 300: + { + std::string gles3exts[] = { + "GL_ARB_uniform_buffer_object", + "GL_ARB_sampler_objects", + "GL_ARB_map_buffer_range", + "GL_ARB_vertex_array_object", + "GL_ARB_framebuffer_object", + "GL_ARB_occlusion_query", + "GL_ARB_get_program_binary", + "GL_ARB_sync", + "GL_ARB_ES2_compatibility", + "VERSION_GLES3", + "VERSION_3_0", + }; + for (auto it : gles3exts) + m_extension_list[it] = true; + } + break; + } } else if (!_isES) { @@ -1920,7 +1953,10 @@ namespace GLExtensions else _GLVersion = 210; if (_isES3) + { + _GLESVersion = _GLVersion; _GLVersion = 330; // Get all the fun things + } } static void* GetFuncAddress(const std::string& name, void **func) diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 767e98f1b6..22e86cfe42 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -50,6 +50,8 @@ static std::string GetGLSLVersionString() return "#version 300 es"; case GLSLES_310: return "#version 310 es"; + case GLSLES_320: + return "#version 320 es"; case GLSL_130: return "#version 130"; case GLSL_140: @@ -521,6 +523,13 @@ void ProgramShaderCache::CreateHeader() { GLSL_VERSION v = g_ogl_config.eSupportedGLSLVersion; bool is_glsles = v >= GLSLES_300; + std::string SupportedESPointSize; + switch (g_ogl_config.SupportedESPointSize) + { + case 1: SupportedESPointSize = "#extension GL_OES_geometry_point_size : enable"; break; + case 2: SupportedESPointSize = "#extension GL_EXT_geometry_point_size : enable"; break; + default: SupportedESPointSize = ""; break; + } snprintf(s_glsl_header, sizeof(s_glsl_header), "%s\n" @@ -532,6 +541,7 @@ void ProgramShaderCache::CreateHeader() "%s\n" // Sampler binding "%s\n" // storage buffer "%s\n" // shader5 + "%s\n" // Geometry point size "%s\n" // AEP "%s\n" // texture buffer @@ -567,7 +577,8 @@ void ProgramShaderCache::CreateHeader() , (g_ogl_config.bSupportSampleShading) ? "#extension GL_ARB_sample_shading : enable" : "" , g_ActiveConfig.backend_info.bSupportsBindingLayout ? "#define SAMPLER_BINDING(x) layout(binding = x)" : "#define SAMPLER_BINDING(x)" , g_ActiveConfig.backend_info.bSupportsBBox ? "#extension GL_ARB_shader_storage_buffer_object : enable" : "" - , g_ActiveConfig.backend_info.bSupportsGSInstancing ? "#extension GL_ARB_gpu_shader5 : enable" : "" + , !is_glsles && g_ActiveConfig.backend_info.bSupportsGSInstancing ? "#extension GL_ARB_gpu_shader5 : enable" : "" + , SupportedESPointSize.c_str() , g_ogl_config.bSupportsAEP ? "#extension GL_ANDROID_extension_pack_es31a : enable" : "" , v(s_MSAASamples); - glMinSampleShadingARB(min_sample_shading_value); + glMinSampleShading(min_sample_shading_value); } else { @@ -491,25 +491,42 @@ Renderer::Renderer() g_ogl_config.bSupportSampleShading = GLExtensions::Supports("GL_ARB_sample_shading"); g_ogl_config.bSupportOGL31 = GLExtensions::Version() >= 310; g_ogl_config.bSupportViewportFloat = GLExtensions::Supports("GL_ARB_viewport_array"); - g_ogl_config.bSupportsDebug = GLExtensions::Supports("GL_KHR_debug") || GLExtensions::Supports("GL_ARB_debug_output"); + g_ogl_config.bSupportsDebug = GLExtensions::Supports("GL_KHR_debug") || + GLExtensions::Supports("GL_ARB_debug_output"); if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3) { + g_ogl_config.SupportedESPointSize = GLExtensions::Supports("GL_OES_geometry_point_size") ? 1 : GLExtensions::Supports("GL_EXT_geometry_point_size") ? 2 : 0; + if (strstr(g_ogl_config.glsl_version, "3.0") || DriverDetails::HasBug(DriverDetails::BUG_BROKENGLES31)) { g_ogl_config.eSupportedGLSLVersion = GLSLES_300; g_ogl_config.bSupportsAEP = false; g_Config.backend_info.bSupportsGeometryShaders = false; } - else + else if (strstr(g_ogl_config.glsl_version, "3.1")) { g_ogl_config.eSupportedGLSLVersion = GLSLES_310; g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a"); g_Config.backend_info.bSupportsBindingLayout = true; g_Config.backend_info.bSupportsEarlyZ = true; g_Config.backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP; + g_Config.backend_info.bSupportsGSInstancing = g_Config.backend_info.bSupportsGeometryShaders && g_ogl_config.SupportedESPointSize > 0; //g_Config.backend_info.bSupportsPaletteConversion = GLExtensions::Supports("GL_EXT_texture_buffer"); } + else + { + g_ogl_config.eSupportedGLSLVersion = GLSLES_320; + g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a"); + g_Config.backend_info.bSupportsBindingLayout = true; + g_Config.backend_info.bSupportsEarlyZ = true; + g_Config.backend_info.bSupportsGeometryShaders = true; + g_Config.backend_info.bSupportsGSInstancing = g_ogl_config.SupportedESPointSize > 0; + g_ogl_config.bSupportsCopySubImage = true; + g_ogl_config.bSupportsGLBaseVertex = true; + g_ogl_config.bSupportSampleShading = true; + g_ogl_config.bSupportsDebug = true; + } } else { diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 78f8a76ead..16e1628204 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -19,6 +19,7 @@ enum GLSL_VERSION GLSL_150, // and above GLSLES_300, // GLES 3.0 GLSLES_310, // GLES 3.1 + GLSLES_320, // GLES 3.2 }; // ogl-only config, so not in VideoConfig.h @@ -37,6 +38,7 @@ struct VideoConfig bool bSupportsAEP; bool bSupportsDebug; bool bSupportsCopySubImage; + u8 SupportedESPointSize; const char* gl_vendor; const char* gl_renderer;