diff options
author | Jonathan Gray <jsg@jsg.id.au> | 2013-03-09 13:31:55 +1100 |
---|---|---|
committer | Jonathan Gray <jsg@jsg.id.au> | 2013-03-09 13:47:15 +1100 |
commit | 07bd0afb1d46fb6c48eda127580c44e060f7162d (patch) | |
tree | ea517cb72f310690abc65824a44d0ad5e14756ce | |
parent | d576a5fc8c0d59545c71c2ceb7bddccb6afbad92 (diff) |
add support for setting the addressing mode
-rw-r--r-- | sys/dev/pci/drm/i915_dma.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.h | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_gem_execbuffer.c | 42 |
4 files changed, 49 insertions, 0 deletions
diff --git a/sys/dev/pci/drm/i915_dma.c b/sys/dev/pci/drm/i915_dma.c index 2a6ffcc250e..1d29dddda55 100644 --- a/sys/dev/pci/drm/i915_dma.c +++ b/sys/dev/pci/drm/i915_dma.c @@ -105,6 +105,9 @@ i915_getparam(struct inteldrm_softc *dev_priv, void *data) return EINVAL; #endif break; + case I915_PARAM_HAS_EXEC_CONSTANTS: + value = INTEL_INFO(dev)->gen >= 4; + break; case I915_PARAM_HAS_GEN7_SOL_RESET: value = 1; break; diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c index 68e98e78d07..18d88f03c55 100644 --- a/sys/dev/pci/drm/i915_drv.c +++ b/sys/dev/pci/drm/i915_drv.c @@ -993,6 +993,8 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) } } + dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; + /* Old X drivers will take 0-2 for front, back, depth buffers */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) dev_priv->fence_reg_start = 3; diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h index 01ce5f93dca..175aa3d5628 100644 --- a/sys/dev/pci/drm/i915_drv.h +++ b/sys/dev/pci/drm/i915_drv.h @@ -715,6 +715,8 @@ struct inteldrm_softc { const struct intel_device_info *info; + int relative_constants_mode; + struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; diff --git a/sys/dev/pci/drm/i915_gem_execbuffer.c b/sys/dev/pci/drm/i915_gem_execbuffer.c index a6dfcc5f6ec..793fb78b6d5 100644 --- a/sys/dev/pci/drm/i915_gem_execbuffer.c +++ b/sys/dev/pci/drm/i915_gem_execbuffer.c @@ -246,6 +246,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, uint32_t reloc_index; uint32_t flags; uint32_t exec_start, exec_len; + uint32_t mask; + int mode; /* * Check for valid execbuffer offset. We can do this early because @@ -295,6 +297,31 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, return (EINVAL); } + mode = args->flags & I915_EXEC_CONSTANTS_MASK; + mask = I915_EXEC_CONSTANTS_MASK; + switch (mode) { + case I915_EXEC_CONSTANTS_REL_GENERAL: + case I915_EXEC_CONSTANTS_ABSOLUTE: + case I915_EXEC_CONSTANTS_REL_SURFACE: + if (ring == &dev_priv->rings[RCS] && + mode != dev_priv->relative_constants_mode) { + if (INTEL_INFO(dev)->gen < 4) + return EINVAL; + + if (INTEL_INFO(dev)->gen > 5 && + mode == I915_EXEC_CONSTANTS_REL_SURFACE) + return EINVAL; + + /* The HW changed the meaning on this bit on gen6 */ + if (INTEL_INFO(dev)->gen >= 6) + mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; + } + break; + default: + DRM_DEBUG("execbuf with unknown constants: %d\n", mode); + return EINVAL; + } + /* Copy in the exec list from userland, check for overflow */ oflow = SIZE_MAX / args->buffer_count; if (oflow < sizeof(*exec_list) || oflow < sizeof(*object_list)) @@ -415,6 +442,21 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, if (ret) goto err; + if (ring == &dev_priv->rings[RCS] && + mode != dev_priv->relative_constants_mode) { + ret = intel_ring_begin(ring, 4); + if (ret) + goto err; + + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, INSTPM); + intel_ring_emit(ring, mask << 16 | mode); + intel_ring_advance(ring); + + dev_priv->relative_constants_mode = mode; + } + if (args->flags & I915_EXEC_GEN7_SOL_RESET) { ret = i915_reset_gen7_sol_offsets(dev, ring); if (ret) |