summaryrefslogtreecommitdiff
path: root/src/i830_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i830_memory.c')
-rw-r--r--src/i830_memory.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 9bfee818..f3c55a34 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -132,10 +132,9 @@ static void i830_clear_tiling(ScrnInfoPtr pScrn, unsigned int fence_nr);
/**
* Returns the fence size for a tiled area of the given size.
*/
-static unsigned long
-i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size)
+unsigned long
+i830_get_fence_size(I830Ptr pI830, unsigned long size)
{
- I830Ptr pI830 = I830PTR(pScrn);
unsigned long i;
unsigned long start;
@@ -158,6 +157,43 @@ i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size)
}
}
+/**
+ * On some chips, pitch width has to be a power of two tile width, so
+ * calculate that here.
+ */
+unsigned long
+i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format)
+{
+ unsigned long i;
+ unsigned long tile_width = (format == I915_TILING_Y) ? 128 : 512;
+
+ if (format == TILE_NONE)
+ return pitch;
+
+ /* 965 is flexible */
+ if (IS_I965G(pI830))
+ return ROUND_TO(pitch, tile_width);
+
+ /* Pre-965 needs power of two tile width */
+ for (i = tile_width; i < pitch; i <<= 1)
+ ;
+
+ return i;
+}
+
+/**
+ * On some chips, pitch width has to be a power of two tile width, so
+ * calculate that here.
+ */
+unsigned long
+i830_get_fence_alignment(I830Ptr pI830, unsigned long size)
+{
+ if (IS_I965G(pI830))
+ return 4096;
+ else
+ return i830_get_fence_size(pI830, size);
+}
+
static Bool
i830_check_display_stride(ScrnInfoPtr pScrn, int stride, Bool tiling)
{
@@ -388,6 +424,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
#ifdef XF86DRI
int dri_major, dri_minor, dri_patch;
struct drm_i915_getparam gp;
+ struct drm_i915_setparam sp;
int has_gem;
int has_dri;
#endif
@@ -499,6 +536,18 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
struct drm_i915_gem_init init;
int ret;
+ sp.param = I915_SETPARAM_NUM_USED_FENCES;
+ if (pI830->use_drm_mode)
+ sp.value = 0; /* kernel gets them all */
+ else if (pI830->directRenderingType == DRI_XF86DRI)
+ sp.value = 3; /* front/back/depth */
+ else
+ sp.value = 2; /* just front for DRI2 (both old & new though) */
+ ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, &sp,
+ sizeof(sp));
+ if (ret == 0)
+ pI830->kernel_exec_fencing = TRUE;
+
init.gtt_start = pI830->memory_manager->offset;
init.gtt_end = pI830->memory_manager->offset +
pI830->memory_manager->size;
@@ -769,7 +818,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
/* Only allocate page-sized increments. */
size = ALIGN(size, GTT_PAGE_SIZE);
- align = ROUND_TO(align, GTT_PAGE_SIZE);
+ align = i830_get_fence_alignment(pI830, size);
mem = xcalloc(1, sizeof(*mem));
if (mem == NULL)
@@ -814,7 +863,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
break;
}
- ret = dri_bo_set_tiling(mem->bo, &bo_tiling_mode);
+ ret = drm_intel_bo_set_tiling(mem->bo, &bo_tiling_mode, pitch);
if (ret != 0 || (bo_tiling_mode == I915_TILING_NONE && tile_format != TILE_NONE)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to set tiling on %s: %s\n",
@@ -887,16 +936,8 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
}
/* round to size necessary for the fence register to work */
- size = i830_get_fence_size(pScrn, size);
- if (IS_I965G(pI830)) {
- if (alignment < GTT_PAGE_SIZE)
- alignment = GTT_PAGE_SIZE;
- } else {
- /* The offset has to be aligned to at least the size of the fence
- * region.
- */
- alignment = size;
- }
+ size = i830_get_fence_size(pI830, size);
+ alignment = i830_get_fence_alignment(pI830, size);
}
#ifdef XF86DRI
if (pI830->use_drm_mode || (pI830->memory_manager &&