[Intel-gfx] [PATCH] Fix textured video when destination is larger than screen

Simon Farnsworth simon.farnsworth at onelan.co.uk
Mon Jan 17 18:38:23 CET 2011


In our application, the screen is never rotated from the point of view
of the driver; instead, the compositor applies a suitable rotation as
it composites the display. This works fine on 945, but on 965, videos
are limited in height to the actual height of the screen.

Change various bits of code so that we use the width and height of the
destination pixmap instead of the width and height of the virtual
screen. This works correctly both for XVideo to offscreen storage
(CompositeRedirect) and for XVideo to the screen (no compositor).
---
This has only seen very light testing on a 965GME, and absolutely no
testing at all on a gen6 (I don't have access to anything that
modern).

To reproduce my setup, set your screen to 1920x1080, no rotation (0°);
redirect a 1000x1500 window using XComposite, and use XVideo to draw
to that window. You will find that when you look at the backing
pixmap, only the top 1080 lines of the redirected window are drawn
without this fix, and with it, all 1500 lines are drawn.

I'd appreciate review from someone who understands things in here a
bit better than I do, in case I've opened up a world of pain - but it
Works For Me.

 src/i965_video.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/i965_video.c b/src/i965_video.c
index 235dfb9..a7374a2 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -414,8 +414,8 @@ static void i965_create_dst_surface_state(ScrnInfoPtr scrn,
 	    intel_emit_reloc(surf_bo, offset + offsetof(struct brw_surface_state, ss1),
 			     pixmap_bo, 0, I915_GEM_DOMAIN_SAMPLER, 0);
 
-	dest_surf_state->ss2.height = scrn->virtualY - 1;
-	dest_surf_state->ss2.width = scrn->virtualX - 1;
+	dest_surf_state->ss2.height = pixmap->drawable.height - 1;
+	dest_surf_state->ss2.width = pixmap->drawable.width - 1;
 	dest_surf_state->ss2.mip_count = 0;
 	dest_surf_state->ss2.render_target_rotation = 0;
 	dest_surf_state->ss3.pitch = intel_pixmap_pitch(pixmap) - 1;
@@ -770,7 +770,7 @@ static drm_intel_bo *i965_create_cc_state(ScrnInfoPtr scrn)
 }
 
 static void
-i965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * surface_state_binding_table_bo, int n_src_surf)
+i965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * surface_state_binding_table_bo, int n_src_surf, PixmapPtr pixmap)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	int urb_vs_start, urb_vs_size;
@@ -877,7 +877,7 @@ i965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * surface_state_binding_tab
 	 */
 	OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
 	OUT_BATCH(0x00000000);	/* ymin, xmin */
-	OUT_BATCH((scrn->virtualX - 1) | (scrn->virtualY - 1) << 16);	/* ymax, xmax */
+	OUT_BATCH((pixmap->drawable.width - 1) | (pixmap->drawable.height - 1) << 16);	/* ymax, xmax */
 	OUT_BATCH(0x00000000);	/* yorigin, xorigin */
 
 	/* skip the depth buffer */
@@ -1212,7 +1212,7 @@ I965DisplayVideoTextured(ScrnInfoPtr scrn,
 
 		intel_batch_start_atomic(scrn, 100);
 
-		i965_emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf);
+		i965_emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf, pixmap);
 
 		/* Set up the pointer to our vertex buffer */
 		OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
@@ -1517,13 +1517,13 @@ gen6_upload_depth_buffer_state(ScrnInfoPtr scrn)
 }
 
 static void
-gen6_upload_drawing_rectangle(ScrnInfoPtr scrn)
+gen6_upload_drawing_rectangle(ScrnInfoPtr scrn, PixmapPtr pixmap)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 
 	OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2);
 	OUT_BATCH(0x00000000);	/* ymin, xmin */
-	OUT_BATCH((scrn->virtualX - 1) | (scrn->virtualY - 1) << 16);	/* ymax, xmax */
+	OUT_BATCH((pixmap->drawable.width - 1) | (pixmap->drawable.height - 1) << 16);	/* ymax, xmax */
 	OUT_BATCH(0x00000000);	/* yorigin, xorigin */
 }
 
@@ -1673,7 +1673,7 @@ gen6_upload_vertex_element_state(ScrnInfoPtr scrn)
 }
 
 static void
-gen6_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_table_bo, int n_src_surf)
+gen6_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_table_bo, int n_src_surf, PixmapPtr pixmap)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 
@@ -1694,7 +1694,7 @@ gen6_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_tabl
 	gen6_upload_wm_state(scrn, n_src_surf == 1 ? TRUE : FALSE);
 	gen6_upload_binding_table(scrn, (n_src_surf + 1) * ALIGN(sizeof(struct brw_surface_state), 32));;
 	gen6_upload_depth_buffer_state(scrn);
-	gen6_upload_drawing_rectangle(scrn);
+	gen6_upload_drawing_rectangle(scrn, pixmap);
 	gen6_upload_vertex_element_state(scrn);
 }
 
@@ -1853,7 +1853,7 @@ void Gen6DisplayVideoTextured(ScrnInfoPtr scrn,
 			intel_batch_submit(scrn, FALSE);
 
 		intel_batch_start_atomic(scrn, 200);
-		gen6_emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf);
+		gen6_emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf, pixmap);
 
 		/* Set up the pointer to our vertex buffer */
 		OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | (5 - 2));
-- 
1.7.0.1




More information about the Intel-gfx mailing list