From: Kenneth Graunke Date: Tue, 2 Jan 2018 22:26:41 +0000 (-0800) Subject: intel: Apply Geminilake "Barrier Mode" workaround. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8eadc2fb8fe395ea0a8202217bd5545978962d1d;p=mesa.git intel: Apply Geminilake "Barrier Mode" workaround. Apparently, Geminilake requires you to whack a chicken bit to select either compute or tessellation mode for barriers. The recommendation is to switch between them at PIPELINE_SELECT time. We may not need to do this all the time, but I don't know that it hurts either. PIPELINE_SELECT is already a pretty giant stall. This appears to fix hangs in tessellation control shaders with barriers on Geminilake. Note that this requires a corresponding kernel change, drm/i915: Whitelist SLICE_COMMON_ECO_CHICKEN1 on Geminilake. in order for the register write to actually happen. Without an updated kernel, this register write will be noop'd and the fix will not work. Reviewed-by: Rafael Antognolli --- diff --git a/src/intel/genxml/gen9.xml b/src/intel/genxml/gen9.xml index 1422463693d..f07ed748ac7 100644 --- a/src/intel/genxml/gen9.xml +++ b/src/intel/genxml/gen9.xml @@ -3710,6 +3710,14 @@ + + + + + + + + diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index b7253d52513..ac95f3ad05a 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -2734,6 +2734,8 @@ static void genX(flush_pipeline_select)(struct anv_cmd_buffer *cmd_buffer, uint32_t pipeline) { + UNUSED const struct gen_device_info *devinfo = &cmd_buffer->device->info; + if (cmd_buffer->state.current_pipeline == pipeline) return; @@ -2784,6 +2786,25 @@ genX(flush_pipeline_select)(struct anv_cmd_buffer *cmd_buffer, ps.PipelineSelection = pipeline; } +#if GEN_GEN == 9 + if (devinfo->is_geminilake) { + /* Project: DevGLK + * + * "This chicken bit works around a hardware issue with barrier logic + * encountered when switching between GPGPU and 3D pipelines. To + * workaround the issue, this mode bit should be set after a pipeline + * is selected." + */ + uint32_t scec; + anv_pack_struct(&scec, GENX(SLICE_COMMON_ECO_CHICKEN1), + .GLKBarrierMode = + pipeline == GPGPU ? GLK_BARRIER_MODE_GPGPU + : GLK_BARRIER_MODE_3D_HULL, + .GLKBarrierModeMask = 1); + emit_lri(&cmd_buffer->batch, GENX(SLICE_COMMON_ECO_CHICKEN1_num), scec); + } +#endif + cmd_buffer->state.current_pipeline = pipeline; } diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 99d41cf1a56..8bf6f68b67c 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1656,4 +1656,9 @@ enum brw_pixel_shader_coverage_mask_mode { #define CS_DEBUG_MODE2 0x20d8 /* Gen9+ */ # define CSDBG2_CONSTANT_BUFFER_ADDRESS_OFFSET_DISABLE (1 << 4) +#define SLICE_COMMON_ECO_CHICKEN1 0x731c /* Gen9+ */ +# define GLK_SCEC_BARRIER_MODE_GPGPU (0 << 7) +# define GLK_SCEC_BARRIER_MODE_3D_HULL (1 << 7) +# define GLK_SCEC_BARRIER_MODE_MASK REG_MASK(1 << 7) + #endif diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index a1ac0abe285..c4ef6812bff 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -516,6 +516,21 @@ brw_emit_select_pipeline(struct brw_context *brw, enum brw_pipeline pipeline) OUT_BATCH(0); ADVANCE_BATCH(); } + + if (devinfo->is_geminilake) { + /* Project: DevGLK + * + * "This chicken bit works around a hardware issue with barrier logic + * encountered when switching between GPGPU and 3D pipelines. To + * workaround the issue, this mode bit should be set after a pipeline + * is selected." + */ + const unsigned barrier_mode = + pipeline == BRW_RENDER_PIPELINE ? GLK_SCEC_BARRIER_MODE_3D_HULL + : GLK_SCEC_BARRIER_MODE_GPGPU; + brw_load_register_imm32(brw, SLICE_COMMON_ECO_CHICKEN1, + barrier_mode | GLK_SCEC_BARRIER_MODE_MASK); + } } /**