diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-19 14:50:12 +0100 |
---|---|---|
committer | Owain G. Ainsworth <oga@openbsd.org> | 2010-05-25 16:31:56 +0100 |
commit | 74fd6a2cb86d484a5af68b9567f910c9f405e3ad (patch) | |
tree | e7607c51fe5fad0dee70dcf3970aacb9bdca11b0 | |
parent | 0727b50b8de9d66474e276e307542760653a320d (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.h | 8 | ||||
-rw-r--r-- | src/i830_batchbuffer.c | 21 | ||||
-rw-r--r-- | src/i830_batchbuffer.h | 12 | ||||
-rw-r--r-- | src/i830_uxa.c | 5 | ||||
-rw-r--r-- | src/i915_reg.h | 27 | ||||
-rw-r--r-- | src/i915_render.c | 448 | ||||
-rw-r--r-- | src/i915_video.c | 2 |
7 files changed, 298 insertions, 225 deletions
@@ -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; |