[Refactor|Fix] (...): Optimize code. Support low-version glsl es.

Signed-off-by: BZLZHH <admin@bzlzhh.top>
This commit is contained in:
BZLZHH 2025-02-07 19:24:45 +08:00
parent b416d6fbb3
commit bda63c0ed7
8 changed files with 126 additions and 60 deletions

View File

@ -24,7 +24,7 @@ void glGetIntegerv(GLenum pname, GLint *params) {
num_extensions = 0; num_extensions = 0;
while (token) { while (token) {
num_extensions++; num_extensions++;
token = strtok(NULL, " "); token = strtok(nullptr, " ");
} }
free(copy); free(copy);
} else { } else {
@ -34,7 +34,7 @@ void glGetIntegerv(GLenum pname, GLint *params) {
(*params) = num_extensions; (*params) = num_extensions;
return; return;
} }
LOAD_GLES(glGetIntegerv, void, GLenum pname, GLint *params); LOAD_GLES_FUNC(glGetIntegerv);
gles_glGetIntegerv(pname, params); gles_glGetIntegerv(pname, params);
LOG_D(" -> %d",*params); LOG_D(" -> %d",*params);
CHECK_GL_ERROR CHECK_GL_ERROR
@ -42,8 +42,12 @@ void glGetIntegerv(GLenum pname, GLint *params) {
GLenum glGetError() { GLenum glGetError() {
LOG(); LOG();
LOAD_GLES(glGetError, GLenum); LOAD_GLES_FUNC(glGetError);
return gles_glGetError(); GLuint err = gles_glGetError();
if (err != GL_NO_ERROR) {
LOG_E(" -> %d", err);
}
return err;
} }
static std::string es_ext; static std::string es_ext;
@ -80,9 +84,58 @@ void AppendExtension(const char* ext) {
es_ext += ' '; es_ext += ' ';
} }
const char* getBeforeThirdSpace(const char* str) {
static char buffer[256];
int spaceCount = 0;
const char* start = str;
while (*str) {
if (*str == ' ') {
spaceCount++;
if (spaceCount == 3) break;
}
str++;
}
int len = str - start;
if (len >= sizeof(buffer)) len = sizeof(buffer) - 1;
strncpy(buffer, start, len);
buffer[len] = '\0';
return buffer;
}
const char* getGpuName() {
LOAD_GLES_FUNC(glGetString);
const char *gpuName = (const char *) gles_glGetString(GL_RENDERER);
return gpuName ? gpuName : "<unknown>";
}
void set_es_version() {
LOAD_GLES_FUNC(glGetString);
const char* ESVersion = getBeforeThirdSpace((const char*)gles_glGetString(GL_VERSION));
int major, minor;
if (sscanf(ESVersion, "OpenGL ES %d.%d", &major, &minor) == 2) {
hardware->es_version = major * 100 + minor * 10;
} else {
hardware->es_version = 300;
}
LOG_I("OpenGL ES Version: %s (%d)", ESVersion, hardware->es_version);
if (hardware->es_version < 300) {
LOG_I("OpenGL ES version is lower than 3.0! This version is not supported!");
LOG_I("Disable glslang and SPIRV-Cross. Using vgpu to process all shaders!");
}
}
const char* getGLESName() {
LOAD_GLES_FUNC(glGetString);
char* ESVersion = (char*)gles_glGetString(GL_VERSION);
return getBeforeThirdSpace(ESVersion);
}
static std::string rendererString;
const GLubyte * glGetString( GLenum name ) { const GLubyte * glGetString( GLenum name ) {
LOG(); LOG();
LOAD_GLES(glGetString, const GLubyte *, GLenum); LOAD_GLES_FUNC(glGetString);
/* Feature in the Future /* Feature in the Future
* Advanced OpenGL driver: NV renderer. * Advanced OpenGL driver: NV renderer.
switch (name) { switch (name) {
@ -104,35 +157,42 @@ const GLubyte * glGetString( GLenum name ) {
case GL_VERSION: case GL_VERSION:
return (const GLubyte *) "4.0.0 MobileGlues"; return (const GLubyte *) "4.0.0 MobileGlues";
case GL_RENDERER: case GL_RENDERER:
return gles_glGetString(GL_RENDERER); {
if (rendererString == std::string("")) {
const char* gpuName = getGpuName();
const char* glesName = getGLESName();
rendererString = std::string(gpuName) + " | " + std::string(glesName);
}
return (const GLubyte *)rendererString.c_str();
}
case GL_SHADING_LANGUAGE_VERSION: case GL_SHADING_LANGUAGE_VERSION:
return (const GLubyte *) "4.50 MobileGlues with glslang and SPIRV-Cross"; return (const GLubyte *) "4.50 MobileGlues with glslang and SPIRV-Cross";
case GL_EXTENSIONS: case GL_EXTENSIONS:
return (const GLubyte *) GetExtensionsList(); return (const GLubyte *) GetExtensionsList();
default:
return gles_glGetString(name);
} }
return gles_glGetString(name);
} }
const GLubyte * glGetStringi(GLenum name, GLuint index) { const GLubyte * glGetStringi(GLenum name, GLuint index) {
LOG(); LOG();
LOAD_GLES(glGetStringi, const GLubyte *, GLenum, GLuint); LOAD_GLES_FUNC(glGetStringi);
typedef struct { typedef struct {
GLenum name; GLenum name;
const char** parts; const char** parts;
GLuint count; GLuint count;
} StringCache; } StringCache;
static StringCache caches[] = { static StringCache caches[] = {
{GL_EXTENSIONS, NULL, 0}, {GL_EXTENSIONS, nullptr, 0},
{GL_VENDOR, NULL, 0}, {GL_VENDOR, nullptr, 0},
{GL_VERSION, NULL, 0}, {GL_VERSION, nullptr, 0},
{GL_SHADING_LANGUAGE_VERSION, NULL, 0} {GL_SHADING_LANGUAGE_VERSION, nullptr, 0}
}; };
static int initialized = 0; static int initialized = 0;
if (!initialized) { if (!initialized) {
for (int i = 0; i < sizeof(caches)/sizeof(StringCache); i++) { for (auto & cache : caches) {
GLenum target = caches[i].name; GLenum target = cache.name;
const GLubyte* str = NULL; const GLubyte* str = nullptr;
const char* delimiter = " "; const char* delimiter = " ";
switch (target) { switch (target) {
@ -150,6 +210,8 @@ const GLubyte * glGetStringi(GLenum name, GLuint index) {
case GL_EXTENSIONS: case GL_EXTENSIONS:
str = glGetString(GL_EXTENSIONS); str = glGetString(GL_EXTENSIONS);
break; break;
default:
return gles_glGetStringi(name, index);
} }
if (!str) continue; if (!str) continue;
@ -157,23 +219,23 @@ const GLubyte * glGetStringi(GLenum name, GLuint index) {
char* copy = strdup((const char*)str); char* copy = strdup((const char*)str);
char* token = strtok(copy, delimiter); char* token = strtok(copy, delimiter);
while (token) { while (token) {
caches[i].parts = (const char**)realloc(caches[i].parts, (caches[i].count + 1) * sizeof(char*)); cache.parts = (const char**)realloc(cache.parts, (cache.count + 1) * sizeof(char*));
caches[i].parts[caches[i].count++] = strdup(token); cache.parts[cache.count++] = strdup(token);
token = strtok(NULL, delimiter); token = strtok(nullptr, delimiter);
} }
free(copy); free(copy);
} }
initialized = 1; initialized = 1;
} }
for (int i = 0; i < sizeof(caches)/sizeof(StringCache); i++) { for (auto & cache : caches) {
if (caches[i].name == name) { if (cache.name == name) {
if (index >= caches[i].count) { if (index >= cache.count) {
return NULL; return nullptr;
} }
return (const GLubyte*)caches[i].parts[index]; return (const GLubyte*)cache.parts[index];
} }
} }
return NULL; return nullptr;
} }

View File

@ -18,16 +18,13 @@ extern "C" {
#endif #endif
GLAPI GLAPIENTRY const GLubyte *glGetString(GLenum name); GLAPI GLAPIENTRY const GLubyte *glGetString(GLenum name);
GLAPI GLAPIENTRY const GLubyte *glGetStringi(GLenum name, GLuint index); GLAPI GLAPIENTRY const GLubyte *glGetStringi(GLenum name, GLuint index);
GLAPI GLAPIENTRY GLenum glGetError(); GLAPI GLAPIENTRY GLenum glGetError();
GLAPI GLAPIENTRY void glGetIntegerv(GLenum pname, GLint *params); GLAPI GLAPIENTRY void glGetIntegerv(GLenum pname, GLint *params);
void AppendExtension(const char* ext); void AppendExtension(const char* ext);
void InitGLESBaseExtensions(); void InitGLESBaseExtensions();
void set_es_version();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -550,9 +550,10 @@ char* GLSLtoGLSLES_2(char* glsl_code, GLenum glsl_type, uint essl_version) {
return result_essl; return result_essl;
} }
char * GLSLtoGLSLES_1(char* glsl_code, GLenum glsl_type) { char * GLSLtoGLSLES_1(char* glsl_code, GLenum glsl_type, unsigned int esversion) {
LOG_W("Warning: use glsl optimizer to convert shader.") LOG_W("Warning: use glsl optimizer to convert shader.")
char * result = MesaConvertShader(glsl_code, glsl_type == GL_VERTEX_SHADER ? 35633 : 35632, 460LL, 320); if (esversion < 300) esversion = 300;
char * result = MesaConvertShader(glsl_code, glsl_type == GL_VERTEX_SHADER ? 35633 : 35632, 460LL, esversion);
char * ret = (char*)malloc(sizeof(char) * strlen(result) + 1); char * ret = (char*)malloc(sizeof(char) * strlen(result) + 1);
strcpy(ret, result); strcpy(ret, result);
return ret; return ret;

View File

@ -14,7 +14,7 @@ extern "C" {
#endif #endif
#include "../mg.h" #include "../mg.h"
__attribute__((visibility("default"))) extern char *GLSLtoGLSLES_1(char *glsl_code, GLenum glsl_type); __attribute__((visibility("default"))) extern char *GLSLtoGLSLES_1(char *glsl_code, GLenum glsl_type, unsigned int esversion);
__attribute__((visibility("default"))) extern char *GLSLtoGLSLES_2(char *glsl_code, GLenum glsl_type, uint essl_version); __attribute__((visibility("default"))) extern char *GLSLtoGLSLES_2(char *glsl_code, GLenum glsl_type, uint essl_version);
__attribute__((visibility("default"))) extern int getGLSLVersion(const char* glsl_code); __attribute__((visibility("default"))) extern int getGLSLVersion(const char* glsl_code);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -6,7 +6,7 @@
#define DEBUG 0 #define DEBUG 0
hard_ext_t hard_ext; hardware_t hardware;
gl_state_t gl_state; gl_state_t gl_state;
FUNC_GL_STATE_SIZEI(proxy_width) FUNC_GL_STATE_SIZEI(proxy_width)

View File

@ -40,11 +40,11 @@ FUNC_GL_STATE_SIZEI_DECLARATION(proxy_height)
FUNC_GL_STATE_ENUM_DECLARATION(proxy_intformat) FUNC_GL_STATE_ENUM_DECLARATION(proxy_intformat)
struct hard_ext_s { struct hardware_s {
GLint maxsize; unsigned int es_version;
}; };
typedef struct hard_ext_s *hard_ext_t; typedef struct hardware_s *hardware_t;
extern hard_ext_t hard_ext; extern hardware_t hardware;
struct gl_state_s { struct gl_state_s {
GLsizei proxy_width; GLsizei proxy_width;

View File

@ -147,10 +147,14 @@ char* process_uniform_declarations(char* glslCode) {
modifiedGlslCode[modifiedCodeIndex++] = *cursor++; modifiedGlslCode[modifiedCodeIndex++] = *cursor++;
} }
if (modifiedCodeIndex >= maxLength - 1) { while (modifiedCodeIndex >= maxLength - 1) {
maxLength *= 2; maxLength *= 2;
modifiedGlslCode = (char*)realloc(modifiedGlslCode, maxLength); char* temp = (char*)realloc(modifiedGlslCode, maxLength);
if (!modifiedGlslCode) return NULL; if (!temp) {
free(modifiedGlslCode);
return NULL;
}
modifiedGlslCode = temp;
} }
} }
@ -158,13 +162,14 @@ char* process_uniform_declarations(char* glslCode) {
return modifiedGlslCode; return modifiedGlslCode;
} }
bool can_run_essl3(int esversion, const char *glsl) { bool can_run_essl3(unsigned int esversion, const char *glsl) {
int glsl_version;
if (strncmp(glsl, "#version 100", 12) == 0) { if (strncmp(glsl, "#version 100", 12) == 0) {
return true; return true;
} else if (strncmp(glsl, "#version 300 es", 15) == 0) { }
return true;
unsigned int glsl_version = 0;
if (strncmp(glsl, "#version 300 es", 15) == 0) {
glsl_version = 300;
} else if (strncmp(glsl, "#version 310 es", 15) == 0) { } else if (strncmp(glsl, "#version 310 es", 15) == 0) {
glsl_version = 310; glsl_version = 310;
} else if (strncmp(glsl, "#version 320 es", 15) == 0) { } else if (strncmp(glsl, "#version 320 es", 15) == 0) {
@ -172,17 +177,13 @@ bool can_run_essl3(int esversion, const char *glsl) {
} else { } else {
return false; return false;
} }
return esversion >= glsl_version;
if (esversion >= glsl_version) {
return true;
} else {
return false;
}
} }
bool is_direct_shader(char *glsl) bool is_direct_shader(char *glsl)
{ {
bool es3_ability = can_run_essl3(320, glsl); //Assuming it is 320 bool es3_ability = can_run_essl3(hardware->es_version, glsl);
return es3_ability; return es3_ability;
} }
@ -220,7 +221,11 @@ void glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, c
LOG_D("%s", source); LOG_D("%s", source);
GLint shaderType; GLint shaderType;
glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType); glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType);
converted = glsl_version<140?GLSLtoGLSLES_1(source, shaderType):GLSLtoGLSLES_2(source,shaderType,320); converted = glsl_version<140?GLSLtoGLSLES_1(source, shaderType, hardware->es_version):GLSLtoGLSLES_2(source,shaderType,hardware->es_version);
if (!converted) {
LOG_E("Failed to convert shader %d.", shader);
return;
}
converted = process_uniform_declarations(converted); converted = process_uniform_declarations(converted);
LOG_D("\n[INFO] [Shader] Converted Shader source: \n%s", converted); LOG_D("\n[INFO] [Shader] Converted Shader source: \n%s", converted);
} }

View File

@ -100,9 +100,9 @@ void *proc_address(void *lib, const char *name) {
return dlsym(lib, name); return dlsym(lib, name);
} }
void set_hard_ext() { void set_hardware() {
hard_ext = (hard_ext_t)calloc(1, sizeof(struct hard_ext_s)); hardware = (hardware_t)calloc(1, sizeof(struct hardware_s));
set_es_version();
} }
void init_gl_state() { void init_gl_state() {
@ -158,8 +158,6 @@ void InitGLESCapabilities() {
void init_target_gles() { void init_target_gles() {
LOG_D("Initializing %s @ %s", RENDERERNAME, __FUNCTION__); LOG_D("Initializing %s @ %s", RENDERERNAME, __FUNCTION__);
LOG_D("Initializing %s @ hard_ext", RENDERERNAME);
set_hard_ext();
LOG_D("Initializing %s @ gl_state", RENDERERNAME); LOG_D("Initializing %s @ gl_state", RENDERERNAME);
init_gl_state(); init_gl_state();
@ -528,6 +526,9 @@ void init_target_gles() {
INIT_GLES_FUNC(glMapBufferRange) INIT_GLES_FUNC(glMapBufferRange)
INIT_GLES_FUNC(glBufferStorageEXT) INIT_GLES_FUNC(glBufferStorageEXT)
LOG_D("Initializing %s @ hardware", RENDERERNAME);
set_hardware();
InitGLESCapabilities(); InitGLESCapabilities();
LogOpenGLExtensions(); LogOpenGLExtensions();
} }