aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-12-19 06:42:05 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2010-12-20 04:41:36 -0500
commit72bfa19c8deb4d1db5ad068c34fd580cb295cbe8 (patch)
treeff1af345701389b7c6b3c8cffa4c6d704f0ccdab
parent3b8d8d91d51c7d15cda51052624169edf7b6dbc6 (diff)
drm/i915: Allow the application to choose the constant addressing mode
The relative-to-general state default is useless as it means having to rewrite the streaming kernels for each batch. Relative-to-surface is more useful, as that stream usually needs to be rewritten for each batch. And absolute addressing mode, vital if you start streaming state, is also only available by adjusting the register... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c35
-rw-r--r--include/drm/i915_drm.h12
5 files changed, 52 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 3f7b20392e26..18746e6cb129 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -778,6 +778,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
778 case I915_PARAM_HAS_COHERENT_RINGS: 778 case I915_PARAM_HAS_COHERENT_RINGS:
779 value = 1; 779 value = 1;
780 break; 780 break;
781 case I915_PARAM_HAS_EXEC_CONSTANTS:
782 value = INTEL_INFO(dev)->gen >= 4;
783 break;
781 default: 784 default:
782 DRM_DEBUG_DRIVER("Unknown parameter %d\n", 785 DRM_DEBUG_DRIVER("Unknown parameter %d\n",
783 param->param); 786 param->param);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2a653cc80395..aac1bf332f75 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -258,6 +258,7 @@ typedef struct drm_i915_private {
258 const struct intel_device_info *info; 258 const struct intel_device_info *info;
259 259
260 int has_gem; 260 int has_gem;
261 int relative_constants_mode;
261 262
262 void __iomem *regs; 263 void __iomem *regs;
263 264
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5a0fbe59dd5b..c79c0b62ef60 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3735,6 +3735,8 @@ i915_gem_load(struct drm_device *dev)
3735 } 3735 }
3736 } 3736 }
3737 3737
3738 dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL;
3739
3738 /* Old X drivers will take 0-2 for front, back, depth buffers */ 3740 /* Old X drivers will take 0-2 for front, back, depth buffers */
3739 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 3741 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3740 dev_priv->fence_reg_start = 3; 3742 dev_priv->fence_reg_start = 3;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index fda0dc858a1f..61129e6759eb 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -957,7 +957,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
957 struct intel_ring_buffer *ring; 957 struct intel_ring_buffer *ring;
958 u32 exec_start, exec_len; 958 u32 exec_start, exec_len;
959 u32 seqno; 959 u32 seqno;
960 int ret, i; 960 int ret, mode, i;
961 961
962 if (!i915_gem_check_execbuffer(args)) { 962 if (!i915_gem_check_execbuffer(args)) {
963 DRM_ERROR("execbuf with invalid offset/length\n"); 963 DRM_ERROR("execbuf with invalid offset/length\n");
@@ -997,6 +997,39 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
997 return -EINVAL; 997 return -EINVAL;
998 } 998 }
999 999
1000 mode = args->flags & I915_EXEC_CONSTANTS_MASK;
1001 switch (mode) {
1002 case I915_EXEC_CONSTANTS_REL_GENERAL:
1003 case I915_EXEC_CONSTANTS_ABSOLUTE:
1004 case I915_EXEC_CONSTANTS_REL_SURFACE:
1005 if (ring == &dev_priv->ring[RCS] &&
1006 mode != dev_priv->relative_constants_mode) {
1007 if (INTEL_INFO(dev)->gen < 4)
1008 return -EINVAL;
1009
1010 if (INTEL_INFO(dev)->gen > 5 &&
1011 mode == I915_EXEC_CONSTANTS_REL_SURFACE)
1012 return -EINVAL;
1013
1014 ret = intel_ring_begin(ring, 4);
1015 if (ret)
1016 return ret;
1017
1018 intel_ring_emit(ring, MI_NOOP);
1019 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
1020 intel_ring_emit(ring, INSTPM);
1021 intel_ring_emit(ring,
1022 I915_EXEC_CONSTANTS_MASK << 16 | mode);
1023 intel_ring_advance(ring);
1024
1025 dev_priv->relative_constants_mode = mode;
1026 }
1027 break;
1028 default:
1029 DRM_ERROR("execbuf with unknown constants: %d\n", mode);
1030 return -EINVAL;
1031 }
1032
1000 if (args->buffer_count < 1) { 1033 if (args->buffer_count < 1) {
1001 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); 1034 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
1002 return -EINVAL; 1035 return -EINVAL;
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index a2776e2807a4..0039f1f97ad8 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -289,6 +289,7 @@ typedef struct drm_i915_irq_wait {
289#define I915_PARAM_HAS_BLT 11 289#define I915_PARAM_HAS_BLT 11
290#define I915_PARAM_HAS_RELAXED_FENCING 12 290#define I915_PARAM_HAS_RELAXED_FENCING 12
291#define I915_PARAM_HAS_COHERENT_RINGS 13 291#define I915_PARAM_HAS_COHERENT_RINGS 13
292#define I915_PARAM_HAS_EXEC_CONSTANTS 14
292 293
293typedef struct drm_i915_getparam { 294typedef struct drm_i915_getparam {
294 int param; 295 int param;
@@ -635,6 +636,17 @@ struct drm_i915_gem_execbuffer2 {
635#define I915_EXEC_RENDER (1<<0) 636#define I915_EXEC_RENDER (1<<0)
636#define I915_EXEC_BSD (2<<0) 637#define I915_EXEC_BSD (2<<0)
637#define I915_EXEC_BLT (3<<0) 638#define I915_EXEC_BLT (3<<0)
639
640/* Used for switching the constants addressing mode on gen4+ RENDER ring.
641 * Gen6+ only supports relative addressing to dynamic state (default) and
642 * absolute addressing.
643 *
644 * These flags are ignored for the BSD and BLT rings.
645 */
646#define I915_EXEC_CONSTANTS_MASK (3<<6)
647#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
648#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6)
649#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
638 __u64 flags; 650 __u64 flags;
639 __u64 rsvd1; 651 __u64 rsvd1;
640 __u64 rsvd2; 652 __u64 rsvd2;