intel: refactor urb configuration, add intel_urb_config

Patch adds a structure holding urb configuration. This makes it nicer
to pass it around as example for blorp. We need to be able to sometimes
compare with last urb configuration to be able to implement some
workaround.

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26920>
This commit is contained in:
Tapani Pälli
2024-01-09 11:12:08 +02:00
committed by Marge Bot
parent 49c1b404e5
commit a1b885b482
10 changed files with 78 additions and 78 deletions
+16 -19
View File
@@ -6058,49 +6058,46 @@ crocus_upload_dirty_render_state(struct crocus_context *ice,
const struct intel_device_info *devinfo = &batch->screen->devinfo;
bool gs_present = ice->shaders.prog[MESA_SHADER_GEOMETRY] != NULL;
bool tess_present = ice->shaders.prog[MESA_SHADER_TESS_EVAL] != NULL;
unsigned entry_size[4];
struct intel_urb_config urb_cfg;
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
if (!ice->shaders.prog[i]) {
entry_size[i] = 1;
urb_cfg.size[i] = 1;
} else {
struct brw_vue_prog_data *vue_prog_data =
(void *) ice->shaders.prog[i]->prog_data;
entry_size[i] = vue_prog_data->urb_entry_size;
urb_cfg.size[i] = vue_prog_data->urb_entry_size;
}
assert(entry_size[i] != 0);
assert(urb_cfg.size[i] != 0);
}
/* If we're just switching between programs with the same URB requirements,
* skip the rest of the logic.
*/
bool no_change = false;
if (ice->urb.vsize == entry_size[MESA_SHADER_VERTEX] &&
if (ice->urb.vsize == urb_cfg.size[MESA_SHADER_VERTEX] &&
ice->urb.gs_present == gs_present &&
ice->urb.gsize == entry_size[MESA_SHADER_GEOMETRY] &&
ice->urb.gsize == urb_cfg.size[MESA_SHADER_GEOMETRY] &&
ice->urb.tess_present == tess_present &&
ice->urb.hsize == entry_size[MESA_SHADER_TESS_CTRL] &&
ice->urb.dsize == entry_size[MESA_SHADER_TESS_EVAL]) {
ice->urb.hsize == urb_cfg.size[MESA_SHADER_TESS_CTRL] &&
ice->urb.dsize == urb_cfg.size[MESA_SHADER_TESS_EVAL]) {
no_change = true;
}
if (!no_change) {
ice->urb.vsize = entry_size[MESA_SHADER_VERTEX];
ice->urb.vsize = urb_cfg.size[MESA_SHADER_VERTEX];
ice->urb.gs_present = gs_present;
ice->urb.gsize = entry_size[MESA_SHADER_GEOMETRY];
ice->urb.gsize = urb_cfg.size[MESA_SHADER_GEOMETRY];
ice->urb.tess_present = tess_present;
ice->urb.hsize = entry_size[MESA_SHADER_TESS_CTRL];
ice->urb.dsize = entry_size[MESA_SHADER_TESS_EVAL];
ice->urb.hsize = urb_cfg.size[MESA_SHADER_TESS_CTRL];
ice->urb.dsize = urb_cfg.size[MESA_SHADER_TESS_EVAL];
unsigned entries[4];
unsigned start[4];
bool constrained;
intel_get_urb_config(devinfo,
batch->screen->l3_config_3d,
tess_present,
gs_present,
entry_size,
entries, start, NULL, &constrained);
&urb_cfg, NULL, &constrained);
#if GFX_VER == 7
if (devinfo->platform == INTEL_PLATFORM_IVB)
@@ -6109,9 +6106,9 @@ crocus_upload_dirty_render_state(struct crocus_context *ice,
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
crocus_emit_cmd(batch, GENX(3DSTATE_URB_VS), urb) {
urb._3DCommandSubOpcode += i;
urb.VSURBStartingAddress = start[i];
urb.VSURBEntryAllocationSize = entry_size[i] - 1;
urb.VSNumberofURBEntries = entries[i];
urb.VSURBStartingAddress = urb_cfg.start[i];
urb.VSURBEntryAllocationSize = urb_cfg.size[i] - 1;
urb.VSNumberofURBEntries = urb_cfg.entries[i];
}
}
}
+2 -2
View File
@@ -410,8 +410,8 @@ iris_blorp_exec_render(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;
for (int i = 0; i < ARRAY_SIZE(ice->shaders.urb.cfg.size); i++)
ice->shaders.urb.cfg.size[i] = 0;
if (params->src.enabled)
iris_bo_bump_seqno(params->src.addr.buffer, batch->next_seqno,
+1 -3
View File
@@ -714,9 +714,7 @@ struct iris_context {
struct iris_compiled_shader *prog[MESA_SHADER_STAGES];
struct iris_compiled_shader *last_vue_shader;
struct {
unsigned size[4];
unsigned entries[4];
unsigned start[4];
struct intel_urb_config cfg;
bool constrained;
} urb;
+1 -1
View File
@@ -1145,7 +1145,7 @@ check_urb_size(struct iris_context *ice,
unsigned needed_size,
gl_shader_stage stage)
{
unsigned last_allocated_size = ice->shaders.urb.size[stage];
unsigned last_allocated_size = ice->shaders.urb.cfg.size[stage];
/* If the last URB allocation wasn't large enough for our needs,
* flag it as needing to be reconfigured. Otherwise, we can use
+7 -9
View File
@@ -6819,31 +6819,29 @@ iris_upload_dirty_render_state(struct iris_context *ice,
if (dirty & IRIS_DIRTY_URB) {
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
if (!ice->shaders.prog[i]) {
ice->shaders.urb.size[i] = 1;
ice->shaders.urb.cfg.size[i] = 1;
} else {
struct brw_vue_prog_data *vue_prog_data =
(void *) ice->shaders.prog[i]->prog_data;
ice->shaders.urb.size[i] = vue_prog_data->urb_entry_size;
ice->shaders.urb.cfg.size[i] = vue_prog_data->urb_entry_size;
}
assert(ice->shaders.urb.size[i] != 0);
assert(ice->shaders.urb.cfg.size[i] != 0);
}
intel_get_urb_config(screen->devinfo,
screen->l3_config_3d,
ice->shaders.prog[MESA_SHADER_TESS_EVAL] != NULL,
ice->shaders.prog[MESA_SHADER_GEOMETRY] != NULL,
ice->shaders.urb.size,
ice->shaders.urb.entries,
ice->shaders.urb.start,
&ice->shaders.urb.cfg,
&ice->state.urb_deref_block_size,
&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 = ice->shaders.urb.start[i];
urb.VSURBEntryAllocationSize = ice->shaders.urb.size[i] - 1;
urb.VSNumberofURBEntries = ice->shaders.urb.entries[i];
urb.VSURBStartingAddress = ice->shaders.urb.cfg.start[i];
urb.VSURBEntryAllocationSize = ice->shaders.urb.cfg.size[i] - 1;
urb.VSNumberofURBEntries = ice->shaders.urb.cfg.entries[i];
}
}
}
+9 -7
View File
@@ -241,14 +241,16 @@ emit_urb_config(struct blorp_batch *batch,
#if GFX_VER >= 7
assert(sf_entry_size == 0);
const unsigned entry_size[4] = { vs_entry_size, 1, 1, 1 };
unsigned entries[4], start[4];
struct intel_urb_config urb_cfg = {
.size = { vs_entry_size, 1, 1, 1 },
};
bool constrained;
intel_get_urb_config(batch->blorp->compiler->devinfo,
blorp_get_l3_config(batch),
false, false, entry_size,
entries, start, deref_block_size, &constrained);
false, false, &urb_cfg,
deref_block_size, &constrained);
#if GFX_VERx10 == 70
/* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
@@ -269,9 +271,9 @@ emit_urb_config(struct blorp_batch *batch,
for (int i = 0; i <= MESA_SHADER_GEOMETRY; i++) {
blorp_emit(batch, GENX(3DSTATE_URB_VS), urb) {
urb._3DCommandSubOpcode += i;
urb.VSURBStartingAddress = start[i];
urb.VSURBEntryAllocationSize = entry_size[i] - 1;
urb.VSNumberofURBEntries = entries[i];
urb.VSURBStartingAddress = urb_cfg.start[i];
urb.VSURBEntryAllocationSize = urb_cfg.size[i] - 1;
urb.VSNumberofURBEntries = urb_cfg.entries[i];
}
}
+7 -2
View File
@@ -106,11 +106,16 @@ enum intel_urb_deref_block_size {
INTEL_URB_DEREF_BLOCK_SIZE_MESH = 3,
};
struct intel_urb_config {
unsigned size[5];
unsigned entries[5];
unsigned start[5];
};
void intel_get_urb_config(const struct intel_device_info *devinfo,
const struct intel_l3_config *l3_cfg,
bool tess_present, bool gs_present,
const unsigned entry_size[4],
unsigned entries[4], unsigned start[4],
struct intel_urb_config *urb_cfg,
enum intel_urb_deref_block_size *deref_block_size,
bool *constrained);
+13 -13
View File
@@ -64,8 +64,7 @@ void
intel_get_urb_config(const struct intel_device_info *devinfo,
const struct intel_l3_config *l3_cfg,
bool tess_present, bool gs_present,
const unsigned entry_size[4],
unsigned entries[4], unsigned start[4],
struct intel_urb_config *urb_cfg,
enum intel_urb_deref_block_size *deref_block_size,
bool *constrained)
{
@@ -110,7 +109,7 @@ intel_get_urb_config(const struct intel_device_info *devinfo,
*/
unsigned granularity[4];
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
granularity[i] = (entry_size[i] < 9) ? 8 : 1;
granularity[i] = (urb_cfg->size[i] < 9) ? 8 : 1;
}
unsigned min_entries[4] = {
@@ -148,7 +147,7 @@ intel_get_urb_config(const struct intel_device_info *devinfo,
unsigned entry_size_bytes[4];
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
entry_size_bytes[i] = 64 * entry_size[i];
entry_size_bytes[i] = 64 * urb_cfg->size[i];
}
/* Initially, assign each stage the minimum amount of URB space it needs,
@@ -208,20 +207,21 @@ intel_get_urb_config(const struct intel_device_info *devinfo,
* allocated to each stage.
*/
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
entries[i] = chunks[i] * chunk_size_bytes / entry_size_bytes[i];
urb_cfg->entries[i] = chunks[i] * chunk_size_bytes / entry_size_bytes[i];
/* Since we rounded up when computing wants[], this may be slightly
* more than the maximum allowed amount, so correct for that.
*/
entries[i] = MIN2(entries[i], devinfo->urb.max_entries[i]);
urb_cfg->entries[i] = MIN2(urb_cfg->entries[i],
devinfo->urb.max_entries[i]);
/* Ensure that we program a multiple of the granularity. */
entries[i] = ROUND_DOWN_TO(entries[i], granularity[i]);
urb_cfg->entries[i] = ROUND_DOWN_TO(urb_cfg->entries[i], granularity[i]);
/* Finally, sanity check to make sure we have at least the minimum
* number of entries needed for each stage.
*/
assert(entries[i] >= min_entries[i]);
assert(urb_cfg->entries[i] >= min_entries[i]);
}
/* Lay out the URB in pipeline order: push constants, VS, HS, DS, GS. */
@@ -245,12 +245,12 @@ intel_get_urb_config(const struct intel_device_info *devinfo,
int next_urb = first_urb;
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
if (entries[i]) {
start[i] = next_urb;
if (urb_cfg->entries[i]) {
urb_cfg->start[i] = next_urb;
next_urb += chunks[i];
} else {
/* Put disabled stages at the beginning of the valid range */
start[i] = first_urb;
urb_cfg->start[i] = first_urb;
}
}
@@ -278,12 +278,12 @@ intel_get_urb_config(const struct intel_device_info *devinfo,
if (gs_present) {
*deref_block_size = INTEL_URB_DEREF_BLOCK_SIZE_PER_POLY;
} else if (tess_present) {
if (entries[MESA_SHADER_TESS_EVAL] < 324)
if (urb_cfg->entries[MESA_SHADER_TESS_EVAL] < 324)
*deref_block_size = INTEL_URB_DEREF_BLOCK_SIZE_PER_POLY;
else
*deref_block_size = INTEL_URB_DEREF_BLOCK_SIZE_32;
} else {
if (entries[MESA_SHADER_VERTEX] < 192)
if (urb_cfg->entries[MESA_SHADER_VERTEX] < 192)
*deref_block_size = INTEL_URB_DEREF_BLOCK_SIZE_PER_POLY;
else
*deref_block_size = INTEL_URB_DEREF_BLOCK_SIZE_32;
+15 -15
View File
@@ -376,22 +376,24 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
{
const struct intel_device_info *devinfo = device->info;
unsigned entries[4];
unsigned start[4];
struct intel_urb_config urb_cfg = {
.size = { entry_size[0], entry_size[1], entry_size[2], entry_size[3], },
};
bool constrained;
intel_get_urb_config(devinfo, l3_config,
active_stages &
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
active_stages & VK_SHADER_STAGE_GEOMETRY_BIT,
entry_size, entries, start, deref_block_size,
&urb_cfg, deref_block_size,
&constrained);
for (int i = 0; i <= MESA_SHADER_GEOMETRY; i++) {
anv_batch_emit(batch, GENX(3DSTATE_URB_VS), urb) {
urb._3DCommandSubOpcode += i;
urb.VSURBStartingAddress = start[i];
urb.VSURBEntryAllocationSize = entry_size[i] - 1;
urb.VSNumberofURBEntries = entries[i];
urb.VSURBStartingAddress = urb_cfg.start[i];
urb.VSURBEntryAllocationSize = urb_cfg.size[i] - 1;
urb.VSNumberofURBEntries = urb_cfg.entries[i];
}
}
#if GFX_VERx10 >= 125
@@ -458,21 +460,19 @@ emit_urb_setup(struct anv_graphics_pipeline *pipeline,
return;
}
#endif
unsigned entry_size[4];
struct intel_urb_config urb_cfg;
for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
const struct brw_vue_prog_data *prog_data =
!anv_pipeline_has_stage(pipeline, i) ? NULL :
(const struct brw_vue_prog_data *) pipeline->base.shaders[i]->prog_data;
entry_size[i] = prog_data ? prog_data->urb_entry_size : 1;
urb_cfg.size[i] = prog_data ? prog_data->urb_entry_size : 1;
}
struct anv_device *device = pipeline->base.base.device;
const struct intel_device_info *devinfo = device->info;
unsigned entries[4];
unsigned start[4];
bool constrained;
intel_get_urb_config(devinfo,
pipeline->base.base.l3_config,
@@ -480,15 +480,15 @@ emit_urb_setup(struct anv_graphics_pipeline *pipeline,
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
pipeline->base.base.active_stages &
VK_SHADER_STAGE_GEOMETRY_BIT,
entry_size, entries, start, deref_block_size,
&urb_cfg, deref_block_size,
&constrained);
for (int i = 0; i <= MESA_SHADER_GEOMETRY; i++) {
anv_pipeline_emit(pipeline, final.urb, GENX(3DSTATE_URB_VS), urb) {
urb._3DCommandSubOpcode += i;
urb.VSURBStartingAddress = start[i];
urb.VSURBEntryAllocationSize = entry_size[i] - 1;
urb.VSNumberofURBEntries = entries[i];
urb.VSURBStartingAddress = urb_cfg.start[i];
urb.VSURBEntryAllocationSize = urb_cfg.size[i] - 1;
urb.VSNumberofURBEntries = urb_cfg.entries[i];
}
}
#if GFX_VERx10 >= 125
+7 -7
View File
@@ -276,16 +276,16 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
enum intel_urb_deref_block_size *deref_block_size)
{
const struct intel_device_info *devinfo = device->info;
struct intel_urb_config urb_cfg = {
.size = { entry_size[0], entry_size[1], entry_size[2], entry_size[3], },
};
unsigned entries[4];
unsigned start[4];
bool constrained;
intel_get_urb_config(devinfo, l3_config,
active_stages &
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
active_stages & VK_SHADER_STAGE_GEOMETRY_BIT,
entry_size, entries, start, deref_block_size,
&constrained);
&urb_cfg, deref_block_size, &constrained);
#if GFX_VERx10 == 70
/* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
@@ -306,9 +306,9 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
for (int i = 0; i <= MESA_SHADER_GEOMETRY; i++) {
anv_batch_emit(batch, GENX(3DSTATE_URB_VS), urb) {
urb._3DCommandSubOpcode += i;
urb.VSURBStartingAddress = start[i];
urb.VSURBEntryAllocationSize = entry_size[i] - 1;
urb.VSNumberofURBEntries = entries[i];
urb.VSURBStartingAddress = urb_cfg.start[i];
urb.VSURBEntryAllocationSize = urb_cfg.size[i] - 1;
urb.VSNumberofURBEntries = urb_cfg.entries[i];
}
}
}