From aa7306b4cfcae3898f5b8ff2ef3022a0e6329649 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 24 Apr 2019 16:43:36 -0700 Subject: [PATCH] iris: Some tidying for preemption support Just enable it during init_render_context on Gen10+, and move the Gen9 state tracking into iris_genx_state so it only exists on Gen9. Reviewed-by: Mike Blumenkrantz Reviewed-by: Rafael Antognolli --- src/gallium/drivers/iris/iris_context.c | 2 - src/gallium/drivers/iris/iris_context.h | 7 +- src/gallium/drivers/iris/iris_draw.c | 66 +---------------- src/gallium/drivers/iris/iris_state.c | 125 ++++++++++++++++++++++++-------- 4 files changed, 102 insertions(+), 98 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c index 91cd6a0..a1d1175 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -218,8 +218,6 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) ice->vtbl.init_render_context(screen, &ice->batches[IRIS_BATCH_RENDER], &ice->vtbl, &ice->dbg); - if (screen->devinfo.gen == 10) - gen10_iris_enable_obj_preemption(ice, &ice->batches[IRIS_BATCH_RENDER], true); ice->vtbl.init_compute_context(screen, &ice->batches[IRIS_BATCH_COMPUTE], &ice->vtbl, &ice->dbg); diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 79e78d0..1153cb8 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -542,8 +542,6 @@ struct iris_context { /** Bitfield of which vertex buffers are bound (non-null). */ uint64_t bound_vertex_buffers; - bool object_preemption; /**< Object level preemption enabled. */ - bool primitive_restart; unsigned cut_index; enum pipe_prim_type prim_mode:8; @@ -819,6 +817,7 @@ void iris_cache_flush_for_depth(struct iris_batch *batch, struct iris_bo *bo); void iris_depth_cache_add_bo(struct iris_batch *batch, struct iris_bo *bo); /* iris_state.c */ -void gen9_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable); -void gen10_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable); +void gen9_toggle_preemption(struct iris_context *ice, + struct iris_batch *batch, + const struct pipe_draw_info *draw); #endif diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c index c859d93..94af728 100644 --- a/src/gallium/drivers/iris/iris_draw.c +++ b/src/gallium/drivers/iris/iris_draw.c @@ -40,67 +40,6 @@ #include "iris_defines.h" /** - * Implement workarounds for preemption: - * - WaDisableMidObjectPreemptionForGSLineStripAdj - * - WaDisableMidObjectPreemptionForTrifanOrPolygon - * - WaDisableMidObjectPreemptionForLineLoop - * - WA#0798 - */ -static void -gen9_emit_preempt_wa(struct iris_context *ice, struct iris_batch *batch, - const struct pipe_draw_info *info) -{ - bool object_preemption = true; - struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; - - /* Only apply these workarounds for gen9 */ - assert(screen->devinfo.gen == 9); - - /* WaDisableMidObjectPreemptionForGSLineStripAdj - * - * WA: Disable mid-draw preemption when draw-call is a linestrip_adj and - * GS is enabled. - */ - if (ice->state.prim_mode == PIPE_PRIM_LINE_STRIP_ADJACENCY && - ice->shaders.prog[MESA_SHADER_GEOMETRY]) - object_preemption = false; - - /* WaDisableMidObjectPreemptionForTrifanOrPolygon - * - * TriFan miscompare in Execlist Preemption test. Cut index that is on a - * previous context. End the previous, the resume another context with a - * tri-fan or polygon, and the vertex count is corrupted. If we prempt - * again we will cause corruption. - * - * WA: Disable mid-draw preemption when draw-call has a tri-fan. - */ - if (ice->state.prim_mode == PIPE_PRIM_TRIANGLE_FAN) - object_preemption = false; - - /* WaDisableMidObjectPreemptionForLineLoop - * - * VF Stats Counters Missing a vertex when preemption enabled. - * - * WA: Disable mid-draw preemption when the draw uses a lineloop - * topology. - */ - if (ice->state.prim_mode == PIPE_PRIM_LINE_LOOP) - object_preemption = false; - - /* WA#0798 - * - * VF is corrupting GAFS data when preempted on an instance boundary and - * replayed with instancing enabled. - * - * WA: Disable preemption when using instanceing. - */ - if (info->instance_count > 1) - object_preemption = false; - - gen9_iris_enable_obj_preemption(ice, batch, object_preemption); -} - -/** * Record the current primitive mode and restart information, flagging * related packets as dirty if necessary. */ @@ -178,6 +117,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) { struct iris_context *ice = (struct iris_context *) ctx; struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen; + const struct gen_device_info *devinfo = &screen->devinfo; struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER) @@ -193,8 +133,8 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) iris_update_draw_info(ice, info); - if (screen->devinfo.gen == 9) - gen9_emit_preempt_wa(ice, batch, info); + if (devinfo->gen == 9) + gen9_toggle_preemption(ice, batch, info); iris_update_compiled_shaders(ice); diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 92275b4..c0c0ed0 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -653,6 +653,24 @@ iris_emit_default_l3_config(struct iris_batch *batch, iris_emit_l3_config(batch, cfg, has_slm, wants_dc_cache); } +#if GEN_GEN >= 9 +static void +iris_enable_obj_preemption(struct iris_batch *batch, bool enable) +{ + uint32_t reg_val; + + /* A fixed function pipe flush is required before modifying this field */ + iris_emit_end_of_pipe_sync(batch, PIPE_CONTROL_RENDER_TARGET_FLUSH); + + /* enable object level preemption */ + iris_pack_state(GENX(CS_CHICKEN1), ®_val, reg) { + reg.ReplayMode = enable; + reg.ReplayModeMask = true; + } + iris_emit_lri(batch, CS_CHICKEN1, reg_val); +} +#endif + /** * Upload the initial GPU state for a render context. * @@ -775,6 +793,11 @@ iris_init_render_context(struct iris_screen *screen, alloc.ConstantBufferSize = i == MESA_SHADER_FRAGMENT ? 8 : 6; } } + +#if GEN_GEN == 10 + /* Gen11+ is enabled for us by the kernel. */ + iris_enable_obj_preemption(batch, true); +#endif } static void @@ -826,6 +849,11 @@ struct iris_genx_state { uint32_t so_buffers[4 * GENX(3DSTATE_SO_BUFFER_length)]; +#if GEN_GEN == 9 + /* Is object level preemption enabled? */ + bool object_preemption; +#endif + struct { #if GEN_GEN == 8 struct brw_image_param image_param[PIPE_MAX_SHADER_IMAGES]; @@ -6180,6 +6208,74 @@ genX(emit_urb_setup)(struct iris_context *ice, } } +#if GEN_GEN == 9 +/** + * Preemption on Gen9 has to be enabled or disabled in various cases. + * + * See these workarounds for preemption: + * - WaDisableMidObjectPreemptionForGSLineStripAdj + * - WaDisableMidObjectPreemptionForTrifanOrPolygon + * - WaDisableMidObjectPreemptionForLineLoop + * - WA#0798 + * + * We don't put this in the vtable because it's only used on Gen9. + */ +void +gen9_toggle_preemption(struct iris_context *ice, + struct iris_batch *batch, + const struct pipe_draw_info *draw) +{ + struct iris_genx_state *genx = ice->state.genx; + bool object_preemption = true; + + /* WaDisableMidObjectPreemptionForGSLineStripAdj + * + * "WA: Disable mid-draw preemption when draw-call is a linestrip_adj + * and GS is enabled." + */ + if (draw->mode == PIPE_PRIM_LINE_STRIP_ADJACENCY && + ice->shaders.prog[MESA_SHADER_GEOMETRY]) + object_preemption = false; + + /* WaDisableMidObjectPreemptionForTrifanOrPolygon + * + * "TriFan miscompare in Execlist Preemption test. Cut index that is + * on a previous context. End the previous, the resume another context + * with a tri-fan or polygon, and the vertex count is corrupted. If we + * prempt again we will cause corruption. + * + * WA: Disable mid-draw preemption when draw-call has a tri-fan." + */ + if (draw->mode == PIPE_PRIM_TRIANGLE_FAN) + object_preemption = false; + + /* WaDisableMidObjectPreemptionForLineLoop + * + * "VF Stats Counters Missing a vertex when preemption enabled. + * + * WA: Disable mid-draw preemption when the draw uses a lineloop + * topology." + */ + if (draw->mode == PIPE_PRIM_LINE_LOOP) + object_preemption = false; + + /* WA#0798 + * + * "VF is corrupting GAFS data when preempted on an instance boundary + * and replayed with instancing enabled. + * + * WA: Disable preemption when using instanceing." + */ + if (draw->instance_count > 1) + object_preemption = false; + + if (genx->object_preemption != object_preemption) { + iris_enable_obj_preemption(batch, object_preemption); + genx->object_preemption = object_preemption; + } +} +#endif + void genX(init_state)(struct iris_context *ice) { @@ -6278,32 +6374,3 @@ genX(init_state)(struct iris_context *ice) }; } } - -#if GEN_GEN >= 9 -/* not called externally */ -void gen11_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable); - -void -genX(iris_enable_obj_preemption)(struct iris_context *ice, struct iris_batch *batch, bool enable) -{ - uint32_t reg_val; - struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; - - assert(screen->devinfo.gen >= 9); - - if (enable == ice->state.object_preemption) - return; - ice->state.object_preemption = enable; - - /* A fixed function pipe flush is required before modifying this field */ - iris_emit_end_of_pipe_sync(batch, - PIPE_CONTROL_RENDER_TARGET_FLUSH); - - /* enable object level preemption */ - iris_pack_state(GENX(CS_CHICKEN1), ®_val, reg) { - reg.ReplayMode = enable; - reg.ReplayModeMask = true; - } - iris_emit_lri(batch, CS_CHICKEN1, reg_val); -} -#endif -- 2.7.4