[PATCH 5/6] drm/i915: Handle framebuffer offsets[]

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Thu May 24 11:08:58 PDT 2012


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Take fb->offset[0] into account when calculating the linear and tile x/y
offsets.

For non-tiled surfaces fb->offset[0] is simply added to the linear
byte offset.

For tiled surfaces treat fb->offsets[0] as a byte offset into the
linearized view of the surface. So we end up converting fb->offsets[0]
into additional x and y offsets.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9df15ee..f4338cb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1826,6 +1826,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 	unsigned long Start, Offset;
 	u32 dspcntr;
 	u32 reg;
+	unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	switch (plane) {
 	case 0:
@@ -1885,12 +1886,14 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 	I915_WRITE(reg, dspcntr);
 
 	Start = obj->gtt_offset;
-	Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
+	Offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp;
 
 	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
 		      Start, Offset, x, y, fb->pitches[0]);
 	I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
 	if (INTEL_INFO(dev)->gen >= 4) {
+		y += fb->offsets[0] / fb->pitches[0];
+		x += fb->offsets[0] % fb->pitches[0] / cpp;
 		I915_MODIFY_DISPBASE(DSPSURF(plane), Start);
 		I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
 		I915_WRITE(DSPADDR(plane), Offset);
@@ -1913,6 +1916,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
 	unsigned long Start, Offset;
 	u32 dspcntr;
 	u32 reg;
+	unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	switch (plane) {
 	case 0:
@@ -1970,7 +1974,10 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
 	I915_WRITE(reg, dspcntr);
 
 	Start = obj->gtt_offset;
-	Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
+	Offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp;
+
+	y += fb->offsets[0] / fb->pitches[0];
+	x += fb->offsets[0] % fb->pitches[0] / cpp;
 
 	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
 		      Start, Offset, x, y, fb->pitches[0]);
@@ -5993,7 +6000,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
 		goto err;
 
 	/* Offset into the new buffer for cases of shared fbs between CRTCs */
-	offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8;
+	offset = fb->offsets[0] + crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8;
 
 	ret = intel_ring_begin(ring, 6);
 	if (ret)
@@ -6039,7 +6046,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
 		goto err;
 
 	/* Offset into the new buffer for cases of shared fbs between CRTCs */
-	offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8;
+	offset = fb->offsets[0] + crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8;
 
 	ret = intel_ring_begin(ring, 6);
 	if (ret)
-- 
1.7.3.4



More information about the dri-devel mailing list