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:
@@ -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);
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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), ®_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), ®_val, reg) {
|
|
||||||
reg.ReplayMode = enable;
|
|
||||||
reg.ReplayModeMask = true;
|
|
||||||
}
|
|
||||||
iris_emit_lri(batch, CS_CHICKEN1, reg_val);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
Reference in New Issue
Block a user