From 392a59a6cc177d66b51b64ad429c69a31e913f1e Mon Sep 17 00:00:00 2001 From: Stanislav Vorobiov Date: Sat, 1 Mar 2014 20:12:34 +0400 Subject: [PATCH] YaGL: Always use EBO with glDrawElementsXXX OpenGL 3.1+ core requires that glDrawElementsXXX be called with EBO bound Change-Id: Id553c682407ae9da2d0a21fe9065d9eb95122c00 --- hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c | 4 ++ hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h | 6 ++ hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c | 63 ++++++++++++++++++- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c index 1debb5c425..01e0e3d14b 100644 --- a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c +++ b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c @@ -49,6 +49,10 @@ void yagl_gles_api_ts_cleanup(struct yagl_gles_api_ts *gles_api_ts) yagl_ensure_ctx(0); + if (gles_api_ts->ebo) { + gles_api_ts->driver->DeleteBuffers(1, &gles_api_ts->ebo); + } + for (i = 0; i < gles_api_ts->num_arrays; ++i) { gles_api_ts->driver->DeleteBuffers(1, &gles_api_ts->arrays[i].vbo); diff --git a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h index 8c4ca8610c..f24ad7cbac 100644 --- a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h +++ b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h @@ -55,6 +55,12 @@ struct yagl_gles_api_ts struct yagl_gles_array *arrays; uint32_t num_arrays; + /* + * See above comments regarding VBO. + */ + GLuint ebo; + uint32_t ebo_size; + /* * -1 when undecided, 0/1 when decided. */ diff --git a/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c b/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c index 17b9b4791c..034f2d3108 100644 --- a/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c +++ b/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c @@ -153,6 +153,51 @@ static GLuint yagl_gles_bind_array(uint32_t indx, return current_vbo; } +static GLuint yagl_gles_bind_ebo(const GLvoid *data, int32_t size) +{ + GLuint current_ebo; + void *ptr; + + YAGL_LOG_FUNC_SET(yagl_gles_bind_ebo); + + if (!gles_api_ts->ebo) { + gles_api_ts->driver->GenBuffers(1, &gles_api_ts->ebo); + } + + gles_api_ts->driver->GetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, + (GLint*)¤t_ebo); + + gles_api_ts->driver->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, gles_api_ts->ebo); + + if (size > gles_api_ts->ebo_size) { + gles_api_ts->driver->BufferData(GL_ELEMENT_ARRAY_BUFFER, + size, NULL, + GL_STREAM_DRAW); + gles_api_ts->ebo_size = size; + } + + if (yagl_gles_use_map_buffer_range()) { + ptr = gles_api_ts->driver->MapBufferRange(GL_ELEMENT_ARRAY_BUFFER, + 0, + size, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + + if (ptr) { + memcpy(ptr, data, size); + + gles_api_ts->driver->UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + } else { + YAGL_LOG_ERROR("glMapBufferRange failed"); + } + } else { + gles_api_ts->driver->Finish(); + gles_api_ts->driver->BufferSubData(GL_ELEMENT_ARRAY_BUFFER, + 0, size, data); + } + + return current_ebo; +} + static bool yagl_gles_program_get_uniform_type(GLuint program, GLint location, GLenum *type) @@ -550,7 +595,11 @@ void yagl_host_glDrawElements(GLenum mode, const GLvoid *indices, int32_t indices_count) { if (indices) { - gles_api_ts->driver->DrawElements(mode, count, type, indices); + GLuint current_ebo = yagl_gles_bind_ebo(indices, indices_count); + + gles_api_ts->driver->DrawElements(mode, count, type, NULL); + + gles_api_ts->driver->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_ebo); } else { gles_api_ts->driver->DrawElements(mode, count, type, (const GLvoid*)(uintptr_t)indices_count); @@ -608,7 +657,11 @@ void yagl_host_glDrawElementsInstanced(GLenum mode, GLsizei primcount) { if (indices) { - gles_api_ts->driver->DrawElementsInstanced(mode, count, type, indices, primcount); + GLuint current_ebo = yagl_gles_bind_ebo(indices, indices_count); + + gles_api_ts->driver->DrawElementsInstanced(mode, count, type, NULL, primcount); + + gles_api_ts->driver->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_ebo); } else { gles_api_ts->driver->DrawElementsInstanced(mode, count, @@ -626,7 +679,11 @@ void yagl_host_glDrawRangeElements(GLenum mode, const GLvoid *indices, int32_t indices_count) { if (indices) { - gles_api_ts->driver->DrawRangeElements(mode, start, end, count, type, indices); + GLuint current_ebo = yagl_gles_bind_ebo(indices, indices_count); + + gles_api_ts->driver->DrawRangeElements(mode, start, end, count, type, NULL); + + gles_api_ts->driver->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_ebo); } else { gles_api_ts->driver->DrawRangeElements(mode, start, end, count, type, (const GLvoid*)(uintptr_t)indices_count); -- 2.34.1