summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-06-16 12:51:08 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-06-16 13:01:17 +0100
commit4ab99d67990d5834061a10b0bd1dd220d4611248 (patch)
treeb0362ec07ed7b4d63ccc74e945f7baa588bac2e9
parent10cb36e1ddc6f4bf41941b24d6557343aa595a13 (diff)
uxa: Allocate frontbuffer to meet old fence constaints
libdrm is a little lax and does not allocate sufficient space for us to safely use buffers on old gen. So compute the size we want for ourselves. Reported-by: Cem Aydin <cem.aydin@gmx.ch> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80088 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/uxa/intel.h8
-rw-r--r--src/uxa/intel_display.c7
-rw-r--r--src/uxa/intel_driver.c5
-rw-r--r--src/uxa/intel_memory.c107
-rw-r--r--src/uxa/intel_uxa.c81
5 files changed, 84 insertions, 124 deletions
diff --git a/src/uxa/intel.h b/src/uxa/intel.h
index 2ebad643..409635d2 100644
--- a/src/uxa/intel.h
+++ b/src/uxa/intel.h
@@ -536,11 +536,13 @@ int intel_crtc_to_pipe(xf86CrtcPtr crtc);
unsigned long intel_get_fence_size(intel_screen_private *intel, unsigned long size);
unsigned long intel_get_fence_pitch(intel_screen_private *intel, unsigned long pitch,
uint32_t tiling_mode);
+Bool intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling);
+void intel_set_gem_max_sizes(ScrnInfoPtr scrn);
drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
- int w, int h, int cpp,
- unsigned long *pitch,
- uint32_t *tiling);
+ int width, int height, int cpp,
+ int *out_stride,
+ uint32_t *out_tiling);
/* i830_render.c */
Bool i830_check_composite(int op,
diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index 5bb9d72a..b90061b0 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -511,7 +511,7 @@ intel_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
ScrnInfoPtr scrn = crtc->scrn;
struct intel_crtc *intel_crtc = crtc->driver_private;
struct intel_mode *mode = intel_crtc->mode;
- unsigned long rotate_pitch;
+ int rotate_pitch;
uint32_t tiling;
int ret;
@@ -1401,7 +1401,7 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
Bool ret;
uint32_t old_fb_id;
int i, old_width, old_height, old_pitch;
- unsigned long pitch;
+ int pitch;
uint32_t tiling;
ScreenPtr screen;
@@ -1431,8 +1431,7 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
intel->front_buffer = intel_allocate_framebuffer(scrn,
width, height,
intel->cpp,
- &pitch,
- &tiling);
+ &pitch, &tiling);
if (!intel->front_buffer)
goto fail;
diff --git a/src/uxa/intel_driver.c b/src/uxa/intel_driver.c
index 1952dcc4..c73d831d 100644
--- a/src/uxa/intel_driver.c
+++ b/src/uxa/intel_driver.c
@@ -717,14 +717,13 @@ intel_init_initial_framebuffer(ScrnInfoPtr scrn)
intel_screen_private *intel = intel_get_screen_private(scrn);
int width = scrn->virtualX;
int height = scrn->virtualY;
- unsigned long pitch;
+ int pitch;
uint32_t tiling;
intel->front_buffer = intel_allocate_framebuffer(scrn,
width, height,
intel->cpp,
- &pitch,
- &tiling);
+ &pitch, &tiling);
if (!intel->front_buffer) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
diff --git a/src/uxa/intel_memory.c b/src/uxa/intel_memory.c
index 7db1a040..809b636d 100644
--- a/src/uxa/intel_memory.c
+++ b/src/uxa/intel_memory.c
@@ -137,11 +137,10 @@ intel_get_fence_pitch(intel_screen_private *intel, unsigned long pitch,
return i;
}
-static Bool
-intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling)
+Bool intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
- int limit = KB(32);
+ int limit;
/* 8xx spec has always 8K limit, but tests show larger limit in
non-tiling mode, which makes large monitor work. */
@@ -154,30 +153,19 @@ intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling)
limit = KB(16);
else
limit = KB(32);
- }
+ } else
+ limit = KB(32);
- if (stride <= limit)
- return TRUE;
- else
- return FALSE;
+ return stride <= limit;
}
-/*
- * Pad to accelerator requirement
- */
-static inline int intel_pad_drawable_width(int width)
-{
- return ALIGN(width, 64);
-}
-
-
static size_t
agp_aperture_size(struct pci_device *dev, int gen)
{
return dev->regions[gen < 030 ? 0 : 2].size;
}
-static void intel_set_gem_max_sizes(ScrnInfoPtr scrn)
+void intel_set_gem_max_sizes(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
size_t agp_size = agp_aperture_size(intel->PciInfo,
@@ -202,86 +190,3 @@ static void intel_set_gem_max_sizes(ScrnInfoPtr scrn)
*/
intel->max_bo_size = intel->max_gtt_map_size;
}
-
-/**
- * Allocates a framebuffer for a screen.
- *
- * Used once for each X screen, so once with RandR 1.2 and twice with classic
- * dualhead.
- */
-drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
- int width, int height, int cpp,
- unsigned long *out_pitch,
- uint32_t *out_tiling)
-{
- intel_screen_private *intel = intel_get_screen_private(scrn);
- drm_intel_bo *front_buffer;
- uint32_t tiling_mode;
- unsigned long pitch;
-
- if (intel->tiling & INTEL_TILING_FB)
- tiling_mode = I915_TILING_X;
- else
- tiling_mode = I915_TILING_NONE;
-
- width = intel_pad_drawable_width(width);
- if (!intel_check_display_stride(scrn, width * intel->cpp,
- tiling_mode != I915_TILING_NONE))
- tiling_mode = I915_TILING_NONE;
- if (!intel_check_display_stride(scrn, width * intel->cpp,
- tiling_mode != I915_TILING_NONE)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Expected front buffer stride %d kB "
- "will exceed display limit\n",
- width * intel->cpp / 1024);
- return NULL;
- }
-
-retry:
- front_buffer = drm_intel_bo_alloc_tiled(intel->bufmgr, "front buffer",
- width, height, intel->cpp,
- &tiling_mode, &pitch, 0);
- if (front_buffer == NULL) {
- if (tiling_mode != I915_TILING_NONE) {
- tiling_mode = I915_TILING_NONE;
- goto retry;
- }
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Failed to allocate framebuffer.\n");
- return NULL;
- }
-
- if (!intel_check_display_stride(scrn, pitch,
- tiling_mode != I915_TILING_NONE)) {
- drm_intel_bo_unreference(front_buffer);
- if (tiling_mode != I915_TILING_NONE) {
- tiling_mode = I915_TILING_NONE;
- goto retry;
- }
-
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Front buffer stride %ld kB "
- "exceeds display limit\n", pitch / 1024);
- return NULL;
- }
-
- /* If we could have used tiling but failed, warn */
- if (intel->tiling & INTEL_TILING_FB &&
- tiling_mode != I915_TILING_X &&
- intel_check_display_stride(scrn, pitch, I915_TILING_X))
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Failed to set tiling on frontbuffer.\n");
-
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "Allocated new frame buffer %dx%d stride %ld, %s\n",
- width, height, pitch,
- tiling_mode == I915_TILING_NONE ? "untiled" : "tiled");
-
- drm_intel_bo_disable_reuse(front_buffer);
-
- intel_set_gem_max_sizes(scrn);
- *out_pitch = pitch;
- *out_tiling = tiling_mode;
-
- return front_buffer;
-}
diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c
index 81c59d2c..5b037f1d 100644
--- a/src/uxa/intel_uxa.c
+++ b/src/uxa/intel_uxa.c
@@ -156,19 +156,15 @@ intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
}
static unsigned int
-intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
- int w, int h,
- uint32_t *tiling,
- int *stride,
- unsigned usage)
+intel_uxa_compute_size(struct intel_screen_private *intel,
+ int w, int h, int bpp, unsigned usage,
+ uint32_t *tiling, int *stride)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
- intel_screen_private *intel = intel_get_screen_private(scrn);
int pitch, size;
if (*tiling != I915_TILING_NONE) {
/* First check whether tiling is necessary. */
- pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
+ pitch = (w * bpp + 7) / 8;
pitch = ALIGN(pitch, 64);
size = pitch * ALIGN (h, 2);
if (INTEL_INFO(intel)->gen < 040) {
@@ -197,7 +193,7 @@ intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
}
}
- pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
+ pitch = (w * bpp + 7) / 8;
if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256)
*tiling = I915_TILING_NONE;
@@ -243,6 +239,58 @@ intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
return size;
}
+drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
+ int width, int height, int cpp,
+ int *out_stride,
+ uint32_t *out_tiling)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ uint32_t tiling;
+ int stride, size;
+ drm_intel_bo *bo;
+
+ if (intel->tiling & INTEL_TILING_FB)
+ tiling = I915_TILING_X;
+ else
+ tiling = I915_TILING_NONE;
+
+retry:
+ size = intel_uxa_compute_size(intel,
+ width, height,
+ intel->cpp*8, 0,
+ &tiling, &stride);
+ if (!intel_check_display_stride(scrn, stride, tiling)) {
+ if (tiling != I915_TILING_NONE) {
+ tiling = I915_TILING_NONE;
+ goto retry;
+ }
+
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Front buffer stride %d kB "
+ "exceeds display limit\n", stride / 1024);
+ return NULL;
+ }
+
+ bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0);
+ if (bo == NULL)
+ return FALSE;
+
+ if (tiling != I915_TILING_NONE)
+ drm_intel_bo_set_tiling(bo, &tiling, stride);
+
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "Allocated new frame buffer %dx%d stride %d, %s\n",
+ width, height, stride,
+ tiling == I915_TILING_NONE ? "untiled" : "tiled");
+
+ drm_intel_bo_disable_reuse(bo);
+
+ intel_set_gem_max_sizes(scrn);
+ *out_stride = stride;
+ *out_tiling = tiling;
+ return bo;
+}
+
static Bool
intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
{
@@ -856,8 +904,10 @@ static Bool intel_uxa_put_image(PixmapPtr pixmap,
dri_bo *bo;
/* Replace busy bo. */
- size = intel_uxa_pixmap_compute_size (pixmap, w, h,
- &tiling, &stride, 0);
+ size = intel_uxa_compute_size(intel,
+ w, h,
+ pixmap->drawable.bitsPerPixel, pixmap->usage_hint,
+ &tiling, &stride);
if (size > intel->max_gtt_map_size)
return FALSE;
@@ -1117,7 +1167,9 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
if (h <= 16 && tiling == I915_TILING_Y)
tiling = I915_TILING_X;
}
- size = intel_uxa_pixmap_compute_size(pixmap, w, h, &tiling, &stride, usage);
+ size = intel_uxa_compute_size(intel,
+ w, h, pixmap->drawable.bitsPerPixel, usage,
+ &tiling, &stride);
/* Fail very large allocations. Large BOs will tend to hit SW fallbacks
* frequently, and also will tend to fail to successfully map when doing
@@ -1258,7 +1310,10 @@ intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle
tiling = I915_TILING_NONE;
- size = intel_uxa_pixmap_compute_size(ppix, ppix->drawable.width, ppix->drawable.height, &tiling, &stride, INTEL_CREATE_PIXMAP_DRI2);
+ size = intel_uxa_compute_size(intel,
+ ppix->drawable.width, ppix->drawable.height,
+ ppix->drawable.bitsPerPixel, INTEL_CREATE_PIXMAP_DRI2,
+ &tiling, &stride);
newbo = drm_intel_bo_alloc_for_render(intel->bufmgr,
"pixmap",