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.
-- Jesse Barnes, Intel Open Source Technology Center diff --git a/src/i830.h b/src/i830.h index 4794169..f9444b1 100644 --- a/src/i830.h +++ b/src/i830.h @@ -969,6 +969,7 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, float *x_out, float *y_out, float *z_out); void i830_enter_render(ScrnInfoPtr); +unsigned long I830GetFencePitch(I830Ptr pI830, unsigned long pitch, int format); static inline void i830_wait_ring_idle(ScrnInfoPtr pScrn) diff --git a/src/i830_dri.c b/src/i830_dri.c index d6698da..72c8a38 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1525,6 +1525,34 @@ I830DRIUnlock(ScrnInfoPtr pScrn) #ifdef DRI2 +/** + * On some chips, pitch width has to be a power of two tile width, so + * calculate that here. + */ +unsigned long +I830GetFencePitch(I830Ptr pI830, unsigned long pitch, int format) +{ + unsigned long i; + unsigned long tile_width = 512; + + if (IS_I965G(pI830)) { + /* 965 is flexible */ + if (format == I915_TILING_Y) + tile_width = 128; + + return ROUND_TO(pitch, tile_width); + } + + if (IS_I945GM(pI830) && format == I915_TILING_Y) + tile_width = 128; + + /* Pre-965 needs power of two tile width */ + for (i = tile_width; i < pitch; i <<= 1) + ; + + return ROUND_TO(pitch, i); +} + typedef struct { PixmapPtr pPixmap; } I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr; @@ -1570,7 +1598,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) pDraw->depth, 0); switch (attachments[i]) { case DRI2BufferDepth: - if (IS_I965G(pI830)) + if (IS_I965G(pI830) || IS_I945GM(pI830)) tiling = I915_TILING_Y; else tiling = I915_TILING_X; @@ -1583,19 +1611,15 @@ 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) tiling = I915_TILING_NONE; if (tiling != I915_TILING_NONE) { + int pitch = (pDraw->width * pDraw->bitsPerPixel + 7) / 8; + int stride = I830GetFencePitch(pI830, pitch, tiling); + bo = i830_get_pixmap_bo(pPixmap); - drm_intel_bo_set_tiling(bo, &tiling, - pDraw->width * pDraw->bitsPerPixel / 8); + drm_intel_bo_set_tiling(bo, &tiling, stride); } } diff --git a/src/i830_exa.c b/src/i830_exa.c index 9249074..3e487f9 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -872,7 +872,7 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag ScrnInfoPtr scrn = xf86Screens[screen->myNum]; I830Ptr i830 = I830PTR(scrn); dri_bo *bo; - int stride; + int stride, align; PixmapPtr pixmap; if (w > 32767 || h > 32767) @@ -884,9 +884,12 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag { stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8, i830->accel_pixmap_pitch_alignment); + + stride = I830GetFencePitch(i830, stride, I915_TILING_X); + + align = stride * h > 1024*1024 ? stride * h : 1024*1024; - bo = dri_bo_alloc (i830->bufmgr, "pixmap", stride * h, - i830->accel_pixmap_offset_alignment); + bo = dri_bo_alloc (i830->bufmgr, "pixmap", stride * h, align); if (!bo) { fbDestroyPixmap (pixmap); return NullPixmap; diff --git a/src/i830_memory.c b/src/i830_memory.c index 9bfee81..7d55910 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -388,6 +388,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 @@ -495,6 +496,17 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) TILE_NONE); if (pI830->memory_manager != NULL) { + 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) */ + /* Don't care about failure, we'll just get slow rendering */ + drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, &sp, + sizeof(sp)); + if (!pI830->use_drm_mode) { struct drm_i915_gem_init init; int ret; @@ -769,7 +781,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 = size > 1024*1024 ? size : 1024*1024; mem = xcalloc(1, sizeof(*mem)); if (mem == NULL) @@ -895,7 +907,7 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, /* The offset has to be aligned to at least the size of the fence * region. */ - alignment = size; + alignment = size > 1024*1024 ? size : 1024*1024; } } #ifdef XF86DRI ------------------------------------------------------------------------------ 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