From 351403fe750c1280d2ced27191ca14f718f608ae Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 19 Apr 2022 09:54:19 -0400 Subject: [PATCH] panfrost: Specialize shader descriptors for Valhall Instead of being globbed into the RSD, Valhall uses minimal shader program descriptors. For IDVS, we need separate descriptors for position and varying shaders. It's actually worse -- we need separate descriptors for drawing points and drawing lines/triangles in order to skip over the gl_PointSize write. Adapt prepare_shader to upload all these descriptors. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 62 +++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index ecc001e47d7..4c9f95d9f30 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -4014,8 +4014,8 @@ static void prepare_shader(struct panfrost_shader_state *state, struct panfrost_pool *pool, bool upload) { - struct mali_renderer_state_packed *out = - (struct mali_renderer_state_packed *)&state->partial_rsd; +#if PAN_ARCH <= 7 + void *out = &state->partial_rsd; if (upload) { struct panfrost_ptr ptr = @@ -4028,6 +4028,64 @@ prepare_shader(struct panfrost_shader_state *state, pan_pack(out, RENDERER_STATE, cfg) { pan_shader_prepare_rsd(&state->info, state->bin.gpu, &cfg); } +#else + assert(upload); + + /* The address in the shader program descriptor must be non-null, but + * the entire shader program descriptor may be omitted. + * + * See dEQP-GLES31.functional.compute.basic.empty + */ + if (!state->bin.gpu) + return; + + bool vs = (state->info.stage == MESA_SHADER_VERTEX); + bool secondary_enable = (vs && state->info.vs.secondary_enable); + + unsigned nr_variants = secondary_enable ? 3 : vs ? 2 : 1; + struct panfrost_ptr ptr = pan_pool_alloc_desc_array(&pool->base, + nr_variants, + SHADER_PROGRAM); + + state->state = panfrost_pool_take_ref(pool, ptr.gpu); + + /* Generic, or IDVS/points */ + pan_pack(ptr.cpu, SHADER_PROGRAM, cfg) { + cfg.stage = pan_shader_stage(&state->info); + cfg.primary_shader = true; + cfg.register_allocation = pan_register_allocation(state->info.work_reg_count); + cfg.binary = state->bin.gpu; + cfg.preload.r48_r63 = (state->info.preload >> 48); + + if (cfg.stage == MALI_SHADER_STAGE_FRAGMENT) + cfg.requires_helper_threads = state->info.contains_barrier; + } + + if (!vs) + return; + + /* IDVS/triangles */ + pan_pack(ptr.cpu + pan_size(SHADER_PROGRAM), SHADER_PROGRAM, cfg) { + cfg.stage = pan_shader_stage(&state->info); + cfg.primary_shader = true; + cfg.register_allocation = pan_register_allocation(state->info.work_reg_count); + cfg.binary = state->bin.gpu + state->info.vs.no_psiz_offset; + cfg.preload.r48_r63 = (state->info.preload >> 48); + } + + if (!secondary_enable) + return; + + pan_pack(ptr.cpu + (pan_size(SHADER_PROGRAM) * 2), SHADER_PROGRAM, cfg) { + unsigned work_count = state->info.vs.secondary_work_reg_count; + + cfg.stage = pan_shader_stage(&state->info); + cfg.primary_shader = false; + cfg.register_allocation = pan_register_allocation(work_count); + cfg.binary = state->bin.gpu + state->info.vs.secondary_offset; + cfg.preload.r48_r63 = (state->info.vs.secondary_preload >> 48); + } +#endif } static void