319 lines
18 KiB
Diff
319 lines
18 KiB
Diff
From c7e6f4c3fb03b06149d8e13b4fc3a093feaf174e Mon Sep 17 00:00:00 2001
|
|
From: ptitSeb <sebastien.chev@gmail.com>
|
|
Date: Sun, 29 Nov 2020 11:54:40 +0100
|
|
Subject: [PATCH 100/233] Improved and fixed handling of
|
|
GL_ELEMENT_ARRAY_BUFFER, and improved debug logs (should help #250)
|
|
|
|
---
|
|
src/gl/buffers.c | 11 +++++++++--
|
|
src/gl/buffers.h | 2 +-
|
|
src/gl/drawing.c | 36 +++++++++++++++++++++++++++---------
|
|
src/gl/fpe.c | 1 +
|
|
src/gl/fpe_shader.c | 4 ++++
|
|
src/gl/program.c | 16 ++++++++++++----
|
|
6 files changed, 54 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/src/gl/buffers.c b/src/gl/buffers.c
|
|
index 93362b96..d575d660 100644
|
|
--- a/src/gl/buffers.c
|
|
+++ b/src/gl/buffers.c
|
|
@@ -682,6 +682,7 @@ void bindBuffer(GLenum target, GLuint buffer)
|
|
if(target==GL_ARRAY_BUFFER) {
|
|
if(glstate->bind_buffer.array == buffer)
|
|
return;
|
|
+ DBG(printf("Bind buffer %d to GL_ARRAY_BUFFER\n", buffer);)
|
|
glstate->bind_buffer.array = buffer;
|
|
gles_glBindBuffer(target, buffer);
|
|
|
|
@@ -690,6 +691,7 @@ void bindBuffer(GLenum target, GLuint buffer)
|
|
if(glstate->bind_buffer.index == buffer)
|
|
return;
|
|
glstate->bind_buffer.index = buffer;
|
|
+ DBG(printf("Bind buffer %d to GL_ELEMENT_ARRAY_BUFFER\n", buffer);)
|
|
gles_glBindBuffer(target, buffer);
|
|
} else {
|
|
LOGE("Warning, unhandled Buffer type %s in bindBuffer\n", PrintEnum(target));
|
|
@@ -698,9 +700,11 @@ void bindBuffer(GLenum target, GLuint buffer)
|
|
glstate->bind_buffer.used = (glstate->bind_buffer.index && glstate->bind_buffer.array)?1:0;
|
|
}
|
|
|
|
-void wantBufferIndex(GLuint buffer)
|
|
+GLuint wantBufferIndex(GLuint buffer)
|
|
{
|
|
+ GLuint ret = glstate->bind_buffer.want_index;
|
|
glstate->bind_buffer.want_index = buffer;
|
|
+ return ret;
|
|
}
|
|
|
|
void realize_bufferIndex()
|
|
@@ -708,7 +712,8 @@ void realize_bufferIndex()
|
|
LOAD_GLES(glBindBuffer);
|
|
if(glstate->bind_buffer.index != glstate->bind_buffer.want_index) {
|
|
glstate->bind_buffer.index = glstate->bind_buffer.want_index;
|
|
- gles_glBindBuffer(GL_ARRAY_BUFFER, glstate->bind_buffer.index);
|
|
+ gles_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glstate->bind_buffer.index);
|
|
+ DBG(printf("Bind buffer %d to GL_ELEMENT_ARRAY_BUFFER\n", glstate->bind_buffer.index);)
|
|
glstate->bind_buffer.used = (glstate->bind_buffer.index && glstate->bind_buffer.array)?1:0;
|
|
}
|
|
}
|
|
@@ -721,11 +726,13 @@ void unboundBuffers()
|
|
if(glstate->bind_buffer.array) {
|
|
glstate->bind_buffer.array = 0;
|
|
gles_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
+ DBG(printf("Bind buffer %d to GL_ARRAY_BUFFER\n", 0);)
|
|
}
|
|
if(glstate->bind_buffer.index) {
|
|
glstate->bind_buffer.index = 0;
|
|
glstate->bind_buffer.want_index = 0;
|
|
gles_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
+ DBG(printf("Bind buffer %d to GL_ELEMENT_ARRAY_BUFFER\n", 0);)
|
|
}
|
|
glstate->bind_buffer.used = 0;
|
|
}
|
|
diff --git a/src/gl/buffers.h b/src/gl/buffers.h
|
|
index 4393f343..d7b85347 100644
|
|
--- a/src/gl/buffers.h
|
|
+++ b/src/gl/buffers.h
|
|
@@ -72,7 +72,7 @@ void bindBuffer(GLenum target, GLuint buffer);
|
|
// unbound all buffer
|
|
void unboundBuffers();
|
|
// update wanted Index Buffer
|
|
-void wantBufferIndex(GLuint buffer);
|
|
+GLuint wantBufferIndex(GLuint buffer);
|
|
// Bind the wanted index buffer if needed
|
|
void realize_bufferIndex();
|
|
|
|
diff --git a/src/gl/drawing.c b/src/gl/drawing.c
|
|
index ddfab1e1..3af7e3c0 100644
|
|
--- a/src/gl/drawing.c
|
|
+++ b/src/gl/drawing.c
|
|
@@ -10,6 +10,13 @@
|
|
#include "loader.h"
|
|
#include "render.h"
|
|
|
|
+//#define DEBUG
|
|
+#ifdef DEBUG
|
|
+#define DBG(a) a
|
|
+#else
|
|
+#define DBG(a)
|
|
+#endif
|
|
+
|
|
static GLboolean is_cache_compatible(GLsizei count) {
|
|
#define T2(AA, A, B) \
|
|
if(glstate->vao->AA!=glstate->vao->B.enabled) return GL_FALSE; \
|
|
@@ -59,7 +66,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
|
|
GLsizei skip, GLsizei count) {
|
|
if (! list)
|
|
list = alloc_renderlist();
|
|
-//LOGD("arrary_to_renderlist, compiling=%d, skip=%d, count=%d\n", glstate->list.compiling, skip, count);
|
|
+ DBG(LOGD("arrary_to_renderlist, compiling=%d, skip=%d, count=%d\n", glstate->list.compiling, skip, count);)
|
|
list->mode = mode;
|
|
list->mode_init = mode;
|
|
list->mode_dimension = rendermode_dimensions(mode);
|
|
@@ -173,6 +180,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
|
|
}
|
|
static renderlist_t *arrays_add_renderlist(renderlist_t *a, GLenum mode,
|
|
GLsizei skip, GLsizei count, GLushort* indices, int ilen_b) {
|
|
+ DBG(LOGD("arrays_add_renderlist(%p, %s, %d, %d, %p, %d)\n", a, PrintEnum(mode), skip, count, indices, ilen_b);)
|
|
// check cache if any
|
|
if(glstate->vao->shared_arrays) {
|
|
if (!is_cache_compatible(count))
|
|
@@ -277,7 +285,7 @@ GLuint len_indices(const GLushort *sindices, const GLuint *iindices, GLsizei cou
|
|
static void glDrawElementsCommon(GLenum mode, GLint first, GLsizei count, GLuint len, const GLushort *sindices, const GLuint *iindices, int instancecount) {
|
|
if (glstate->raster.bm_drawing)
|
|
bitmap_flush();
|
|
- //printf("glDrawElementsCommon(%s, %d, %d, %d, %p, %p, %d)\n", PrintEnum(mode), first, count, len, sindices, iindices, instancecount);
|
|
+ DBG(printf("glDrawElementsCommon(%s, %d, %d, %d, %p, %p, %d)\n", PrintEnum(mode), first, count, len, sindices, iindices, instancecount);)
|
|
LOAD_GLES_FPE(glDrawElements);
|
|
LOAD_GLES_FPE(glDrawArrays);
|
|
LOAD_GLES_FPE(glNormalPointer);
|
|
@@ -445,7 +453,7 @@ if(count>500000) return;
|
|
#define MAX_BATCH globals4es.maxbatch
|
|
|
|
void gl4es_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {
|
|
- //printf("glDrawRangeElements(%s, %i, %i, %i, %s, @%p), inlist=%i, pending=%d\n", PrintEnum(mode), start, end, count, PrintEnum(type), indices, (glstate->list.active)?1:0, glstate->list.pending);
|
|
+ DBG(printf("glDrawRangeElements(%s, %i, %i, %i, %s, @%p), inlist=%i, pending=%d\n", PrintEnum(mode), start, end, count, PrintEnum(type), indices, (glstate->list.active)?1:0, glstate->list.pending);)
|
|
count = adjust_vertices(mode, count);
|
|
|
|
if (count<0) {
|
|
@@ -549,7 +557,7 @@ void glDrawRangeElementsEXT(GLenum mode,GLuint start,GLuint end,GLsizei count,GL
|
|
|
|
|
|
void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
|
|
- //printf("glDrawElements(%s, %d, %s, %p), vtx=%p map=%p, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL, glstate->list.pending);
|
|
+ DBG(printf("glDrawElements(%s, %d, %s, %p), vtx=%p map=%p, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL, glstate->list.pending);)
|
|
// TODO: split for count > 65535?
|
|
// special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex...
|
|
count = adjust_vertices(mode, count);
|
|
@@ -653,7 +661,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
|
|
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) AliasExport("gl4es_glDrawElements");
|
|
|
|
void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
|
- //printf("glDrawArrays(%s, %d, %d), list=%p pending=%d\n", PrintEnum(mode), first, count, glstate->list.active, glstate->list.pending);
|
|
+ DBG(printf("glDrawArrays(%s, %d, %d), list=%p pending=%d\n", PrintEnum(mode), first, count, glstate->list.active, glstate->list.pending);)
|
|
// special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex...
|
|
count = adjust_vertices(mode, count);
|
|
|
|
@@ -743,7 +751,9 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
|
*(p++) = j + 3;
|
|
}
|
|
}
|
|
+ GLuint old_buffer = wantBufferIndex(0);
|
|
glDrawElementsCommon(GL_TRIANGLES, 0, count*3/2, count, indices+(first-indfirst)*3/2, NULL, 1);
|
|
+ wantBufferIndex(old_buffer);
|
|
return;
|
|
}
|
|
|
|
@@ -755,6 +765,7 @@ void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count) AliasExport("gl4es
|
|
|
|
void gl4es_glMultiDrawArrays(GLenum mode, const GLint *firsts, const GLsizei *counts, GLsizei primcount)
|
|
{
|
|
+ DBG(printf("glMultiDrawArrays(%s, %p, %p, %d), list=%p pending=%d\n", PrintEnum(mode), firsts, counts, primcount, glstate->list.active, glstate->list.pending);)
|
|
if(!primcount) {
|
|
noerrorShim();
|
|
return;
|
|
@@ -850,7 +861,9 @@ void gl4es_glMultiDrawArrays(GLenum mode, const GLint *firsts, const GLsizei *co
|
|
*(p++) = j + 3;
|
|
}
|
|
}
|
|
+ GLuint old_buffer = wantBufferIndex(0);
|
|
glDrawElementsCommon(GL_TRIANGLES, 0, count*3/2, count, indices+(first-indfirst)*3/2, NULL, 1);
|
|
+ wantBufferIndex(old_buffer);
|
|
continue;
|
|
}
|
|
|
|
@@ -871,6 +884,7 @@ void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GL
|
|
|
|
void gl4es_glMultiDrawElements( GLenum mode, GLsizei *counts, GLenum type, const void * const *indices, GLsizei primcount)
|
|
{
|
|
+ DBG(printf("glMultiDrawElements(%s, %p, %s, %p, %d), list=%p pending=%d\n", PrintEnum(mode), counts, PrintEnum(type), indices, primcount, glstate->list.active, glstate->list.pending);)
|
|
if(!primcount) {
|
|
noerrorShim();
|
|
return;
|
|
@@ -987,7 +1001,7 @@ void gl4es_glMultiDrawElements( GLenum mode, GLsizei *counts, GLenum type, const
|
|
void glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount) AliasExport("gl4es_glMultiDrawElements");
|
|
|
|
void gl4es_glMultiDrawElementsBaseVertex( GLenum mode, GLsizei *counts, GLenum type, const void * const *indices, GLsizei primcount, const GLint * basevertex) {
|
|
- //printf("glMultiDrawElementsBaseVertex(%s, %p, %s, @%p, %d, @%p), inlist=%i, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, primcount, basevertex, (glstate->list.active)?1:0, glstate->list.pending);
|
|
+ DBG(printf("glMultiDrawElementsBaseVertex(%s, %p, %s, @%p, %d, @%p), inlist=%i, pending=%d\n", PrintEnum(mode), counts, PrintEnum(type), indices, primcount, basevertex, (glstate->list.active)?1:0, glstate->list.pending);)
|
|
// divide the call, should try something better one day...
|
|
bool compiling = (glstate->list.active);
|
|
bool intercept = should_intercept_render(mode);
|
|
@@ -1090,7 +1104,7 @@ void glMultiDrawElementsBaseVertex( GLenum mode, GLsizei *count, GLenum type, co
|
|
void glMultiDrawElementsBaseVertexARB( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount, const GLint * basevertex) AliasExport("gl4es_glMultiDrawElementsBaseVertex");
|
|
|
|
void gl4es_glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
|
|
- //printf("glDrawElementsBaseVertex(%s, %d, %s, %p, %d), vtx=%p map=%p, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, basevertex, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL, glstate->list.pending);
|
|
+ DBG(printf("glDrawElementsBaseVertex(%s, %d, %s, %p, %d), vtx=%p map=%p, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, basevertex, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL, glstate->list.pending);)
|
|
if(basevertex==0)
|
|
gl4es_glDrawElements(mode, count, type, indices);
|
|
else {
|
|
@@ -1186,7 +1200,7 @@ void glDrawElementsBaseVertexARB(GLenum mode, GLsizei count, GLenum type, const
|
|
|
|
|
|
void gl4es_glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
|
|
- //printf("glDrawRangeElementsBaseVertex(%s, %i, %i, %i, %s, @%p, %d), inlist=%i, pending=%d\n", PrintEnum(mode), start, end, count, PrintEnum(type), indices, basevertex, (glstate->list.active)?1:0, glstate->list.pending);
|
|
+ DBG(printf("glDrawRangeElementsBaseVertex(%s, %i, %i, %i, %s, @%p, %d), inlist=%i, pending=%d\n", PrintEnum(mode), start, end, count, PrintEnum(type), indices, basevertex, (glstate->list.active)?1:0, glstate->list.pending);)
|
|
if(basevertex==0) {
|
|
gl4es_glDrawRangeElements(mode, start, end, count, type, indices);
|
|
} else {
|
|
@@ -1279,6 +1293,7 @@ void glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsize
|
|
void glDrawRangeElementsBaseVertexARB(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) AliasExport("gl4es_glDrawRangeElementsBaseVertex");
|
|
|
|
void gl4es_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
|
|
+ DBG(printf("glDrawArraysInstanced(%s, %d, %d, %d), list=%p pending=%d\n", PrintEnum(mode), first, count, primcount, glstate->list.active, glstate->list.pending);)
|
|
count = adjust_vertices(mode, count);
|
|
|
|
if (count<0) {
|
|
@@ -1362,7 +1377,9 @@ void gl4es_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsize
|
|
*(p++) = j + 3;
|
|
}
|
|
}
|
|
+ GLuint old_buffer = wantBufferIndex(0);
|
|
glDrawElementsCommon(GL_TRIANGLES, 0, count*3/2, count, indices+(first-indfirst)*3/2, NULL, primcount);
|
|
+ wantBufferIndex(old_buffer);
|
|
return;
|
|
}
|
|
|
|
@@ -1373,6 +1390,7 @@ void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei prim
|
|
void glDrawArraysInstancedARB(GLenum mode, GLint first, GLsizei count, GLsizei primcount) AliasExport("gl4es_glDrawArraysInstanced");
|
|
|
|
void gl4es_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount) {
|
|
+ DBG(printf("glDrawElementsInstanced(%s, %d, %s, %p, %d), list=%p pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, primcount, glstate->list.active, glstate->list.pending);)
|
|
count = adjust_vertices(mode, count);
|
|
|
|
if (count<0) {
|
|
@@ -1473,7 +1491,7 @@ void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void
|
|
void glDrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount) AliasExport("gl4es_glDrawElementsInstanced");
|
|
|
|
void gl4es_glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex) {
|
|
- //printf("glDrawElementsInstanceBaseVertex(%s, %d, %s, %p, %d, %d), vtx=%p map=%p, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, primcount, basevertex, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL, glstate->list.pending);
|
|
+ DBG(printf("glDrawElementsInstanceBaseVertex(%s, %d, %s, %p, %d, %d), vtx=%p map=%p, pending=%d\n", PrintEnum(mode), count, PrintEnum(type), indices, primcount, basevertex, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL, glstate->list.pending);)
|
|
if(basevertex==0)
|
|
gl4es_glDrawElementsInstanced(mode, count, type, indices, primcount);
|
|
else {
|
|
diff --git a/src/gl/fpe.c b/src/gl/fpe.c
|
|
index d45fc94d..a8e90ce1 100644
|
|
--- a/src/gl/fpe.c
|
|
+++ b/src/gl/fpe.c
|
|
@@ -804,6 +804,7 @@ void fpe_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *i
|
|
use_vbo = 1;
|
|
bindBuffer(GL_ELEMENT_ARRAY_BUFFER, glstate->vao->elements->real_buffer);
|
|
indices = (GLvoid*)((uintptr_t)indices - (uintptr_t)(glstate->vao->elements->data));
|
|
+ DBG(printf("Using VBO %d for indices\n", glstate->vao->elements->real_buffer);)
|
|
}
|
|
realize_bufferIndex();
|
|
gles_glDrawElements(mode, count, type, indices);
|
|
diff --git a/src/gl/fpe_shader.c b/src/gl/fpe_shader.c
|
|
index f36938c7..54b2c274 100644
|
|
--- a/src/gl/fpe_shader.c
|
|
+++ b/src/gl/fpe_shader.c
|
|
@@ -821,6 +821,10 @@ const char* const* fpe_VertexShader(shaderconv_need_t* need, fpe_state_t *state)
|
|
}
|
|
|
|
const char* const* fpe_FragmentShader(shaderconv_need_t* need, fpe_state_t *state) {
|
|
+ // state can be NULL, so provide a 0 default
|
|
+ fpe_state_t default_state = {0};
|
|
+ int is_default = !!need;
|
|
+ if(!state) state = &default_state;
|
|
int headers = 0;
|
|
int lighting = state->lighting;
|
|
int twosided = state->twosided && lighting;
|
|
diff --git a/src/gl/program.c b/src/gl/program.c
|
|
index edd9a7ea..368d7131 100644
|
|
--- a/src/gl/program.c
|
|
+++ b/src/gl/program.c
|
|
@@ -746,10 +746,8 @@ void gl4es_glLinkProgram(GLuint program) {
|
|
for (int i=0; i<glprogram->attach_size; i++) {
|
|
accumShaderNeeds(glprogram->attach[i], &needs);
|
|
}
|
|
- // now check if vertex shader is missing
|
|
- int has_vertex = glprogram->last_vert?1:0;
|
|
- // and create one if needed!
|
|
- if(!has_vertex) {
|
|
+ // create one vertex shader if needed!
|
|
+ if(!glprogram->last_vert) {
|
|
glprogram->default_need = (shaderconv_need_t*)malloc(sizeof(shaderconv_need_t));
|
|
memcpy(glprogram->default_need, &needs, sizeof(shaderconv_need_t));
|
|
glprogram->default_vertex = 1;
|
|
@@ -758,6 +756,16 @@ void gl4es_glLinkProgram(GLuint program) {
|
|
gl4es_glCompileShader(vtx);
|
|
gl4es_glAttachShader(glprogram->id, vtx);
|
|
}
|
|
+ // create one fragment shader if needed!
|
|
+ if(!glprogram->last_frag) {
|
|
+ glprogram->default_need = (shaderconv_need_t*)malloc(sizeof(shaderconv_need_t));
|
|
+ memcpy(glprogram->default_need, &needs, sizeof(shaderconv_need_t));
|
|
+ glprogram->default_fragment = 1;
|
|
+ GLenum vtx = gl4es_glCreateShader(GL_FRAGMENT_SHADER);
|
|
+ gl4es_glShaderSource(vtx, 1, fpe_FragmentShader(&needs, NULL), NULL);
|
|
+ gl4es_glCompileShader(vtx);
|
|
+ gl4es_glAttachShader(glprogram->id, vtx);
|
|
+ }
|
|
int compatible = 1;
|
|
// now is everyone ok?
|
|
for (int i=0; i<glprogram->attach_size && compatible; i++) {
|
|
--
|
|
2.11.0
|
|
|