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