state_tracker: remove software handling of primitive restart
The VBO module now can handle primitive restart in software if required. Therefore this support is no londer required. Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -638,175 +638,6 @@ check_uniforms(struct gl_context *ctx)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Notes on primitive restart:
|
||||
* The code below is used when the gallium driver does not support primitive
|
||||
* restart itself. We map the index buffer, find the restart indexes, unmap
|
||||
* the index buffer then draw the sub-primitives delineated by the restarts.
|
||||
* A couple possible optimizations:
|
||||
* 1. Save the list of sub-primitive (start, count) values in a list attached
|
||||
* to the index buffer for re-use in subsequent draws. The list would be
|
||||
* invalidated when the contents of the buffer changed.
|
||||
* 2. If drawing triangle strips or quad strips, create a new index buffer
|
||||
* that uses duplicated vertices to render the disjoint strips as one
|
||||
* long strip. We'd have to be careful to avoid using too much memory
|
||||
* for this.
|
||||
* Finally, some apps might perform better if they don't use primitive restart
|
||||
* at all rather than this fallback path. Set MESA_EXTENSION_OVERRIDE to
|
||||
* "-GL_NV_primitive_restart" to test that.
|
||||
*/
|
||||
|
||||
|
||||
struct sub_primitive
|
||||
{
|
||||
unsigned start, count;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scan the elements array to find restart indexes. Return a list
|
||||
* of primitive (start,count) pairs to indicate how to draw the sub-
|
||||
* primitives delineated by the restart index.
|
||||
*/
|
||||
static struct sub_primitive *
|
||||
find_sub_primitives(const void *elements, unsigned element_size,
|
||||
unsigned start, unsigned end, unsigned restart_index,
|
||||
unsigned *num_sub_prims)
|
||||
{
|
||||
const unsigned max_prims = end - start;
|
||||
struct sub_primitive *sub_prims;
|
||||
unsigned i, cur_start, cur_count, num;
|
||||
|
||||
sub_prims = (struct sub_primitive *)
|
||||
malloc(max_prims * sizeof(struct sub_primitive));
|
||||
|
||||
if (!sub_prims) {
|
||||
*num_sub_prims = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cur_start = start;
|
||||
cur_count = 0;
|
||||
num = 0;
|
||||
|
||||
#define SCAN_ELEMENTS(TYPE) \
|
||||
for (i = start; i < end; i++) { \
|
||||
if (((const TYPE *) elements)[i] == restart_index) { \
|
||||
if (cur_count > 0) { \
|
||||
assert(num < max_prims); \
|
||||
sub_prims[num].start = cur_start; \
|
||||
sub_prims[num].count = cur_count; \
|
||||
num++; \
|
||||
} \
|
||||
cur_start = i + 1; \
|
||||
cur_count = 0; \
|
||||
} \
|
||||
else { \
|
||||
cur_count++; \
|
||||
} \
|
||||
} \
|
||||
if (cur_count > 0) { \
|
||||
assert(num < max_prims); \
|
||||
sub_prims[num].start = cur_start; \
|
||||
sub_prims[num].count = cur_count; \
|
||||
num++; \
|
||||
}
|
||||
|
||||
switch (element_size) {
|
||||
case 1:
|
||||
SCAN_ELEMENTS(ubyte);
|
||||
break;
|
||||
case 2:
|
||||
SCAN_ELEMENTS(ushort);
|
||||
break;
|
||||
case 4:
|
||||
SCAN_ELEMENTS(uint);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "bad index_size in find_sub_primitives()");
|
||||
}
|
||||
|
||||
#undef SCAN_ELEMENTS
|
||||
|
||||
*num_sub_prims = num;
|
||||
|
||||
return sub_prims;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For gallium drivers that don't support the primitive restart
|
||||
* feature, handle it here by breaking up the indexed primitive into
|
||||
* sub-primitives.
|
||||
*/
|
||||
static void
|
||||
handle_fallback_primitive_restart(struct cso_context *cso,
|
||||
struct pipe_context *pipe,
|
||||
const struct _mesa_index_buffer *ib,
|
||||
struct pipe_index_buffer *ibuffer,
|
||||
struct pipe_draw_info *orig_info)
|
||||
{
|
||||
const unsigned start = orig_info->start;
|
||||
const unsigned count = orig_info->count;
|
||||
struct pipe_draw_info info = *orig_info;
|
||||
struct pipe_transfer *transfer = NULL;
|
||||
unsigned instance, i;
|
||||
const void *ptr = NULL;
|
||||
struct sub_primitive *sub_prims;
|
||||
unsigned num_sub_prims;
|
||||
|
||||
assert(info.indexed);
|
||||
assert(ibuffer->buffer || ibuffer->user_buffer);
|
||||
assert(ib);
|
||||
|
||||
if (!ibuffer->buffer || !ibuffer->user_buffer || !ib)
|
||||
return;
|
||||
|
||||
info.primitive_restart = FALSE;
|
||||
info.instance_count = 1;
|
||||
|
||||
if (_mesa_is_bufferobj(ib->obj)) {
|
||||
ptr = pipe_buffer_map_range(pipe, ibuffer->buffer,
|
||||
start * ibuffer->index_size, /* start */
|
||||
count * ibuffer->index_size, /* length */
|
||||
PIPE_TRANSFER_READ, &transfer);
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
ptr = (uint8_t*)ptr + (ibuffer->offset - start * ibuffer->index_size);
|
||||
}
|
||||
else {
|
||||
ptr = ib->ptr;
|
||||
if (!ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
sub_prims = find_sub_primitives(ptr, ibuffer->index_size,
|
||||
0, count, orig_info->restart_index,
|
||||
&num_sub_prims);
|
||||
|
||||
if (transfer)
|
||||
pipe_buffer_unmap(pipe, transfer);
|
||||
|
||||
/* Now draw the sub primitives.
|
||||
* Need to loop over instances as well to preserve draw order.
|
||||
*/
|
||||
for (instance = 0; instance < orig_info->instance_count; instance++) {
|
||||
info.start_instance = instance + orig_info->start_instance;
|
||||
for (i = 0; i < num_sub_prims; i++) {
|
||||
info.start = sub_prims[i].start;
|
||||
info.count = sub_prims[i].count;
|
||||
if (u_trim_pipe_prim(info.mode, &info.count)) {
|
||||
cso_draw_vbo(cso, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sub_prims)
|
||||
free(sub_prims);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
|
||||
* the corresponding Gallium type.
|
||||
@@ -994,15 +825,8 @@ st_draw_vbo(struct gl_context *ctx,
|
||||
cso_draw_vbo(st->cso_context, &info);
|
||||
}
|
||||
else if (info.primitive_restart) {
|
||||
if (st->sw_primitive_restart) {
|
||||
/* Handle primitive restart for drivers that doesn't support it */
|
||||
handle_fallback_primitive_restart(st->cso_context, pipe, ib,
|
||||
&ibuffer, &info);
|
||||
}
|
||||
else {
|
||||
/* don't trim, restarts might be inside index list */
|
||||
cso_draw_vbo(st->cso_context, &info);
|
||||
}
|
||||
/* don't trim, restarts might be inside index list */
|
||||
cso_draw_vbo(st->cso_context, &info);
|
||||
}
|
||||
else if (u_trim_pipe_prim(info.mode, &info.count))
|
||||
cso_draw_vbo(st->cso_context, &info);
|
||||
|
Reference in New Issue
Block a user