aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2012-01-03 12:23:29 -0500
committerKeith Packard <keithp@keithp.com>2012-01-03 12:31:18 -0500
commitae662d31264979e52581bd2573bf0b82812f52ab (patch)
tree678d7f4483b6fe9a78e1ece0cb8bdefe1582dcf0 /drivers/gpu
parente959b5db4aacc27bcf92889e658445326ebc4bfb (diff)
drm/i915: Add support for resetting the SO write pointers on gen7.
These registers are automatically incremented by the hardware during transform feedback to track where the next streamed vertex output should go. Unlike the previous generation, which had a packet for setting the corresponding registers to a defined value, gen7 only has MI_LOAD_REGISTER_IMM to do so. That's a secure packet (since it loads an arbitrary register), so we need to do it from the kernel, and it needs to be settable atomically with the batchbuffer execution so that two clients doing transform feedback don't stomp on each others' state. Instead of building a more complicated interface involcing setting the registers to a specific value, just set them to 0 when asked and userland can tweak its pointers accordingly. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c31
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h6
3 files changed, 40 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,
781 case I915_PARAM_HAS_RELAXED_DELTA: 781 case I915_PARAM_HAS_RELAXED_DELTA:
782 value = 1; 782 value = 1;
783 break; 783 break;
784 case I915_PARAM_HAS_GEN7_SOL_RESET:
785 value = 1;
786 break;
784 default: 787 default:
785 DRM_DEBUG_DRIVER("Unknown parameter %d\n", 788 DRM_DEBUG_DRIVER("Unknown parameter %d\n",
786 param->param); 789 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,
971} 971}
972 972
973static int 973static int
974i915_reset_gen7_sol_offsets(struct drm_device *dev,
975 struct intel_ring_buffer *ring)
976{
977 drm_i915_private_t *dev_priv = dev->dev_private;
978 int ret, i;
979
980 if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS])
981 return 0;
982
983 ret = intel_ring_begin(ring, 4 * 3);
984 if (ret)
985 return ret;
986
987 for (i = 0; i < 4; i++) {
988 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
989 intel_ring_emit(ring, GEN7_SO_WRITE_OFFSET(i));
990 intel_ring_emit(ring, 0);
991 }
992
993 intel_ring_advance(ring);
994
995 return 0;
996}
997
998static int
974i915_gem_do_execbuffer(struct drm_device *dev, void *data, 999i915_gem_do_execbuffer(struct drm_device *dev, void *data,
975 struct drm_file *file, 1000 struct drm_file *file,
976 struct drm_i915_gem_execbuffer2 *args, 1001 struct drm_i915_gem_execbuffer2 *args,
@@ -1184,6 +1209,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1184 dev_priv->relative_constants_mode = mode; 1209 dev_priv->relative_constants_mode = mode;
1185 } 1210 }
1186 1211
1212 if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
1213 ret = i915_reset_gen7_sol_offsets(dev, ring);
1214 if (ret)
1215 goto err;
1216 }
1217
1187 trace_i915_gem_ring_dispatch(ring, seqno); 1218 trace_i915_gem_ring_dispatch(ring, seqno);
1188 1219
1189 exec_start = batch_obj->gtt_offset + args->batch_start_offset; 1220 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 @@
3736#define CPT_AUD_CNTL_ST_A 0xE50B4 3736#define CPT_AUD_CNTL_ST_A 0xE50B4
3737#define CPT_AUD_CNTRL_ST2 0xE50C0 3737#define CPT_AUD_CNTRL_ST2 0xE50C0
3738 3738
3739/* These are the 4 32-bit write offset registers for each stream
3740 * output buffer. It determines the offset from the
3741 * 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to.
3742 */
3743#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4)
3744
3739#endif /* _I915_REG_H_ */ 3745#endif /* _I915_REG_H_ */