[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;
while (token) {
num_extensions++;
token = strtok(NULL, " ");
token = strtok(nullptr, " ");
}
free(copy);
} else {
@ -34,7 +34,7 @@ void glGetIntegerv(GLenum pname, GLint *params) {
(*params) = num_extensions;
return;
}
LOAD_GLES(glGetIntegerv, void, GLenum pname, GLint *params);
LOAD_GLES_FUNC(glGetIntegerv);
gles_glGetIntegerv(pname, params);
LOG_D(" -> %d",*params);
CHECK_GL_ERROR
@ -42,8 +42,12 @@ void glGetIntegerv(GLenum pname, GLint *params) {
GLenum glGetError() {
LOG();
LOAD_GLES(glGetError, GLenum);
return gles_glGetError();
LOAD_GLES_FUNC(glGetError);
GLuint err = gles_glGetError();
if (err != GL_NO_ERROR) {
LOG_E(" -> %d", err);
}
return err;
}
static std::string es_ext;
@ -80,9 +84,58 @@ void AppendExtension(const char* 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 ) {
LOG();
LOAD_GLES(glGetString, const GLubyte *, GLenum);
LOAD_GLES_FUNC(glGetString);
/* Feature in the Future
* Advanced OpenGL driver: NV renderer.
switch (name) {
@ -103,36 +156,43 @@ const GLubyte * glGetString( GLenum name ) {
return (const GLubyte *) "Swung0x48, BZLZHH, Tungsten";
case GL_VERSION:
return (const GLubyte *) "4.0.0 MobileGlues";
case GL_RENDERER:
return gles_glGetString(GL_RENDERER);
case 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:
return (const GLubyte *) "4.50 MobileGlues with glslang and SPIRV-Cross";
case GL_EXTENSIONS:
return (const GLubyte *) GetExtensionsList();
default:
return gles_glGetString(name);
}
return gles_glGetString(name);
}
const GLubyte * glGetStringi(GLenum name, GLuint index) {
LOG();
LOAD_GLES(glGetStringi, const GLubyte *, GLenum, GLuint);
LOAD_GLES_FUNC(glGetStringi);
typedef struct {
GLenum name;
const char** parts;
GLuint count;
} StringCache;
static StringCache caches[] = {
{GL_EXTENSIONS, NULL, 0},
{GL_VENDOR, NULL, 0},
{GL_VERSION, NULL, 0},
{GL_SHADING_LANGUAGE_VERSION, NULL, 0}
{GL_EXTENSIONS, nullptr, 0},
{GL_VENDOR, nullptr, 0},
{GL_VERSION, nullptr, 0},
{GL_SHADING_LANGUAGE_VERSION, nullptr, 0}
};
static int initialized = 0;
if (!initialized) {
for (int i = 0; i < sizeof(caches)/sizeof(StringCache); i++) {
GLenum target = caches[i].name;
const GLubyte* str = NULL;
for (auto & cache : caches) {
GLenum target = cache.name;
const GLubyte* str = nullptr;
const char* delimiter = " ";
switch (target) {
@ -150,6 +210,8 @@ const GLubyte * glGetStringi(GLenum name, GLuint index) {
case GL_EXTENSIONS:
str = glGetString(GL_EXTENSIONS);
break;
default:
return gles_glGetStringi(name, index);
}
if (!str) continue;
@ -157,23 +219,23 @@ const GLubyte * glGetStringi(GLenum name, GLuint index) {
char* copy = strdup((const char*)str);
char* token = strtok(copy, delimiter);
while (token) {
caches[i].parts = (const char**)realloc(caches[i].parts, (caches[i].count + 1) * sizeof(char*));
caches[i].parts[caches[i].count++] = strdup(token);
token = strtok(NULL, delimiter);
cache.parts = (const char**)realloc(cache.parts, (cache.count + 1) * sizeof(char*));
cache.parts[cache.count++] = strdup(token);
token = strtok(nullptr, delimiter);
}
free(copy);
}
initialized = 1;
}
for (int i = 0; i < sizeof(caches)/sizeof(StringCache); i++) {
if (caches[i].name == name) {
if (index >= caches[i].count) {
return NULL;
for (auto & cache : caches) {
if (cache.name == name) {
if (index >= cache.count) {
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
GLAPI GLAPIENTRY const GLubyte *glGetString(GLenum name);
GLAPI GLAPIENTRY const GLubyte *glGetStringi(GLenum name, GLuint index);
GLAPI GLAPIENTRY GLenum glGetError();
GLAPI GLAPIENTRY void glGetIntegerv(GLenum pname, GLint *params);
void AppendExtension(const char* ext);
void InitGLESBaseExtensions();
void set_es_version();
#ifdef __cplusplus
}

View File

@ -550,9 +550,10 @@ char* GLSLtoGLSLES_2(char* glsl_code, GLenum glsl_type, uint essl_version) {
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.")
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);
strcpy(ret, result);
return ret;

View File

@ -14,7 +14,7 @@ extern "C" {
#endif
#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 int getGLSLVersion(const char* glsl_code);
#ifdef __cplusplus

View File

@ -6,7 +6,7 @@
#define DEBUG 0
hard_ext_t hard_ext;
hardware_t hardware;
gl_state_t gl_state;
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)
struct hard_ext_s {
GLint maxsize;
struct hardware_s {
unsigned int es_version;
};
typedef struct hard_ext_s *hard_ext_t;
extern hard_ext_t hard_ext;
typedef struct hardware_s *hardware_t;
extern hardware_t hardware;
struct gl_state_s {
GLsizei proxy_width;

View File

@ -147,10 +147,14 @@ char* process_uniform_declarations(char* glslCode) {
modifiedGlslCode[modifiedCodeIndex++] = *cursor++;
}
if (modifiedCodeIndex >= maxLength - 1) {
while (modifiedCodeIndex >= maxLength - 1) {
maxLength *= 2;
modifiedGlslCode = (char*)realloc(modifiedGlslCode, maxLength);
if (!modifiedGlslCode) return NULL;
char* temp = (char*)realloc(modifiedGlslCode, maxLength);
if (!temp) {
free(modifiedGlslCode);
return NULL;
}
modifiedGlslCode = temp;
}
}
@ -158,13 +162,14 @@ char* process_uniform_declarations(char* glslCode) {
return modifiedGlslCode;
}
bool can_run_essl3(int esversion, const char *glsl) {
int glsl_version;
bool can_run_essl3(unsigned int esversion, const char *glsl) {
if (strncmp(glsl, "#version 100", 12) == 0) {
return true;
} else if (strncmp(glsl, "#version 300 es", 15) == 0) {
return true;
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) {
glsl_version = 310;
} else if (strncmp(glsl, "#version 320 es", 15) == 0) {
@ -172,17 +177,13 @@ bool can_run_essl3(int esversion, const char *glsl) {
} else {
return false;
}
if (esversion >= glsl_version) {
return true;
} else {
return false;
}
return esversion >= glsl_version;
}
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;
}
@ -220,7 +221,11 @@ void glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, c
LOG_D("%s", source);
GLint 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);
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);
}
void set_hard_ext() {
hard_ext = (hard_ext_t)calloc(1, sizeof(struct hard_ext_s));
void set_hardware() {
hardware = (hardware_t)calloc(1, sizeof(struct hardware_s));
set_es_version();
}
void init_gl_state() {
@ -158,8 +158,6 @@ void InitGLESCapabilities() {
void init_target_gles() {
LOG_D("Initializing %s @ %s", RENDERERNAME, __FUNCTION__);
LOG_D("Initializing %s @ hard_ext", RENDERERNAME);
set_hard_ext();
LOG_D("Initializing %s @ gl_state", RENDERERNAME);
init_gl_state();
@ -527,6 +525,9 @@ void init_target_gles() {
INIT_GLES_FUNC(glTexStorage3DMultisample)
INIT_GLES_FUNC(glMapBufferRange)
INIT_GLES_FUNC(glBufferStorageEXT)
LOG_D("Initializing %s @ hardware", RENDERERNAME);
set_hardware();
InitGLESCapabilities();
LogOpenGLExtensions();