diff --git a/src/mesa/drivers/dri/i965/brw_primitive_restart.c b/src/mesa/drivers/dri/i965/brw_primitive_restart.c index a571123bcef..4d15ea51e7f 100644 --- a/src/mesa/drivers/dri/i965/brw_primitive_restart.c +++ b/src/mesa/drivers/dri/i965/brw_primitive_restart.c @@ -149,7 +149,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[ib->index_size_shift]) { return GL_FALSE; } diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index 75dccad00bf..f1cda59a689 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -903,7 +903,7 @@ genX(upload_cut_index)(struct brw_context *brw) const struct gl_context *ctx = &brw->ctx; brw_batch_emit(brw, GENX(3DSTATE_VF), vf) { - if (ctx->Array._PrimitiveRestart && brw->ib.ib) { + if (ctx->Array._PrimitiveRestart[brw->ib.ib->index_size_shift] && brw->ib.ib) { vf.IndexedDrawCutIndexEnable = true; vf.CutIndex = ctx->Array._RestartIndex[brw->ib.index_size - 1]; } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 45018188168..6f7ac3b6841 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1610,8 +1610,9 @@ copy_array_attrib(struct gl_context *ctx, dest->LockCount = src->LockCount; dest->PrimitiveRestart = src->PrimitiveRestart; dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex; - dest->_PrimitiveRestart = src->_PrimitiveRestart; dest->RestartIndex = src->RestartIndex; + memcpy(dest->_PrimitiveRestart, src->_PrimitiveRestart, + sizeof(src->_PrimitiveRestart)); memcpy(dest->_RestartIndex, src->_RestartIndex, sizeof(src->_RestartIndex)); /* skip NewState */ /* skip RebindArrays */ diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 1d83ba04f78..4fc8dafefec 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -47,11 +47,31 @@ void _mesa_update_derived_primitive_restart_state(struct gl_context *ctx) { - ctx->Array._PrimitiveRestart = ctx->Array.PrimitiveRestart || - ctx->Array.PrimitiveRestartFixedIndex; - ctx->Array._RestartIndex[0] = _mesa_primitive_restart_index(ctx, 1); - ctx->Array._RestartIndex[1] = _mesa_primitive_restart_index(ctx, 2); - ctx->Array._RestartIndex[3] = _mesa_primitive_restart_index(ctx, 4); + if (ctx->Array.PrimitiveRestart || + ctx->Array.PrimitiveRestartFixedIndex) { + unsigned restart_index[3] = { + _mesa_primitive_restart_index(ctx, 1), + _mesa_primitive_restart_index(ctx, 2), + _mesa_primitive_restart_index(ctx, 4), + }; + + ctx->Array._RestartIndex[0] = restart_index[0]; + ctx->Array._RestartIndex[1] = restart_index[1]; + ctx->Array._RestartIndex[3] = restart_index[2]; + + /* Enable primitive restart only when the restart index can have an + * effect. This is required for correctness in AMD GFX8 support. + * Other hardware may also benefit from taking a faster, non-restart path + * when possible. + */ + ctx->Array._PrimitiveRestart[0] = true && restart_index[0] <= UINT8_MAX; + ctx->Array._PrimitiveRestart[1] = true && restart_index[1] <= UINT16_MAX; + ctx->Array._PrimitiveRestart[2] = true; + } else { + ctx->Array._PrimitiveRestart[0] = false; + ctx->Array._PrimitiveRestart[1] = false; + ctx->Array._PrimitiveRestart[2] = false; + } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 6b203345d93..6bdbbb92588 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1631,7 +1631,7 @@ struct gl_array_attrib /*@{*/ GLboolean PrimitiveRestart; GLboolean PrimitiveRestartFixedIndex; - GLboolean _PrimitiveRestart; + GLboolean _PrimitiveRestart[3]; /**< Enable indexed by index_size_shift. */ GLuint RestartIndex; GLuint _RestartIndex[4]; /**< Restart indices for index_size - 1. */ /*@}*/ diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 16298e177b2..ac50dd01914 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -69,28 +69,6 @@ #include "cso_cache/cso_context.h" -/** - * Set the restart index. - */ -static void -setup_primitive_restart(struct gl_context *ctx, struct pipe_draw_info *info) -{ - if (ctx->Array._PrimitiveRestart) { - unsigned index_size = info->index_size; - - info->restart_index = ctx->Array._RestartIndex[index_size - 1]; - - /* Enable primitive restart only when the restart index can have an - * effect. This is required for correctness in radeonsi GFX8 support. - * Other hardware may also benefit from taking a faster, non-restart path - * when possible. - */ - if (index_size == 4 || info->restart_index < (1 << (index_size * 8))) - info->primitive_restart = true; - } -} - - /** * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to * the corresponding Gallium type. @@ -214,7 +192,8 @@ st_draw_vbo(struct gl_context *ctx, info.index.user = ib->ptr; } - setup_primitive_restart(ctx, &info); + info.restart_index = ctx->Array._RestartIndex[info.index_size - 1]; + info.primitive_restart = ctx->Array._PrimitiveRestart[ib->index_size_shift]; } else { info.index_size = 0; @@ -287,8 +266,8 @@ st_indirect_draw_vbo(struct gl_context *ctx, info.index.resource = st_buffer_object(bufobj)->buffer; draw.start = pointer_to_offset(ib->ptr) >> ib->index_size_shift; - /* Primitive restart is not handled by the VBO module in this case. */ - setup_primitive_restart(ctx, &info); + info.restart_index = ctx->Array._RestartIndex[info.index_size - 1]; + info.primitive_restart = ctx->Array._PrimitiveRestart[ib->index_size_shift]; } info.mode = translate_prim(ctx, mode); diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 45d325551e3..ba77869ee55 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -213,10 +213,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, (ubyte *) mapped_indices, index_size, ~0); - if (ctx->Array._PrimitiveRestart) { - info.primitive_restart = true; - info.restart_index = ctx->Array._RestartIndex[index_size - 1]; - } + info.primitive_restart = ctx->Array._PrimitiveRestart[ib->index_size_shift]; + info.restart_index = ctx->Array._RestartIndex[index_size - 1]; } else { info.index_size = 0; info.has_user_indices = false; diff --git a/src/mesa/vbo/vbo_minmax_index.c b/src/mesa/vbo/vbo_minmax_index.c index 62c8b6466f6..d92bf19dfc8 100644 --- a/src/mesa/vbo/vbo_minmax_index.c +++ b/src/mesa/vbo/vbo_minmax_index.c @@ -326,7 +326,7 @@ vbo_get_minmax_index(struct gl_context *ctx, GLuint *min_index, GLuint *max_index, const GLuint count) { - const GLboolean restart = ctx->Array._PrimitiveRestart; + const GLboolean restart = ctx->Array._PrimitiveRestart[ib->index_size_shift]; const GLuint restartIndex = ctx->Array._RestartIndex[(1 << ib->index_size_shift) - 1]; const char *indices; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 7540da53381..a83c6415704 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -1376,7 +1376,7 @@ _save_OBE_MultiDrawArrays(GLenum mode, const GLint *first, static void array_element(struct gl_context *ctx, - GLint basevertex, GLuint elt, unsigned index_size) + GLint basevertex, GLuint elt, unsigned index_size_shift) { /* Section 10.3.5 Primitive Restart: * [...] @@ -1387,8 +1387,8 @@ array_element(struct gl_context *ctx, /* If PrimitiveRestart is enabled and the index is the RestartIndex * then we call PrimitiveRestartNV and return. */ - if (ctx->Array._PrimitiveRestart && - elt == ctx->Array._RestartIndex[index_size - 1]) { + if (ctx->Array._PrimitiveRestart[index_size_shift] && + elt == ctx->Array._RestartIndex[(1 << index_size_shift) - 1]) { CALL_PrimitiveRestartNV(ctx->CurrentServerDispatch, ()); return; } @@ -1442,15 +1442,15 @@ _save_OBE_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, switch (type) { case GL_UNSIGNED_BYTE: for (i = 0; i < count; i++) - array_element(ctx, basevertex, ((GLubyte *) indices)[i], 1); + array_element(ctx, basevertex, ((GLubyte *) indices)[i], 0); break; case GL_UNSIGNED_SHORT: for (i = 0; i < count; i++) - array_element(ctx, basevertex, ((GLushort *) indices)[i], 2); + array_element(ctx, basevertex, ((GLushort *) indices)[i], 1); break; case GL_UNSIGNED_INT: for (i = 0; i < count; i++) - array_element(ctx, basevertex, ((GLuint *) indices)[i], 4); + array_element(ctx, basevertex, ((GLuint *) indices)[i], 2); break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)");