mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-24 03:31:43 -04:00
[Feat] (...): Add "DrawElements" multi-draw mode.
This commit is contained in:
parent
77450d6e4c
commit
d609b8ceab
@ -42,7 +42,7 @@ void init_settings() {
|
|||||||
enableExtComputeShader = 0;
|
enableExtComputeShader = 0;
|
||||||
if (enableCompatibleMode < 0 || enableCompatibleMode > 1)
|
if (enableCompatibleMode < 0 || enableCompatibleMode > 1)
|
||||||
enableCompatibleMode = 0;
|
enableCompatibleMode = 0;
|
||||||
if ((int)multidrawMode < 0 || (int)multidrawMode > 3)
|
if ((int)multidrawMode < 0 || (int)multidrawMode > 4)
|
||||||
multidrawMode = multidraw_mode_t::Auto;
|
multidrawMode = multidraw_mode_t::Auto;
|
||||||
|
|
||||||
// 1205
|
// 1205
|
||||||
@ -138,6 +138,9 @@ void init_settings() {
|
|||||||
case multidraw_mode_t::PreferMultidrawIndirect:
|
case multidraw_mode_t::PreferMultidrawIndirect:
|
||||||
draw_mode_str = "Multidraw indirect";
|
draw_mode_str = "Multidraw indirect";
|
||||||
break;
|
break;
|
||||||
|
case multidraw_mode_t::DrawElements:
|
||||||
|
draw_mode_str = "DrawElements";
|
||||||
|
break;
|
||||||
case multidraw_mode_t::Auto:
|
case multidraw_mode_t::Auto:
|
||||||
draw_mode_str = "Auto";
|
draw_mode_str = "Auto";
|
||||||
break;
|
break;
|
||||||
@ -166,8 +169,13 @@ void init_settings_post() {
|
|||||||
switch (global_settings.multidraw_mode) {
|
switch (global_settings.multidraw_mode) {
|
||||||
case multidraw_mode_t::PreferIndirect:
|
case multidraw_mode_t::PreferIndirect:
|
||||||
LOG_V("multidrawMode = PreferIndirect")
|
LOG_V("multidrawMode = PreferIndirect")
|
||||||
|
if (indirect) {
|
||||||
global_settings.multidraw_mode = multidraw_mode_t::PreferIndirect;
|
global_settings.multidraw_mode = multidraw_mode_t::PreferIndirect;
|
||||||
LOG_V(" -> Indirect (OK)")
|
LOG_V(" -> Indirect (OK)")
|
||||||
|
} else {
|
||||||
|
global_settings.multidraw_mode = multidraw_mode_t::DrawElements;
|
||||||
|
LOG_V(" -> DrawElements (Preferred not supported, falling back)")
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case multidraw_mode_t::PreferBaseVertex:
|
case multidraw_mode_t::PreferBaseVertex:
|
||||||
LOG_V("multidrawMode = PreferUnroll")
|
LOG_V("multidrawMode = PreferUnroll")
|
||||||
@ -177,20 +185,30 @@ void init_settings_post() {
|
|||||||
} else if (multidraw) {
|
} else if (multidraw) {
|
||||||
global_settings.multidraw_mode = multidraw_mode_t::PreferMultidrawIndirect;
|
global_settings.multidraw_mode = multidraw_mode_t::PreferMultidrawIndirect;
|
||||||
LOG_V(" -> MultidrawIndirect (Preferred not supported, falling back)")
|
LOG_V(" -> MultidrawIndirect (Preferred not supported, falling back)")
|
||||||
} else {
|
} else if (indirect) {
|
||||||
global_settings.multidraw_mode = multidraw_mode_t::PreferIndirect;
|
global_settings.multidraw_mode = multidraw_mode_t::PreferIndirect;
|
||||||
LOG_V(" -> Indirect (Preferred not supported, falling back)")
|
LOG_V(" -> Indirect (Preferred not supported, falling back)")
|
||||||
|
} else {
|
||||||
|
global_settings.multidraw_mode = multidraw_mode_t::DrawElements;
|
||||||
|
LOG_V(" -> DrawElements (Preferred not supported, falling back)")
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case multidraw_mode_t::DrawElements:
|
||||||
|
LOG_V("multidrawMode = DrawElements")
|
||||||
|
global_settings.multidraw_mode = multidraw_mode_t::DrawElements;
|
||||||
|
break;
|
||||||
case multidraw_mode_t::Auto:
|
case multidraw_mode_t::Auto:
|
||||||
default:
|
default:
|
||||||
LOG_V("multidrawMode = Auto")
|
LOG_V("multidrawMode = Auto")
|
||||||
if (multidraw) {
|
if (multidraw) {
|
||||||
global_settings.multidraw_mode = multidraw_mode_t::PreferMultidrawIndirect;
|
global_settings.multidraw_mode = multidraw_mode_t::PreferMultidrawIndirect;
|
||||||
LOG_V(" -> MultidrawIndirect")
|
LOG_V(" -> MultidrawIndirect")
|
||||||
} else {
|
} else if (indirect) {
|
||||||
global_settings.multidraw_mode = multidraw_mode_t::PreferIndirect;
|
global_settings.multidraw_mode = multidraw_mode_t::PreferIndirect;
|
||||||
LOG_V(" -> Indirect")
|
LOG_V(" -> Indirect (Preferred not supported, falling back)")
|
||||||
|
} else {
|
||||||
|
global_settings.multidraw_mode = multidraw_mode_t::DrawElements;
|
||||||
|
LOG_V(" -> DrawElements (Preferred not supported, falling back)")
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ enum class multidraw_mode_t: int {
|
|||||||
Auto = 0,
|
Auto = 0,
|
||||||
PreferIndirect,
|
PreferIndirect,
|
||||||
PreferBaseVertex,
|
PreferBaseVertex,
|
||||||
PreferMultidrawIndirect
|
PreferMultidrawIndirect,
|
||||||
|
DrawElements
|
||||||
};
|
};
|
||||||
|
|
||||||
struct global_settings_t {
|
struct global_settings_t {
|
||||||
@ -25,7 +26,7 @@ struct global_settings_t {
|
|||||||
int ext_compute_shader; // 0, 1
|
int ext_compute_shader; // 0, 1
|
||||||
size_t max_glsl_cache_size; // 0~
|
size_t max_glsl_cache_size; // 0~
|
||||||
int enable_compatible_mode; // 0, 1
|
int enable_compatible_mode; // 0, 1
|
||||||
multidraw_mode_t multidraw_mode; // 0, 1, 2, 3
|
multidraw_mode_t multidraw_mode; // 0, 1, 2, 3, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct global_settings_t global_settings;
|
extern struct global_settings_t global_settings;
|
||||||
|
@ -12,8 +12,6 @@ static bool g_indirect_cmds_inited = false;
|
|||||||
static GLsizei g_cmdbufsize = 0;
|
static GLsizei g_cmdbufsize = 0;
|
||||||
GLuint g_indirectbuffer = 0;
|
GLuint g_indirectbuffer = 0;
|
||||||
|
|
||||||
#define DRAW_INDIRECT
|
|
||||||
|
|
||||||
void prepare_indirect_buffer(const GLsizei *counts, GLenum type, const void *const *indices,
|
void prepare_indirect_buffer(const GLsizei *counts, GLenum type, const void *const *indices,
|
||||||
GLsizei primcount, const GLint *basevertex) {
|
GLsizei primcount, const GLint *basevertex) {
|
||||||
if (!g_indirect_cmds_inited) {
|
if (!g_indirect_cmds_inited) {
|
||||||
@ -74,6 +72,91 @@ void prepare_indirect_buffer(const GLsizei *counts, GLenum type, const void *con
|
|||||||
GLES.glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
GLES.glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_glMultiDrawElementsBaseVertex_drawelements(GLenum mode, GLsizei* counts, GLenum type, const void* const* indices, GLsizei primcount, const GLint* basevertex) {
|
||||||
|
LOG()
|
||||||
|
|
||||||
|
GLint prevElementBuffer;
|
||||||
|
GLES.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevElementBuffer);
|
||||||
|
|
||||||
|
for (GLsizei i = 0; i < primcount; ++i) {
|
||||||
|
if (counts[i] <= 0) continue;
|
||||||
|
|
||||||
|
GLsizei currentCount = counts[i];
|
||||||
|
const GLvoid *currentIndices = indices[i];
|
||||||
|
GLint currentBaseVertex = basevertex[i];
|
||||||
|
|
||||||
|
size_t indexSize;
|
||||||
|
switch (type) {
|
||||||
|
case GL_UNSIGNED_INT: indexSize = sizeof(GLuint); break;
|
||||||
|
case GL_UNSIGNED_SHORT: indexSize = sizeof(GLushort); break;
|
||||||
|
case GL_UNSIGNED_BYTE: indexSize = sizeof(GLubyte); break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint tempBuffer;
|
||||||
|
GLES.glGenBuffers(1, &tempBuffer);
|
||||||
|
GLES.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tempBuffer);
|
||||||
|
|
||||||
|
void *srcData = nullptr;
|
||||||
|
void *tempIndices = malloc(currentCount * indexSize);
|
||||||
|
if (!tempIndices) {
|
||||||
|
GLES.glDeleteBuffers(1, &tempBuffer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevElementBuffer != 0) {
|
||||||
|
GLES.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevElementBuffer);
|
||||||
|
srcData = GLES.glMapBufferRange(
|
||||||
|
GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
(GLintptr)currentIndices,
|
||||||
|
currentCount * indexSize,
|
||||||
|
GL_MAP_READ_BIT
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!srcData) {
|
||||||
|
free(tempIndices);
|
||||||
|
GLES.glDeleteBuffers(1, &tempBuffer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srcData = (void*)currentIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case GL_UNSIGNED_INT:
|
||||||
|
for (int j = 0; j < currentCount; ++j) {
|
||||||
|
((GLuint *)tempIndices)[j] = ((GLuint *)srcData)[j] + currentBaseVertex;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_UNSIGNED_SHORT:
|
||||||
|
for (int j = 0; j < currentCount; ++j) {
|
||||||
|
((GLushort *)tempIndices)[j] = ((GLushort *)srcData)[j] + currentBaseVertex;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_UNSIGNED_BYTE:
|
||||||
|
for (int j = 0; j < currentCount; ++j) {
|
||||||
|
((GLubyte *)tempIndices)[j] = ((GLubyte *)srcData)[j] + currentBaseVertex;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevElementBuffer != 0) {
|
||||||
|
GLES.glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tempBuffer);
|
||||||
|
GLES.glBufferData(GL_ELEMENT_ARRAY_BUFFER, currentCount * indexSize, tempIndices, GL_STREAM_DRAW);
|
||||||
|
free(tempIndices);
|
||||||
|
GLES.glDrawElements(mode, currentCount, type, 0);
|
||||||
|
|
||||||
|
GLES.glDeleteBuffers(1, &tempBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevElementBuffer);
|
||||||
|
|
||||||
|
CHECK_GL_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
void mg_glMultiDrawElementsBaseVertex_indirect(GLenum mode, GLsizei* counts, GLenum type, const void* const* indices, GLsizei primcount, const GLint* basevertex) {
|
void mg_glMultiDrawElementsBaseVertex_indirect(GLenum mode, GLsizei* counts, GLenum type, const void* const* indices, GLsizei primcount, const GLint* basevertex) {
|
||||||
LOG()
|
LOG()
|
||||||
|
|
||||||
@ -125,6 +208,19 @@ void mg_glMultiDrawElements_indirect(GLenum mode, const GLsizei *count, GLenum t
|
|||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_glMultiDrawElements_drawelements(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount) {
|
||||||
|
LOG()
|
||||||
|
|
||||||
|
for (GLsizei i = 0; i < primcount; ++i) {
|
||||||
|
const GLsizei c = count[i];
|
||||||
|
if (c > 0) {
|
||||||
|
GLES.glDrawElements(mode, c, type, indices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_GL_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
void mg_glMultiDrawElements_multiindirect(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount) {
|
void mg_glMultiDrawElements_multiindirect(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount) {
|
||||||
LOG()
|
LOG()
|
||||||
|
|
||||||
@ -152,8 +248,6 @@ void mg_glMultiDrawElements_basevertex(GLenum mode, const GLsizei *count, GLenum
|
|||||||
void glMultiDrawElementsBaseVertex(GLenum mode, GLsizei* counts, GLenum type, const void* const* indices, GLsizei primcount, const GLint* basevertex) {
|
void glMultiDrawElementsBaseVertex(GLenum mode, GLsizei* counts, GLenum type, const void* const* indices, GLsizei primcount, const GLint* basevertex) {
|
||||||
LOG()
|
LOG()
|
||||||
|
|
||||||
#ifdef DRAW_INDIRECT
|
|
||||||
|
|
||||||
if (!g_indirect_cmds_inited) {
|
if (!g_indirect_cmds_inited) {
|
||||||
GLES.glGenBuffers(1, &g_indirectbuffer);
|
GLES.glGenBuffers(1, &g_indirectbuffer);
|
||||||
GLES.glBindBuffer(GL_DRAW_INDIRECT_BUFFER, g_indirectbuffer);
|
GLES.glBindBuffer(GL_DRAW_INDIRECT_BUFFER, g_indirectbuffer);
|
||||||
@ -217,26 +311,12 @@ void glMultiDrawElementsBaseVertex(GLenum mode, GLsizei* counts, GLenum type, co
|
|||||||
GLES.glDrawElementsIndirect(mode, type, offset);
|
GLES.glDrawElementsIndirect(mode, type, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
for (GLsizei i = 0; i < primcount; ++i) {
|
|
||||||
const GLsizei count = counts[i];
|
|
||||||
if (count > 0) {
|
|
||||||
LOG_D("GLES.glDrawElementsBaseVertex, mode = %s, count = %d, type = %s, indices[i] = 0x%x, basevertex[i] = %d",
|
|
||||||
glEnumToString(mode), count, glEnumToString(type), indices[i], basevertex[i])
|
|
||||||
GLES.glDrawElementsBaseVertex(mode, count, type, indices[i], basevertex[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
void glMultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, GLsizei primcount) {
|
void glMultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, GLsizei primcount) {
|
||||||
LOG()
|
LOG()
|
||||||
|
|
||||||
#ifdef DRAW_INDIRECT
|
|
||||||
if (!g_indirect_cmds_inited) {
|
if (!g_indirect_cmds_inited) {
|
||||||
GLES.glGenBuffers(1, &g_indirectbuffer);
|
GLES.glGenBuffers(1, &g_indirectbuffer);
|
||||||
GLES.glBindBuffer(GL_DRAW_INDIRECT_BUFFER, g_indirectbuffer);
|
GLES.glBindBuffer(GL_DRAW_INDIRECT_BUFFER, g_indirectbuffer);
|
||||||
@ -300,16 +380,6 @@ void glMultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const v
|
|||||||
GLES.glDrawElementsIndirect(mode, type, offset);
|
GLES.glDrawElementsIndirect(mode, type, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
for (GLsizei i = 0; i < primcount; ++i) {
|
|
||||||
const GLsizei c = count[i];
|
|
||||||
if (c > 0) {
|
|
||||||
GLES.glDrawElements(mode, c, type, indices[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// solve the crash error for ANGLE, but it will make Derivative Main with Optifine not work!
|
// solve the crash error for ANGLE, but it will make Derivative Main with Optifine not work!
|
||||||
|
@ -37,12 +37,16 @@ GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_multiindirect(GLenum mode
|
|||||||
|
|
||||||
GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_basevertex(GLenum mode, GLsizei *counts, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
|
GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_basevertex(GLenum mode, GLsizei *counts, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
|
||||||
|
|
||||||
|
GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_drawelements(GLenum mode, GLsizei *counts, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
|
||||||
|
|
||||||
GLAPI GLAPIENTRY void mg_glMultiDrawElements_indirect(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
GLAPI GLAPIENTRY void mg_glMultiDrawElements_indirect(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
||||||
|
|
||||||
GLAPI GLAPIENTRY void mg_glMultiDrawElements_multiindirect(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
GLAPI GLAPIENTRY void mg_glMultiDrawElements_multiindirect(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
||||||
|
|
||||||
GLAPI GLAPIENTRY void mg_glMultiDrawElements_basevertex(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
GLAPI GLAPIENTRY void mg_glMultiDrawElements_basevertex(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
||||||
|
|
||||||
|
GLAPI GLAPIENTRY void mg_glMultiDrawElements_drawelements(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
||||||
|
|
||||||
GLAPI GLAPIENTRY void glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
GLAPI GLAPIENTRY void glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
||||||
|
|
||||||
GLAPI GLAPIENTRY void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
GLAPI GLAPIENTRY void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
||||||
|
@ -33,6 +33,9 @@ void* get_multidraw_func(const char* name) {
|
|||||||
case multidraw_mode_t::PreferMultidrawIndirect:
|
case multidraw_mode_t::PreferMultidrawIndirect:
|
||||||
namestr += "_multiindirect";
|
namestr += "_multiindirect";
|
||||||
break;
|
break;
|
||||||
|
case multidraw_mode_t::DrawElements:
|
||||||
|
namestr += "_drawelements";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_W("get_multidraw_func() cannot determine multidraw emulation mode!")
|
LOG_W("get_multidraw_func() cannot determine multidraw emulation mode!")
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -52,7 +55,7 @@ void *glXGetProcAddress(const char *name) {
|
|||||||
|
|
||||||
if (!proc) {
|
if (!proc) {
|
||||||
fprintf(stderr, "Failed to get OpenGL function %s: %s\n", name, dlerror());
|
fprintf(stderr, "Failed to get OpenGL function %s: %s\n", name, dlerror());
|
||||||
LOG_W("Failed to get OpenGL function: %s", (const char*)name);
|
LOG_W("Failed to get OpenGL function: %s", (const char*)name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +73,7 @@ void *glXGetProcAddressARB(const char *name) {
|
|||||||
|
|
||||||
if (!proc) {
|
if (!proc) {
|
||||||
fprintf(stderr, "Failed to get OpenGL function %s: %s\n", name, dlerror());
|
fprintf(stderr, "Failed to get OpenGL function %s: %s\n", name, dlerror());
|
||||||
LOG_W("Failed to get OpenGL function: %s", (const char*)name);
|
LOG_W("Failed to get OpenGL function: %s", (const char*)name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user