From 42ed81a7c3eec215a543c47239cc30536f284ada Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 10 Aug 2012 22:28:27 -0700 Subject: [PATCH] mesa/es3: Add support for GL_PRIMITIVE_RESTART_FIXED_INDEX This requires some derived state. The cut vertex used is either the value specified by glPrimitiveRestartIndex or it's hard-coded to ~0. The derived state gl_array_attrib::_RestartIndex captures this value. In addition, the derived state gl_array_attrib::_PrimitiveRestart is set whenever either gl_array_attrib::PrimitiveRestart or gl_array_attrib::PrimitiveRestartFixedIndex is set. v2: Use _mesa_is_gles3. Signed-off-by: Ian Romanick --- .../drivers/dri/i965/brw_primitive_restart.c | 8 ++--- src/mesa/main/api_arrayelt.c | 2 +- src/mesa/main/attrib.c | 3 ++ src/mesa/main/enable.c | 33 +++++++++++++++++++ src/mesa/main/mtypes.h | 13 +++++++- src/mesa/main/varray.c | 5 +-- src/mesa/state_tracker/st_draw.c | 4 +-- src/mesa/vbo/vbo_exec_array.c | 16 ++++----- src/mesa/vbo/vbo_primitive_restart.c | 2 +- 9 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_primitive_restart.c b/src/mesa/drivers/dri/i965/brw_primitive_restart.c index 38b52438c09..8c7219d4f92 100644 --- a/src/mesa/drivers/dri/i965/brw_primitive_restart.c +++ b/src/mesa/drivers/dri/i965/brw_primitive_restart.c @@ -52,13 +52,13 @@ can_cut_index_handle_restart_index(struct gl_context *ctx, switch (ib->type) { case GL_UNSIGNED_BYTE: - cut_index_will_work = (ctx->Array.RestartIndex & 0xff) == 0xff; + cut_index_will_work = (ctx->Array._RestartIndex & 0xff) == 0xff; break; case GL_UNSIGNED_SHORT: - cut_index_will_work = (ctx->Array.RestartIndex & 0xffff) == 0xffff; + cut_index_will_work = (ctx->Array._RestartIndex & 0xffff) == 0xffff; break; case GL_UNSIGNED_INT: - cut_index_will_work = ctx->Array.RestartIndex == 0xffffffff; + cut_index_will_work = ctx->Array._RestartIndex == 0xffffffff; break; default: cut_index_will_work = false; @@ -157,7 +157,7 @@ brw_handle_primitive_restart(struct gl_context *ctx, /* If PrimitiveRestart is not enabled, then we aren't concerned about * handling this draw. */ - if (!(ctx->Array.PrimitiveRestart)) { + if (!(ctx->Array._PrimitiveRestart)) { return GL_FALSE; } diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c index 0fa2429976b..ea3361488ce 100644 --- a/src/mesa/main/api_arrayelt.c +++ b/src/mesa/main/api_arrayelt.c @@ -1636,7 +1636,7 @@ void GLAPIENTRY _ae_ArrayElement( GLint elt ) /* If PrimitiveRestart is enabled and the index is the RestartIndex * then we call PrimitiveRestartNV and return. */ - if (ctx->Array.PrimitiveRestart && (elt == ctx->Array.RestartIndex)) { + if (ctx->Array._PrimitiveRestart && (elt == ctx->Array._RestartIndex)) { CALL_PrimitiveRestartNV((struct _glapi_table *)disp, ()); return; } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index a19d610545d..d6f298d93c6 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1377,7 +1377,10 @@ copy_array_attrib(struct gl_context *ctx, dest->LockFirst = src->LockFirst; dest->LockCount = src->LockCount; dest->PrimitiveRestart = src->PrimitiveRestart; + dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex; + dest->_PrimitiveRestart = src->_PrimitiveRestart; dest->RestartIndex = src->RestartIndex; + dest->_RestartIndex = src->_RestartIndex; /* skip NewState */ /* skip RebindArrays */ diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index b48794f950b..73257290ed8 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -48,6 +48,20 @@ } +static void +update_derived_primitive_restart_state(struct gl_context *ctx) +{ + /* Update derived primitive restart state. + */ + if (ctx->Array.PrimitiveRestart) + ctx->Array._RestartIndex = ctx->Array.RestartIndex; + else + ctx->Array._RestartIndex = ~0; + + ctx->Array._PrimitiveRestart = ctx->Array.PrimitiveRestart + || ctx->Array.PrimitiveRestartFixedIndex; +} + /** * Helper to enable/disable client-side state. */ @@ -119,6 +133,8 @@ client_state(struct gl_context *ctx, GLenum cap, GLboolean state) *var = state; + update_derived_primitive_restart_state(ctx); + if (state) arrayObj->_Enabled |= flag; else @@ -967,6 +983,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) if (ctx->Array.PrimitiveRestart != state) { FLUSH_VERTICES(ctx, _NEW_TRANSFORM); ctx->Array.PrimitiveRestart = state; + update_derived_primitive_restart_state(ctx); + } + break; + + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + if (!_mesa_is_gles3(ctx) && !ctx->Extensions.ARB_ES3_compatibility) + goto invalid_enum_error; + if (ctx->Array.PrimitiveRestartFixedIndex != state) { + FLUSH_VERTICES(ctx, _NEW_TRANSFORM); + ctx->Array.PrimitiveRestartFixedIndex = state; + update_derived_primitive_restart_state(ctx); } break; @@ -1542,6 +1569,12 @@ _mesa_IsEnabled( GLenum cap ) } return ctx->Array.PrimitiveRestart; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + if (!_mesa_is_gles3(ctx) && !ctx->Extensions.ARB_ES3_compatibility) { + goto invalid_enum_error; + } + return ctx->Array.PrimitiveRestartFixedIndex; + /* GL3.0 - GL_framebuffer_sRGB */ case GL_FRAMEBUFFER_SRGB_EXT: if (!_mesa_is_desktop_gl(ctx)) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 318dcb548d8..f44ec4947ed 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1634,9 +1634,20 @@ struct gl_array_attrib GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */ GLuint LockCount; /**< GL_EXT_compiled_vertex_array */ - /** GL 3.1 (slightly different from GL_NV_primitive_restart) */ + /** + * \name Primitive restart controls + * + * Primitive restart is enabled if either \c PrimitiveRestart or + * \c PrimitiveRestart is set. If \c PrimitiveRestart is set, then + * \c RestartIndex is used as the cut vertex. Otherwise ~0 is used. + */ + /*@{*/ GLboolean PrimitiveRestart; + GLboolean PrimitiveRestartFixedIndex; + GLboolean _PrimitiveRestart; GLuint RestartIndex; + GLuint _RestartIndex; + /*@}*/ /* GL_ARB_vertex_buffer_object */ struct gl_buffer_object *ArrayBufferObj; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 5e4d6c3e638..e453b3b0e64 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -1113,9 +1113,10 @@ _mesa_PrimitiveRestartIndex(GLuint index) ASSERT_OUTSIDE_BEGIN_END(ctx); - if (ctx->Array.RestartIndex != index) { + ctx->Array.RestartIndex = index; + if (ctx->Array.PrimitiveRestart && ctx->Array._RestartIndex != index) { FLUSH_VERTICES(ctx, _NEW_TRANSFORM); - ctx->Array.RestartIndex = index; + ctx->Array._RestartIndex = index; } } diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 4800e1c879f..7de2bb9b853 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -230,8 +230,8 @@ st_draw_vbo(struct gl_context *ctx, /* The VBO module handles restart for the non-indexed GLDrawArrays * so we only set these fields for indexed drawing: */ - info.primitive_restart = ctx->Array.PrimitiveRestart; - info.restart_index = ctx->Array.RestartIndex; + info.primitive_restart = ctx->Array._PrimitiveRestart; + info.restart_index = ctx->Array._RestartIndex; } else { /* Transform feedback drawing is always non-indexed. */ diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 4b2c5298d1c..7e61f7b31fd 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -90,8 +90,8 @@ vbo_get_minmax_index(struct gl_context *ctx, GLuint *min_index, GLuint *max_index, const GLuint count) { - const GLboolean restart = ctx->Array.PrimitiveRestart; - const GLuint restartIndex = ctx->Array.RestartIndex; + const GLboolean restart = ctx->Array._PrimitiveRestart; + const GLuint restartIndex = ctx->Array._RestartIndex; const int index_size = vbo_sizeof_ib_type(ib->type); const char *indices; GLuint i; @@ -536,7 +536,7 @@ vbo_handle_primitive_restart(struct gl_context *ctx, if ((ib != NULL) && ctx->Const.PrimitiveRestartInSoftware && - ctx->Array.PrimitiveRestart) { + ctx->Array._PrimitiveRestart) { /* Handle primitive restart in software */ vbo_sw_primitive_restart(ctx, prim, nr_prims, ib); } else { @@ -572,10 +572,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, prim[0].base_instance = baseInstance; /* Implement the primitive restart index */ - if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) { + if (ctx->Array._PrimitiveRestart && ctx->Array._RestartIndex < count) { GLuint primCount = 0; - if (ctx->Array.RestartIndex == start) { + if (ctx->Array._RestartIndex == start) { /* special case: RestartIndex at beginning */ if (count > 1) { prim[0].start = start + 1; @@ -583,7 +583,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, primCount = 1; } } - else if (ctx->Array.RestartIndex == start + count - 1) { + else if (ctx->Array._RestartIndex == start + count - 1) { /* special case: RestartIndex at end */ if (count > 1) { prim[0].start = start; @@ -594,10 +594,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, else { /* general case: RestartIndex in middle, split into two prims */ prim[0].start = start; - prim[0].count = ctx->Array.RestartIndex - start; + prim[0].count = ctx->Array._RestartIndex - start; prim[1] = prim[0]; - prim[1].start = ctx->Array.RestartIndex + 1; + prim[1].start = ctx->Array._RestartIndex + 1; prim[1].count = count - prim[1].start; primCount = 2; diff --git a/src/mesa/vbo/vbo_primitive_restart.c b/src/mesa/vbo/vbo_primitive_restart.c index 6f9d61c9bbc..a6a0149ca63 100644 --- a/src/mesa/vbo/vbo_primitive_restart.c +++ b/src/mesa/vbo/vbo_primitive_restart.c @@ -171,7 +171,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx, GLuint sub_prim_num; GLuint end_index; GLuint sub_end_index; - GLuint restart_index = ctx->Array.RestartIndex; + GLuint restart_index = ctx->Array._RestartIndex; struct _mesa_prim temp_prim; struct vbo_context *vbo = vbo_context(ctx); vbo_draw_func draw_prims_func = vbo->draw_prims; -- 2.30.2