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 <michael.blumenkrantz@gmail.com>
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
This commit is contained in:
Kenneth Graunke
2019-04-24 16:43:36 -07:00
parent 383f406591
commit aa7306b4cf
4 changed files with 102 additions and 98 deletions

View File

@@ -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.init_render_context(screen, &ice->batches[IRIS_BATCH_RENDER],
&ice->vtbl, &ice->dbg); &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.init_compute_context(screen, &ice->batches[IRIS_BATCH_COMPUTE],
&ice->vtbl, &ice->dbg); &ice->vtbl, &ice->dbg);

View File

@@ -542,8 +542,6 @@ struct iris_context {
/** Bitfield of which vertex buffers are bound (non-null). */ /** Bitfield of which vertex buffers are bound (non-null). */
uint64_t bound_vertex_buffers; uint64_t bound_vertex_buffers;
bool object_preemption; /**< Object level preemption enabled. */
bool primitive_restart; bool primitive_restart;
unsigned cut_index; unsigned cut_index;
enum pipe_prim_type prim_mode:8; 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); void iris_depth_cache_add_bo(struct iris_batch *batch, struct iris_bo *bo);
/* iris_state.c */ /* iris_state.c */
void gen9_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable); void gen9_toggle_preemption(struct iris_context *ice,
void gen10_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable); struct iris_batch *batch,
const struct pipe_draw_info *draw);
#endif #endif

View File

@@ -39,67 +39,6 @@
#include "iris_context.h" #include "iris_context.h"
#include "iris_defines.h" #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 * Record the current primitive mode and restart information, flagging
* related packets as dirty if necessary. * 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_context *ice = (struct iris_context *) ctx;
struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen; 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]; struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_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); iris_update_draw_info(ice, info);
if (screen->devinfo.gen == 9) if (devinfo->gen == 9)
gen9_emit_preempt_wa(ice, batch, info); gen9_toggle_preemption(ice, batch, info);
iris_update_compiled_shaders(ice); iris_update_compiled_shaders(ice);

View File

@@ -653,6 +653,24 @@ iris_emit_default_l3_config(struct iris_batch *batch,
iris_emit_l3_config(batch, cfg, has_slm, wants_dc_cache); 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), &reg_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. * 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; 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 static void
@@ -826,6 +849,11 @@ struct iris_genx_state {
uint32_t so_buffers[4 * GENX(3DSTATE_SO_BUFFER_length)]; uint32_t so_buffers[4 * GENX(3DSTATE_SO_BUFFER_length)];
#if GEN_GEN == 9
/* Is object level preemption enabled? */
bool object_preemption;
#endif
struct { struct {
#if GEN_GEN == 8 #if GEN_GEN == 8
struct brw_image_param image_param[PIPE_MAX_SHADER_IMAGES]; 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 void
genX(init_state)(struct iris_context *ice) 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), &reg_val, reg) {
reg.ReplayMode = enable;
reg.ReplayModeMask = true;
}
iris_emit_lri(batch, CS_CHICKEN1, reg_val);
}
#endif