diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 35 | ||||
-rw-r--r-- | include/drm/i915_drm.h | 12 |
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 | ||
293 | typedef struct drm_i915_getparam { | 294 | typedef 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; |