They are never used by multi draws and internal draws.
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3990>
const struct _mesa_prim *prim,
uint32_t hw_prim,
bool is_indexed,
+ GLuint num_instances, GLuint base_instance,
struct brw_transform_feedback_object *xfb_obj,
unsigned stream,
bool is_indirect,
BEGIN_BATCH(9);
OUT_BATCH(MI_LOAD_REGISTER_IMM | (9 - 2));
OUT_BATCH(GEN7_3DPRIM_INSTANCE_COUNT);
- OUT_BATCH(prim->num_instances);
+ OUT_BATCH(num_instances);
OUT_BATCH(GEN7_3DPRIM_START_VERTEX);
OUT_BATCH(0);
OUT_BATCH(GEN7_3DPRIM_BASE_VERTEX);
}
OUT_BATCH(verts_per_instance);
OUT_BATCH(start_vertex_location);
- OUT_BATCH(prim->num_instances);
- OUT_BATCH(prim->base_instance);
+ OUT_BATCH(num_instances);
+ OUT_BATCH(base_instance);
OUT_BATCH(base_vertex_location);
ADVANCE_BATCH();
*/
static void
gen9_emit_preempt_wa(struct brw_context *brw,
- const struct _mesa_prim *prim)
+ const struct _mesa_prim *prim, GLuint num_instances)
{
bool object_preemption = true;
ASSERTED const struct gen_device_info *devinfo = &brw->screen->devinfo;
*
* WA: Disable preemption when using instanceing.
*/
- if (prim->num_instances > 1)
+ if (num_instances > 1)
object_preemption = false;
brw_enable_obj_preemption(brw, object_preemption);
const struct _mesa_prim *prim,
unsigned prim_id,
bool is_indexed,
+ GLuint num_instances, GLuint base_instance,
struct brw_transform_feedback_object *xfb_obj,
unsigned stream,
GLsizeiptr indirect_offset)
intel_batchbuffer_save_state(brw);
fail_next = intel_batchbuffer_saved_state_is_empty(brw);
- if (brw->num_instances != prim->num_instances ||
+ if (brw->num_instances != num_instances ||
brw->basevertex != prim->basevertex ||
- brw->baseinstance != prim->base_instance) {
- brw->num_instances = prim->num_instances;
+ brw->baseinstance != base_instance) {
+ brw->num_instances = num_instances;
brw->basevertex = prim->basevertex;
- brw->baseinstance = prim->base_instance;
+ brw->baseinstance = base_instance;
if (prim_id > 0) { /* For i == 0 we just did this before the loop */
brw->ctx.NewDriverState |= BRW_NEW_VERTICES;
brw_merge_inputs(brw);
*/
const int new_firstvertex =
is_indexed ? prim->basevertex : prim->start;
- const int new_baseinstance = prim->base_instance;
+ const int new_baseinstance = base_instance;
const struct brw_vs_prog_data *vs_prog_data =
brw_vs_prog_data(brw->vs.base.prog_data);
if (prim_id > 0) {
}
if (devinfo->gen == 9)
- gen9_emit_preempt_wa(brw, prim);
+ gen9_emit_preempt_wa(brw, prim, num_instances);
- brw_emit_prim(brw, prim, brw->primitive, is_indexed, xfb_obj, stream,
- is_indirect, indirect_offset);
+ brw_emit_prim(brw, prim, brw->primitive, is_indexed, num_instances,
+ base_instance, xfb_obj, stream, is_indirect,
+ indirect_offset);
brw->batch.no_wrap = false;
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *gl_xfb_obj,
unsigned stream)
{
return;
/* Handle primitive restart if needed */
- if (brw_handle_primitive_restart(ctx, prims, nr_prims, ib)) {
+ if (brw_handle_primitive_restart(ctx, prims, nr_prims, ib, num_instances,
+ base_instance)) {
/* The draw was handled, so we can exit now */
return;
}
_mesa_enum_to_string(ctx->RenderMode));
_swsetup_Wakeup(ctx);
_tnl_wakeup(ctx);
- _tnl_draw(ctx, prims, nr_prims, ib,
- index_bounds_valid, min_index, max_index, NULL, 0);
+ _tnl_draw(ctx, prims, nr_prims, ib, index_bounds_valid, min_index,
+ max_index, num_instances, base_instance, NULL, 0);
return;
}
brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;
}
- brw_draw_single_prim(ctx, &prims[i], i, ib != NULL, xfb_obj, stream,
+ brw_draw_single_prim(ctx, &prims[i], i, ib != NULL, num_instances,
+ base_instance, xfb_obj, stream,
brw->draw.draw_indirect_offset +
brw->draw.draw_indirect_stride * i);
}
brw->draw.draw_indirect_data = indirect_data;
- brw_draw_prims(ctx, prim, draw_count,
- ib, false, 0, ~0,
- NULL, 0);
+ brw_draw_prims(ctx, prim, draw_count, ib, false, 0, ~0, 0, 0, NULL, 0);
brw->draw.draw_indirect_data = NULL;
free(prim);
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *unused_tfb_object,
unsigned stream);
brw_handle_primitive_restart(struct gl_context *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
- const struct _mesa_index_buffer *ib);
+ const struct _mesa_index_buffer *ib,
+ GLuint num_instances, GLuint base_instance);
void
brw_draw_indirect_prims(struct gl_context *ctx,
brw_handle_primitive_restart(struct gl_context *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
- const struct _mesa_index_buffer *ib)
+ const struct _mesa_index_buffer *ib,
+ GLuint num_instances, GLuint base_instance)
{
struct brw_context *brw = brw_context(ctx);
/* Cut index should work for primitive restart, so use it
*/
brw->prim_restart.enable_cut_index = true;
- brw_draw_prims(ctx, prims, nr_prims, ib, GL_FALSE, -1, -1, NULL, 0);
+ brw_draw_prims(ctx, prims, nr_prims, ib, GL_FALSE, -1, -1,
+ num_instances, base_instance, NULL, 0);
brw->prim_restart.enable_cut_index = false;
} else {
/* Not all the primitive draw modes are supported by the cut index,
/* Clear this to make the draw direct. */
brw->draw.draw_indirect_data = NULL;
- vbo_sw_primitive_restart(ctx, prims, nr_prims, ib,
- indirect_data,
+ vbo_sw_primitive_restart(ctx, prims, nr_prims, ib, num_instances,
+ base_instance, indirect_data,
brw->draw.draw_indirect_offset);
}
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream);
vbo_maybe_split(struct gl_context *ctx, const struct tnl_vertex_array *arrays,
const struct _mesa_prim *prims, GLuint nr_prims,
const struct _mesa_index_buffer *ib,
- GLuint min_index, GLuint max_index)
+ GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance)
{
struct nouveau_context *nctx = to_nouveau_context(ctx);
struct nouveau_render_state *render = to_render_state(ctx);
};
_tnl_split_prims(ctx, arrays, prims, nr_prims, ib, min_index,
- max_index, TAG(vbo_render_prims), &limits);
+ max_index, num_instances, base_instance,
+ TAG(vbo_render_prims), &limits);
return GL_TRUE;
}
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
vbo_choose_attrs(ctx, arrays);
if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index,
- max_index))
+ max_index, num_instances, base_instance))
return;
vbo_init_arrays(ctx, ib, arrays);
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
if (nctx->fallback == HWTNL)
TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib,
index_bounds_valid, min_index, max_index,
- tfb_vertcount, stream);
+ num_instances, base_instance,
+ tfb_vertcount, stream);
if (nctx->fallback == SWTNL)
_tnl_draw_prims(ctx, arrays, prims, nr_prims, ib,
index_bounds_valid, min_index, max_index,
+ num_instances, base_instance,
tfb_vertcount, stream);
}
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
TAG(vbo_check_render_prims)(ctx, arrays,
prims, nr_prims, ib,
index_bounds_valid, min_index, max_index,
+ num_instances, base_instance,
tfb_vertcount, stream);
}
* \param index_bounds_valid are min_index and max_index valid?
* \param min_index lowest vertex index used
* \param max_index highest vertex index used
+ * \param num_instances instance count from ARB_draw_instanced
+ * \param base_instance base instance from ARB_base_instance
* \param tfb_vertcount if non-null, indicates which transform feedback
* object has the vertex count.
* \param tfb_stream If called via DrawTransformFeedbackStream, specifies
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned tfb_stream);
.begin = 1,
.end = 1,
.mode = mode,
- .num_instances = numInstances,
- .base_instance = baseInstance,
.draw_id = drawID,
.start = start,
.count = count,
};
ctx->Driver.Draw(ctx, &prim, 1, NULL,
- GL_TRUE, start, start + count - 1, NULL, 0);
+ GL_TRUE, start, start + count - 1,
+ numInstances, baseInstance, NULL, 0);
if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
_mesa_flush(ctx);
prim.start = 0;
prim.count = count;
prim.basevertex = basevertex;
- prim.num_instances = numInstances;
- prim.base_instance = baseInstance;
prim.draw_id = 0;
/* Need to give special consideration to rendering a range of
*/
ctx->Driver.Draw(ctx, &prim, 1, &ib,
- index_bounds_valid, start, end, NULL, 0);
+ index_bounds_valid, start, end,
+ numInstances, baseInstance, NULL, 0);
if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
_mesa_flush(ctx);
prim[i].start =
((uintptr_t) indices[i] - min_index_ptr) / index_type_size;
prim[i].count = count[i];
- prim[i].num_instances = 1;
- prim[i].base_instance = 0;
prim[i].draw_id = i;
if (basevertex != NULL)
prim[i].basevertex = basevertex[i];
}
ctx->Driver.Draw(ctx, prim, primcount, &ib,
- false, 0, ~0, NULL, 0);
+ false, 0, ~0, 1, 0, NULL, 0);
}
else {
/* render one prim at a time */
prim[0].mode = mode;
prim[0].start = 0;
prim[0].count = count[i];
- prim[0].num_instances = 1;
- prim[0].base_instance = 0;
prim[0].draw_id = i;
if (basevertex != NULL)
prim[0].basevertex = basevertex[i];
else
prim[0].basevertex = 0;
- ctx->Driver.Draw(ctx, prim, 1, &ib, false, 0, ~0, NULL, 0);
+ ctx->Driver.Draw(ctx, prim, 1, &ib, false, 0, ~0, 1, 0, NULL, 0);
}
}
prim.begin = 1;
prim.end = 1;
prim.mode = mode;
- prim.num_instances = numInstances;
- prim.base_instance = 0;
/* Maybe we should do some primitive splitting for primitive restart
* (like in DrawArrays), but we have no way to know how many vertices
* will be rendered. */
- ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, obj, stream);
+ ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, numInstances, 0,
+ obj, stream);
if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
_mesa_flush(ctx);
GLuint start;
GLuint count;
GLint basevertex;
- GLuint num_instances;
- GLuint base_instance;
GLuint draw_id;
};
rs->prim.end = 1;
rs->prim.start = 0;
rs->prim.count = 1;
- rs->prim.num_instances = 1;
- rs->prim.base_instance = 0;
return rs;
}
_mesa_set_draw_vao(ctx, rs->VAO, VERT_BIT_POS);
/* Draw the point. */
- st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1,
+ st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1, 1, 0,
NULL, 0);
/* restore draw's rasterization stage depending on rendermode */
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
info.indirect = NULL;
info.count_from_stream_output = NULL;
info.restart_index = 0;
+ info.start_instance = base_instance;
+ info.instance_count = num_instances;
if (ib) {
struct gl_buffer_object *bufobj = ib->obj;
info.mode = translate_prim(ctx, prims[i].mode);
info.start = start + prims[i].start;
- info.start_instance = prims[i].base_instance;
- info.instance_count = prims[i].num_instances;
info.index_bias = prims[i].basevertex;
info.drawid = prims[i].draw_id;
if (!ib) {
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream);
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
}
draw_set_images(draw, PIPE_SHADER_VERTEX, images, prog->info.num_images);
+ info.start_instance = base_instance;
+ info.instance_count = num_instances;
+
/* draw here */
for (i = 0; i < nr_prims; i++) {
info.count = prims[i].count;
info.mode = prims[i].mode;
info.start = start + prims[i].start;
- info.start_instance = prims[i].base_instance;
- info.instance_count = prims[i].num_instances;
info.index_bias = prims[i].basevertex;
info.drawid = prims[i].draw_id;
if (!ib) {
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
/* We always translate away calls with min_index != 0.
*/
t_rebase_prims( ctx, arrays, prim, nr_prims, ib,
- min_index, max_index,
+ min_index, max_index, num_instances, base_instance,
_tnl_draw_prims );
return;
}
*/
_tnl_split_prims( ctx, arrays, prim, nr_prims, ib,
0, max_index + prim->basevertex,
+ num_instances, base_instance,
_tnl_draw_prims,
&limits );
}
GLuint nr_bo = 0;
GLuint inst;
+ assert(num_instances > 0);
+
for (i = 0; i < nr_prims;) {
GLuint this_nr_prims;
break;
}
- assert(prim[i].num_instances > 0);
-
/* Binding inputs may imply mapping some vertex buffer objects.
* They will need to be unmapped below.
*/
- for (inst = 0; inst < prim[i].num_instances; inst++) {
+ for (inst = 0; inst < num_instances; inst++) {
bind_prims(ctx, &prim[i], this_nr_prims);
bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
const struct _mesa_prim *prim, GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid, GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream)
{
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib,
index_bounds_valid, min_index, max_index,
- tfb_vertcount, stream);
+ num_instances, base_instance, tfb_vertcount, stream);
}
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
tnl_draw_func draw )
{
struct gl_array_attributes tmp_attribs[VERT_ATTRIB_MAX];
GL_TRUE,
0,
max_index - min_index,
+ num_instances, base_instance,
NULL, 0);
free(tmp_indices);
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
tnl_draw_func draw );
#endif
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
tnl_draw_func draw,
const struct split_limits *limits)
{
* individual primitives.
*/
_tnl_split_inplace(ctx, arrays, prim, nr_prims, ib,
- min_index, max_index, draw, limits);
+ min_index, max_index, num_instances,
+ base_instance, draw, limits);
}
else {
/* Why were we called? */
* otherwise try to split the individual primitives.
*/
_tnl_split_inplace(ctx, arrays, prim, nr_prims, ib,
- min_index, max_index, draw, limits);
+ min_index, max_index, num_instances,
+ base_instance, draw, limits);
}
else {
/* Why were we called? */
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
tnl_draw_func draw,
const struct split_limits *limits);
GL_TRUE,
0,
copy->dstbuf_nr - 1,
+ 1,
+ 0,
NULL, 0);
/* Reset all pointers:
prim->mode = mode;
prim->begin = begin_flag;
- prim->num_instances = 1;
}
const struct _mesa_index_buffer *ib;
GLuint min_index;
GLuint max_index;
+ GLuint num_instances;
+ GLuint base_instance;
tnl_draw_func draw;
const struct split_limits *limits;
!split->ib,
split->min_index,
split->max_index,
+ split->num_instances,
+ split->base_instance,
NULL, 0);
split->dstprim_nr = 0;
outprim->end = (nr == remaining && prim->end);
outprim->start = prim->start + j;
outprim->count = nr;
- outprim->num_instances = prim->num_instances;
- outprim->base_instance = prim->base_instance;
update_index_bounds(split, outprim);
tmpprim = *prim;
tmpprim.start = 0;
tmpprim.count = count;
- tmpprim.num_instances = 1;
- tmpprim.base_instance = 0;
flush_vertex(split);
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
tnl_draw_func draw,
const struct split_limits *limits)
{
/* Empty interval, makes calculations simpler. */
split.min_index = ~0;
split.max_index = 0;
+ split.num_instances = num_instances;
+ split.base_instance = base_instance;
split.draw = draw;
split.limits = limits;
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned stream);
const struct _mesa_prim *prim, GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid, GLuint min_index, GLuint max_index,
+ GLuint num_instances, GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount, unsigned stream);
extern void
GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
struct gl_transform_feedback_object *tfb_vertcount,
unsigned tfb_stream);
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
+ GLuint num_instances,
+ GLuint base_instance,
tnl_draw_func draw,
const struct split_limits *limits);
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLuint num_instances, GLuint base_instance,
struct gl_buffer_object *indirect,
GLsizeiptr indirect_offset);
if (p0->start + p0->count != p1->start)
return false;
- assert(p0->basevertex == p1->basevertex &&
- p0->num_instances == p1->num_instances &&
- p0->base_instance == p1->base_instance);
+ assert(p0->basevertex == p1->basevertex);
/* can always merge subsequent GL_POINTS primitives */
if (p0->mode == GL_POINTS)
exec->vtx.prim[i].end = 0;
exec->vtx.prim[i].start = exec->vtx.vert_count;
exec->vtx.prim[i].count = 0;
- exec->vtx.prim[i].num_instances = 1;
- exec->vtx.prim[i].base_instance = 0;
ctx->Driver.CurrentExecPrimitive = mode;
exec->vtx.vert_count);
ctx->Driver.Draw(ctx, exec->vtx.prim, exec->vtx.prim_count,
- NULL, GL_TRUE, 0, exec->vtx.vert_count - 1,
+ NULL, GL_TRUE, 0, exec->vtx.vert_count - 1, 1, 0,
NULL, 0);
/* Get new storage -- unless asked not to. */
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLuint num_instances, GLuint base_instance,
struct gl_buffer_object *indirect,
GLsizeiptr indirect_offset)
{
indirect_offset);
new_prim.count = indirect_params[0];
- new_prim.num_instances = indirect_params[1];
new_prim.start = indirect_params[2];
new_prim.basevertex = indirect_params[3];
- new_prim.base_instance = indirect_params[4];
+
+ num_instances = indirect_params[1];
+ base_instance = indirect_params[4];
new_ib = *ib;
new_ib.count = new_prim.count;
(temp_prim.count == sub_prim->count)) {
ctx->Driver.Draw(ctx, &temp_prim, 1, ib, GL_TRUE,
sub_prim->min_index, sub_prim->max_index,
+ num_instances, base_instance,
NULL, 0);
} else {
ctx->Driver.Draw(ctx, &temp_prim, 1, ib,
GL_FALSE, -1, -1,
+ num_instances, base_instance,
NULL, 0);
}
}
save->prims[0].end = 0;
save->prims[0].start = 0;
save->prims[0].count = 0;
- save->prims[0].num_instances = 1;
- save->prims[0].base_instance = 0;
save->prim_count = 1;
}
save->prims[i].end = 0;
save->prims[i].start = save->vert_count;
save->prims[i].count = 0;
- save->prims[i].num_instances = 1;
- save->prims[i].base_instance = 0;
save->no_current_update = no_current_update;
GLuint min_index = _vbo_save_get_min_index(node);
GLuint max_index = _vbo_save_get_max_index(node);
ctx->Driver.Draw(ctx, node->prims, node->prim_count, NULL, GL_TRUE,
- min_index, max_index, NULL, 0);
+ min_index, max_index, 1, 0, NULL, 0);
}
}