This makes st_feedback_draw_vbo implement the DrawGallium.
That's the last users of the fallback functions.
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18828>
}
return ctx->tmp_prims;
}
-
-/**
- * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw.
- */
-void
-_mesa_draw_gallium_fallback(struct gl_context *ctx,
- struct pipe_draw_info *info,
- unsigned drawid_offset,
- const struct pipe_draw_start_count_bias *draws,
- unsigned num_draws)
-{
- struct _mesa_index_buffer ib;
- unsigned index_size = info->index_size;
- unsigned min_index = 0, max_index = ~0u;
- bool index_bounds_valid = false;
-
- if (!info->instance_count)
- return;
-
- if (index_size) {
- if (info->index_bounds_valid) {
- min_index = info->min_index;
- max_index = info->max_index;
- index_bounds_valid = true;
- }
- } else {
- /* The index_bounds_valid field and min/max_index are not used for
- * non-indexed draw calls (they are undefined), but classic drivers
- * need the index bounds. They will be computed manually.
- */
- index_bounds_valid = true;
- }
-
- ib.index_size_shift = util_logbase2(index_size);
-
- /* Single draw or a fallback for user indices. */
- if (num_draws == 1) {
- if (!draws[0].count)
- return;
-
- if (index_size) {
- ib.count = draws[0].count;
-
- if (info->has_user_indices) {
- ib.obj = NULL;
- ib.ptr = (const char*)info->index.user;
- } else {
- ib.obj = info->index.gl_bo;
- ib.ptr = NULL;
- }
- }
-
- struct _mesa_prim prim;
- prim.mode = info->mode;
- prim.begin = 1;
- prim.end = 1;
- prim.start = draws[0].start;
- prim.count = draws[0].count;
- prim.basevertex = index_size ? draws[0].index_bias : 0;
- prim.draw_id = drawid_offset;
-
- if (!index_size) {
- min_index = draws[0].start;
- max_index = draws[0].start + draws[0].count - 1;
- }
-
- st_feedback_draw_vbo(ctx, &prim, 1, index_size ? &ib : NULL,
- index_bounds_valid, info->primitive_restart,
- info->restart_index, min_index, max_index,
- info->instance_count, info->start_instance);
- return;
- }
-
- struct _mesa_prim *prim = get_temp_prims(ctx, num_draws);
- if (!prim)
- return;
-
- unsigned max_count = 0;
- unsigned num_prims = 0;
-
- min_index = ~0u;
- max_index = 0;
-
- for (unsigned i = 0; i < num_draws; i++) {
- if (!draws[i].count)
- continue;
-
- prim[num_prims].mode = info->mode;
- prim[num_prims].begin = 1;
- prim[num_prims].end = 1;
- prim[num_prims].start = draws[i].start;
- prim[num_prims].count = draws[i].count;
- prim[num_prims].basevertex = info->index_size ? draws[i].index_bias : 0;
- prim[num_prims].draw_id = drawid_offset + (info->increment_draw_id ? i : 0);
-
- if (!index_size) {
- min_index = MIN2(min_index, draws[i].start);
- max_index = MAX2(max_index, draws[i].start + draws[i].count - 1);
- }
-
- max_count = MAX2(max_count, prim[num_prims].count);
- num_prims++;
- }
-
- if (info->index_size) {
- ib.count = max_count;
- ib.index_size_shift = util_logbase2(index_size);
-
- if (info->has_user_indices) {
- ib.obj = NULL;
- ib.ptr = (const char*)info->index.user;
- } else {
- ib.obj = info->index.gl_bo;
- ib.ptr = NULL;
- }
- }
-
- if (num_prims)
- st_feedback_draw_vbo(ctx, prim, num_prims, index_size ? &ib : NULL,
- index_bounds_valid, info->primitive_restart,
- info->restart_index, min_index, max_index,
- info->instance_count, info->start_instance);
-}
-
-
-/**
- * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw.
- */
-void
-_mesa_draw_gallium_multimode_fallback(struct gl_context *ctx,
- struct pipe_draw_info *info,
- const struct pipe_draw_start_count_bias *draws,
- const unsigned char *mode,
- unsigned num_draws)
-{
- unsigned i, first;
-
- /* Find consecutive draws where mode doesn't vary. */
- for (i = 0, first = 0; i <= num_draws; i++) {
- if (i == num_draws || mode[i] != mode[first]) {
- info->mode = mode[first];
- ctx->Driver.DrawGallium(ctx, info, 0, &draws[first], i - first);
- first = i;
- }
- }
-}
/**
* Check that element 'j' of the array has reasonable data.
GLbitfield filter);
void
-_mesa_draw_gallium_fallback(struct gl_context *ctx,
- struct pipe_draw_info *info,
- unsigned drawid_offset,
- const struct pipe_draw_start_count_bias *draws,
- unsigned num_draws);
-
-void
-_mesa_draw_gallium_multimode_fallback(struct gl_context *ctx,
- struct pipe_draw_info *info,
- const struct pipe_draw_start_count_bias *draws,
- const unsigned char *mode,
- unsigned num_draws);
-
-void
_mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height,
GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
const GLubyte *bitmap, struct pipe_resource *tex);
st->selection_stage = draw_glselect_stage(ctx, draw);
draw_set_rasterize_stage(draw, st->selection_stage);
/* Plug in new vbo draw function */
- ctx->Driver.DrawGallium = _mesa_draw_gallium_fallback;
- ctx->Driver.DrawGalliumMultiMode = _mesa_draw_gallium_multimode_fallback;
+ ctx->Driver.DrawGallium = st_feedback_draw_vbo;
+ ctx->Driver.DrawGalliumMultiMode = st_feedback_draw_vbo_multi_mode;
}
}
else {
st->feedback_stage = draw_glfeedback_stage(ctx, draw);
draw_set_rasterize_stage(draw, st->feedback_stage);
/* Plug in new vbo draw function */
- ctx->Driver.DrawGallium = _mesa_draw_gallium_fallback;
- ctx->Driver.DrawGalliumMultiMode = _mesa_draw_gallium_multimode_fallback;
+ ctx->Driver.DrawGallium = st_feedback_draw_vbo;
+ ctx->Driver.DrawGalliumMultiMode = st_feedback_draw_vbo_multi_mode;
/* need to generate/use a vertex program that emits pos/color/tex */
if (vp)
st->dirty |= ST_NEW_VERTEX_PROGRAM(st, vp);
/* vertex attrib info we can setup once and re-use */
struct gl_vertex_array_object *VAO;
- struct _mesa_prim prim;
+ struct pipe_draw_info info;
+ struct pipe_draw_start_count_bias draw;
};
GL_RGBA, GL_FALSE, GL_FALSE, GL_FALSE, 0);
_mesa_enable_vertex_array_attrib(ctx, rs->VAO, 0);
- rs->prim.mode = GL_POINTS;
- rs->prim.begin = 1;
- rs->prim.end = 1;
- rs->prim.start = 0;
- rs->prim.count = 1;
+ rs->info.mode = PIPE_PRIM_POINTS;
+ rs->info.instance_count = 1;
+ rs->draw.count = 1;
return rs;
}
rs->VAO->NewVertexElements = true;
_mesa_set_draw_vao(ctx, rs->VAO, VERT_BIT_POS);
- /* Draw the point. */
- st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, true, false, 0, 0, 1, 1, 0);
+ st_feedback_draw_vbo(ctx, &rs->info, 0, &rs->draw, 1);
/* restore draw's rasterization stage depending on rendermode */
if (ctx->RenderMode == GL_FEEDBACK) {
struct draw_context *st_get_draw_context(struct st_context *st);
-extern void
+void
st_feedback_draw_vbo(struct gl_context *ctx,
- const struct _mesa_prim *prims,
- unsigned nr_prims,
- const struct _mesa_index_buffer *ib,
- bool index_bounds_valid,
- bool primitive_restart,
- unsigned restart_index,
- unsigned min_index,
- unsigned max_index,
- unsigned num_instances,
- unsigned base_instance);
+ struct pipe_draw_info *info,
+ unsigned drawid_offset,
+ const struct pipe_draw_start_count_bias *draws,
+ unsigned num_draws);
+
+void
+st_feedback_draw_vbo_multi_mode(struct gl_context *ctx,
+ struct pipe_draw_info *info,
+ const struct pipe_draw_start_count_bias *draws,
+ const unsigned char *mode,
+ unsigned num_draws);
/**
* When drawing with VBOs, the addresses specified with
*/
void
st_feedback_draw_vbo(struct gl_context *ctx,
- const struct _mesa_prim *prims,
- unsigned nr_prims,
- const struct _mesa_index_buffer *ib,
- bool index_bounds_valid,
- bool primitive_restart,
- unsigned restart_index,
- unsigned min_index,
- unsigned max_index,
- unsigned num_instances,
- unsigned base_instance)
+ struct pipe_draw_info *info,
+ unsigned drawid_offset,
+ const struct pipe_draw_start_count_bias *draws,
+ unsigned num_draws)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct pipe_transfer *ib_transfer = NULL;
GLuint i;
const void *mapped_indices = NULL;
- struct pipe_draw_info info;
if (!draw)
return;
- /* Initialize pipe_draw_info. */
- info.primitive_restart = false;
- info.take_index_buffer_ownership = false;
- info.restart_index = 0;
- info.view_mask = 0;
-
st_flush_bitmap_cache(st);
st_invalidate_readpix_cache(st);
st_validate_state(st, ST_PIPELINE_RENDER);
- if (ib && !index_bounds_valid) {
- vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims,
- primitive_restart, restart_index);
- index_bounds_valid = true;
+ if (info->index_size && info->has_user_indices && !info->index_bounds_valid) {
+ vbo_get_minmax_indices_gallium(ctx, info, draws, num_draws);
+ info->index_bounds_valid = true;
}
/* must get these after state validation! */
draw_set_vertex_buffers(draw, 0, num_vbuffers, 0, vbuffers);
draw_set_vertex_elements(draw, vp->num_inputs, velements.velems);
- unsigned start = 0;
-
- if (ib) {
- struct gl_buffer_object *bufobj = ib->obj;
- unsigned index_size = 1 << ib->index_size_shift;
-
- if (index_size == 0)
- goto out_unref_vertex;
-
- if (bufobj && bufobj->Name) {
- start = pointer_to_offset(ib->ptr) >> ib->index_size_shift;
- mapped_indices = pipe_buffer_map(pipe, bufobj->buffer,
+ if (info->index_size) {
+ if (info->has_user_indices) {
+ mapped_indices = info->index.user;
+ } else {
+ info->index.resource = info->index.gl_bo->buffer;
+ if (!info->index.resource)
+ return; /* glBufferData wasn't called on the buffer */
+ mapped_indices = pipe_buffer_map(pipe, info->index.resource,
PIPE_MAP_READ, &ib_transfer);
}
- else {
- mapped_indices = ib->ptr;
- }
- info.index_size = index_size;
- info.index_bounds_valid = index_bounds_valid;
- info.min_index = min_index;
- info.max_index = max_index;
- info.has_user_indices = true;
- info.index.user = mapped_indices;
-
- draw_set_indexes(draw,
- (ubyte *) mapped_indices,
- index_size, ~0);
-
- info.primitive_restart = primitive_restart;
- info.restart_index = restart_index;
- } else {
- info.index_size = 0;
- info.has_user_indices = false;
+ draw_set_indexes(draw, (ubyte *)mapped_indices, info->index_size, ~0);
}
/* set constant buffer 0 */
}
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++) {
- struct pipe_draw_start_count_bias d;
-
- d.count = prims[i].count;
-
- if (!d.count)
- continue;
-
- d.start = start + prims[i].start;
-
- info.mode = prims[i].mode;
- d.index_bias = prims[i].basevertex;
- if (!ib) {
- info.min_index = d.start;
- info.max_index = d.start + d.count - 1;
- }
-
- draw_vbo(draw, &info, prims[i].draw_id, NULL, &d, 1,
- ctx->TessCtrlProgram.patch_vertices);
+ for (i = 0; i < num_draws; i++) {
+ /* TODO: indirect draws */
+ draw_vbo(draw, info, info->increment_draw_id ? i : 0, NULL,
+ &draws[i], 1, ctx->TessCtrlProgram.patch_vertices);
}
/* unmap images */
/*
* unmap vertex/index buffers
*/
- if (ib) {
+ if (info->index_size) {
draw_set_indexes(draw, NULL, 0, 0);
if (ib_transfer)
pipe_buffer_unmap(pipe, ib_transfer);
}
- out_unref_vertex:
for (unsigned buf = 0; buf < num_vbuffers; ++buf) {
if (vb_transfer[buf])
pipe_buffer_unmap(pipe, vb_transfer[buf]);
draw_bind_vertex_shader(draw, NULL);
}
+
+void
+st_feedback_draw_vbo_multi_mode(struct gl_context *ctx,
+ struct pipe_draw_info *info,
+ const struct pipe_draw_start_count_bias *draws,
+ const unsigned char *mode,
+ unsigned num_draws)
+{
+ for (unsigned i = 0; i < num_draws; i++) {
+ info->mode = mode[i];
+ st_feedback_draw_vbo(ctx, info, 0, &draws[i], 1);
+ }
+}