/* 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;
}
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];
}
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 */
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;
+ }
}
/*@{*/
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. */
/*@}*/
/**
- * 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.
*/
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;
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);
(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;
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;
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:
* [...]
/* 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;
}
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)");