Work around broken Adreno 200 GPU

- Rework checks to compare with POSIX Regexs ... which themselves appear broken with android-10 NDK ... sigh
This commit is contained in:
Aaron Culliney 2015-09-30 21:55:07 -07:00
parent dc4f2a27f8
commit f7acde244c
7 changed files with 107 additions and 13 deletions

View File

@ -182,6 +182,7 @@ static void alert_render(void) {
glBindTexture(GL_TEXTURE_2D, messageModel->textureName);
if (messageModel->texDirty) {
messageModel->texDirty = false;
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_MESSAGE, messageModel->textureName);
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, messageModel->texWidth, messageModel->texHeight, /*border*/0, TEX_FORMAT, TEX_TYPE, messageModel->texPixels);
}
glUniform1i(texSamplerLoc, TEXTURE_ID_MESSAGE);

View File

@ -140,7 +140,7 @@ void glhud_renderDefault(GLModel *parent) {
#endif
// Draw the object
GL_DRAW_CALL_PRE();
_HACKAROUND_GLDRAW_PRE();
glDrawElements(parent->primType, parent->numElements, parent->elementType, 0);
GL_ERRLOG("glhudparent render");
}

View File

@ -294,6 +294,7 @@ static void gltouchjoy_render(void) {
glBindTexture(GL_TEXTURE_2D, axes.model->textureName);
if (axes.model->texDirty) {
axes.model->texDirty = false;
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_TOUCHJOY_AXIS, axes.model->textureName);
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, axes.model->texWidth, axes.model->texHeight, /*border*/0, TEX_FORMAT, TEX_TYPE, axes.model->texPixels);
}
if (axes.modelDirty) {
@ -315,6 +316,7 @@ static void gltouchjoy_render(void) {
glBindTexture(GL_TEXTURE_2D, buttons.model->textureName);
if (buttons.model->texDirty) {
buttons.model->texDirty = false;
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_TOUCHJOY_BUTTON, buttons.model->textureName);
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, buttons.model->texWidth, buttons.model->texHeight, /*border*/0, TEX_FORMAT, TEX_TYPE, buttons.model->texPixels);
}
if (buttons.modelDirty) {

View File

@ -524,6 +524,7 @@ static void gltouchkbd_render(void) {
glBindTexture(GL_TEXTURE_2D, kbd.model->textureName);
if (kbd.model->texDirty) {
kbd.model->texDirty = false;
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_TOUCHKBD, kbd.model->textureName);
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, kbd.model->texWidth, kbd.model->texHeight, /*border*/0, TEX_FORMAT, TEX_TYPE, kbd.model->texPixels);
}
if (kbd.modelDirty) {

View File

@ -430,6 +430,7 @@ static void gltouchmenu_render(void) {
glBindTexture(GL_TEXTURE_2D, menu.model->textureName);
if (menu.model->texDirty) {
menu.model->texDirty = false;
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_TOUCHMENU, menu.model->textureName);
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, menu.model->texWidth, menu.model->texHeight, /*border*/0, TEX_FORMAT, TEX_TYPE, menu.model->texPixels);
}
glUniform1i(texSamplerLoc, TEXTURE_ID_TOUCHMENU);

View File

@ -16,6 +16,8 @@
#include "video/glinput.h"
#include "video/glnode.h"
#include <regex.h>
bool safe_to_do_opengl_logging = false;
bool renderer_shutting_down = false;
@ -35,7 +37,9 @@ static int adjustedHeight = 0;
GLint texSamplerLoc = UNINITIALIZED_GL;
GLint alphaValue = UNINITIALIZED_GL;
GLuint mainShaderProgram = UNINITIALIZED_GL;
bool hackAroundBrokenAdreno200 = false;
bool hackAroundBrokenAdreno205 = false;
static GLint uniformMVPIdx = UNINITIALIZED_GL;
static GLenum crtElementType = UNINITIALIZED_GL;
@ -496,24 +500,89 @@ static demoSource *_create_shader_source(const char *fileName) {
static void gldriver_render(void);
static void gldriver_init_common(void) {
static void _gldriver_setup_hackarounds(void) {
const char *vendor = (const char *)glGetString(GL_VENDOR);
const char *renderer = (const char *)glGetString(GL_RENDERER);
const char *version = (const char *)glGetString(GL_VERSION);
if (vendor && renderer && version) {
LOG("GL_VENDOR:%s GL_RENDERER:%s GL_VERSION:%s", vendor, renderer, version);
LOG("GL_VENDOR:[%s] GL_RENDERER:[%s] GL_VERSION:[%s]", vendor, renderer, version);
} else {
RELEASE_LOG("One or more of GL_VENDOR, GL_RENDERER, and GL_VERSION is NULL ... possibly about to crash ...");
RELEASE_LOG("One or more of GL_VENDOR, GL_RENDERER, and GL_VERSION is NULL ... this is bad ...");
return;
}
if (vendor && strcasestr(vendor, "qualcomm")) {
if (renderer && strcasestr(renderer, "adreno")) {
if (strcasestr(renderer, "200")) {
LOG("HACKING AROUND BROKEN ADRENO 200");
hackAroundBrokenAdreno200 = true;
}
regex_t qualcommRegex = { 0 };
regex_t adrenoRegex = { 0 };
regex_t twoHundredRegex = { 0 };
regex_t twoHundredFiveRegex = { 0 };
do {
// As if we didn't have enough problems with Android ... Bionic's POSIX Regex support for android-10 appears
// very basic ... we can't match the word-boundary atomics \> \< \b ... sigh ... hopefully by the time there is
// an Adreno 2000 we can remove these hackarounds ;-)
int err = regcomp(&qualcommRegex, "qualcomm", REG_ICASE|REG_NOSUB|REG_EXTENDED);
if (err) {
LOG("Cannot compile regex : %d", err);
break;
}
}
int nomatch = regexec(&qualcommRegex, vendor, /*nmatch:*/0, /*pmatch:*/NULL, /*eflags:*/0);
if (nomatch) {
LOG("NO MATCH QUALCOMM >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
break;
}
err = regcomp(&adrenoRegex, "adreno", REG_ICASE|REG_NOSUB|REG_EXTENDED);
if (err) {
LOG("Cannot compile regex : %d", err);
break;
}
nomatch = regexec(&adrenoRegex, renderer, /*nmatch:*/0, /*pmatch:*/NULL, /*eflags:*/0);
if (nomatch) {
LOG("NO MATCH ADRENO >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
break;
}
err = regcomp(&twoHundredRegex, "200", REG_ICASE|REG_NOSUB|REG_EXTENDED);
if (err) {
LOG("Cannot compile regex : %d", err);
break;
}
err = regcomp(&twoHundredFiveRegex, "205", REG_ICASE|REG_NOSUB|REG_EXTENDED);
if (err) {
LOG("Cannot compile regex : %d", err);
break;
}
int found200 = !regexec(&twoHundredRegex, renderer, /*nmatch:*/0, /*pmatch:*/NULL, /*eflags:*/0);
int found205 = !regexec(&twoHundredFiveRegex, renderer, /*nmatch:*/0, /*pmatch:*/NULL, /*eflags:*/0);
if (found200) {
LOG("HACKING AROUND BROKEN ADRENO 200");
hackAroundBrokenAdreno200 = true;
break;
}
if (found205) {
LOG("HACKING AROUND BROKEN ADRENO 205");
hackAroundBrokenAdreno200 = true;
hackAroundBrokenAdreno205 = true;
break;
}
} while (0);
regfree(&qualcommRegex);
regfree(&adrenoRegex);
regfree(&twoHundredRegex);
regfree(&twoHundredFiveRegex);
}
static void gldriver_init_common(void) {
_gldriver_setup_hackarounds();
GLint value = UNINITIALIZED_GL;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
LOG("GL_MAX_TEXTURE_SIZE:%d", value);
renderer_shutting_down = false;
@ -721,6 +790,7 @@ static void gldriver_render(void) {
glBindTexture(GL_TEXTURE_2D, a2TextureName);
glUniform1i(texSamplerLoc, TEXTURE_ID_FRAMEBUFFER);
if (wasDirty) {
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_FRAMEBUFFER, a2TextureName);
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, SCANWIDTH, SCANHEIGHT, /*border*/0, TEX_FORMAT, TEX_TYPE, (GLvoid *)&pixels[0]);
}
@ -764,7 +834,7 @@ static void gldriver_render(void) {
//glCullFace(GL_BACK);
// Draw the CRT object and others
GL_DRAW_CALL_PRE();
_HACKAROUND_GLDRAW_PRE();
glDrawElements(GL_TRIANGLES, crtNumElements, crtElementType, 0);
// Render HUD nodes

View File

@ -50,7 +50,8 @@ extern GLuint mainShaderProgram;
// http://stackoverflow.com/questions/13676070/how-to-properly-mix-drawing-calls-and-changes-of-a-sampler-value-with-a-single-s
// https://developer.qualcomm.com/forum/qdevnet-forums/mobile-gaming-graphics-optimization-adreno/8896
extern bool hackAroundBrokenAdreno200;
#define GL_DRAW_CALL_PRE() \
extern bool hackAroundBrokenAdreno205;
#define _HACKAROUND_GLDRAW_PRE() \
({ \
if (hackAroundBrokenAdreno200) { \
glUseProgram(0); \
@ -58,5 +59,23 @@ extern bool hackAroundBrokenAdreno200;
} \
})
#define _HACKAROUND_GLTEXIMAGE2D_PRE(ACTIVE, NAME) \
({ \
if (hackAroundBrokenAdreno205) { \
/* Adreno 205 driver (HTC Desire) is even more broken than the 200! It appears that we must delete and recreate textures every time we upload new pixels! */ \
glBindTexture(GL_TEXTURE_2D, 0); \
glDeleteTextures(1, &(NAME)); \
glGenTextures(1, &(NAME)); \
glActiveTexture((ACTIVE)); \
glBindTexture(GL_TEXTURE_2D, (NAME)); \
/* HACK NOTE : these should match what is (currently hardcoded) in modelUtil.c */ \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); \
} \
})
#endif