From 80f1d611c5ddca6a719e0a470d3967a3d20ebcda Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 21 Aug 2020 14:35:35 -0400 Subject: [PATCH] panfrost: Use preuploaded shader descriptors For non-fragment shaders, we can just use the preuploaded BO as-is and do no packing/copying at draw-time. Fragment shaders are still a bit of an edge case, in having rasterizer/zsa/blend state in the same descriptor, but now we can specialize that path further for fragment-only. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Tomeu Vizoso Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 119 ++++++++----------- src/gallium/drivers/panfrost/pan_cmdstream.h | 9 +- src/gallium/drivers/panfrost/pan_compute.c | 2 +- src/gallium/drivers/panfrost/pan_context.c | 5 +- 4 files changed, 60 insertions(+), 75 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 7dd43f4e3e9..801a39216f2 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -306,22 +306,6 @@ panfrost_vt_set_draw_info(struct panfrost_context *ctx, } } -static void -panfrost_emit_compute_shader(struct panfrost_context *ctx, - enum pipe_shader_type st, - struct mali_shader_meta *meta) -{ - const struct panfrost_device *dev = pan_device(ctx->base.screen); - struct panfrost_shader_state *ss = panfrost_get_shader_state(ctx, st); - - memset(meta, 0, sizeof(*meta)); - memcpy(&meta->shader, &ss->shader, sizeof(ss->shader)); - memcpy(&meta->midgard_props, &ss->properties, sizeof(ss->properties)); - - if (dev->quirks & IS_BIFROST) - memcpy(&meta->bifrost_preload, &ss->preload, sizeof(ss->preload)); -} - static unsigned translate_tex_wrap(enum pipe_tex_wrap w) { @@ -715,78 +699,77 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx, } } -void -panfrost_emit_shader_meta(struct panfrost_batch *batch, - enum pipe_shader_type st, - struct mali_vertex_tiler_postfix *postfix) +mali_ptr +panfrost_emit_compute_shader_meta(struct panfrost_batch *batch, enum pipe_shader_type stage) { - struct panfrost_context *ctx = batch->ctx; - struct panfrost_shader_state *ss = panfrost_get_shader_state(ctx, st); + struct panfrost_shader_state *ss = panfrost_get_shader_state(batch->ctx, stage); - if (!ss) { - postfix->shader = 0; - return; - } - - struct mali_shader_meta meta; - - /* Add the shader BO to the batch. */ panfrost_batch_add_bo(batch, ss->bo, PAN_BO_ACCESS_PRIVATE | PAN_BO_ACCESS_READ | - panfrost_bo_access_for_stage(st)); + PAN_BO_ACCESS_VERTEX_TILER); - mali_ptr shader_ptr; + panfrost_batch_add_bo(batch, pan_resource(ss->upload.rsrc)->bo, + PAN_BO_ACCESS_PRIVATE | + PAN_BO_ACCESS_READ | + PAN_BO_ACCESS_VERTEX_TILER); - if (st == PIPE_SHADER_FRAGMENT) { - struct panfrost_device *dev = pan_device(ctx->base.screen); - unsigned rt_count = MAX2(ctx->pipe_framebuffer.nr_cbufs, 1); - size_t desc_size = sizeof(meta); - void *rts = NULL; - struct panfrost_transfer xfer; - unsigned rt_size; + return pan_resource(ss->upload.rsrc)->bo->gpu + ss->upload.offset; +} - if (dev->quirks & MIDGARD_SFBD) - rt_size = 0; - else if (dev->quirks & IS_BIFROST) - rt_size = sizeof(struct bifrost_blend_rt); - else - rt_size = sizeof(struct midgard_blend_rt); +mali_ptr +panfrost_emit_frag_shader_meta(struct panfrost_batch *batch) +{ + struct panfrost_context *ctx = batch->ctx; + struct panfrost_shader_state *ss = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT); + struct mali_shader_meta meta; - desc_size += rt_size * rt_count; + /* Add the shader BO to the batch. */ + panfrost_batch_add_bo(batch, ss->bo, + PAN_BO_ACCESS_PRIVATE | + PAN_BO_ACCESS_READ | + PAN_BO_ACCESS_FRAGMENT); - if (rt_size) - rts = rzalloc_size(ctx, rt_size * rt_count); + struct panfrost_device *dev = pan_device(ctx->base.screen); + unsigned rt_count = MAX2(ctx->pipe_framebuffer.nr_cbufs, 1); + size_t desc_size = sizeof(meta); + void *rts = NULL; + struct panfrost_transfer xfer; + unsigned rt_size; + + if (dev->quirks & MIDGARD_SFBD) + rt_size = 0; + else if (dev->quirks & IS_BIFROST) + rt_size = sizeof(struct bifrost_blend_rt); + else + rt_size = sizeof(struct midgard_blend_rt); - struct panfrost_blend_final blend[PIPE_MAX_COLOR_BUFS]; + desc_size += rt_size * rt_count; - for (unsigned c = 0; c < ctx->pipe_framebuffer.nr_cbufs; ++c) - blend[c] = panfrost_get_blend_for_context(ctx, c); + if (rt_size) + rts = rzalloc_size(ctx, rt_size * rt_count); - panfrost_emit_frag_shader(ctx, &meta, blend); + struct panfrost_blend_final blend[PIPE_MAX_COLOR_BUFS]; - if (!(dev->quirks & MIDGARD_SFBD)) - panfrost_emit_blend(batch, rts, blend); - else - batch->draws |= PIPE_CLEAR_COLOR0; + for (unsigned c = 0; c < ctx->pipe_framebuffer.nr_cbufs; ++c) + blend[c] = panfrost_get_blend_for_context(ctx, c); - xfer = panfrost_pool_alloc_aligned(&batch->pool, desc_size, sizeof(meta)); + panfrost_emit_frag_shader(ctx, &meta, blend); - memcpy(xfer.cpu, &meta, sizeof(meta)); - memcpy(xfer.cpu + sizeof(meta), rts, rt_size * rt_count); + if (!(dev->quirks & MIDGARD_SFBD)) + panfrost_emit_blend(batch, rts, blend); + else + batch->draws |= PIPE_CLEAR_COLOR0; - if (rt_size) - ralloc_free(rts); + xfer = panfrost_pool_alloc_aligned(&batch->pool, desc_size, sizeof(meta)); - shader_ptr = xfer.gpu; - } else { - panfrost_emit_compute_shader(ctx, st, &meta); + memcpy(xfer.cpu, &meta, sizeof(meta)); + memcpy(xfer.cpu + sizeof(meta), rts, rt_size * rt_count); - shader_ptr = panfrost_pool_upload(&batch->pool, &meta, - sizeof(meta)); - } + if (rt_size) + ralloc_free(rts); - postfix->shader = shader_ptr; + return xfer.gpu; } void diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.h b/src/gallium/drivers/panfrost/pan_cmdstream.h index c6916033cc1..f03d1a61761 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.h +++ b/src/gallium/drivers/panfrost/pan_cmdstream.h @@ -51,10 +51,11 @@ panfrost_vt_set_draw_info(struct panfrost_context *ctx, unsigned *vertex_count, unsigned *padded_count); -void -panfrost_emit_shader_meta(struct panfrost_batch *batch, - enum pipe_shader_type st, - struct mali_vertex_tiler_postfix *postfix); +mali_ptr +panfrost_emit_compute_shader_meta(struct panfrost_batch *batch, enum pipe_shader_type stage); + +mali_ptr +panfrost_emit_frag_shader_meta(struct panfrost_batch *batch); void panfrost_emit_viewport(struct panfrost_batch *batch, diff --git a/src/gallium/drivers/panfrost/pan_compute.c b/src/gallium/drivers/panfrost/pan_compute.c index 64d86844844..8ad1485a566 100644 --- a/src/gallium/drivers/panfrost/pan_compute.c +++ b/src/gallium/drivers/panfrost/pan_compute.c @@ -119,7 +119,7 @@ panfrost_launch_grid(struct pipe_context *pipe, panfrost_vt_init(ctx, PIPE_SHADER_COMPUTE, &payload.prefix, &payload.postfix); - panfrost_emit_shader_meta(batch, PIPE_SHADER_COMPUTE, &payload.postfix); + payload.postfix.shader = panfrost_emit_compute_shader_meta(batch, PIPE_SHADER_COMPUTE); panfrost_emit_const_buf(batch, PIPE_SHADER_COMPUTE, &payload.postfix); panfrost_emit_shared_memory(batch, info, &payload); diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index bcf0d199bd4..7b0edd6853d 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -325,8 +325,6 @@ panfrost_draw_vbo( ctx->instance_count, &vertex_postfix, &tiler_postfix, &primitive_size); - panfrost_emit_shader_meta(batch, PIPE_SHADER_VERTEX, &vertex_postfix); - panfrost_emit_shader_meta(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); panfrost_emit_sampler_descriptors(batch, PIPE_SHADER_VERTEX, &vertex_postfix); panfrost_emit_sampler_descriptors(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); panfrost_emit_texture_descriptors(batch, PIPE_SHADER_VERTEX, &vertex_postfix); @@ -335,6 +333,9 @@ panfrost_draw_vbo( panfrost_emit_const_buf(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); panfrost_emit_viewport(batch, &tiler_postfix); + vertex_postfix.shader = panfrost_emit_compute_shader_meta(batch, PIPE_SHADER_VERTEX); + tiler_postfix.shader = panfrost_emit_frag_shader_meta(batch); + panfrost_vt_update_primitive_size(ctx, &tiler_prefix, &primitive_size); /* Fire off the draw itself */ -- 2.30.2