aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;