xf86-video-intel: 3 commits - src/i830_3d.c src/i830_accel.c src/i830_batchbuffer.c src/i830_batchbuffer.h src/i830_driver.c src/i830.h src/i830_render.c src/i830_uxa.c src/i915_3d.c src/i915_3d.h src/i915_render.c src/i915_trapezoids.c src/i915_video.c src/i965_render.c src/i965_video.c src/Makefile.am uxa/uxa.c uxa/uxa-glyphs.c uxa/uxa.h uxa/uxa-render.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jun 9 02:02:46 PDT 2010


 src/Makefile.am        |    1 
 src/i830.h             |   14 +-
 src/i830_3d.c          |    6 -
 src/i830_accel.c       |    5 
 src/i830_batchbuffer.c |   35 ++++--
 src/i830_batchbuffer.h |    8 +
 src/i830_driver.c      |   25 ----
 src/i830_render.c      |    3 
 src/i830_uxa.c         |    3 
 src/i915_3d.c          |   10 -
 src/i915_3d.h          |   15 ++
 src/i915_render.c      |   34 +++---
 src/i915_trapezoids.c  |  257 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/i915_video.c       |    2 
 src/i965_render.c      |    2 
 src/i965_video.c       |    1 
 uxa/uxa-glyphs.c       |    4 
 uxa/uxa-render.c       |   50 ++++++++-
 uxa/uxa.c              |    3 
 uxa/uxa.h              |    5 
 20 files changed, 389 insertions(+), 94 deletions(-)

New commits:
commit 994aa1ef571ac2ab05f6588f9068d33b536c7a37
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 9 09:59:36 2010 +0100

    uxa: Handle all-clipped out case with destination glyphs.
    
    Fixes the crash reported in:
    
      Bug 28446 - Garbled Font with Mathematica 7
      https://bugs.freedesktop.org/show_bug.cgi?id=28446
    
    pDst=0x3d663c0, src_x=0, src_y=0, xDst=142, yDst=112, nlist=0,
    list=0x7fffea026580, glyphs=0x7fffea025d88, extents=0x0)
        at uxa-glyphs.c:809
            dx = 0
            y1 = 101
            x2 = 150
            x1 = 142
            dy = 0
            y2 = 112
            rects = 0x5491000
            this_atlas = 0x2456d00
            mask_y = 128
            glyph = 0x35933a0
            mask_x = 736
            priv = 0x39309e0
            screen = 0x8d2cc0
            uxa_screen = 0x2443eb0
            src_pixmap = 0x37c29e0
            dst_pixmap = 0x45ddbf0
            localSrc = 0x361a450
            glyph_atlas = 0x2456d00
            x = 142
            y = 112
            n = 18
            nrect = -9975128
            box = {x1 = 23152, y1 = -5630, x2 = 32767, y2 = 0}
            __PRETTY_FUNCTION__ = "uxa_glyphs_to_dst"
    
    Though the meat of that bug regarding the incorrect remains unsolved.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index e679b4e..31bf915 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -800,7 +800,7 @@ uxa_glyphs_to_dst(CARD8 op,
 							    glyph->info.height);
 			} else {
 				BoxPtr rects = REGION_RECTS(pDst->pCompositeClip);
-				do {
+				while (nrect--) {
 					int x1 = x - glyph->info.x, dx = 0;
 					int y1 = y - glyph->info.y, dy = 0;
 					int x2 = x1 + glyph->info.width;
@@ -823,7 +823,7 @@ uxa_glyphs_to_dst(CARD8 op,
 									    x2 - x1, y2 - y1);
 					}
 					rects++;
-				} while (--nrect);
+				}
 			}
 
 next_glyph:
commit f429fb9d872950705e11171d0e7407fb7673c786
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 8 10:24:51 2010 +0100

    xp:trapezoids

diff --git a/src/Makefile.am b/src/Makefile.am
index 864660e..d99d85f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,6 +80,7 @@ intel_drv_la_SOURCES = \
 	 i830_render.c \
 	 i915_render.c \
 	 i965_render.c \
+	 i915_trapezoids.c \
 	 drmmode_display.c
 
 EXTRA_DIST = 		\
diff --git a/src/i830.h b/src/i830.h
index 0992088..a812cca 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -366,7 +366,6 @@ typedef struct intel_screen_private {
 		uint32_t dst_format;
 	} i915_render_state;
 
-	uint32_t prim_offset;
 	void (*prim_emit)(PixmapPtr dest,
 			  int srcX, int srcY,
 			  int maskX, int maskY,
@@ -428,15 +427,18 @@ intel_get_screen_private(ScrnInfoPtr scrn)
 #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 
-unsigned long intel_get_pixmap_pitch(PixmapPtr pixmap);
+static inline unsigned long intel_get_pixmap_pitch(PixmapPtr pixmap)
+{
+	return (unsigned long)pixmap->devKind;
+}
+
 
 /* Batchbuffer support macros and functions */
 #include "i830_batchbuffer.h"
 
 /* I830 specific functions */
-extern void IntelEmitInvarientState(ScrnInfoPtr scrn);
-extern void I830EmitInvarientState(ScrnInfoPtr scrn);
-extern void I915EmitInvarientState(ScrnInfoPtr scrn);
+extern void I830EmitInvarientState(intel_screen_private *intel);
+extern void I915EmitInvarientState(intel_screen_private *intel);
 
 extern void I830EmitFlush(ScrnInfoPtr scrn);
 
@@ -501,6 +503,8 @@ Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
 			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
 void i915_composite(PixmapPtr dest, int srcX, int srcY,
 		    int maskX, int maskY, int dstX, int dstY, int w, int h);
+Bool i915_check_trapezoids(int width, int height, int depth);
+Bool i915_rasterize_trapezoids(PixmapPtr pixmap, Bool clear, int ntrap, xTrapezoid *trap, int dst_x, int dst_y);
 void i915_vertex_flush(intel_screen_private *intel);
 void i915_batch_flush_notify(ScrnInfoPtr scrn);
 void i830_batch_flush_notify(ScrnInfoPtr scrn);
diff --git a/src/i830_3d.c b/src/i830_3d.c
index a92da05..56fa91b 100644
--- a/src/i830_3d.c
+++ b/src/i830_3d.c
@@ -34,12 +34,8 @@
 
 #include "i830_reg.h"
 
-void I830EmitInvarientState(ScrnInfoPtr scrn)
+void I830EmitInvarientState(intel_screen_private *intel)
 {
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-
-	assert(intel->in_batch_atomic);
-
 	OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
 	OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
 	OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(2));
diff --git a/src/i830_accel.c b/src/i830_accel.c
index da7e773..84b02be 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -45,11 +45,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i810_reg.h"
 #include "i915_drm.h"
 
-unsigned long intel_get_pixmap_pitch(PixmapPtr pixmap)
-{
-	return (unsigned long)pixmap->devKind;
-}
-
 void i830_debug_flush(ScrnInfoPtr scrn)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 26fade3..38fad49 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -53,11 +53,13 @@ static void intel_end_vertex(intel_screen_private *intel)
 
 void intel_next_vertex(intel_screen_private *intel)
 {
+	assert(intel->vertex_count == 0);
+
 	intel_end_vertex(intel);
 
 	intel->vertex_bo =
 		dri_bo_alloc(intel->bufmgr, "vertex", sizeof (intel->vertex_ptr), 4096);
-	intel->vertex_used = 0;
+	intel->vertex_used = intel->vertex_index = 0;
 }
 
 static void intel_next_batch(ScrnInfoPtr scrn)
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 7508a9c..3ae316d 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -50,12 +50,15 @@ static inline int intel_vertex_space(intel_screen_private *intel)
 	return intel->vertex_bo ? intel->vertex_bo->size - (4*intel->vertex_used) : 0;
 }
 
-static inline void
+static inline Bool
 intel_batch_require_space(ScrnInfoPtr scrn, intel_screen_private *intel, GLuint sz)
 {
 	assert(sz < intel->batch_bo->size - 8);
-	if (intel_batch_space(intel) < sz)
+	if (intel_batch_space(intel) < sz) {
 		intel_batch_submit(scrn);
+		return TRUE;
+	}
+	return FALSE;
 }
 
 static inline void intel_batch_start_atomic(ScrnInfoPtr scrn, unsigned int sz)
diff --git a/src/i830_driver.c b/src/i830_driver.c
index eed755c..b7717c7 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -824,31 +824,6 @@ enum pipe {
 	PIPE_B,
 };
 
-/**
- * Intialiazes the hardware for the 3D pipeline use in the 2D driver.
- *
- * Some state caching is performed to avoid redundant state emits.  This
- * function is also responsible for marking the state as clobbered for DRI
- * clients.
- */
-void IntelEmitInvarientState(ScrnInfoPtr scrn)
-{
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-
-	/* If we've emitted our state since the last clobber by another client,
-	 * skip it.
-	 */
-	if (intel->last_3d != LAST_3D_OTHER)
-		return;
-
-	if (!IS_I965G(intel)) {
-		if (IS_I9XX(intel))
-			I915EmitInvarientState(scrn);
-		else
-			I830EmitInvarientState(scrn);
-	}
-}
-
 static void
 I830BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
 {
diff --git a/src/i830_render.c b/src/i830_render.c
index cba65eb..ab5ce93 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -566,7 +566,8 @@ static void i830_emit_composite_state(ScrnInfoPtr scrn)
 
 	intel->needs_render_state_emit = FALSE;
 
-	IntelEmitInvarientState(scrn);
+	if (intel->last_3d == LAST_3D_OTHER)
+		I830EmitInvarientState(intel);
 	intel->last_3d = LAST_3D_RENDER;
 
 	assert(intel->in_batch_atomic);
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index bf364f8..3faddb3 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -1100,7 +1100,6 @@ Bool i830_uxa_init(ScreenPtr screen)
 	intel->uxa_driver->uxa_minor = 0;
 
 	intel->render_current_dest = NULL;
-	intel->prim_offset = 0;
 	intel->vertex_count = 0;
 	intel->floats_per_vertex = 0;
 	intel->last_floats_per_vertex = 0;
@@ -1134,6 +1133,8 @@ Bool i830_uxa_init(ScreenPtr screen)
 		intel->uxa_driver->prepare_composite = i915_prepare_composite;
 		intel->uxa_driver->composite = i915_composite;
 		intel->uxa_driver->done_composite = i830_done_composite;
+		intel->uxa_driver->check_trapezoids = i915_check_trapezoids;
+		intel->uxa_driver->rasterize_trapezoids = i915_rasterize_trapezoids;
 	} else {
 		intel->uxa_driver->check_composite = i965_check_composite;
 		intel->uxa_driver->check_composite_texture = i965_check_composite_texture;
diff --git a/src/i915_3d.c b/src/i915_3d.c
index 906043b..8078838 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -34,12 +34,8 @@
 
 #include "i915_reg.h"
 
-void I915EmitInvarientState(ScrnInfoPtr scrn)
+void I915EmitInvarientState(intel_screen_private *intel)
 {
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-
-	assert(intel->in_batch_atomic);
-
 	OUT_BATCH(_3DSTATE_AA_CMD |
 		  AA_LINE_ECAAR_WIDTH_ENABLE |
 		  AA_LINE_ECAAR_WIDTH_1_0 |
@@ -70,7 +66,9 @@ void I915EmitInvarientState(ScrnInfoPtr scrn)
 		  CSB_TCB(2, 2) |
 		  CSB_TCB(3, 3) |
 		  CSB_TCB(4, 4) |
-		  CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7));
+		  CSB_TCB(5, 5) |
+		  CSB_TCB(6, 6) |
+		  CSB_TCB(7, 7));
 
 	OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
 		  ENABLE_POINT_RASTER_RULE |
diff --git a/src/i915_3d.h b/src/i915_3d.h
index 04531f3..3386bf5 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -598,6 +598,21 @@ enum i915_fs_channel {
 	} while (0)
 
 /**
+ * Perform a 4-component dot-product of operand0 and operand1 and put the
+ * resulting scalar in the channels of dest_reg specified by the dest_mask.
+ */
+#define i915_fs_dp4(dest_reg, dest_mask, op0, op1)	\
+	do {									\
+		if (dest_mask) {							\
+			i915_fs_arith_masked (DP4, dest_reg, dest_mask, \
+					      op0, op1,\
+					      i915_fs_operand_none());			\
+		} else { \
+			i915_fs_arith (DP4, dest_reg, op0, op1,\
+				       i915_fs_operand_none());			\
+		} \
+	} while (0)
+/**
  * Sets up local state for accumulating a fragment shader buffer.
  *
  * \param x maximum number of shader commands that may be used between
diff --git a/src/i915_render.c b/src/i915_render.c
index b2bc7a7..9e3cb50 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -993,7 +993,8 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
 
 	intel->needs_render_state_emit = FALSE;
 
-	IntelEmitInvarientState(scrn);
+	if (intel->last_3d == LAST_3D_OTHER)
+		I915EmitInvarientState(intel);
 	intel->last_3d = LAST_3D_RENDER;
 
 	is_solid_src = intel->render_source_is_solid;
@@ -1140,18 +1141,12 @@ i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
 		intel->needs_render_vertex_emit = FALSE;
 	}
 
-	if (intel->prim_offset == 0) {
-		if (intel->needs_render_ca_pass) {
-			OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
-			OUT_BATCH(i915_get_blend_cntl(PictOpOutReverse,
-						      intel->render_mask_picture,
-						      intel->render_dest_picture->format));
-			i915_composite_emit_shader(intel, PictOpOutReverse);
-		}
-
-		intel->prim_offset = intel->batch_used;
-		OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL);
-		OUT_BATCH(intel->vertex_index);
+	if (intel->vertex_count == 0 && intel->needs_render_ca_pass) {
+		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
+		OUT_BATCH(i915_get_blend_cntl(PictOpOutReverse,
+					      intel->render_mask_picture,
+					      intel->render_dest_picture->format));
+		i915_composite_emit_shader(intel, PictOpOutReverse);
 	}
 	intel->vertex_count += 3;
 
@@ -1167,11 +1162,11 @@ i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
 void
 i915_vertex_flush(intel_screen_private *intel)
 {
-	if (intel->prim_offset == 0)
+	if (intel->vertex_count == 0)
 		return;
 
-	intel->batch_ptr[intel->prim_offset] |= intel->vertex_count;
-	intel->prim_offset = 0;
+	OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL | intel->vertex_count);
+	OUT_BATCH(intel->vertex_index);
 
 	if (intel->needs_render_ca_pass) {
 		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
diff --git a/src/i915_trapezoids.c b/src/i915_trapezoids.c
new file mode 100644
index 0000000..53c781f
--- /dev/null
+++ b/src/i915_trapezoids.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xaarop.h"
+#include "i830.h"
+#include "i915_reg.h"
+#include "i915_3d.h"
+
+#define FLOATS_PER_VERTEX 6
+
+Bool
+i915_check_trapezoids(int width, int height, int depth)
+{
+	return width <= 2048 && height <= 2048 && depth == 8;
+}
+
+static inline float
+line_x_for_y(xLineFixed *l, xFixed y)
+{
+	if (y == l->p1.y)
+		return l->p1.x;
+	if (y == l->p2.y)
+		return l->p2.x;
+	if (l->p2.x == l->p1.x)
+		return l->p1.x;
+
+	return l->p1.x + (y - l->p1.y) * (float) (l->p2.x - l->p1.x) / (l->p2.y - l->p1.y);
+}
+
+#define OUT_TRAP_VERTEX(x, y) do { \
+	xFixed fy = IntToxFixed(y); \
+	float sf = 1. / xFixed1; \
+	OUT_VERTEX(x + dst_x); \
+	OUT_VERTEX(y + dst_y); \
+	OUT_VERTEX(y - trap->top*sf); \
+	OUT_VERTEX(trap->bottom*sf - y); \
+	OUT_VERTEX(x - sf*line_x_for_y(&trap->left, fy)); \
+	OUT_VERTEX(sf*line_x_for_y(&trap->right, fy) - x); \
+} while (0)
+
+static void
+i915_trapezoids_set_target(intel_screen_private *intel, PixmapPtr pixmap)
+{
+	if (intel->last_3d == LAST_3D_OTHER)
+		I915EmitInvarientState(intel);
+	intel->last_3d = LAST_3D_RENDER;
+
+	if (intel->render_current_dest != pixmap) {
+	    uint32_t tiling_bits;
+
+	    tiling_bits = 0;
+	    switch(i830_get_pixmap_intel(pixmap)->tiling) {
+	    case I915_TILING_NONE: break;
+	    case I915_TILING_Y: tiling_bits |= BUF_3D_TILE_WALK_Y;
+	    case I915_TILING_X: tiling_bits |= BUF_3D_TILED_SURFACE; break;
+	    }
+
+	    OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
+	    OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits |
+		      BUF_3D_PITCH(intel_get_pixmap_pitch(pixmap)));
+	    OUT_RELOC_PIXMAP(pixmap, I915_GEM_DOMAIN_RENDER,
+			     I915_GEM_DOMAIN_RENDER, 0);
+
+	    OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
+	    OUT_BATCH(COLR_BUF_8BIT);
+
+	    /* draw rect is unconditional */
+	    OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
+	    OUT_BATCH(0x00000000);
+	    OUT_BATCH(0x00000000);	/* ymin, xmin */
+	    OUT_BATCH(DRAW_YMAX(pixmap->drawable.height - 1) |
+		      DRAW_XMAX(pixmap->drawable.width - 1));
+	    /* yorig, xorig (relate to color buffer?) */
+	    OUT_BATCH(0x00000000);
+
+	    intel->render_current_dest = pixmap;
+	}
+}
+
+static void
+i915_trapezoids_set_shader(intel_screen_private *intel)
+{
+	FS_LOCALS();
+
+	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
+	OUT_BATCH(~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(0, TEXCOORDFMT_4D));
+	OUT_BATCH(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
+		  (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) |
+		  (BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+		  (BLENDFACT_ONE << S6_CBUF_DST_BLEND_FACT_SHIFT));
+
+	FS_BEGIN();
+	i915_fs_dcl(FS_T0);
+	i915_fs_min(FS_U0,
+		    i915_fs_operand(FS_R0, ZERO, ONE, ZERO, ONE),
+		    i915_fs_operand_reg(FS_T0));
+	i915_fs_add(FS_U0,
+		    i915_fs_operand(FS_U0, X, Z, ZERO, ZERO),
+		    i915_fs_operand(FS_U0, Y, W, ZERO, ZERO));
+	i915_fs_mul(FS_OC,
+		    i915_fs_operand(FS_U0, X, X, X, X),
+		    i915_fs_operand(FS_U0, Y, Y, Y, Y));
+	FS_END();
+}
+
+static void
+i915_trapezoids_set_vertices(intel_screen_private *intel)
+{
+	intel->floats_per_vertex = FLOATS_PER_VERTEX;
+	if (intel_vertex_space(intel) < 3*4*FLOATS_PER_VERTEX) {
+		intel_next_vertex(intel);
+
+		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+			  I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
+		OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
+		OUT_BATCH((FLOATS_PER_VERTEX << S1_VERTEX_WIDTH_SHIFT) |
+			  (FLOATS_PER_VERTEX << S1_VERTEX_PITCH_SHIFT));
+	} else if (FLOATS_PER_VERTEX != intel->last_floats_per_vertex){
+		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+			  I1_LOAD_S(1) | 0);
+		OUT_BATCH((FLOATS_PER_VERTEX << S1_VERTEX_WIDTH_SHIFT) |
+			  (FLOATS_PER_VERTEX << S1_VERTEX_PITCH_SHIFT));
+
+		intel->vertex_index =
+			(intel->vertex_used + FLOATS_PER_VERTEX - 1) / FLOATS_PER_VERTEX;
+		intel->vertex_used = intel->vertex_index * FLOATS_PER_VERTEX;
+	}
+	intel->last_floats_per_vertex = FLOATS_PER_VERTEX;
+}
+
+Bool
+i915_rasterize_trapezoids(PixmapPtr pixmap, Bool clear,
+			  int ntrap, xTrapezoid *trap,
+			  int dst_x, int dst_y)
+{
+	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+
+	if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048)
+		return FALSE;
+
+	if(!intel_check_pitch_3d(pixmap))
+		return FALSE;
+
+	intel_batch_require_space(scrn, intel, 150);
+	i915_trapezoids_set_target(intel, pixmap);
+
+	if (clear) {
+#if 1
+		FS_LOCALS();
+
+		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
+		OUT_BATCH(~0);
+		OUT_BATCH(S6_COLOR_WRITE_ENABLE);
+
+		FS_BEGIN();
+		i915_fs_mov(FS_OC, i915_fs_operand_zero());
+		FS_END();
+
+		OUT_BATCH(PRIM3D_RECTLIST | 5);
+		OUT_BATCH_F(pixmap->drawable.width);
+		OUT_BATCH_F(pixmap->drawable.height);
+		OUT_BATCH_F(0);
+		OUT_BATCH_F(pixmap->drawable.height);
+		OUT_BATCH_F(0);
+		OUT_BATCH_F(0);
+#else
+		OUT_BATCH(XY_COLOR_BLT_CMD);
+		OUT_BATCH(ROP_0 | intel_get_pixmap_pitch(pixmap));
+		OUT_BATCH(0);
+		OUT_BATCH((pixmap->drawable.height << 16) | pixmap->drawable.width);
+		OUT_RELOC_PIXMAP_FENCED(pixmap, I915_GEM_DOMAIN_RENDER,
+					I915_GEM_DOMAIN_RENDER, 0);
+		OUT_BATCH(0);
+#endif
+	}
+
+	i915_trapezoids_set_shader(intel);
+	i915_trapezoids_set_vertices(intel);
+
+	for (; ntrap--; trap++) {
+		int x1, x2, y1, y2;
+
+		if (!xTrapezoidValid(trap))
+			continue;
+
+		x1 = xFixedToInt(min(trap->left.p1.x, trap->left.p2.x));
+		x2 = xFixedToInt(xFixedCeil(max(trap->right.p1.x, trap->right.p2.x)));
+		y1 = xFixedToInt(trap->top);
+		y2 = xFixedToInt(xFixedCeil(trap->bottom));
+
+		if (x2 + dst_x <= 0 || x1 + dst_x >= pixmap->drawable.width ||
+		    y2 + dst_y <= 0 || y1 + dst_y >= pixmap->drawable.height)
+			continue;
+
+		if (intel_vertex_space(intel) < 3*4*FLOATS_PER_VERTEX) {
+			i915_vertex_flush(intel);
+
+			if (intel_batch_require_space(scrn, intel, 16)) {
+				i915_trapezoids_set_target(intel, pixmap);
+				i915_trapezoids_set_shader(intel);
+
+				intel_next_vertex(intel);
+				OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+					  I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
+				OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
+				OUT_BATCH((FLOATS_PER_VERTEX << S1_VERTEX_WIDTH_SHIFT) |
+					  (FLOATS_PER_VERTEX << S1_VERTEX_PITCH_SHIFT));
+
+				intel->last_floats_per_vertex = FLOATS_PER_VERTEX;
+				intel->floats_per_vertex = FLOATS_PER_VERTEX;
+			} else {
+				intel_next_vertex(intel);
+				OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+					  I1_LOAD_S(0) | 0);
+				OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
+			}
+		}
+
+		OUT_TRAP_VERTEX(x2, y2);
+		OUT_TRAP_VERTEX(x1, y2);
+		OUT_TRAP_VERTEX(x1, y1);
+		intel->vertex_count += 3;
+	}
+
+	i915_vertex_flush(intel);
+	return TRUE;
+}
diff --git a/src/i915_video.c b/src/i915_video.c
index 893855b..ad0bba9 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -101,8 +101,6 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
 		nbox_total -= nbox_this_time;
 
 		intel_batch_start_atomic(scrn, 200 + 20 * nbox_this_time);
-
-		IntelEmitInvarientState(scrn);
 		intel->last_3d = LAST_3D_VIDEO;
 
 		/* draw rect -- just clipping */
diff --git a/src/i965_render.c b/src/i965_render.c
index 4f68b04..83b31a7 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1156,8 +1156,6 @@ static void i965_emit_composite_state(ScrnInfoPtr scrn)
 	dri_bo *binding_table_bo = composite_op->binding_table_bo;
 
 	intel->needs_render_state_emit = FALSE;
-
-	IntelEmitInvarientState(scrn);
 	intel->last_3d = LAST_3D_RENDER;
 
 	urb_vs_start = 0;
diff --git a/src/i965_video.c b/src/i965_video.c
index 855f0b5..b3079e6 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -764,7 +764,6 @@ i965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * bind_bo, int n_src_surf)
 	int urb_cs_start, urb_cs_size;
 	int pipe_ctl;
 
-	IntelEmitInvarientState(scrn);
 	intel->last_3d = LAST_3D_VIDEO;
 
 	urb_vs_start = 0;
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index abfef8e..6783a21 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -1759,6 +1759,7 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
 	       int ntrap, xTrapezoid * traps)
 {
 	ScreenPtr screen = dst->pDrawable->pScreen;
+	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
 	BoxRec bounds;
 	Bool direct;
 
@@ -1783,12 +1784,19 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
 		xoff += pDraw->x;
 		yoff += pDraw->y;
 
-		if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
-			PictureScreenPtr ps = GetPictureScreen(screen);
-
-			for (; ntrap; ntrap--, traps++)
-				(*ps->RasterizeTrapezoid) (dst, traps, 0, 0);
-			uxa_finish_access(pDraw);
+		if (!(uxa_pixmap_is_offscreen(pixmap) &&
+		      uxa_screen->info->check_trapezoids &&
+		      uxa_screen->info->check_trapezoids(pixmap->drawable.width,
+							 pixmap->drawable.height,
+							 pixmap->drawable.depth) &&
+		      uxa_screen->info->rasterize_trapezoids(pixmap, FALSE, ntrap, traps, xoff, yoff))) {
+			if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
+				PictureScreenPtr ps = GetPictureScreen(screen);
+
+				for (; ntrap; ntrap--, traps++)
+					(*ps->RasterizeTrapezoid) (dst, traps, 0, 0);
+				uxa_finish_access(pDraw);
+			}
 		}
 	} else if (maskFormat) {
 		PixmapPtr scratch = NULL;
@@ -1805,6 +1813,36 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
 		width  = bounds.x2 - bounds.x1;
 		height = bounds.y2 - bounds.y1;
 
+		if (uxa_drawable_is_offscreen(dst->pDrawable) &&
+		    uxa_screen->info->check_trapezoids &&
+		    uxa_screen->info->check_trapezoids(width, height, maskFormat->depth)) {
+			PixmapPtr pixmap;
+
+			pixmap = screen->CreatePixmap(screen, width, height, maskFormat->depth,
+						       CREATE_PIXMAP_USAGE_SCRATCH);
+			if (uxa_screen->info->rasterize_trapezoids(pixmap, TRUE,
+								   ntrap, traps,
+								   -bounds.x1, -bounds.y1)) {
+				int error;
+
+				mask = CreatePicture(0, &pixmap->drawable, maskFormat,
+						     0, 0, serverClient, &error);
+				if (mask) {
+					CompositePicture(op, src, mask, dst,
+							 bounds.x1 + xSrc - xDst,
+							 bounds.y1 + ySrc - yDst,
+							 0, 0,
+							 bounds.x1, bounds.y1,
+							 width, height);
+					FreePicture(mask, 0);
+					screen->DestroyPixmap(pixmap);
+					return;
+				}
+			}
+
+			screen->DestroyPixmap(pixmap);
+		}
+
 		format = maskFormat->format |
 			(BitsPerPixel(maskFormat->depth) << 24);
 		image =
diff --git a/uxa/uxa.c b/uxa/uxa.c
index 8689933..80de1ae 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -577,6 +577,9 @@ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver)
 	if (uxa_driver->get_image != NULL) {
 		LogMessage(X_INFO, "        get_image\n");
 	}
+	if (uxa_driver->rasterize_trapezoids != NULL) {
+		LogMessage(X_INFO, "        trapezoids\n");
+	}
 
 	return TRUE;
 }
diff --git a/uxa/uxa.h b/uxa/uxa.h
index e001c53..80ac2f9 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -402,6 +402,11 @@ typedef struct _UxaDriver {
 	 * This call is required if prepare_composite() ever succeeds.
 	 */
 	void (*done_composite) (PixmapPtr pDst);
+
+	Bool(*check_trapezoids) (int width, int height, int depth);
+	Bool(*rasterize_trapezoids) (PixmapPtr pixmap, Bool clear,
+				     int ntraps, xTrapezoid *traps,
+				     int dst_x, int dst_y);
 	/** @} */
 
 	/**
commit 0776a42b70f2de7b7d7d8804046c79442da1cb8a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 8 10:43:24 2010 +0100

    implicit-flush

diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 1b6a56e..26fade3 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -144,6 +144,24 @@ void intel_batch_teardown(ScrnInfoPtr scrn)
 	}
 }
 
+void intel_batch_do_flush(ScrnInfoPtr scrn)
+{
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+
+	while (!list_is_empty(&intel->flush_pixmaps)) {
+		struct intel_pixmap *entry;
+
+		entry = list_first_entry(&intel->flush_pixmaps,
+					 struct intel_pixmap,
+					 flush);
+
+		entry->flush_read_domains = entry->flush_write_domain = 0;
+		list_del(&entry->flush);
+	}
+
+	intel->need_mi_flush = FALSE;
+}
+
 void intel_batch_emit_flush(ScrnInfoPtr scrn)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -160,18 +178,7 @@ void intel_batch_emit_flush(ScrnInfoPtr scrn)
 	OUT_BATCH(MI_FLUSH | flags);
 	ADVANCE_BATCH();
 
-	while (!list_is_empty(&intel->flush_pixmaps)) {
-		struct intel_pixmap *entry;
-
-		entry = list_first_entry(&intel->flush_pixmaps,
-					 struct intel_pixmap,
-					 flush);
-
-		entry->flush_read_domains = entry->flush_write_domain = 0;
-		list_del(&entry->flush);
-	}
-
-	intel->need_mi_flush = FALSE;
+	intel_batch_do_flush(scrn);
 }
 
 void intel_batch_submit(ScrnInfoPtr scrn)
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index b5c729a..7508a9c 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 void intel_batch_init(ScrnInfoPtr scrn);
 void intel_batch_teardown(ScrnInfoPtr scrn);
 void intel_batch_emit_flush(ScrnInfoPtr scrn);
+void intel_batch_do_flush(ScrnInfoPtr scrn);
 void intel_batch_submit(ScrnInfoPtr scrn);
 void intel_batch_wait_last(ScrnInfoPtr scrn);
 
diff --git a/src/i915_render.c b/src/i915_render.c
index c71a7c8..b2bc7a7 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -832,8 +832,11 @@ i915_prepare_composite(int op, PicturePtr source_picture,
 
 	intel->i915_render_state.op = op;
 
-	if((source && i830_uxa_pixmap_is_dirty(source)) ||
-	   (mask && i830_uxa_pixmap_is_dirty(mask)))
+	/* BUF_INFO is an implicit flush */
+	if (dest != intel->render_current_dest)
+		intel_batch_do_flush(scrn);
+	else if((source && i830_uxa_pixmap_is_dirty(source)) ||
+		(mask && i830_uxa_pixmap_is_dirty(mask)))
 		intel_batch_emit_flush(scrn);
 
 	intel->needs_render_state_emit = TRUE;


More information about the xorg-commit mailing list