All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Anholt <eric@anholt.net>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH] Allocate a correctly sized framebuffer when tiling by using libdrm's support.
Date: Sun,  6 Jun 2010 23:49:09 -0700	[thread overview]
Message-ID: <1275893349-20058-1-git-send-email-eric@anholt.net> (raw)

When I made libdrm stop overallocating so much memory for the purpose
of bo caching, things started scribbling on the bottom of my
frontbuffer (and vice versa, leading to GPU hangs).  We had the usual
mistake of size = tiled_pitch * height instead of size = tiled_pitch *
tile_aligned_height.
---
 src/drmmode_display.c |   11 +++---
 src/i830.h            |    2 -
 src/i830_driver.c     |   65 ++++----------------------------------
 src/i830_memory.c     |   82 +++++++++++--------------------------------------
 4 files changed, 30 insertions(+), 130 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 3ea9b0f..df0282e 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1263,11 +1263,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 		return TRUE;
 
 	w = i830_pad_drawable_width(width);
-	i830_tiled_width(intel, &w, intel->cpp);
-	pitch = w * intel->cpp;
-	xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		   "Allocate new frame buffer %dx%d stride %d\n",
-		   width, height, pitch);
 
 	old_width = scrn->virtualX;
 	old_height = scrn->virtualY;
@@ -1277,10 +1272,14 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 
 	scrn->virtualX = width;
 	scrn->virtualY = height;
-	scrn->displayWidth = w;
 	intel->front_buffer = i830_allocate_framebuffer(scrn);
 	if (!intel->front_buffer)
 		goto fail;
+	pitch = scrn->displayWidth * intel->cpp;
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		   "Allocated new frame buffer %dx%d stride %d\n",
+		   width, height, scrn->displayWidth * intel->cpp);
 
 	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
 			   scrn->bitsPerPixel, pitch,
diff --git a/src/i830.h b/src/i830.h
index 8c96841..07fbbaf 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -459,8 +459,6 @@ extern Bool I830AccelInit(ScreenPtr pScreen);
 void i830_reset_allocations(ScrnInfoPtr scrn);
 void i830_init_bufmgr(ScrnInfoPtr scrn);
 
-Bool i830_tiled_width(intel_screen_private *intel, int *width, int cpp);
-
 /* i830_memory.c */
 unsigned long i830_get_fence_size(intel_screen_private *intel, unsigned long size);
 unsigned long i830_get_fence_pitch(intel_screen_private *intel, unsigned long pitch,
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 89a4525..c3f3062 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -348,49 +348,6 @@ static void PreInitCleanup(ScrnInfoPtr scrn)
 }
 
 /*
- * Adjust *width to allow for tiling if possible
- */
-Bool i830_tiled_width(intel_screen_private *intel, int *width, int cpp)
-{
-	Bool tiled = FALSE;
-
-	/*
-	 * Adjust the display width to allow for front buffer tiling if possible
-	 */
-	if (intel->tiling) {
-		if (IS_I965G(intel)) {
-			int tile_pixels = 512 / cpp;
-			*width = (*width + tile_pixels - 1) &
-			    ~(tile_pixels - 1);
-			tiled = TRUE;
-		} else {
-			/* Good pitches to allow tiling.  Don't care about pitches < 1024
-			 * pixels.
-			 */
-			static const int pitches[] = {
-				1024,
-				2048,
-				4096,
-				8192,
-				0
-			};
-			int pitch;
-			int i;
-
-			pitch = *width * cpp;
-			for (i = 0; pitches[i] != 0; i++) {
-				if (pitches[i] >= pitch) {
-					*width = pitches[i] / cpp;
-					tiled = TRUE;
-					break;
-				}
-			}
-		}
-	}
-	return tiled;
-}
-
-/*
  * DRM mode setting Linux only at this point... later on we could
  * add a wrapper here.
  */
@@ -1006,31 +963,23 @@ static Bool i830_try_memory_allocation(ScrnInfoPtr scrn)
 static Bool i830_memory_init(ScrnInfoPtr scrn)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
-	int savedDisplayWidth = scrn->displayWidth;
-	Bool tiled = FALSE;
-
-	tiled = i830_tiled_width(intel, &scrn->displayWidth, intel->cpp);
 
 	xf86DrvMsg(scrn->scrnIndex,
 		   intel->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
 		   "VideoRam: %d KB\n", scrn->videoRam);
 
+	if (i830_try_memory_allocation(scrn))
+		return TRUE;
+
 	/* Tiled first if we got a good displayWidth */
-	if (tiled) {
+	if (intel->tiling) {
+		intel->tiling = FALSE;
+		i830_reset_allocations(scrn);
+
 		if (i830_try_memory_allocation(scrn))
 			return TRUE;
-		else {
-			i830_reset_allocations(scrn);
-			intel->tiling = FALSE;
-		}
 	}
 
-	/* If tiling fails we have to disable FBC */
-	scrn->displayWidth = savedDisplayWidth;
-
-	if (i830_try_memory_allocation(scrn))
-		return TRUE;
-
 	return FALSE;
 }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 611b548..e71cbde 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -177,39 +177,6 @@ void i830_reset_allocations(ScrnInfoPtr scrn)
 	intel->front_buffer = NULL;
 }
 
-static Bool IsTileable(ScrnInfoPtr scrn, int pitch)
-{
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-
-	if (IS_I965G(intel)) {
-		if (pitch / 512 * 512 == pitch && pitch <= KB(128))
-			return TRUE;
-		else
-			return FALSE;
-	}
-
-	/*
-	 * Allow tiling for pitches that are a power of 2 multiple of 128 bytes,
-	 * up to 64 * 128 (= 8192) bytes.
-	 */
-	switch (pitch) {
-	case 128:
-	case 256:
-		if (IS_I945G(intel) || IS_I945GM(intel) || IS_G33CLASS(intel))
-			return TRUE;
-		else
-			return FALSE;
-	case 512:
-	case KB(1):
-	case KB(2):
-	case KB(4):
-	case KB(8):
-		return TRUE;
-	default:
-		return FALSE;
-	}
-}
-
 /**
  * Allocates a framebuffer for a screen.
  *
@@ -220,51 +187,38 @@ drm_intel_bo *i830_allocate_framebuffer(ScrnInfoPtr scrn)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	drm_intel_bo *front_buffer;
-	long size, fb_height;
-	unsigned int pitch;
-	uint32_t tiling_mode, requested_tiling_mode;
-	int ret;
+	unsigned long pitch;
+	uint32_t tiling_mode;
 
-	/* We'll allocate the fb such that the root window will fit regardless of
-	 * rotation.
-	 */
-	fb_height = scrn->virtualY;
-
-	pitch = scrn->displayWidth * intel->cpp;
-	size = ROUND_TO_PAGE(pitch * fb_height);
-
-	if (intel->tiling && IsTileable(scrn, pitch))
+	if (intel->tiling)
 		tiling_mode = I915_TILING_X;
 	else
 		tiling_mode = I915_TILING_NONE;
 
-	if (!i830_check_display_stride(scrn, pitch,
-				       tiling_mode != I915_TILING_NONE)) {
+	front_buffer = drm_intel_bo_alloc_tiled(intel->bufmgr, "front buffer",
+						scrn->displayWidth,
+						scrn->virtualY, intel->cpp,
+						&tiling_mode, &pitch, 0);
+	if (front_buffer == NULL) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Front buffer stride %d kB "
-			   "exceed display limit\n", pitch / 1024);
+			   "Failed to allocate framebuffer.\n");
 		return NULL;
 	}
 
-	if (tiling_mode != I915_TILING_NONE) {
-		/* round to size necessary for the fence register to work */
-		size = i830_get_fence_size(intel, size);
-	}
-
-	front_buffer = drm_intel_bo_alloc(intel->bufmgr, "front buffer",
-					  size, GTT_PAGE_SIZE);
-	if (front_buffer == NULL) {
+	if (!i830_check_display_stride(scrn, pitch,
+				       tiling_mode != I915_TILING_NONE)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to allocate framebuffer.\n");
+			   "Front buffer stride %ld kB "
+			   "exceeds display limit\n", pitch / 1024);
+		drm_intel_bo_unreference(front_buffer);
 		return NULL;
 	}
 
-	requested_tiling_mode = tiling_mode;
-	ret = drm_intel_bo_set_tiling(front_buffer, &tiling_mode, pitch);
-	if (ret != 0 || tiling_mode != requested_tiling_mode) {
+	scrn->displayWidth = pitch / intel->cpp;
+
+	if (intel->tiling && tiling_mode != I915_TILING_X) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to set tiling on frontbuffer: %s\n",
-			   ret == 0 ? "rejected by kernel" : strerror(-ret));
+			   "Failed to set tiling on frontbuffer.\n");
 	}
 
 	drm_intel_bo_disable_reuse(front_buffer);
-- 
1.7.1

             reply	other threads:[~2010-06-07  6:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-07  6:49 Eric Anholt [this message]
2010-06-07 14:00 ` [PATCH] Allocate a correctly sized framebuffer when tiling by using libdrm support Chris Wilson
2010-06-07 14:25 ` Chris Wilson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1275893349-20058-1-git-send-email-eric@anholt.net \
    --to=eric@anholt.net \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.