diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 6 | ||||
-rw-r--r-- | include/drm/i915_drm.h | 4 |
4 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 77dace6a01f6..5f4d5893e983 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -781,6 +781,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_RELAXED_DELTA: value = 1; break; + case I915_PARAM_HAS_GEN7_SOL_RESET: + value = 1; + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 11545ff90db6..c01cb2018497 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -971,6 +971,31 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, } static int +i915_reset_gen7_sol_offsets(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int ret, i; + + if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS]) + return 0; + + ret = intel_ring_begin(ring, 4 * 3); + if (ret) + return ret; + + for (i = 0; i < 4; i++) { + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, GEN7_SO_WRITE_OFFSET(i)); + intel_ring_emit(ring, 0); + } + + intel_ring_advance(ring); + + return 0; +} + +static int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file, struct drm_i915_gem_execbuffer2 *args, @@ -1184,6 +1209,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, dev_priv->relative_constants_mode = mode; } + if (args->flags & I915_EXEC_GEN7_SOL_RESET) { + ret = i915_reset_gen7_sol_offsets(dev, ring); + if (ret) + goto err; + } + trace_i915_gem_ring_dispatch(ring, seqno); exec_start = batch_obj->gtt_offset + args->batch_start_offset; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index edced95aa75f..c3afb783cb9d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3736,4 +3736,10 @@ #define CPT_AUD_CNTL_ST_A 0xE50B4 #define CPT_AUD_CNTRL_ST2 0xE50C0 +/* These are the 4 32-bit write offset registers for each stream + * output buffer. It determines the offset from the + * 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to. + */ +#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) + #endif /* _I915_REG_H_ */ diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 1b4da1a9ec0f..924f6a454fed 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -295,6 +295,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_COHERENT_RINGS 13 #define I915_PARAM_HAS_EXEC_CONSTANTS 14 #define I915_PARAM_HAS_RELAXED_DELTA 15 +#define I915_PARAM_HAS_GEN7_SOL_RESET 16 typedef struct drm_i915_getparam { int param; @@ -657,6 +658,9 @@ struct drm_i915_gem_execbuffer2 { __u64 rsvd2; }; +/** Resets the SO write offset registers for transform feedback on gen7. */ +#define I915_EXEC_GEN7_SOL_RESET (1<<8) + struct drm_i915_gem_pin { /** Handle of the buffer to be pinned. */ __u32 handle; |