panfrost: Hook up indirect draw support
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8700>
This commit is contained in:
parent
54526d8eca
commit
d760a995e3
|
@ -2237,11 +2237,14 @@ panfrost_emit_vertex_tiler_jobs(struct panfrost_batch *batch,
|
|||
|
||||
unsigned vertex = panfrost_add_job(&batch->pool, &batch->scoreboard,
|
||||
MALI_JOB_TYPE_VERTEX, false, false,
|
||||
0, 0, vertex_job, false);
|
||||
ctx->indirect_draw ?
|
||||
batch->indirect_draw_job_id : 0,
|
||||
0, vertex_job, false);
|
||||
|
||||
if (ctx->rasterizer->base.rasterizer_discard)
|
||||
return;
|
||||
|
||||
panfrost_add_job(&batch->pool, &batch->scoreboard, MALI_JOB_TYPE_TILER,
|
||||
false, false, vertex, 0, tiler_job, false);
|
||||
panfrost_add_job(&batch->pool, &batch->scoreboard,
|
||||
MALI_JOB_TYPE_TILER, false, false,
|
||||
vertex, 0, tiler_job, false);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "midgard_pack.h"
|
||||
#include "pan_screen.h"
|
||||
#include "pan_cmdstream.h"
|
||||
#include "pan_indirect_draw.h"
|
||||
#include "pan_util.h"
|
||||
#include "decode.h"
|
||||
#include "util/pan_lower_framebuffer.h"
|
||||
|
@ -596,7 +597,137 @@ panfrost_indirect_draw(struct panfrost_context *ctx,
|
|||
return;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
/* Indirect draw count and multi-draw not supported. */
|
||||
assert(indirect->draw_count == 1 && !indirect->indirect_draw_count);
|
||||
|
||||
/* TODO: update statistics (see panfrost_statistics_record()) */
|
||||
/* TODO: Increment transform feedback offsets */
|
||||
assert(ctx->streamout.num_targets == 0);
|
||||
|
||||
struct panfrost_device *dev = pan_device(ctx->base.screen);
|
||||
|
||||
assert(ctx->draw_modes & (1 << info->mode));
|
||||
ctx->active_prim = info->mode;
|
||||
ctx->indirect_draw = true;
|
||||
|
||||
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
|
||||
|
||||
/* Don't add too many jobs to a single batch */
|
||||
if (batch->scoreboard.job_index + (indirect->draw_count * 3) > 10000)
|
||||
batch = panfrost_get_fresh_batch_for_fbo(ctx);
|
||||
|
||||
panfrost_batch_set_requirements(batch);
|
||||
|
||||
mali_ptr shared_mem = panfrost_batch_reserve_framebuffer(batch);
|
||||
|
||||
struct panfrost_ptr tiler =
|
||||
panfrost_pool_alloc_aligned(&batch->pool,
|
||||
pan_is_bifrost(dev) ?
|
||||
MALI_BIFROST_TILER_JOB_LENGTH :
|
||||
MALI_MIDGARD_TILER_JOB_LENGTH,
|
||||
64);
|
||||
struct panfrost_ptr vertex =
|
||||
panfrost_pool_alloc_aligned(&batch->pool,
|
||||
MALI_COMPUTE_JOB_LENGTH,
|
||||
64);
|
||||
|
||||
struct panfrost_shader_state *vs =
|
||||
panfrost_get_shader_state(ctx, PIPE_SHADER_VERTEX);
|
||||
|
||||
struct panfrost_bo *index_buf = NULL;
|
||||
|
||||
if (info->index_size) {
|
||||
assert(!info->has_user_indices);
|
||||
index_buf = pan_resource(info->index.resource)->bo;
|
||||
panfrost_batch_add_bo(batch,
|
||||
index_buf,
|
||||
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ |
|
||||
PAN_BO_ACCESS_VERTEX_TILER);
|
||||
}
|
||||
|
||||
mali_ptr varyings = 0, vs_vary = 0, fs_vary = 0, pos = 0, psiz = 0;
|
||||
unsigned varying_buf_count;
|
||||
|
||||
/* We want to create templates, set all count fields to 0 to reflect
|
||||
* that.
|
||||
*/
|
||||
ctx->instance_count = ctx->vertex_count = ctx->padded_count = 0;
|
||||
ctx->offset_start = 0;
|
||||
|
||||
panfrost_emit_varying_descriptor(batch, 0,
|
||||
&vs_vary, &fs_vary, &varyings,
|
||||
&varying_buf_count, &pos, &psiz);
|
||||
|
||||
mali_ptr attribs, attrib_bufs;
|
||||
attribs = panfrost_emit_vertex_data(batch, &attrib_bufs);
|
||||
|
||||
/* Zero-ed invocation, the compute job will update it. */
|
||||
static struct mali_invocation_packed invocation;
|
||||
|
||||
/* Fire off the draw itself */
|
||||
panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem,
|
||||
vs_vary, varyings, attribs, attrib_bufs,
|
||||
vertex.cpu);
|
||||
panfrost_draw_emit_tiler(batch, info, NULL, &invocation, shared_mem,
|
||||
index_buf ? index_buf->ptr.gpu : 0,
|
||||
fs_vary, varyings, pos, psiz, tiler.cpu);
|
||||
|
||||
/* Add the varying heap BO to the batch if we're allocating varyings. */
|
||||
if (varyings) {
|
||||
panfrost_batch_add_bo(batch,
|
||||
dev->indirect_draw_shaders.varying_heap,
|
||||
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_RW |
|
||||
PAN_BO_ACCESS_VERTEX_TILER);
|
||||
}
|
||||
|
||||
assert(indirect->buffer);
|
||||
|
||||
struct panfrost_resource *draw_buf = pan_resource(indirect->buffer);
|
||||
|
||||
/* Don't count images: those attributes don't need to be patched. */
|
||||
unsigned attrib_count =
|
||||
vs->info.attribute_count -
|
||||
util_bitcount(ctx->image_mask[PIPE_SHADER_VERTEX]);
|
||||
|
||||
panfrost_batch_add_bo(batch, draw_buf->bo,
|
||||
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ |
|
||||
PAN_BO_ACCESS_VERTEX_TILER);
|
||||
|
||||
struct pan_indirect_draw_info draw_info = {
|
||||
.last_indirect_draw = batch->indirect_draw_job_id,
|
||||
.draw_buf = draw_buf->bo->ptr.gpu + indirect->offset,
|
||||
.index_buf = index_buf ? index_buf->ptr.gpu : 0,
|
||||
.vertex_job = vertex.gpu,
|
||||
.tiler_job = tiler.gpu,
|
||||
.attrib_bufs = attrib_bufs,
|
||||
.attribs = attribs,
|
||||
.attrib_count = attrib_count,
|
||||
.varying_bufs = varyings,
|
||||
.index_size = info->index_size,
|
||||
};
|
||||
|
||||
if (panfrost_writes_point_size(ctx))
|
||||
draw_info.flags |= PAN_INDIRECT_DRAW_UPDATE_PRIM_SIZE;
|
||||
|
||||
if (vs->info.vs.writes_point_size)
|
||||
draw_info.flags |= PAN_INDIRECT_DRAW_HAS_PSIZ;
|
||||
|
||||
|
||||
if (info->primitive_restart) {
|
||||
draw_info.restart_index = info->restart_index;
|
||||
draw_info.flags |= PAN_INDIRECT_DRAW_PRIMITIVE_RESTART;
|
||||
}
|
||||
|
||||
batch->indirect_draw_job_id =
|
||||
panfrost_emit_indirect_draw(&batch->pool,
|
||||
&batch->scoreboard,
|
||||
&draw_info,
|
||||
&batch->indirect_draw_ctx);
|
||||
|
||||
panfrost_emit_vertex_tiler_jobs(batch, &vertex, &tiler);
|
||||
|
||||
/* Adjust the batch stack size based on the new shader stack sizes. */
|
||||
panfrost_batch_adjust_stack_size(batch);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -125,6 +125,10 @@ struct panfrost_batch {
|
|||
|
||||
/* Batch dependencies */
|
||||
struct util_dynarray dependencies;
|
||||
|
||||
/* Indirect draw data */
|
||||
struct panfrost_ptr indirect_draw_ctx;
|
||||
unsigned indirect_draw_job_id;
|
||||
};
|
||||
|
||||
/* Functions for managing the above */
|
||||
|
|
|
@ -301,6 +301,9 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||
case PIPE_CAP_SHAREABLE_SHADERS:
|
||||
return 0;
|
||||
|
||||
case PIPE_CAP_DRAW_INDIRECT:
|
||||
return is_deqp;
|
||||
|
||||
default:
|
||||
return u_pipe_screen_get_param_defaults(screen, param);
|
||||
}
|
||||
|
@ -686,6 +689,7 @@ panfrost_destroy_screen(struct pipe_screen *pscreen)
|
|||
{
|
||||
struct panfrost_device *dev = pan_device(pscreen);
|
||||
|
||||
panfrost_cleanup_indirect_draw_shaders(dev);
|
||||
pan_blend_shaders_cleanup(dev);
|
||||
|
||||
if (dev->ro)
|
||||
|
@ -860,6 +864,7 @@ panfrost_create_screen(int fd, struct renderonly *ro)
|
|||
panfrost_resource_screen_init(&screen->base);
|
||||
panfrost_init_blit_shaders(dev);
|
||||
pan_blend_shaders_init(dev);
|
||||
panfrost_init_indirect_draw_shaders(dev);
|
||||
|
||||
return &screen->base;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue