mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-24 19:52:49 -04:00
[Optimization] (multidraw, compute): miniature draw command ssbo
This commit is contained in:
parent
da9d3952c0
commit
079fcaa06b
@ -71,6 +71,67 @@ void prepare_indirect_buffer(const GLsizei *counts, GLenum type, const void *con
|
||||
GLES.glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
|
||||
static bool g_drawssbo_inited = false;
|
||||
static GLsizei g_drawssbo_size = 0;
|
||||
GLuint g_drawssbo = 0;
|
||||
|
||||
void prepare_compute_drawcmd_ssbo(const GLsizei *counts, GLenum type, const void *const *indices,
|
||||
GLsizei primcount, const GLint *basevertex) {
|
||||
if (!g_drawssbo_inited) {
|
||||
GLES.glGenBuffers(1, &g_drawssbo);
|
||||
GLES.glBindBuffer(GL_DRAW_INDIRECT_BUFFER, g_drawssbo);
|
||||
g_drawssbo_size = 1;
|
||||
GLES.glBufferData(GL_DRAW_INDIRECT_BUFFER,
|
||||
g_drawssbo_size * sizeof(drawcmd_compute_t), NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
g_drawssbo_inited = true;
|
||||
}
|
||||
|
||||
if (g_drawssbo_size < primcount) {
|
||||
size_t sz = g_drawssbo_size;
|
||||
|
||||
LOG_D("Before resize: %d", sz)
|
||||
|
||||
// 2-exponential to reduce reallocation
|
||||
while (sz < primcount)
|
||||
sz *= 2;
|
||||
|
||||
GLES.glBufferData(GL_DRAW_INDIRECT_BUFFER,
|
||||
sz * sizeof(drawcmd_compute_t), NULL, GL_DYNAMIC_DRAW);
|
||||
g_drawssbo_size = sz;
|
||||
}
|
||||
|
||||
LOG_D("After resize: %d", g_drawssbo_size)
|
||||
|
||||
auto* pcmds = (drawcmd_compute_t*)
|
||||
GLES.glMapBufferRange(GL_DRAW_INDIRECT_BUFFER,
|
||||
0, primcount * sizeof(drawcmd_compute_t),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
|
||||
GLsizei elementSize;
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
elementSize = 1;
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
elementSize = 2;
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
elementSize = 4;
|
||||
break;
|
||||
default:
|
||||
elementSize = 4;
|
||||
}
|
||||
|
||||
for (GLsizei i = 0; i < primcount; ++i) {
|
||||
auto byteOffset = reinterpret_cast<uintptr_t>(indices[i]);
|
||||
pcmds[i].firstIndex = static_cast<GLuint>(byteOffset / elementSize);
|
||||
pcmds[i].baseVertex = basevertex ? basevertex[i] : 0;
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@ -250,11 +311,11 @@ R"(#version 310 es
|
||||
layout(local_size_x = 64) in;
|
||||
|
||||
struct DrawCommand {
|
||||
uint count;
|
||||
uint instanceCount;
|
||||
// uint count;
|
||||
// uint instanceCount;
|
||||
uint firstIndex;
|
||||
int baseVertex;
|
||||
uint reservedMustBeZero;
|
||||
// uint reservedMustBeZero;
|
||||
};
|
||||
|
||||
layout(std430, binding = 0) readonly buffer Input { uint in_indices[]; };
|
||||
@ -295,7 +356,6 @@ void main() {
|
||||
|
||||
// Write out
|
||||
out_indices[outIdx] = uint(int(in_indices[inIndex]) + cmd.baseVertex);
|
||||
// out_indices[outIdx] = uint(cmd.baseVertex);
|
||||
}
|
||||
|
||||
)";
|
||||
@ -367,7 +427,8 @@ GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_compute(
|
||||
// TODO: support `types` other than GL_UNSIGNED_INT
|
||||
|
||||
// Align compute shader input format with standard OpenGL indirect-draw format
|
||||
prepare_indirect_buffer(counts, type, indices, primcount, basevertex);
|
||||
// prepare_indirect_buffer(counts, type, indices, primcount, basevertex);
|
||||
prepare_compute_drawcmd_ssbo(counts, type, indices, primcount, basevertex);
|
||||
|
||||
// Init compute buffers
|
||||
if (!g_compute_inited) {
|
||||
@ -381,8 +442,8 @@ GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_compute(
|
||||
}
|
||||
|
||||
// Resize prefix sum buffer if needed
|
||||
if (g_prefix_sum.size() < g_cmdbufsize)
|
||||
g_prefix_sum.resize(g_cmdbufsize);
|
||||
if (g_prefix_sum.size() < g_drawssbo_size)
|
||||
g_prefix_sum.resize(g_drawssbo_size);
|
||||
|
||||
// Calculate prefix sum
|
||||
g_prefix_sum[0] = counts[0];
|
||||
@ -414,7 +475,7 @@ GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_compute(
|
||||
// Bind buffers
|
||||
GLES.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ibo);
|
||||
CHECK_GL_ERROR_NO_INIT
|
||||
GLES.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, g_indirectbuffer);
|
||||
GLES.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, g_drawssbo);
|
||||
CHECK_GL_ERROR_NO_INIT
|
||||
GLES.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, g_prefixsumbuffer);
|
||||
CHECK_GL_ERROR_NO_INIT
|
||||
|
@ -28,6 +28,11 @@ struct draw_elements_indirect_command_t {
|
||||
GLuint reservedMustBeZero;
|
||||
};
|
||||
|
||||
struct drawcmd_compute_t {
|
||||
GLuint firstIndex;
|
||||
GLint baseVertex;
|
||||
};
|
||||
|
||||
GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_indirect(GLenum mode, GLsizei *counts, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
|
||||
|
||||
GLAPI GLAPIENTRY void mg_glMultiDrawElementsBaseVertex_multiindirect(GLenum mode, GLsizei *counts, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
|
||||
|
Loading…
x
Reference in New Issue
Block a user