diff --git a/src/gallium/drivers/iris/iris_blorp.c b/src/gallium/drivers/iris/iris_blorp.c index a36dfdd6c6f..c08ed8ab2d4 100644 --- a/src/gallium/drivers/iris/iris_blorp.c +++ b/src/gallium/drivers/iris/iris_blorp.c @@ -360,6 +360,9 @@ iris_blorp_exec(struct blorp_batch *blorp_batch, ice->state.dirty |= ~skip_bits; ice->state.stage_dirty |= ~skip_stage_bits; + for (int i = 0; i < ARRAY_SIZE(ice->shaders.urb.size); i++) + ice->shaders.urb.size[i] = 0; + if (params->src.enabled) iris_bo_bump_seqno(params->src.addr.buffer, batch->next_seqno, IRIS_DOMAIN_OTHER_READ); diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c index 9fc6bb389ca..391e0d15da2 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -97,6 +97,7 @@ iris_lost_context_state(struct iris_batch *batch) ice->state.dirty = ~0ull; ice->state.stage_dirty = ~0ull; ice->state.current_hash_scale = 0; + memset(&ice->shaders.urb, 0, sizeof(ice->shaders.urb)); memset(ice->state.last_block, 0, sizeof(ice->state.last_block)); memset(ice->state.last_grid, 0, sizeof(ice->state.last_grid)); batch->last_surface_base_address = ~0ull; diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 830dc223499..ffdd96ec922 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -608,6 +608,12 @@ struct iris_context { struct iris_uncompiled_shader *uncompiled[MESA_SHADER_STAGES]; struct iris_compiled_shader *prog[MESA_SHADER_STAGES]; struct brw_vue_map *last_vue_map; + struct { + unsigned size[4]; + unsigned entries[4]; + unsigned start[4]; + bool constrained; + } urb; /** List of shader variants whose deletion has been deferred for now */ struct list_head deleted_variants[MESA_SHADER_STAGES]; diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index bd123be839b..8d4542ecc10 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -1851,12 +1851,6 @@ iris_update_compiled_shaders(struct iris_context *ice) const uint64_t dirty = ice->state.dirty; const uint64_t stage_dirty = ice->state.stage_dirty; - struct brw_vue_prog_data *old_prog_datas[4]; - if (!(dirty & IRIS_DIRTY_URB)) { - for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) - old_prog_datas[i] = get_vue_prog_data(ice, i); - } - if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_TCS | IRIS_STAGE_DIRTY_UNCOMPILED_TES)) { struct iris_uncompiled_shader *tes = @@ -1931,10 +1925,20 @@ iris_update_compiled_shaders(struct iris_context *ice) /* Changing shader interfaces may require a URB configuration. */ if (!(dirty & IRIS_DIRTY_URB)) { for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) { - struct brw_vue_prog_data *old = old_prog_datas[i]; - struct brw_vue_prog_data *new = get_vue_prog_data(ice, i); - if (!!old != !!new || - (new && new->urb_entry_size != old->urb_entry_size)) { + struct brw_vue_prog_data *prog_data = get_vue_prog_data(ice, i); + + unsigned needed_size = prog_data ? prog_data->urb_entry_size : 0; + unsigned last_allocated_size = ice->shaders.urb.size[i]; + + /* If the last URB allocation wasn't large enough for our needs, + * flag it as needing to be reconfigured. Otherwise, we can use + * the existing config. However, if the URB is constrained, and + * we can shrink our size for this stage, we may be able to gain + * extra concurrency by reconfiguring it to be smaller. Do so. + */ + if (last_allocated_size < needed_size || + (ice->shaders.urb.constrained && + last_allocated_size > needed_size)) { ice->state.dirty |= IRIS_DIRTY_URB; break; } diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 151182b62d2..ca5215e8c9c 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -5581,35 +5581,33 @@ iris_upload_dirty_render_state(struct iris_context *ice, } if (dirty & IRIS_DIRTY_URB) { - unsigned size[4]; - for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) { if (!ice->shaders.prog[i]) { - size[i] = 1; + ice->shaders.urb.size[i] = 1; } else { struct brw_vue_prog_data *vue_prog_data = (void *) ice->shaders.prog[i]->prog_data; - size[i] = vue_prog_data->urb_entry_size; + ice->shaders.urb.size[i] = vue_prog_data->urb_entry_size; } - assert(size[i] != 0); + assert(ice->shaders.urb.size[i] != 0); } - bool constrained; - unsigned entries[4], start[4]; gen_get_urb_config(&batch->screen->devinfo, batch->screen->l3_config_3d, ice->shaders.prog[MESA_SHADER_TESS_EVAL] != NULL, ice->shaders.prog[MESA_SHADER_GEOMETRY] != NULL, - size, entries, start, + ice->shaders.urb.size, + ice->shaders.urb.entries, + ice->shaders.urb.start, &ice->state.urb_deref_block_size, - &constrained); + &ice->shaders.urb.constrained); for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) { iris_emit_cmd(batch, GENX(3DSTATE_URB_VS), urb) { urb._3DCommandSubOpcode += i; - urb.VSURBStartingAddress = start[i]; - urb.VSURBEntryAllocationSize = size[i] - 1; - urb.VSNumberofURBEntries = entries[i]; + urb.VSURBStartingAddress = ice->shaders.urb.start[i]; + urb.VSURBEntryAllocationSize = ice->shaders.urb.size[i] - 1; + urb.VSNumberofURBEntries = ice->shaders.urb.entries[i]; } } }