diff --git a/src/i830.h b/src/i830.h index 4e82036..132be4c 100644 --- a/src/i830.h +++ b/src/i830.h @@ -86,6 +86,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "exa.h" Bool I830EXAInit(ScreenPtr pScreen); unsigned long long I830TexOffsetStart(PixmapPtr pPix); +Bool intel_exa_check_pitch(PixmapPtr, PixmapPtr, PixmapPtr); #endif #ifdef I830_USE_XAA diff --git a/src/i830_exa.c b/src/i830_exa.c index 9b5bb93..7f7f8c2 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -419,6 +419,26 @@ i830_transform_is_affine (PictTransformPtr t) return t->matrix[2][0] == 0 && t->matrix[2][1] == 0; } +Bool +intel_exa_check_pitch(PixmapPtr s, PixmapPtr m, PixmapPtr d) +{ + /* XXX this should be null if exa_minor >=3, but current + * exa just ignores devKind check in ModifyPixmapHeader which + * makes it useless to check home made pixmap like for rotate_pixmap. + * So we just check it here in all cases now... + */ + ScrnInfoPtr pScrn = xf86Screens[s->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + uint32_t src_pitch = intel_get_pixmap_pitch(s); + uint32_t mask_pitch = m ? intel_get_pixmap_pitch(m) : 0; + uint32_t dst_pitch = intel_get_pixmap_pitch(d); + + if (!IS_I965G(pI830) && (src_pitch > KB(8) || + mask_pitch > KB(8) || dst_pitch > KB(8))) + return FALSE; + return TRUE; +} + /* * TODO: * - Dual head? @@ -510,11 +530,17 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->pixmapPitchAlign = 16; pI830->EXADriverPtr->maxX = 8192; pI830->EXADriverPtr->maxY = 8192; + /* maxPitchXXX setting not necessary on 965, as hw support + * max pitch supported by exa, 128KB*/ } else { pI830->EXADriverPtr->pixmapOffsetAlign = 4; pI830->EXADriverPtr->pixmapPitchAlign = 16; pI830->EXADriverPtr->maxX = 2048; pI830->EXADriverPtr->maxY = 2048; +#if EXA_VERSION_MINOR >= 3 + pI830->EXADriverPtr->maxPitchPixels = pI830->EXADriverPtr->maxX; + pI830->EXADriverPtr->maxPitchBytes = KB(8); +#endif } /* Sync */ diff --git a/src/i830_render.c b/src/i830_render.c index 195e9a8..59b7b67 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -398,6 +398,9 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, Bool is_affine_src, is_affine_mask; Bool is_nearest = FALSE; + if (!intel_exa_check_pitch(pSrc, pMask, pDst)) + I830FALLBACK("pitch is too large."); + IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; diff --git a/src/i915_render.c b/src/i915_render.c index 2b9ed04..9b50c2d 100644 --- a/src/i915_render.c +++ b/src/i915_render.c @@ -323,6 +323,9 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, Bool is_affine_src, is_affine_mask; Bool is_nearest = FALSE; + if (!intel_exa_check_pitch(pSrc, pMask, pDst)) + I830FALLBACK("pitch is too large."); + IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; diff --git a/src/i965_render.c b/src/i965_render.c index 95ac063..6cbd7f4 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -915,6 +915,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, int state_base_offset; uint32_t src_blend, dst_blend; + if (!intel_exa_check_pitch(pSrc, pMask, pDst)) + I830FALLBACK("pitch is too large."); + IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER;