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:
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user