diff options
author | Kristian Høgsberg <krh@redhat.com> | 2009-02-02 11:51:47 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2009-02-02 11:51:50 -0500 |
commit | 2013799b20599a58de48cb21a5a389e898a58af1 (patch) | |
tree | 0ddde73476d9228191785db8471e5a6967b18bb6 | |
parent | 127330bfd53ac7571bdd12a551142528b972893f (diff) |
Un-revert the I915_SETPARAM_NUM_USED_FENCES commit reverted by accident.
Oops, my bad. Reverted 8d4bc36fae50b09a73ba2cfab920adb32141a358
since my kernel doesn't yet have the new param, committed
the revert by accident.
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/i830.h | 4 | ||||
-rw-r--r-- | src/i830_dri.c | 13 | ||||
-rw-r--r-- | src/i830_driver.c | 1 | ||||
-rw-r--r-- | src/i830_exa.c | 20 | ||||
-rw-r--r-- | src/i830_memory.c | 71 |
6 files changed, 84 insertions, 27 deletions
diff --git a/src/common.h b/src/common.h index 4a87acb6..be222df5 100644 --- a/src/common.h +++ b/src/common.h @@ -367,6 +367,8 @@ extern int I810_DEBUG; #define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_G4X(pI810)) /* dsparb controlled by hw only */ #define DSPARB_HWCONTROL(pI810) (IS_G4X(pI810)) +/* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */ +#define SUPPORTS_YTILING(pI810) (IS_I965G(pI830)) #define GTT_PAGE_SIZE KB(4) #define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) @@ -723,6 +723,7 @@ typedef struct _I830Rec { enum last_3d *last_3d; Bool use_drm_mode; + Bool kernel_exec_fencing; /** Enables logging of debug output related to mode switching. */ Bool debug_modes; @@ -911,6 +912,9 @@ extern void i830WaitSync(ScrnInfoPtr pScrn); /* i830_memory.c */ Bool i830_bind_all_memory(ScrnInfoPtr pScrn); Bool i830_unbind_all_memory(ScrnInfoPtr pScrn); +unsigned long i830_get_fence_size(I830Ptr pI830, unsigned long size); +unsigned long i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format); +unsigned long i830_get_fence_alignment(I830Ptr pI830, unsigned long size); Bool I830BindAGPMemory(ScrnInfoPtr pScrn); Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); diff --git a/src/i830_dri.c b/src/i830_dri.c index ec83abdb..f03be43c 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1570,7 +1570,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) pDraw->depth, 0); switch (attachments[i]) { case DRI2BufferDepth: - if (IS_I965G(pI830)) + if (SUPPORTS_YTILING(pI830)) tiling = I915_TILING_Y; else tiling = I915_TILING_X; @@ -1583,19 +1583,14 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) break; } - /* Disable tiling on 915-class 3D for now. Because the 2D blitter - * requires fence regs to operate, and they're not being managed - * by the kernel yet, we don't want to expose tiled buffers to the - * 3D client as it'll just render incorrectly if it pays attention - * to our tiling bits at all. - */ - if (!IS_I965G(pI830)) + if (!pI830->tiling || + (!IS_I965G(pI830) && !pI830->kernel_exec_fencing)) tiling = I915_TILING_NONE; if (tiling != I915_TILING_NONE) { bo = i830_get_pixmap_bo(pPixmap); drm_intel_bo_set_tiling(bo, &tiling, - pDraw->width * pDraw->bitsPerPixel / 8); + intel_get_pixmap_pitch(pPixmap)); } } diff --git a/src/i830_driver.c b/src/i830_driver.c index 235c01a3..b8d8d37f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1842,6 +1842,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->SaveGeneration = -1; pI830->pEnt = pEnt; pI830->use_drm_mode = drm_mode_setting; + pI830->kernel_exec_fencing = pI830->use_drm_mode; if (!I830LoadSyms(pScrn)) return FALSE; diff --git a/src/i830_exa.c b/src/i830_exa.c index 92490741..28be786b 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -882,11 +882,25 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag if (w && h) { + unsigned int size; + stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8, i830->accel_pixmap_pitch_alignment); - - bo = dri_bo_alloc (i830->bufmgr, "pixmap", stride * h, - i830->accel_pixmap_offset_alignment); + + /* Use the I915_FENCE_TILING_X even if it may end up being TILING_Y, + * as it just results in larger alignment. Really, we need to use the + * usage hint to tell what the pixmap's going to be. + */ + stride = i830_get_fence_pitch(i830, stride, I915_TILING_X); + /* Round the object up to the size of the fence it will live in + * if necessary. We could potentially make the kernel allocate + * a larger aperture space and just bind the subset of pages in, + * but this is easier and also keeps us out of trouble (as much) + * with drm_intel_bufmgr_check_aperture(). + */ + size = i830_get_fence_size(i830, stride * h); + + bo = dri_bo_alloc (i830->bufmgr, "pixmap", size, 0); if (!bo) { fbDestroyPixmap (pixmap); return NullPixmap; diff --git a/src/i830_memory.c b/src/i830_memory.c index e8348f18..e5d70fa2 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 && |