Permalink
Browse files

Merge pull request #11418 from unknownbrackets/gl-lookup

GLES: Properly parse GL extension names
  • Loading branch information...
hrydgard committed Sep 25, 2018
2 parents 68b005c + d1929ea commit e263b3af85b17c54becedd06943743ffde0ce9f6
@@ -818,7 +818,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
if (!isModeThrough) {
WRITE(p, " float3 projPos = outPos.xyz / outPos.w;\n");
// Vertex range culling doesn't happen when depth is clamped, so only do this if in range.
WRITE(p, " if (u_cullRangeMin.w <= 0.0f || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");
const char *outMin = "projPos.x < u_cullRangeMin.x || projPos.y < u_cullRangeMin.y || projPos.z < u_cullRangeMin.z";
const char *outMax = "projPos.x > u_cullRangeMax.x || projPos.y > u_cullRangeMax.y || projPos.z > u_cullRangeMax.z";
WRITE(p, " if (%s || %s) {\n", outMin, outMax);
@@ -912,7 +912,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
if (!isModeThrough) {
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
// Vertex range culling doesn't happen when depth is clamped, so only do this if in range.
WRITE(p, " if (u_cullRangeMin.w <= 0.0f || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");
const char *outMin = "projPos.x < u_cullRangeMin.x || projPos.y < u_cullRangeMin.y || projPos.z < u_cullRangeMin.z";
const char *outMax = "projPos.x > u_cullRangeMax.x || projPos.y > u_cullRangeMax.y || projPos.z > u_cullRangeMax.z";
WRITE(p, " if (%s || %s) {\n", outMin, outMax);
@@ -698,7 +698,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
if (!isModeThrough) {
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
// Vertex range culling doesn't happen when depth is clamped, so only do this if in range.
WRITE(p, " if (base.cullRangeMin.w <= 0.0f || (projPos.z >= base.cullRangeMin.z && projPos.z <= base.cullRangeMax.z)) {\n");
WRITE(p, " if (base.cullRangeMin.w <= 0.0 || (projPos.z >= base.cullRangeMin.z && projPos.z <= base.cullRangeMax.z)) {\n");
const char *outMin = "projPos.x < base.cullRangeMin.x || projPos.y < base.cullRangeMin.y || projPos.z < base.cullRangeMin.z";
const char *outMax = "projPos.x > base.cullRangeMax.x || projPos.y > base.cullRangeMax.y || projPos.z > base.cullRangeMax.z";
WRITE(p, " if (%s || %s) {\n", outMin, outMax);
@@ -1,6 +1,7 @@
#include "ppsspp_config.h"
#include <cstring>
#include <set>
#include "base/logging.h"
#include "base/stringutil.h"
@@ -37,11 +38,32 @@ PFNGLISVERTEXARRAYOESPROC glIsVertexArrayOES;
GLExtensions gl_extensions;
std::string g_all_gl_extensions;
std::set<std::string> g_set_gl_extensions;
std::string g_all_egl_extensions;
std::set<std::string> g_set_egl_extensions;
static bool extensionsDone = false;
static bool useCoreContext = false;
static void ParseExtensionsString(const std::string& str, std::set<std::string> &output) {
output.clear();
size_t next = 0;
for (size_t pos = 0, len = str.length(); pos < len; ++pos) {
if (str[pos] == ' ') {
output.insert(str.substr(next, pos - next));
// Skip the delimiter itself.
next = pos + 1;
}
}
if (next == 0 && str.length() != 0) {
output.insert(str);
} else if (next < str.length()) {
output.insert(str.substr(next));
}
}
bool GLExtensions::VersionGEThan(int major, int minor, int sub) {
if (gl_extensions.ver[0] > major)
return true;
@@ -275,32 +297,28 @@ void CheckGLExtensions() {
// Let's use the new way for OpenGL 3.x+, required in the core profile.
GLint numExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
g_all_gl_extensions = "";
g_all_gl_extensions.clear();
g_set_gl_extensions.clear();
for (GLint i = 0; i < numExtensions; ++i) {
g_all_gl_extensions += (const char *)glGetStringi(GL_EXTENSIONS, i);
const char *ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
g_set_gl_extensions.insert(ext);
g_all_gl_extensions += ext;
g_all_gl_extensions += " ";
}
extString = g_all_gl_extensions.c_str();
} else {
extString = (const char *)glGetString(GL_EXTENSIONS);
if (extString) {
g_all_gl_extensions = extString;
} else {
g_all_gl_extensions = "";
extString = "";
}
g_all_gl_extensions = extString ? extString : "";
ParseExtensionsString(g_all_gl_extensions, g_set_gl_extensions);
}
#ifdef WIN32
const char *wglString = 0;
if (wglGetExtensionsStringEXT)
wglString = wglGetExtensionsStringEXT();
if (wglString) {
gl_extensions.EXT_swap_control_tear = strstr(wglString, "WGL_EXT_swap_control_tear") != 0;
g_all_egl_extensions = wglString;
} else {
g_all_egl_extensions = "";
}
g_all_egl_extensions = wglString ? wglString : "";
ParseExtensionsString(g_all_egl_extensions, g_set_egl_extensions);
gl_extensions.EXT_swap_control_tear = g_set_egl_extensions.count("WGL_EXT_swap_control_tear") != 0;
#elif !defined(USING_GLES2)
// const char *glXString = glXQueryExtensionString();
// gl_extensions.EXT_swap_control_tear = strstr(glXString, "GLX_EXT_swap_control_tear") != 0;
@@ -309,41 +327,41 @@ void CheckGLExtensions() {
// Check the desktop extension instead of the OES one. They are very similar.
// Also explicitly check those ATI devices that claims to support npot
if (renderer) {
gl_extensions.OES_texture_npot = strstr(extString, "GL_ARB_texture_non_power_of_two") != 0
gl_extensions.OES_texture_npot = g_set_gl_extensions.count("GL_ARB_texture_non_power_of_two") != 0
&& !(((strncmp(renderer, "ATI RADEON X", 12) == 0) || (strncmp(renderer, "ATI MOBILITY RADEON X", 21) == 0)));
}
gl_extensions.ARB_blend_func_extended = strstr(extString, "GL_ARB_blend_func_extended") != 0;
gl_extensions.EXT_blend_func_extended = strstr(extString, "GL_EXT_blend_func_extended") != 0;
gl_extensions.ARB_conservative_depth = strstr(extString, "GL_ARB_conservative_depth") != 0;
gl_extensions.ARB_shader_image_load_store = (strstr(extString, "GL_ARB_shader_image_load_store") != 0) || (strstr(extString, "GL_EXT_shader_image_load_store") != 0);
gl_extensions.EXT_bgra = strstr(extString, "GL_EXT_bgra") != 0;
gl_extensions.EXT_gpu_shader4 = strstr(extString, "GL_EXT_gpu_shader4") != 0;
gl_extensions.NV_framebuffer_blit = strstr(extString, "GL_NV_framebuffer_blit") != 0;
gl_extensions.NV_copy_image = strstr(extString, "GL_NV_copy_image") != 0;
gl_extensions.OES_copy_image = strstr(extString, "GL_OES_copy_image") != 0;
gl_extensions.EXT_copy_image = strstr(extString, "GL_EXT_copy_image") != 0;
gl_extensions.ARB_copy_image = strstr(extString, "GL_ARB_copy_image") != 0;
gl_extensions.ARB_buffer_storage = strstr(extString, "GL_ARB_buffer_storage") != 0;
gl_extensions.ARB_vertex_array_object = strstr(extString, "GL_ARB_vertex_array_object") != 0;
gl_extensions.ARB_texture_float = strstr(extString, "GL_ARB_texture_float") != 0;
gl_extensions.EXT_texture_filter_anisotropic = strstr(extString, "GL_EXT_texture_filter_anisotropic") != 0;
gl_extensions.EXT_draw_instanced = strstr(extString, "GL_EXT_draw_instanced") != 0;
gl_extensions.ARB_draw_instanced = strstr(extString, "GL_ARB_draw_instanced") != 0;
gl_extensions.ARB_blend_func_extended = g_set_gl_extensions.count("GL_ARB_blend_func_extended") != 0;
gl_extensions.EXT_blend_func_extended = g_set_gl_extensions.count("GL_EXT_blend_func_extended") != 0;
gl_extensions.ARB_conservative_depth = g_set_gl_extensions.count("GL_ARB_conservative_depth") != 0;
gl_extensions.ARB_shader_image_load_store = (g_set_gl_extensions.count("GL_ARB_shader_image_load_store") != 0) || (g_set_gl_extensions.count("GL_EXT_shader_image_load_store") != 0);
gl_extensions.EXT_bgra = g_set_gl_extensions.count("GL_EXT_bgra") != 0;
gl_extensions.EXT_gpu_shader4 = g_set_gl_extensions.count("GL_EXT_gpu_shader4") != 0;
gl_extensions.NV_framebuffer_blit = g_set_gl_extensions.count("GL_NV_framebuffer_blit") != 0;
gl_extensions.NV_copy_image = g_set_gl_extensions.count("GL_NV_copy_image") != 0;
gl_extensions.OES_copy_image = g_set_gl_extensions.count("GL_OES_copy_image") != 0;
gl_extensions.EXT_copy_image = g_set_gl_extensions.count("GL_EXT_copy_image") != 0;
gl_extensions.ARB_copy_image = g_set_gl_extensions.count("GL_ARB_copy_image") != 0;
gl_extensions.ARB_buffer_storage = g_set_gl_extensions.count("GL_ARB_buffer_storage") != 0;
gl_extensions.ARB_vertex_array_object = g_set_gl_extensions.count("GL_ARB_vertex_array_object") != 0;
gl_extensions.ARB_texture_float = g_set_gl_extensions.count("GL_ARB_texture_float") != 0;
gl_extensions.EXT_texture_filter_anisotropic = g_set_gl_extensions.count("GL_EXT_texture_filter_anisotropic") != 0;
gl_extensions.EXT_draw_instanced = g_set_gl_extensions.count("GL_EXT_draw_instanced") != 0;
gl_extensions.ARB_draw_instanced = g_set_gl_extensions.count("GL_ARB_draw_instanced") != 0;
if (gl_extensions.IsGLES) {
gl_extensions.OES_texture_npot = strstr(extString, "GL_OES_texture_npot") != 0;
gl_extensions.OES_packed_depth_stencil = (strstr(extString, "GL_OES_packed_depth_stencil") != 0) || gl_extensions.GLES3;
gl_extensions.OES_depth24 = strstr(extString, "GL_OES_depth24") != 0;
gl_extensions.OES_depth_texture = strstr(extString, "GL_OES_depth_texture") != 0;
gl_extensions.OES_mapbuffer = strstr(extString, "GL_OES_mapbuffer") != 0;
gl_extensions.EXT_blend_minmax = strstr(extString, "GL_EXT_blend_minmax") != 0;
gl_extensions.EXT_unpack_subimage = strstr(extString, "GL_EXT_unpack_subimage") != 0;
gl_extensions.EXT_shader_framebuffer_fetch = strstr(extString, "GL_EXT_shader_framebuffer_fetch") != 0;
gl_extensions.NV_shader_framebuffer_fetch = strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0;
gl_extensions.ARM_shader_framebuffer_fetch = strstr(extString, "GL_ARM_shader_framebuffer_fetch") != 0;
gl_extensions.OES_texture_float = strstr(extString, "GL_OES_texture_float") != 0;
gl_extensions.EXT_buffer_storage = strstr(extString, "GL_EXT_buffer_storage") != 0;
gl_extensions.OES_texture_npot = g_set_gl_extensions.count("GL_OES_texture_npot") != 0;
gl_extensions.OES_packed_depth_stencil = (g_set_gl_extensions.count("GL_OES_packed_depth_stencil") != 0) || gl_extensions.GLES3;
gl_extensions.OES_depth24 = g_set_gl_extensions.count("GL_OES_depth24") != 0;
gl_extensions.OES_depth_texture = g_set_gl_extensions.count("GL_OES_depth_texture") != 0;
gl_extensions.OES_mapbuffer = g_set_gl_extensions.count("GL_OES_mapbuffer") != 0;
gl_extensions.EXT_blend_minmax = g_set_gl_extensions.count("GL_EXT_blend_minmax") != 0;
gl_extensions.EXT_unpack_subimage = g_set_gl_extensions.count("GL_EXT_unpack_subimage") != 0;
gl_extensions.EXT_shader_framebuffer_fetch = g_set_gl_extensions.count("GL_EXT_shader_framebuffer_fetch") != 0;
gl_extensions.NV_shader_framebuffer_fetch = g_set_gl_extensions.count("GL_NV_shader_framebuffer_fetch") != 0;
gl_extensions.ARM_shader_framebuffer_fetch = g_set_gl_extensions.count("GL_ARM_shader_framebuffer_fetch") != 0;
gl_extensions.OES_texture_float = g_set_gl_extensions.count("GL_OES_texture_float") != 0;
gl_extensions.EXT_buffer_storage = g_set_gl_extensions.count("GL_EXT_buffer_storage") != 0;
#if defined(__ANDROID__)
// On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though.
@@ -367,7 +385,7 @@ void CheckGLExtensions() {
glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)eglGetProcAddress("glBlitFramebufferNV");
}
gl_extensions.OES_vertex_array_object = strstr(extString, "GL_OES_vertex_array_object") != 0;
gl_extensions.OES_vertex_array_object = g_set_gl_extensions.count("GL_OES_vertex_array_object") != 0;
if (gl_extensions.OES_vertex_array_object) {
glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
@@ -376,7 +394,7 @@ void CheckGLExtensions() {
}
// Hm, this should be available on iOS too.
gl_extensions.EXT_discard_framebuffer = strstr(extString, "GL_EXT_discard_framebuffer") != 0;
gl_extensions.EXT_discard_framebuffer = g_set_gl_extensions.count("GL_EXT_discard_framebuffer") != 0;
if (gl_extensions.EXT_discard_framebuffer) {
glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)eglGetProcAddress("glDiscardFramebufferEXT");
}
@@ -405,35 +423,34 @@ void CheckGLExtensions() {
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
const char *eglString = eglQueryString(display, EGL_EXTENSIONS);
if (eglString) {
g_all_egl_extensions = eglString;
g_all_egl_extensions = eglString ? eglString : "";
ParseExtensionsString(g_all_egl_extensions, g_set_egl_extensions);
gl_extensions.EGL_NV_system_time = strstr(eglString, "EGL_NV_system_time") != 0;
gl_extensions.EGL_NV_coverage_sample = strstr(eglString, "EGL_NV_coverage_sample") != 0;
gl_extensions.EGL_NV_system_time = g_set_egl_extensions.count("EGL_NV_system_time") != 0;
gl_extensions.EGL_NV_coverage_sample = g_set_egl_extensions.count("EGL_NV_coverage_sample") != 0;
if (gl_extensions.EGL_NV_system_time) {
eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)eglGetProcAddress("eglGetSystemTimeNV");
eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)eglGetProcAddress("eglGetSystemTimeFrequencyNV");
}
} else {
g_all_egl_extensions = "";
if (gl_extensions.EGL_NV_system_time) {
eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)eglGetProcAddress("eglGetSystemTimeNV");
eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)eglGetProcAddress("eglGetSystemTimeFrequencyNV");
}
#elif defined(USING_GLES2) && defined(__linux__)
const char *eglString = eglQueryString(NULL, EGL_EXTENSIONS);
g_all_egl_extensions = eglString ? eglString : "";
if (eglString) {
g_all_egl_extensions = std::string(eglString);
g_all_egl_extensions.append(" ");
g_all_egl_extensions.append(eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS));
} else {
g_all_egl_extensions = "";
eglString = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
if (eglString) {
g_all_egl_extensions.append(" ");
g_all_egl_extensions.append(eglString);
}
}
ParseExtensionsString(g_all_egl_extensions, g_set_egl_extensions);
#endif
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &gl_extensions.maxVertexTextureUnits);
#ifdef GL_LOW_FLOAT
// This is probably a waste of time, implementations lie.
if (gl_extensions.IsGLES || strstr(extString, "GL_ARB_ES2_compatibility") || gl_extensions.VersionGEThan(4, 1)) {
if (gl_extensions.IsGLES || g_set_gl_extensions.count("GL_ARB_ES2_compatibility") || gl_extensions.VersionGEThan(4, 1)) {
const GLint precisions[6] = {
GL_LOW_FLOAT, GL_MEDIUM_FLOAT, GL_HIGH_FLOAT,
GL_LOW_INT, GL_MEDIUM_INT, GL_HIGH_INT
@@ -449,10 +466,10 @@ void CheckGLExtensions() {
}
#endif
gl_extensions.ARB_framebuffer_object = strstr(extString, "GL_ARB_framebuffer_object") != 0;
gl_extensions.EXT_framebuffer_object = strstr(extString, "GL_EXT_framebuffer_object") != 0;
gl_extensions.ARB_pixel_buffer_object = strstr(extString, "GL_ARB_pixel_buffer_object") != 0;
gl_extensions.NV_pixel_buffer_object = strstr(extString, "GL_NV_pixel_buffer_object") != 0;
gl_extensions.ARB_framebuffer_object = g_set_gl_extensions.count("GL_ARB_framebuffer_object") != 0;
gl_extensions.EXT_framebuffer_object = g_set_gl_extensions.count("GL_EXT_framebuffer_object") != 0;
gl_extensions.ARB_pixel_buffer_object = g_set_gl_extensions.count("GL_ARB_pixel_buffer_object") != 0;
gl_extensions.NV_pixel_buffer_object = g_set_gl_extensions.count("GL_NV_pixel_buffer_object") != 0;
if (!gl_extensions.IsGLES && gl_extensions.IsCoreContext) {
// These are required, and don't need to be specified by the driver (they aren't on Apple.)

0 comments on commit e263b3a

Please sign in to comment.