On Friday, January 23, 2009 5:57 pm Eric Anholt wrote: > On Fri, 2009-01-23 at 16:24 -0800, Eric Anholt wrote: > > On Fri, 2009-01-23 at 14:15 -0800, Jesse Barnes wrote: > > > Set alignments, tile settings and flags correctly in the 2D driver to > > > support tiled rendering. UXA's create pixmap function currently > > > assumes the worst about the alignment constraints; that should probably > > > be fixed. Some of the 1M alignment fixes could probably be done more > > > cleanly as well. > > Updated version incorporating my comments. Note the XXXs. With this > I've seen OA go from 5.5fps to 34.7fps on my eee 901, so I think we're > looking pretty good once we clean a few messes up. I had to disable > TILING_Y to get correct rendering with OA, which we should probably look > into. > > From 1d9cda617f29badf50584bafa42ea597f1a5b27d Mon Sep 17 00:00:00 2001 > From: Jesse Barnes <jbar...@virtuousgeek.org> > Date: Fri, 23 Jan 2009 14:15:26 -0800 > Subject: [PATCH] Support tiled back/depth on 915-class hardware with DRI2. > > Set alignments, tile settings and flags correctly in the 2D driver to > support tiled rendering. UXA's create pixmap function currently assumes > the worst about the alignment constraints; that should probably be fixed. > Some of the 1M alignment fixes could probably be done more cleanly as well.
Ok this one should be a little cleaner. I just removed the alignment passing in create_pixmap since we don't use it anyway. As for size & stride, we can probably calculate that in the kernel given the object's tiling mode, but then our obj->size wouldn't match reality (right now I think it give an accurate view of aperture space required for an object, might be a pain to lose that). Testers welcome on this patchset (the libdrm portion hasn't changed); hope we can get it pushed upstream soon. Thanks, Jesse diff --git a/src/common.h b/src/common.h index 4a87acb..be222df 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)) diff --git a/src/i830.h b/src/i830.h index 4ee9c39..f601dbd 100644 --- a/src/i830.h +++ b/src/i830.h @@ -725,6 +725,7 @@ typedef struct _I830Rec { enum last_3d *last_3d; Bool use_drm_mode; + Bool kernel_exec_fencing; #ifdef XF86DRM_MODE drmmode_rec drmmode; int drm_mm_init; @@ -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 d6698da..7a95d02 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 bf5ecc4..2c4ea07 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1822,6 +1822,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 9249074..0a8dced 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -882,11 +882,22 @@ 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); + /* XXX: Hack! The kernel should really just allocate the aperture + * space for us, and stuff our tiny object into it. + */ + 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 ab4e5ce..9709480 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -133,10 +133,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; @@ -159,6 +158,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) { @@ -390,6 +426,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 @@ -501,6 +538,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; @@ -771,7 +820,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) @@ -889,16 +938,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 && ------------------------------------------------------------------------------ This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel