diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-18 23:54:13 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-24 09:32:30 +0100 |
commit | bc41f84e01f18548b05c670e1fd0d641adc28d0f (patch) | |
tree | 865f756045b44fadc6ee78edbc01f4d70a53ee3b | |
parent | 4a3476ea094e84887fefb558e0bba023fee34151 (diff) |
i915: Emit composite primitive with specialised functions.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/i830.h | 5 | ||||
-rw-r--r-- | src/i915_render.c | 559 |
2 files changed, 358 insertions, 206 deletions
@@ -360,6 +360,11 @@ typedef struct intel_screen_private { 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); /* 965 render acceleration state */ struct gen4_render_state *gen4_render_state; diff --git a/src/i915_render.c b/src/i915_render.c index 7c204b62..ed7bec5b 100644 --- a/src/i915_render.c +++ b/src/i915_render.c @@ -478,6 +478,343 @@ i915_prepare_composite(int op, PicturePtr source_picture, return TRUE; } +static void +i915_emit_composite_primitive_constant(PixmapPtr dest, + int srcX, int srcY, + int maskX, int maskY, + int dstX, int dstY, + int w, int h) +{ + ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + float x, y; + + ATOMIC_BATCH((intel->prim_offset == 0) + 6); + + 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_BATCH_F(x); + OUT_BATCH_F(y + h); + + OUT_BATCH_F(x); + OUT_BATCH_F(y); + + ADVANCE_BATCH(); +} + +static void +i915_emit_composite_primitive_identity_source(PixmapPtr dest, + int srcX, int srcY, + int maskX, int maskY, + int dstX, int dstY, + int w, int h) +{ + ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + float dst_x, dst_y, src_x, src_y; + + ATOMIC_BATCH((intel->prim_offset == 0) + 12); + + 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_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_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]); + + ADVANCE_BATCH(); +} + +static void +i915_emit_composite_primitive_affine_source(PixmapPtr dest, + int srcX, int srcY, + int maskX, int maskY, + int dstX, int dstY, + int w, int h) +{ + ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + float x, y, src_x[3], src_y[3]; + + x = srcX + intel->src_coord_adjust; + y = srcY + intel->src_coord_adjust; + + if (!i830_get_transformed_coordinates(x, y, + intel->transform[0], + &src_x[0], + &src_y[0])) + return; + + if (!i830_get_transformed_coordinates(x, y + h, + intel->transform[0], + &src_x[1], + &src_y[1])) + return; + + if (!i830_get_transformed_coordinates(x + w, y + h, + intel->transform[0], + &src_x[2], + &src_y[2])) + return; + + ATOMIC_BATCH((intel->prim_offset == 0) + 12); + + 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_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_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]); + + ADVANCE_BATCH(); +} + +static void +i915_emit_composite_primitive(PixmapPtr dest, + int srcX, int srcY, + int maskX, int maskY, + int dstX, int dstY, int w, int h) +{ + ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + Bool is_affine_src, is_affine_mask = TRUE; + int per_vertex, num_floats; + int tex_unit = 0; + int src_unit = -1, mask_unit = -1; + float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; + + per_vertex = 2; /* dest x/y */ + + if (! intel->render_source_is_solid) { + float x = srcX + intel->src_coord_adjust; + float y = srcY + intel->src_coord_adjust; + + src_unit = tex_unit++; + + is_affine_src = i830_transform_is_affine(intel->transform[src_unit]); + if (is_affine_src) { + if (!i830_get_transformed_coordinates(x, y, + intel-> + transform[src_unit], + &src_x[0], + &src_y[0])) + return; + + if (!i830_get_transformed_coordinates(x, y + h, + intel-> + transform[src_unit], + &src_x[1], + &src_y[1])) + return; + + if (!i830_get_transformed_coordinates(x + w, y + h, + intel-> + transform[src_unit], + &src_x[2], + &src_y[2])) + return; + + per_vertex += 2; /* src x/y */ + } else { + if (!i830_get_transformed_coordinates_3d(x, y, + intel-> + transform[src_unit], + &src_x[0], + &src_y[0], + &src_w[0])) + return; + + if (!i830_get_transformed_coordinates_3d(x, y + h, + intel-> + transform[src_unit], + &src_x[1], + &src_y[1], + &src_w[1])) + return; + + if (!i830_get_transformed_coordinates_3d(x + w, y + h, + intel-> + transform[src_unit], + &src_x[2], + &src_y[2], + &src_w[2])) + return; + + per_vertex += 4; /* src x/y/z/w */ + } + } + + if (intel->render_mask && ! intel->render_mask_is_solid) { + float x = maskX + intel->mask_coord_adjust; + float y = maskY + intel->mask_coord_adjust; + + mask_unit = tex_unit++; + + is_affine_mask = i830_transform_is_affine(intel->transform[mask_unit]); + if (is_affine_mask) { + if (!i830_get_transformed_coordinates(x, y, + intel-> + transform[mask_unit], + &mask_x[0], + &mask_y[0])) + return; + + if (!i830_get_transformed_coordinates(x, y + h, + intel-> + transform[mask_unit], + &mask_x[1], + &mask_y[1])) + return; + + if (!i830_get_transformed_coordinates(x + w, y + h, + intel-> + transform[mask_unit], + &mask_x[2], + &mask_y[2])) + return; + + per_vertex += 2; /* mask x/y */ + } else { + if (!i830_get_transformed_coordinates_3d(x, y, + intel-> + transform[mask_unit], + &mask_x[0], + &mask_y[0], + &mask_w[0])) + return; + + if (!i830_get_transformed_coordinates_3d(x, y + h, + intel-> + transform[mask_unit], + &mask_x[1], + &mask_y[1], + &mask_w[1])) + return; + + if (!i830_get_transformed_coordinates_3d(x + w, y + h, + intel-> + transform[mask_unit], + &mask_x[2], + &mask_y[2], + &mask_w[2])) + return; + + per_vertex += 4; /* mask x/y/z/w */ + } + } + + num_floats = 3 * per_vertex; + + ATOMIC_BATCH(num_floats); + + intel->prim_count += num_floats; + + OUT_BATCH_F(intel->dst_coord_adjust + dstX + w); + OUT_BATCH_F(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]); + if (!is_affine_src) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(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]); + if (!is_affine_mask) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(mask_w[2]); + } + } + + OUT_BATCH_F(intel->dst_coord_adjust + dstX); + OUT_BATCH_F(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]); + if (!is_affine_src) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(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]); + if (!is_affine_mask) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(mask_w[1]); + } + } + + OUT_BATCH_F(intel->dst_coord_adjust + dstX); + OUT_BATCH_F(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]); + if (!is_affine_src) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(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]); + if (!is_affine_mask) { + OUT_BATCH_F(0.0); + OUT_BATCH_F(mask_w[0]); + } + } + + ADVANCE_BATCH(); +} + static void i915_emit_composite_setup(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); @@ -711,210 +1048,17 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn) intel->prim_offset = 0; intel->prim_count = 0; -} - -/* Emit the vertices for a single composite rectangle. - * - * This function is no longer shared between i830 and i915 generation code. - */ -static void -i915_emit_composite_primitive(PixmapPtr dest, - int srcX, int srcY, - int maskX, int maskY, - int dstX, int dstY, int w, int h) -{ - ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; - intel_screen_private *intel = intel_get_screen_private(scrn); - Bool is_affine_src, is_affine_mask = TRUE; - int per_vertex, num_floats; - int tex_unit = 0; - int src_unit = -1, mask_unit = -1; - float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; - - per_vertex = 2; /* dest x/y */ - - if (! intel->render_source_is_solid) { - float x = srcX + intel->src_coord_adjust; - float y = srcY + intel->src_coord_adjust; - - src_unit = tex_unit++; - - is_affine_src = i830_transform_is_affine(intel->transform[src_unit]); - if (is_affine_src) { - if (!i830_get_transformed_coordinates(x, y, - intel-> - transform[src_unit], - &src_x[0], - &src_y[0])) - return; - - if (!i830_get_transformed_coordinates(x, y + h, - intel-> - transform[src_unit], - &src_x[1], - &src_y[1])) - return; - - if (!i830_get_transformed_coordinates(x + w, y + h, - intel-> - transform[src_unit], - &src_x[2], - &src_y[2])) - return; - - per_vertex += 2; /* src x/y */ - } else { - if (!i830_get_transformed_coordinates_3d(x, y, - intel-> - transform[src_unit], - &src_x[0], - &src_y[0], - &src_w[0])) - return; - - if (!i830_get_transformed_coordinates_3d(x, y + h, - intel-> - transform[src_unit], - &src_x[1], - &src_y[1], - &src_w[1])) - return; - - if (!i830_get_transformed_coordinates_3d(x + w, y + h, - intel-> - transform[src_unit], - &src_x[2], - &src_y[2], - &src_w[2])) - return; - - per_vertex += 4; /* src x/y/z/w */ - } - } - - if (intel->render_mask && ! intel->render_mask_is_solid) { - float x = maskX + intel->mask_coord_adjust; - float y = maskY + intel->mask_coord_adjust; - - mask_unit = tex_unit++; - - is_affine_mask = i830_transform_is_affine(intel->transform[mask_unit]); - if (is_affine_mask) { - if (!i830_get_transformed_coordinates(x, y, - intel-> - transform[mask_unit], - &mask_x[0], - &mask_y[0])) - return; - - if (!i830_get_transformed_coordinates(x, y + h, - intel-> - transform[mask_unit], - &mask_x[1], - &mask_y[1])) - return; - - if (!i830_get_transformed_coordinates(x + w, y + h, - intel-> - transform[mask_unit], - &mask_x[2], - &mask_y[2])) - return; - - per_vertex += 2; /* mask x/y */ - } else { - if (!i830_get_transformed_coordinates_3d(x, y, - intel-> - transform[mask_unit], - &mask_x[0], - &mask_y[0], - &mask_w[0])) - return; - - if (!i830_get_transformed_coordinates_3d(x, y + h, - intel-> - transform[mask_unit], - &mask_x[1], - &mask_y[1], - &mask_w[1])) - return; - - if (!i830_get_transformed_coordinates_3d(x + w, y + h, - intel-> - transform[mask_unit], - &mask_x[2], - &mask_y[2], - &mask_w[2])) - return; - - per_vertex += 4; /* mask x/y/z/w */ - } - } - - num_floats = 3 * per_vertex; - - ATOMIC_BATCH(num_floats); - - intel->prim_count += num_floats; - - OUT_BATCH_F(intel->dst_coord_adjust + dstX + w); - OUT_BATCH_F(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]); - if (!is_affine_src) { - OUT_BATCH_F(0.0); - OUT_BATCH_F(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]); - if (!is_affine_mask) { - OUT_BATCH_F(0.0); - OUT_BATCH_F(mask_w[2]); - } - } - - OUT_BATCH_F(intel->dst_coord_adjust + dstX); - OUT_BATCH_F(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]); - if (!is_affine_src) { - OUT_BATCH_F(0.0); - OUT_BATCH_F(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]); - if (!is_affine_mask) { - OUT_BATCH_F(0.0); - OUT_BATCH_F(mask_w[1]); - } - } - - OUT_BATCH_F(intel->dst_coord_adjust + dstX); - OUT_BATCH_F(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]); - if (!is_affine_src) { - OUT_BATCH_F(0.0); - OUT_BATCH_F(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]); - if (!is_affine_mask) { - OUT_BATCH_F(0.0); - OUT_BATCH_F(mask_w[0]); - } - } - - ADVANCE_BATCH(); + 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 @@ -937,8 +1081,11 @@ i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, ADVANCE_BATCH(); } - i915_emit_composite_primitive(dest, srcX, srcY, maskX, maskY, dstX, - dstY, w, h); + intel->prim_emit(dest, + srcX, srcY, + maskX, maskY, + dstX, dstY, + w, h); intel_batch_end_atomic(scrn); } |