summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-19 14:50:12 +0100
committerOwain G. Ainsworth <oga@openbsd.org>2010-05-25 16:31:56 +0100
commit74fd6a2cb86d484a5af68b9567f910c9f405e3ad (patch)
treee7607c51fe5fad0dee70dcf3970aacb9bdca11b0
parent0727b50b8de9d66474e276e307542760653a320d (diff)
i915: Move vertices into a vertex buffer object.
In theory this should allow us to pack far more operations into a single batch buffer, and reduce our overheads. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Owain G. Ainsworth <oga@openbsd.org>
-rw-r--r--src/i830.h8
-rw-r--r--src/i830_batchbuffer.c21
-rw-r--r--src/i830_batchbuffer.h12
-rw-r--r--src/i830_uxa.c5
-rw-r--r--src/i915_reg.h27
-rw-r--r--src/i915_render.c448
-rw-r--r--src/i915_video.c2
7 files changed, 298 insertions, 225 deletions
diff --git a/src/i830.h b/src/i830.h
index 81851388..1099e9f2 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -588,6 +588,7 @@ typedef struct intel_screen_private {
Bool render_source_is_solid;
Bool render_mask_is_solid;
Bool needs_render_state_emit;
+ Bool needs_render_vertex_emit;
/* i830 render accel state */
uint32_t render_dest_format;
@@ -604,12 +605,17 @@ typedef struct intel_screen_private {
} i915_render_state;
uint32_t prim_offset;
- uint32_t prim_count;
void (*prim_emit)(PixmapPtr dest,
int srcX, int srcY,
int maskX, int maskY,
int dstX, int dstY,
int w, int h);
+ int floats_per_vertex;
+ uint32_t vertex_count;
+ uint32_t vertex_index;
+ uint32_t vertex_used;
+ float vertex_ptr[4*1024];
+ dri_bo *vertex_bo;
/* 965 render acceleration state */
struct gen4_render_state *gen4_render_state;
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index c33d0114..916bdd0d 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -102,6 +102,26 @@ intel_nondrm_wait(unsigned int fence, void *priv)
i830_wait_ring_idle(scrn);
}
+static void intel_end_vertex(intel_screen_private *intel)
+{
+ if (intel->vertex_bo) {
+ if (intel->vertex_used)
+ dri_bo_subdata(intel->vertex_bo, 0, intel->vertex_used*4, intel->vertex_ptr);
+
+ dri_bo_unreference(intel->vertex_bo);
+ intel->vertex_bo = NULL;
+ }
+}
+
+void intel_next_vertex(intel_screen_private *intel)
+{
+ intel_end_vertex(intel);
+
+ intel->vertex_bo =
+ dri_bo_alloc(intel->bufmgr, "vertex", sizeof (intel->vertex_ptr), 4096);
+ intel->vertex_used = 0;
+}
+
static void intel_next_batch(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -233,6 +253,7 @@ void intel_batch_submit(ScrnInfoPtr scrn)
if (intel->vertex_flush)
intel->vertex_flush(intel);
+ intel_end_vertex(intel);
/* Mark the end of the batchbuffer. */
OUT_BATCH(MI_BATCH_BUFFER_END);
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 10704dc1..12fa0ada 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -44,6 +44,11 @@ static inline int intel_batch_space(intel_screen_private *intel)
return (intel->batch_bo->size - BATCH_RESERVED) - (4*intel->batch_used);
}
+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
intel_batch_require_space(ScrnInfoPtr scrn, intel_screen_private *intel, GLuint sz)
{
@@ -210,4 +215,11 @@ do { \
intel->batch_emitting = 0; \
} while (0)
+void intel_next_vertex(intel_screen_private *intel);
+static inline void intel_vertex_emit(intel_screen_private *intel, float v)
+{
+ intel->vertex_ptr[intel->vertex_used++] = v;
+}
+#define OUT_VERTEX(v) intel_vertex_emit(intel, v)
+
#endif /* _INTEL_BATCHBUFFER_H */
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 3448cc31..b9f7bfc9 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -1054,8 +1054,11 @@ Bool i830_uxa_init(ScreenPtr screen)
intel->uxa_driver->uxa_major = 1;
intel->uxa_driver->uxa_minor = 0;
+ intel->needs_render_vertex_emit = TRUE;
intel->prim_offset = 0;
- intel->prim_count = 0;
+ intel->vertex_count = 0;
+ intel->floats_per_vertex = 0;
+ intel->vertex_bo = NULL;
/* Solid fill */
intel->uxa_driver->check_solid = i830_uxa_check_solid;
diff --git a/src/i915_reg.h b/src/i915_reg.h
index a61bc401..746a4131 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -32,19 +32,20 @@
#define CMD_3D (0x3<<29)
-#define PRIM3D_INLINE (CMD_3D | (0x1f<<24))
-#define PRIM3D_TRILIST (0x0<<18)
-#define PRIM3D_TRISTRIP (0x1<<18)
-#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
-#define PRIM3D_TRIFAN (0x3<<18)
-#define PRIM3D_POLY (0x4<<18)
-#define PRIM3D_LINELIST (0x5<<18)
-#define PRIM3D_LINESTRIP (0x6<<18)
-#define PRIM3D_RECTLIST (0x7<<18)
-#define PRIM3D_POINTLIST (0x8<<18)
-#define PRIM3D_DIB (0x9<<18)
-#define PRIM3D_CLEAR_RECT (0xa<<18)
-#define PRIM3D_ZONE_INIT (0xd<<18)
+#define PRIM3D (CMD_3D | (0x1f<<24))
+#define PRIM3D_INDIRECT_SEQUENTIAL ((1<<23) | (0<<17))
+#define PRIM3D_TRILIST (PRIM3D | (0x0<<18))
+#define PRIM3D_TRISTRIP (PRIM3D | (0x1<<18))
+#define PRIM3D_TRISTRIP_RVRSE (PRIM3D | (0x2<<18))
+#define PRIM3D_TRIFAN (PRIM3D | (0x3<<18))
+#define PRIM3D_POLY (PRIM3D | (0x4<<18))
+#define PRIM3D_LINELIST (PRIM3D | (0x5<<18))
+#define PRIM3D_LINESTRIP (PRIM3D | (0x6<<18))
+#define PRIM3D_RECTLIST (PRIM3D | (0x7<<18))
+#define PRIM3D_POINTLIST (PRIM3D | (0x8<<18))
+#define PRIM3D_DIB (PRIM3D | (0x9<<18))
+#define PRIM3D_CLEAR_RECT (PRIM3D | (0xa<<18))
+#define PRIM3D_ZONE_INIT (PRIM3D | (0xd<<18))
#define PRIM3D_MASK (0x1f<<18)
/* p137 */
diff --git a/src/i915_render.c b/src/i915_render.c
index 80f05e2a..bddbd098 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -364,116 +364,6 @@ static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
return TRUE;
}
-Bool
-i915_prepare_composite(int op, PicturePtr source_picture,
- PicturePtr mask_picture, PicturePtr dest_picture,
- PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
-{
- ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
- intel_screen_private *intel = intel_get_screen_private(scrn);
- drm_intel_bo *bo_table[] = {
- NULL, /* batch_bo */
- i830_get_pixmap_bo(dest),
- source ? i830_get_pixmap_bo(source) : NULL,
- mask ? i830_get_pixmap_bo(mask) : NULL,
- };
- int tex_unit = 0;
-
- intel->render_source_picture = source_picture;
- intel->render_source = source;
- intel->render_mask_picture = mask_picture;
- intel->render_mask = mask;
- intel->render_dest_picture = dest_picture;
- intel->render_dest = dest;
-
- intel->render_source_is_solid = FALSE;
- if (source_picture->pSourcePict) {
- SourcePict *source = source_picture->pSourcePict;
- if (source->type == SourcePictTypeSolidFill) {
- intel->render_source_is_solid = TRUE;
- intel->render_source_solid = source->solidFill.color;
- }
- }
- if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
- return FALSE;
-
- intel->render_mask_is_solid = FALSE;
- if (mask) {
- if (mask_picture->pSourcePict) {
- SourcePict *source = mask_picture->pSourcePict;
- if (source->type == SourcePictTypeSolidFill) {
- intel->render_mask_is_solid = TRUE;
- intel->render_mask_solid = source->solidFill.color;
- }
- }
- if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
- return FALSE;
- }
-
- if (!intel_check_pitch_3d(dest))
- return FALSE;
-
- if (!i915_get_dest_format(dest_picture,
- &intel->i915_render_state.dst_format))
- return FALSE;
-
- if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
- return FALSE;
- intel->dst_coord_adjust = 0;
- intel->src_coord_adjust = 0;
- intel->mask_coord_adjust = 0;
-
- intel->transform[0] = NULL;
- intel->scale_units[0][0] = -1;
- intel->scale_units[0][1] = -1;
- intel->transform[1] = NULL;
- intel->scale_units[1][0] = -1;
- intel->scale_units[1][1] = -1;
-
- if (! intel->render_source_is_solid) {
- if (!i915_texture_setup(source_picture, source, tex_unit++)) {
- intel_debug_fallback(scrn, "fail to setup src texture\n");
- return FALSE;
- }
-
- if (source_picture->filter == PictFilterNearest) {
-#if PIXEL_CENTRE_SAMPLE
- intel->src_coord_adjust = 0.375;
-#else
- intel->dst_coord_adjust = -0.125;
-#endif
- }
- }
-
- if (mask != NULL) {
- if (! intel->render_mask_is_solid) {
- if (!i915_texture_setup(mask_picture, mask, tex_unit++)) {
- intel_debug_fallback(scrn,
- "fail to setup mask texture\n");
- return FALSE;
- }
-
- if (mask_picture->filter == PictFilterNearest) {
-#if PIXEL_CENTRE_SAMPLE
- intel->mask_coord_adjust = 0.375;
-#else
- intel->dst_coord_adjust = -0.125;
-#endif
- }
- }
- }
-
- intel->i915_render_state.op = op;
-
- 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;
-
- return TRUE;
-}
-
static void
i915_emit_composite_primitive_constant(PixmapPtr dest,
int srcX, int srcY,
@@ -485,23 +375,17 @@ i915_emit_composite_primitive_constant(PixmapPtr dest,
intel_screen_private *intel = intel_get_screen_private(scrn);
float x, y;
- if (intel->prim_offset == 0) {
- intel->prim_offset = intel->batch_used;
- OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST);
- }
- intel->prim_count += 6;
-
x = dstX + intel->dst_coord_adjust;
y = dstY + intel->dst_coord_adjust;
- OUT_BATCH_F(x + w);
- OUT_BATCH_F(y + h);
+ OUT_VERTEX(x + w);
+ OUT_VERTEX(y + h);
- OUT_BATCH_F(x);
- OUT_BATCH_F(y + h);
+ OUT_VERTEX(x);
+ OUT_VERTEX(y + h);
- OUT_BATCH_F(x);
- OUT_BATCH_F(y);
+ OUT_VERTEX(x);
+ OUT_VERTEX(y);
}
static void
@@ -515,31 +399,25 @@ i915_emit_composite_primitive_identity_source(PixmapPtr dest,
intel_screen_private *intel = intel_get_screen_private(scrn);
float dst_x, dst_y, src_x, src_y;
- if (intel->prim_offset == 0) {
- intel->prim_offset = intel->batch_used;
- OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST);
- }
- intel->prim_count += 12;
-
dst_x = dstX + intel->dst_coord_adjust;
dst_y = dstY + intel->dst_coord_adjust;
src_x = srcX + intel->src_coord_adjust;
src_y = srcY + intel->src_coord_adjust;
- OUT_BATCH_F(dst_x + w);
- OUT_BATCH_F(dst_y + h);
- OUT_BATCH_F((src_x + w) / intel->scale_units[0][0]);
- OUT_BATCH_F((src_y + h) / intel->scale_units[0][1]);
+ OUT_VERTEX(dst_x + w);
+ OUT_VERTEX(dst_y + h);
+ OUT_VERTEX((src_x + w) / intel->scale_units[0][0]);
+ OUT_VERTEX((src_y + h) / intel->scale_units[0][1]);
- OUT_BATCH_F(dst_x);
- OUT_BATCH_F(dst_y + h);
- OUT_BATCH_F(src_x / intel->scale_units[0][0]);
- OUT_BATCH_F((src_y + h) / intel->scale_units[0][1]);
+ OUT_VERTEX(dst_x);
+ OUT_VERTEX(dst_y + h);
+ OUT_VERTEX(src_x / intel->scale_units[0][0]);
+ OUT_VERTEX((src_y + h) / intel->scale_units[0][1]);
- OUT_BATCH_F(dst_x);
- OUT_BATCH_F(dst_y);
- OUT_BATCH_F(src_x / intel->scale_units[0][0]);
- OUT_BATCH_F(src_y / intel->scale_units[0][1]);
+ OUT_VERTEX(dst_x);
+ OUT_VERTEX(dst_y);
+ OUT_VERTEX(src_x / intel->scale_units[0][0]);
+ OUT_VERTEX(src_y / intel->scale_units[0][1]);
}
static void
@@ -574,29 +452,23 @@ i915_emit_composite_primitive_affine_source(PixmapPtr dest,
&src_y[2]))
return;
- if (intel->prim_offset == 0) {
- intel->prim_offset = intel->batch_used;
- OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST);
- }
- intel->prim_count += 12;
-
x = dstX + intel->dst_coord_adjust;
y = dstY + intel->dst_coord_adjust;
- OUT_BATCH_F(x + w);
- OUT_BATCH_F(y + h);
- OUT_BATCH_F(src_x[2] / intel->scale_units[0][0]);
- OUT_BATCH_F(src_y[2] / intel->scale_units[0][1]);
+ OUT_VERTEX(x + w);
+ OUT_VERTEX(y + h);
+ OUT_VERTEX(src_x[2] / intel->scale_units[0][0]);
+ OUT_VERTEX(src_y[2] / intel->scale_units[0][1]);
- OUT_BATCH_F(x);
- OUT_BATCH_F(y + h);
- OUT_BATCH_F(src_x[1] / intel->scale_units[0][0]);
- OUT_BATCH_F(src_y[1] / intel->scale_units[0][1]);
+ OUT_VERTEX(x);
+ OUT_VERTEX(y + h);
+ OUT_VERTEX(src_x[1] / intel->scale_units[0][0]);
+ OUT_VERTEX(src_y[1] / intel->scale_units[0][1]);
- OUT_BATCH_F(x);
- OUT_BATCH_F(y);
- OUT_BATCH_F(src_x[0] / intel->scale_units[0][0]);
- OUT_BATCH_F(src_y[0] / intel->scale_units[0][1]);
+ OUT_VERTEX(x);
+ OUT_VERTEX(y);
+ OUT_VERTEX(src_x[0] / intel->scale_units[0][0]);
+ OUT_VERTEX(src_y[0] / intel->scale_units[0][1]);
}
static void
@@ -735,64 +607,201 @@ i915_emit_composite_primitive(PixmapPtr dest,
num_floats = 3 * per_vertex;
- intel->prim_count += num_floats;
-
- OUT_BATCH_F(intel->dst_coord_adjust + dstX + w);
- OUT_BATCH_F(intel->dst_coord_adjust + dstY + h);
+ OUT_VERTEX(intel->dst_coord_adjust + dstX + w);
+ OUT_VERTEX(intel->dst_coord_adjust + dstY + h);
if (! intel->render_source_is_solid) {
- OUT_BATCH_F(src_x[2] / intel->scale_units[src_unit][0]);
- OUT_BATCH_F(src_y[2] / intel->scale_units[src_unit][1]);
+ OUT_VERTEX(src_x[2] / intel->scale_units[src_unit][0]);
+ OUT_VERTEX(src_y[2] / intel->scale_units[src_unit][1]);
if (!is_affine_src) {
- OUT_BATCH_F(0.0);
- OUT_BATCH_F(src_w[2]);
+ OUT_VERTEX(0.0);
+ OUT_VERTEX(src_w[2]);
}
}
if (intel->render_mask && ! intel->render_mask_is_solid) {
- OUT_BATCH_F(mask_x[2] / intel->scale_units[mask_unit][0]);
- OUT_BATCH_F(mask_y[2] / intel->scale_units[mask_unit][1]);
+ OUT_VERTEX(mask_x[2] / intel->scale_units[mask_unit][0]);
+ OUT_VERTEX(mask_y[2] / intel->scale_units[mask_unit][1]);
if (!is_affine_mask) {
- OUT_BATCH_F(0.0);
- OUT_BATCH_F(mask_w[2]);
+ OUT_VERTEX(0.0);
+ OUT_VERTEX(mask_w[2]);
}
}
- OUT_BATCH_F(intel->dst_coord_adjust + dstX);
- OUT_BATCH_F(intel->dst_coord_adjust + dstY + h);
+ OUT_VERTEX(intel->dst_coord_adjust + dstX);
+ OUT_VERTEX(intel->dst_coord_adjust + dstY + h);
if (! intel->render_source_is_solid) {
- OUT_BATCH_F(src_x[1] / intel->scale_units[src_unit][0]);
- OUT_BATCH_F(src_y[1] / intel->scale_units[src_unit][1]);
+ OUT_VERTEX(src_x[1] / intel->scale_units[src_unit][0]);
+ OUT_VERTEX(src_y[1] / intel->scale_units[src_unit][1]);
if (!is_affine_src) {
- OUT_BATCH_F(0.0);
- OUT_BATCH_F(src_w[1]);
+ OUT_VERTEX(0.0);
+ OUT_VERTEX(src_w[1]);
}
}
if (intel->render_mask && ! intel->render_mask_is_solid) {
- OUT_BATCH_F(mask_x[1] / intel->scale_units[mask_unit][0]);
- OUT_BATCH_F(mask_y[1] / intel->scale_units[mask_unit][1]);
+ OUT_VERTEX(mask_x[1] / intel->scale_units[mask_unit][0]);
+ OUT_VERTEX(mask_y[1] / intel->scale_units[mask_unit][1]);
if (!is_affine_mask) {
- OUT_BATCH_F(0.0);
- OUT_BATCH_F(mask_w[1]);
+ OUT_VERTEX(0.0);
+ OUT_VERTEX(mask_w[1]);
}
}
- OUT_BATCH_F(intel->dst_coord_adjust + dstX);
- OUT_BATCH_F(intel->dst_coord_adjust + dstY);
+ OUT_VERTEX(intel->dst_coord_adjust + dstX);
+ OUT_VERTEX(intel->dst_coord_adjust + dstY);
if (! intel->render_source_is_solid) {
- OUT_BATCH_F(src_x[0] / intel->scale_units[src_unit][0]);
- OUT_BATCH_F(src_y[0] / intel->scale_units[src_unit][1]);
+ OUT_VERTEX(src_x[0] / intel->scale_units[src_unit][0]);
+ OUT_VERTEX(src_y[0] / intel->scale_units[src_unit][1]);
if (!is_affine_src) {
- OUT_BATCH_F(0.0);
- OUT_BATCH_F(src_w[0]);
+ OUT_VERTEX(0.0);
+ OUT_VERTEX(src_w[0]);
}
}
if (intel->render_mask && ! intel->render_mask_is_solid) {
- OUT_BATCH_F(mask_x[0] / intel->scale_units[mask_unit][0]);
- OUT_BATCH_F(mask_y[0] / intel->scale_units[mask_unit][1]);
+ OUT_VERTEX(mask_x[0] / intel->scale_units[mask_unit][0]);
+ OUT_VERTEX(mask_y[0] / intel->scale_units[mask_unit][1]);
if (!is_affine_mask) {
- OUT_BATCH_F(0.0);
- OUT_BATCH_F(mask_w[0]);
+ OUT_VERTEX(0.0);
+ OUT_VERTEX(mask_w[0]);
+ }
+ }
+}
+
+Bool
+i915_prepare_composite(int op, PicturePtr source_picture,
+ PicturePtr mask_picture, PicturePtr dest_picture,
+ PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
+{
+ ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ drm_intel_bo *bo_table[] = {
+ NULL, /* batch_bo */
+ i830_get_pixmap_bo(dest),
+ source ? i830_get_pixmap_bo(source) : NULL,
+ mask ? i830_get_pixmap_bo(mask) : NULL,
+ };
+ int tex_unit = 0;
+ int floats_per_vertex;
+
+ intel->render_source_picture = source_picture;
+ intel->render_source = source;
+ intel->render_mask_picture = mask_picture;
+ intel->render_mask = mask;
+ intel->render_dest_picture = dest_picture;
+ intel->render_dest = dest;
+
+ intel->render_source_is_solid = FALSE;
+ if (source_picture->pSourcePict) {
+ SourcePict *source = source_picture->pSourcePict;
+ if (source->type == SourcePictTypeSolidFill) {
+ intel->render_source_is_solid = TRUE;
+ intel->render_source_solid = source->solidFill.color;
}
}
+ if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
+ return FALSE;
+
+ intel->render_mask_is_solid = FALSE;
+ if (mask) {
+ if (mask_picture->pSourcePict) {
+ SourcePict *source = mask_picture->pSourcePict;
+ if (source->type == SourcePictTypeSolidFill) {
+ intel->render_mask_is_solid = TRUE;
+ intel->render_mask_solid = source->solidFill.color;
+ }
+ }
+ if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
+ return FALSE;
+ }
+
+ if (!intel_check_pitch_3d(dest))
+ return FALSE;
+
+ if (!i915_get_dest_format(dest_picture,
+ &intel->i915_render_state.dst_format))
+ return FALSE;
+
+ if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
+ return FALSE;
+ intel->dst_coord_adjust = 0;
+ intel->src_coord_adjust = 0;
+ intel->mask_coord_adjust = 0;
+
+ intel->transform[0] = NULL;
+ intel->scale_units[0][0] = -1;
+ intel->scale_units[0][1] = -1;
+ intel->transform[1] = NULL;
+ intel->scale_units[1][0] = -1;
+ intel->scale_units[1][1] = -1;
+
+ floats_per_vertex = 2; /* dest x/y */
+ if (! intel->render_source_is_solid) {
+ if (!i915_texture_setup(source_picture, source, tex_unit++)) {
+ intel_debug_fallback(scrn, "fail to setup src texture\n");
+ return FALSE;
+ }
+
+ if (i830_transform_is_affine(source_picture->transform))
+ floats_per_vertex += 2; /* src x/y */
+ else
+ floats_per_vertex += 4; /* src x/y/z/w */
+
+ if (source_picture->filter == PictFilterNearest) {
+#if PIXEL_CENTRE_SAMPLE
+ intel->src_coord_adjust = 0.375;
+#else
+ intel->dst_coord_adjust = -0.125;
+#endif
+ }
+ }
+
+ if (mask != NULL) {
+ if (! intel->render_mask_is_solid) {
+ if (!i915_texture_setup(mask_picture, mask, tex_unit++)) {
+ intel_debug_fallback(scrn,
+ "fail to setup mask texture\n");
+ return FALSE;
+ }
+
+ if (i830_transform_is_affine(mask_picture->transform))
+ floats_per_vertex += 2; /* mask x/y */
+ else
+ floats_per_vertex += 4; /* mask x/y/z/w */
+
+ if (mask_picture->filter == PictFilterNearest) {
+#if PIXEL_CENTRE_SAMPLE
+ intel->mask_coord_adjust = 0.375;
+#else
+ intel->dst_coord_adjust = -0.125;
+#endif
+ }
+ }
+ }
+
+ intel->i915_render_state.op = op;
+
+ 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;
+
+ if (!mask) {
+ if (intel->render_source_is_solid)
+ intel->prim_emit = i915_emit_composite_primitive_constant;
+ else if (intel->transform[0] == NULL)
+ intel->prim_emit = i915_emit_composite_primitive_identity_source;
+ else if (i830_transform_is_affine(intel->transform[0]))
+ intel->prim_emit = i915_emit_composite_primitive_affine_source;
+ else
+ intel->prim_emit = i915_emit_composite_primitive;
+ } else
+ intel->prim_emit = i915_emit_composite_primitive;
+
+ if (floats_per_vertex != intel->floats_per_vertex) {
+ intel->floats_per_vertex = floats_per_vertex;
+ intel->needs_render_vertex_emit = TRUE;
+ }
+
+ return TRUE;
}
static void i915_emit_composite_setup(ScrnInfoPtr scrn)
@@ -1016,20 +1025,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
FS_END();
}
-
- intel->prim_offset = 0;
- intel->prim_count = 0;
- if (!mask) {
- if (is_solid_src)
- intel->prim_emit = i915_emit_composite_primitive_constant;
- else if (intel->transform[0] == NULL)
- intel->prim_emit = i915_emit_composite_primitive_identity_source;
- else if (i830_transform_is_affine(intel->transform[0]))
- intel->prim_emit = i915_emit_composite_primitive_affine_source;
- else
- intel->prim_emit = i915_emit_composite_primitive;
- } else
- intel->prim_emit = i915_emit_composite_primitive;
}
void
@@ -1045,10 +1040,41 @@ i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
if (intel->needs_render_state_emit)
i915_emit_composite_setup(scrn);
+ if (intel_vertex_space(intel) < 3*4*intel->floats_per_vertex)
+ intel->needs_render_vertex_emit = TRUE;
+
+ if (intel->needs_render_vertex_emit) {
+ i915_vertex_flush(intel);
+
+ if (intel_vertex_space(intel) < 256) {
+ 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((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) |
+ (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT));
+ intel->vertex_index = 0;
+ } else {
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+ I1_LOAD_S(1) | 0);
+ OUT_BATCH((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) |
+ (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT));
+
+ intel->vertex_index =
+ (intel->vertex_used + intel->floats_per_vertex - 1) / intel->floats_per_vertex;
+ intel->vertex_used = intel->vertex_index * intel->floats_per_vertex;
+ }
+
+ intel->needs_render_vertex_emit = FALSE;
+ }
+
if (intel->prim_offset == 0) {
intel->prim_offset = intel->batch_used;
- OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST);
+ OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL);
+ OUT_BATCH(intel->vertex_index);
}
+ intel->vertex_count += 3;
intel->prim_emit(dest,
srcX, srcY,
@@ -1062,10 +1088,14 @@ i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
void
i915_vertex_flush(intel_screen_private *intel)
{
- if (intel->prim_offset) {
- intel->batch_ptr[intel->prim_offset] |= intel->prim_count - 1;
- intel->prim_offset = 0;
- }
+ if (intel->prim_offset == 0)
+ return;
+
+ intel->batch_ptr[intel->prim_offset] |= intel->vertex_count;
+ intel->prim_offset = 0;
+
+ intel->vertex_index += intel->vertex_count;
+ intel->vertex_count = 0;
}
void
diff --git a/src/i915_video.c b/src/i915_video.c
index 2ccd502c..bbac610b 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -397,7 +397,7 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
dxo = dstRegion->extents.x1;
dyo = dstRegion->extents.y1;
- OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (12 * nbox_this_time - 1));
+ OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1));
while (nbox_this_time--) {
int box_x1 = pbox->x1;
int box_y1 = pbox->y1;