iris: add preemption support on gen9

this is basically just porting the following two commits to gallium:
d8b50e152a
5c454661c6

resolves kwg/mesa#49

Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
This commit is contained in:
Mike Blumenkrantz 2019-04-11 10:07:15 -04:00 committed by Rafael Antognolli
parent 21688a306b
commit 7315882023
3 changed files with 99 additions and 0 deletions

View file

@ -542,6 +542,8 @@ 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;
@ -816,4 +818,7 @@ void iris_render_cache_add_bo(struct iris_batch *batch,
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);
#endif

View file

@ -39,6 +39,67 @@
#include "iris_context.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
* related packets as dirty if necessary.
@ -116,6 +177,7 @@ void
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;
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
@ -131,6 +193,9 @@ 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);
iris_update_compiled_shaders(ice);
if (ice->state.dirty & IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES) {

View file

@ -6278,3 +6278,32 @@ 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