diff options
author | Alexei Shlychkov <x0177296@ti.com> | 2012-10-09 11:56:44 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit2@git.omapzoom.org> | 2012-10-22 05:36:22 -0500 |
commit | 96f44ed1b3cb23011920a3ff022a82e461d76258 (patch) | |
tree | 6bbacd726be72e907442fc3850b3c2c5fda0c3ec /drivers/misc | |
parent | 1c9f7059175fc0646d7e242467ca57ecf80c0458 (diff) | |
download | kernel_samsung_espresso10-96f44ed1b3cb23011920a3ff022a82e461d76258.zip kernel_samsung_espresso10-96f44ed1b3cb23011920a3ff022a82e461d76258.tar.gz kernel_samsung_espresso10-96f44ed1b3cb23011920a3ff022a82e461d76258.tar.bz2 |
gcx: source setup optimization.
Share the same setup routines for blitting and
scaling. Use old-style registers for source 0
in blit setup due to a hardware problem.
Change-Id: Ic9ed5c95d37833521f2eda21d818f8a8696bcd4c
Signed-off-by: Alexei Shlychkov <x0177296@ti.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/gcx/gcbv/gcblit.c | 462 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcbv.c | 451 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcbv.h | 23 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcfilter.c | 173 |
4 files changed, 665 insertions, 444 deletions
diff --git a/drivers/misc/gcx/gcbv/gcblit.c b/drivers/misc/gcx/gcbv/gcblit.c index 17aa297..04fa86a 100644 --- a/drivers/misc/gcx/gcbv/gcblit.c +++ b/drivers/misc/gcx/gcbv/gcblit.c @@ -123,12 +123,6 @@ static enum bverror do_blit_end(struct bvbltparams *bvbltparams, ? GCREG_DEST_CONFIG_COMMAND_MULTI_SOURCE_BLT : GCREG_DEST_CONFIG_COMMAND_BIT_BLT; - /* Set ROP. */ - gcmobltconfig->rop_ldst = gcmobltconfig_rop_ldst; - gcmobltconfig->rop.raw = 0; - gcmobltconfig->rop.reg.type = GCREG_ROP_TYPE_ROP3; - gcmobltconfig->rop.reg.fg = (unsigned char) gcblit->rop; - /*********************************************************************** * Start the operation. */ @@ -173,8 +167,8 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, enum bverror bverror = BVERR_NONE; struct gccontext *gccontext = get_context(); + struct gcmosrc0 *gcmosrc0; struct gcmosrc *gcmosrc; - struct gcmoxsrcalpha *gcmoxsrcalpha; struct gcblit *gcblit; unsigned int index; @@ -187,8 +181,6 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, int dstoffsetX, dstoffsetY; int srcshiftX, srcshiftY; - int srcpixalign, srcbyteshift; - struct gcrect srcclipped; int srcsurfwidth, srcsurfheight; unsigned int physwidth, physheight; @@ -275,35 +267,36 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, } /* Compute the source surface offset in bytes. */ - srcbyteshift = srcshiftY * (int) srcinfo->geom->virtstride - + srcshiftX * (int) srcinfo->format.bitspp / 8; + srcinfo->bytealign = srcshiftY * (int) srcinfo->geom->virtstride + + srcshiftX * (int) srcinfo->format.bitspp / 8; /* Compute the source offset in pixels needed to compensate * for the surface base address misalignment if any. */ - srcpixalign = get_pixel_offset(srcinfo, srcbyteshift); + srcinfo->pixalign = get_pixel_offset(srcinfo, srcinfo->bytealign); GCDBG(GCZONE_SURF, "source surface %d:\n", srcinfo->index + 1); GCDBG(GCZONE_SURF, " surface offset (pixels) = %d,%d\n", srcshiftX, srcshiftY); GCDBG(GCZONE_SURF, " surface offset (bytes) = 0x%08X\n", - srcbyteshift); + srcinfo->bytealign); GCDBG(GCZONE_SURF, " srcpixalign = %d\n", - srcpixalign); + srcinfo->pixalign); /* Apply the source alignment. */ - srcbyteshift += srcpixalign * (int) srcinfo->format.bitspp / 8; - srcshiftX += srcpixalign; + srcinfo->bytealign += srcinfo->pixalign + * (int) srcinfo->format.bitspp / 8; + srcshiftX += srcinfo->pixalign; GCDBG(GCZONE_SURF, " adjusted surface offset (pixels) = %d,%d\n", srcshiftX, srcshiftY); GCDBG(GCZONE_SURF, " adjusted surface offset (bytes) = 0x%08X\n", - srcbyteshift); + srcinfo->bytealign); /* Determine the destination surface shift. Vertical shift only applies * if the destination angle is ahead by 270 degrees. */ dstshiftX = dstinfo->pixalign; dstshiftY = (((srcinfo->angle + 3) % 4) == dstinfo->angle) - ? srcpixalign : 0; + ? srcinfo->pixalign : 0; /* Compute the destination surface offset in bytes. */ dstbyteshift = dstshiftY * (int) dstinfo->geom->virtstride @@ -322,50 +315,55 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, dstpixalign); if ((dstpixalign != 0) || - ((srcpixalign != 0) && (srcinfo->angle == dstinfo->angle))) { + ((srcinfo->pixalign != 0) && (srcinfo->angle == dstinfo->angle))) { /* Compute the source offset in pixels needed to compensate * for the surface base address misalignment if any. */ - srcpixalign = get_pixel_offset(srcinfo, 0); + srcinfo->pixalign = get_pixel_offset(srcinfo, 0); /* Compute the surface offsets in bytes. */ - srcbyteshift = srcpixalign * (int) srcinfo->format.bitspp / 8; + srcinfo->bytealign = srcinfo->pixalign + * (int) srcinfo->format.bitspp / 8; GCDBG(GCZONE_SURF, "recomputed for single-source setup:\n"); GCDBG(GCZONE_SURF, " srcpixalign = %d\n", - srcpixalign); + srcinfo->pixalign); GCDBG(GCZONE_SURF, " srcsurf offset (bytes) = 0x%08X\n", - srcbyteshift); + srcinfo->bytealign); GCDBG(GCZONE_SURF, " dstsurf offset (bytes) = 0x%08X\n", dstinfo->bytealign); switch (srcinfo->angle) { case ROT_ANGLE_0: /* Adjust left coordinate. */ - srcclipped.left -= srcpixalign; + srcclipped.left -= srcinfo->pixalign; /* Determine source size. */ - srcsurfwidth = srcinfo->geom->width - srcpixalign; + srcsurfwidth = srcinfo->geom->width + - srcinfo->pixalign; srcsurfheight = srcinfo->geom->height; break; case ROT_ANGLE_90: /* Adjust top coordinate. */ - srcclipped.top -= srcpixalign; + srcclipped.top -= srcinfo->pixalign; /* Determine source size. */ - srcsurfwidth = srcinfo->geom->height - srcpixalign; + srcsurfwidth = srcinfo->geom->height + - srcinfo->pixalign; srcsurfheight = srcinfo->geom->width; break; case ROT_ANGLE_180: /* Determine source size. */ - srcsurfwidth = srcinfo->geom->width - srcpixalign; + srcsurfwidth = srcinfo->geom->width + - srcinfo->pixalign; srcsurfheight = srcinfo->geom->height; break; case ROT_ANGLE_270: /* Determine source size. */ - srcsurfwidth = srcinfo->geom->height - srcpixalign; + srcsurfwidth = srcinfo->geom->height + - srcinfo->pixalign; srcsurfheight = srcinfo->geom->width; break; @@ -387,9 +385,8 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, physwidth = dstinfo->physwidth; physheight = dstinfo->physheight; - /* Disable multi source for YUV and for the cases where - * the destination and the base address alignment does - * not match. */ + /* Disable multi source for the cases where the destination + * and the base address alignment does not match. */ multisrc = 0; GCDBG(GCZONE_SURF, "multi-source disabled.\n"); } else { @@ -401,36 +398,36 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, switch (srcinfo->angle) { case ROT_ANGLE_0: /* Adjust the destination horizontally. */ - dstoffsetX = srcpixalign; + dstoffsetX = srcinfo->pixalign; dstoffsetY = 0; /* Apply the source alignment. */ if ((dstinfo->angle == ROT_ANGLE_0) || (dstinfo->angle == ROT_ANGLE_180)) { physwidth = dstinfo->physwidth - - srcpixalign; + - srcinfo->pixalign; physheight = dstinfo->physheight; } else { physwidth = dstinfo->physwidth; physheight = dstinfo->physheight - - srcpixalign; + - srcinfo->pixalign; } break; case ROT_ANGLE_90: /* Adjust the destination vertically. */ dstoffsetX = 0; - dstoffsetY = srcpixalign; + dstoffsetY = srcinfo->pixalign; /* Apply the source alignment. */ if ((dstinfo->angle == ROT_ANGLE_0) || (dstinfo->angle == ROT_ANGLE_180)) { physwidth = dstinfo->physwidth; physheight = dstinfo->physheight - - srcpixalign; + - srcinfo->pixalign; } else { physwidth = dstinfo->physwidth - - srcpixalign; + - srcinfo->pixalign; physheight = dstinfo->physheight; } break; @@ -444,12 +441,12 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, if ((dstinfo->angle == ROT_ANGLE_0) || (dstinfo->angle == ROT_ANGLE_180)) { physwidth = dstinfo->physwidth - - srcpixalign; + - srcinfo->pixalign; physheight = dstinfo->physheight; } else { physwidth = dstinfo->physwidth; physheight = dstinfo->physheight - - srcpixalign; + - srcinfo->pixalign; } break; @@ -463,10 +460,10 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, (dstinfo->angle == ROT_ANGLE_180)) { physwidth = dstinfo->physwidth; physheight = dstinfo->physheight - - srcpixalign; + - srcinfo->pixalign; } else { physwidth = dstinfo->physwidth - - srcpixalign; + - srcinfo->pixalign; physheight = dstinfo->physheight; } break; @@ -532,7 +529,6 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, gcblit->blockenable = 0; gcblit->srccount = 0; gcblit->multisrc = multisrc; - gcblit->rop = srcinfo->rop; /* Set the destination format. */ gcblit->format = dstinfo->format.format; @@ -569,7 +565,7 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, goto exit; } - /*************************************************************** + /*********************************************************************** ** Configure source. */ @@ -577,255 +573,171 @@ enum bverror do_blit(struct bvbltparams *bvbltparams, * surfaces are orthogonal to each other. */ batch->op.blit.blockenable |= orthogonal; - /* Allocate command buffer. */ - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmosrc), - (void **) &gcmosrc); - if (bverror != BVERR_NONE) - goto exit; - /* Shortcut to the register index. */ index = batch->op.blit.srccount; /* Set surface parameters. */ - gcmosrc->address_ldst = gcmosrc_address_ldst[index]; - gcmosrc->address = GET_MAP_HANDLE(srcmap); - add_fixup(bvbltparams, batch, &gcmosrc->address, srcbyteshift); - - gcmosrc->stride_ldst = gcmosrc_stride_ldst[index]; - gcmosrc->stride = srcinfo->geom->virtstride; - - gcmosrc->rotation_ldst = gcmosrc_rotation_ldst[index]; - gcmosrc->rotation.raw = 0; - gcmosrc->rotation.reg.surf_width = srcsurfwidth; - - gcmosrc->config_ldst = gcmosrc_config_ldst[index]; - gcmosrc->config.raw = 0; - gcmosrc->config.reg.swizzle = srcinfo->format.swizzle; - gcmosrc->config.reg.format = srcinfo->format.format; - - gcmosrc->origin_ldst = gcmosrc_origin_ldst[index]; - gcmosrc->origin.reg.x = srcclipped.left; - gcmosrc->origin.reg.y = srcclipped.top; - - gcmosrc->size_ldst = gcmosrc_size_ldst[index]; - gcmosrc->size.reg = gcregsrcsize_max; - - gcmosrc->rotationheight_ldst - = gcmosrc_rotationheight_ldst[index]; - gcmosrc->rotationheight.reg.height = srcsurfheight; - - gcmosrc->rotationangle_ldst - = gcmosrc_rotationangle_ldst[index]; - gcmosrc->rotationangle.raw = 0; - gcmosrc->rotationangle.reg.src = rotencoding[srcinfo->angle]; - gcmosrc->rotationangle.reg.dst = rotencoding[dstinfo->angle]; - gcmosrc->rotationangle.reg.src_mirror = srcinfo->mirror; - gcmosrc->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE; - - gcmosrc->rop_ldst = gcmosrc_rop_ldst[index]; - gcmosrc->rop.raw = 0; - gcmosrc->rop.reg.type = GCREG_ROP_TYPE_ROP3; - gcmosrc->rop.reg.fg = (unsigned char) batch->op.blit.rop; - - gcmosrc->mult_ldst = gcmosrc_mult_ldst[index]; - gcmosrc->mult.raw = 0; - gcmosrc->mult.reg.srcglobalpremul - = GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE; - - if (srcinfo->format.premultiplied) - gcmosrc->mult.reg.srcpremul - = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE; - else - gcmosrc->mult.reg.srcpremul - = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE; - - if (dstinfo->format.premultiplied) { - gcmosrc->mult.reg.dstpremul - = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE; - - gcmosrc->mult.reg.dstdemul - = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE; - } else { - gcmosrc->mult.reg.dstpremul - = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE; - - gcmosrc->mult.reg.dstdemul - = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE; - } - - if (srcinfo->gca == NULL) { - GCDBG(GCZONE_BLEND, "blending disabled.\n"); - gcmosrc->alphacontrol_ldst - = gcmosrc_alphacontrol_ldst[index]; - gcmosrc->alphacontrol.reg = gcregalpha_off; - } else { - gcmosrc->alphacontrol_ldst - = gcmosrc_alphacontrol_ldst[index]; - gcmosrc->alphacontrol.reg = gcregalpha_on; - + if (index == 0) { /* Allocate command buffer. */ bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcalpha), - (void **) &gcmoxsrcalpha); + sizeof(struct gcmosrc0), + (void **) &gcmosrc0); if (bverror != BVERR_NONE) goto exit; - gcmoxsrcalpha->alphamodes_ldst - = gcmoxsrcalpha_alphamodes_ldst[index]; - gcmoxsrcalpha->alphamodes.raw = 0; - gcmoxsrcalpha->alphamodes.reg.src_global_alpha_mode - = srcinfo->gca->src_global_alpha_mode; - gcmoxsrcalpha->alphamodes.reg.dst_global_alpha_mode - = srcinfo->gca->dst_global_alpha_mode; - - gcmoxsrcalpha->alphamodes.reg.src_blend - = srcinfo->gca->srcconfig->factor_mode; - gcmoxsrcalpha->alphamodes.reg.src_color_reverse - = srcinfo->gca->srcconfig->color_reverse; - - gcmoxsrcalpha->alphamodes.reg.dst_blend - = srcinfo->gca->dstconfig->factor_mode; - gcmoxsrcalpha->alphamodes.reg.dst_color_reverse - = srcinfo->gca->dstconfig->color_reverse; - - GCDBG(GCZONE_BLEND, "dst blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoxsrcalpha->alphamodes.reg.dst_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoxsrcalpha->alphamodes.reg.dst_color_reverse); - - GCDBG(GCZONE_BLEND, "src blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoxsrcalpha->alphamodes.reg.src_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoxsrcalpha->alphamodes.reg.src_color_reverse); - - gcmoxsrcalpha->srcglobal_ldst - = gcmoxsrcalpha_srcglobal_ldst[index]; - gcmoxsrcalpha->srcglobal.raw = srcinfo->gca->src_global_color; - - gcmoxsrcalpha->dstglobal_ldst - = gcmoxsrcalpha_dstglobal_ldst[index]; - gcmoxsrcalpha->dstglobal.raw = srcinfo->gca->dst_global_color; - } + add_fixup(bvbltparams, batch, &gcmosrc0->address, + srcinfo->bytealign); + + gcmosrc0->config_ldst = gcmosrc0_config_ldst; + gcmosrc0->address = GET_MAP_HANDLE(srcmap); + gcmosrc0->stride = srcinfo->geom->virtstride; + gcmosrc0->rotation.raw = 0; + gcmosrc0->rotation.reg.surf_width = srcsurfwidth; + gcmosrc0->config.raw = 0; + gcmosrc0->config.reg.swizzle = srcinfo->format.swizzle; + gcmosrc0->config.reg.format = srcinfo->format.format; + gcmosrc0->origin.reg.x = srcclipped.left; + gcmosrc0->origin.reg.y = srcclipped.top; + gcmosrc0->size.reg = gcregsrcsize_max; + + gcmosrc0->rotation_ldst = gcmosrc0_rotation_ldst; + gcmosrc0->rotationheight.reg.height = srcsurfheight; + gcmosrc0->rotationangle.raw = 0; + gcmosrc0->rotationangle.reg.src = rotencoding[srcinfo->angle]; + gcmosrc0->rotationangle.reg.dst = rotencoding[dstinfo->angle]; + gcmosrc0->rotationangle.reg.src_mirror = srcinfo->mirror; + gcmosrc0->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE; + + gcmosrc0->rop_ldst = gcmosrc0_rop_ldst; + gcmosrc0->rop.raw = 0; + gcmosrc0->rop.reg.type = GCREG_ROP_TYPE_ROP3; + gcmosrc0->rop.reg.fg = (unsigned char) srcinfo->rop; + + gcmosrc0->mult_ldst = gcmosrc0_mult_ldst; + gcmosrc0->mult.raw = 0; + gcmosrc0->mult.reg.srcglobalpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE; + + if (srcinfo->format.premultiplied) + gcmosrc0->mult.reg.srcpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE; + else + gcmosrc0->mult.reg.srcpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE; + + if (dstinfo->format.premultiplied) { + gcmosrc0->mult.reg.dstpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE; + + gcmosrc0->mult.reg.dstdemul + = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE; + } else { + gcmosrc0->mult.reg.dstpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE; - /* Program YUV source. */ - if (srcinfo->format.type == BVFMT_YUV) { - struct gcmoxsrcyuv1 *gcmoxsrcyuv1; - struct gcmoxsrcyuv2 *gcmoxsrcyuv2; - struct gcmoxsrcyuv3 *gcmoxsrcyuv3; - int ushift, vshift; - unsigned int srcheight; - - switch (srcinfo->format.cs.yuv.planecount) { - case 1: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcyuv1), - (void **) &gcmoxsrcyuv1); - if (bverror != BVERR_NONE) - goto exit; + gcmosrc0->mult.reg.dstdemul + = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE; + } - gcmoxsrcyuv1->pectrl_ldst - = gcmoxsrcyuv_pectrl_ldst[index]; - gcmoxsrcyuv1->pectrl.raw = 0; - gcmoxsrcyuv1->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoxsrcyuv1->pectrl.reg.swizzle - = srcinfo->format.swizzle; - break; + /* Program blending. */ + bverror = set_blending(bvbltparams, batch, srcinfo); + if (bverror != BVERR_NONE) + goto exit; - case 2: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcyuv2), - (void **) &gcmoxsrcyuv2); + /* Program YUV source. */ + if (srcinfo->format.type == BVFMT_YUV) { + bverror = set_yuvsrc(bvbltparams, batch, + srcinfo, srcmap); if (bverror != BVERR_NONE) goto exit; + } + } else { + /* Allocate command buffer. */ + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmosrc), + (void **) &gcmosrc); + if (bverror != BVERR_NONE) + goto exit; - gcmoxsrcyuv2->pectrl_ldst - = gcmoxsrcyuv_pectrl_ldst[index]; - gcmoxsrcyuv2->pectrl.raw = 0; - gcmoxsrcyuv2->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoxsrcyuv2->pectrl.reg.swizzle - = srcinfo->format.swizzle; - - srcheight = ((srcinfo->angle % 2) == 0) - ? srcinfo->geom->height - : srcinfo->geom->width; - - ushift = srcbyteshift - + srcinfo->geom->virtstride - * srcheight; - GCDBG(GCZONE_SURF, "ushift = 0x%08X (%d)\n", - ushift, ushift); - - add_fixup(bvbltparams, batch, - &gcmoxsrcyuv2->uplaneaddress, ushift); - - gcmoxsrcyuv2->uplaneaddress_ldst - = gcmoxsrcyuv_uplaneaddress_ldst[index]; - gcmoxsrcyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap); - - gcmoxsrcyuv2->uplanestride_ldst - = gcmoxsrcyuv_uplanestride_ldst[index]; - gcmoxsrcyuv2->uplanestride = srcinfo->geom->virtstride; - break; + add_fixup(bvbltparams, batch, &gcmosrc->address, + srcinfo->bytealign); + + gcmosrc->address_ldst = gcmosrc_address_ldst[index]; + gcmosrc->address = GET_MAP_HANDLE(srcmap); + gcmosrc->stride_ldst = gcmosrc_stride_ldst[index]; + gcmosrc->stride = srcinfo->geom->virtstride; + + gcmosrc->rotation_ldst = gcmosrc_rotation_ldst[index]; + gcmosrc->rotation.raw = 0; + gcmosrc->rotation.reg.surf_width = srcsurfwidth; + + gcmosrc->config_ldst = gcmosrc_config_ldst[index]; + gcmosrc->config.raw = 0; + gcmosrc->config.reg.swizzle = srcinfo->format.swizzle; + gcmosrc->config.reg.format = srcinfo->format.format; + + gcmosrc->origin_ldst = gcmosrc_origin_ldst[index]; + gcmosrc->origin.reg.x = srcclipped.left; + gcmosrc->origin.reg.y = srcclipped.top; + + gcmosrc->size_ldst = gcmosrc_size_ldst[index]; + gcmosrc->size.reg = gcregsrcsize_max; + + gcmosrc->rotationheight_ldst + = gcmosrc_rotationheight_ldst[index]; + gcmosrc->rotationheight.reg.height = srcsurfheight; + + gcmosrc->rotationangle_ldst + = gcmosrc_rotationangle_ldst[index]; + gcmosrc->rotationangle.raw = 0; + gcmosrc->rotationangle.reg.src = rotencoding[srcinfo->angle]; + gcmosrc->rotationangle.reg.dst = rotencoding[dstinfo->angle]; + gcmosrc->rotationangle.reg.src_mirror = srcinfo->mirror; + gcmosrc->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE; + + gcmosrc->rop_ldst = gcmosrc_rop_ldst[index]; + gcmosrc->rop.raw = 0; + gcmosrc->rop.reg.type = GCREG_ROP_TYPE_ROP3; + gcmosrc->rop.reg.fg = (unsigned char) srcinfo->rop; + + gcmosrc->mult_ldst = gcmosrc_mult_ldst[index]; + gcmosrc->mult.raw = 0; + gcmosrc->mult.reg.srcglobalpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE; + + if (srcinfo->format.premultiplied) + gcmosrc->mult.reg.srcpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE; + else + gcmosrc->mult.reg.srcpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE; + + if (dstinfo->format.premultiplied) { + gcmosrc->mult.reg.dstpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE; + + gcmosrc->mult.reg.dstdemul + = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE; + } else { + gcmosrc->mult.reg.dstpremul + = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE; - case 3: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcyuv3), - (void **) &gcmoxsrcyuv3); + gcmosrc->mult.reg.dstdemul + = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE; + } + + /* Program blending. */ + bverror = set_blending_index(bvbltparams, batch, + srcinfo, index); + if (bverror != BVERR_NONE) + goto exit; + + /* Program YUV source. */ + if (srcinfo->format.type == BVFMT_YUV) { + bverror = set_yuvsrc_index(bvbltparams, batch, + srcinfo, srcmap, index); if (bverror != BVERR_NONE) goto exit; - - gcmoxsrcyuv3->pectrl_ldst - = gcmoxsrcyuv_pectrl_ldst[index]; - gcmoxsrcyuv3->pectrl.raw = 0; - gcmoxsrcyuv3->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoxsrcyuv3->pectrl.reg.swizzle - = srcinfo->format.swizzle; - - srcheight = ((srcinfo->angle % 2) == 0) - ? srcinfo->geom->height - : srcinfo->geom->width; - - ushift = srcbyteshift - + srcinfo->geom->virtstride - * srcheight; - vshift = ushift - + srcinfo->geom->virtstride - * srcheight / 4; - - GCDBG(GCZONE_SURF, "ushift = 0x%08X (%d)\n", - ushift, ushift); - GCDBG(GCZONE_SURF, "vshift = 0x%08X (%d)\n", - vshift, vshift); - - add_fixup(bvbltparams, batch, - &gcmoxsrcyuv3->uplaneaddress, ushift); - add_fixup(bvbltparams, batch, - &gcmoxsrcyuv3->vplaneaddress, vshift); - - gcmoxsrcyuv3->uplaneaddress_ldst - = gcmoxsrcyuv_uplaneaddress_ldst[index]; - gcmoxsrcyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap); - - gcmoxsrcyuv3->uplanestride_ldst - = gcmoxsrcyuv_uplanestride_ldst[index]; - gcmoxsrcyuv3->uplanestride - = srcinfo->geom->virtstride / 2; - - gcmoxsrcyuv3->vplaneaddress_ldst - = gcmoxsrcyuv_vplaneaddress_ldst[index]; - gcmoxsrcyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap); - - gcmoxsrcyuv3->vplanestride_ldst - = gcmoxsrcyuv_vplanestride_ldst[index]; - gcmoxsrcyuv3->vplanestride - = srcinfo->geom->virtstride / 2; - break; } } diff --git a/drivers/misc/gcx/gcbv/gcbv.c b/drivers/misc/gcx/gcbv/gcbv.c index 90ace0c..d86d550 100644 --- a/drivers/misc/gcx/gcbv/gcbv.c +++ b/drivers/misc/gcx/gcbv/gcbv.c @@ -66,6 +66,7 @@ #define GCZONE_CACHE (1 << 7) #define GCZONE_CALLBACK (1 << 8) #define GCZONE_TEMP (1 << 9) +#define GCZONE_BLEND (1 << 10) GCDBG_FILTERDEF(bv, GCZONE_NONE, "mapping", @@ -77,7 +78,8 @@ GCDBG_FILTERDEF(bv, GCZONE_NONE, "blit", "cache", "callback", - "tempbuffer") + "tempbuffer", + "blending") /******************************************************************************* @@ -542,6 +544,453 @@ exit: return bverror; } +/******************************************************************************* + * Program blending. + */ + +enum bverror set_blending(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo) +{ + enum bverror bverror = BVERR_NONE; + struct gcmoalphaoff *gcmoalphaoff; + struct gcmoalpha *gcmoalpha; + struct gcmoglobal *gcmoglobal; + struct gcalpha *gca; + + GCENTER(GCZONE_BLEND); + + gca = srcinfo->gca; + if (gca == NULL) { + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoalphaoff), + (void **) &gcmoalphaoff); + if (bverror != BVERR_NONE) + goto exit; + + gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst[0]; + gcmoalphaoff->control.reg = gcregalpha_off; + + GCDBG(GCZONE_BLEND, "blending disabled.\n"); + } else { + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoalpha), + (void **) &gcmoalpha); + if (bverror != BVERR_NONE) + goto exit; + + gcmoalpha->config_ldst = gcmoalpha_config_ldst; + gcmoalpha->control.reg = gcregalpha_on; + + gcmoalpha->mode.raw = 0; + gcmoalpha->mode.reg.src_global_alpha_mode + = gca->src_global_alpha_mode; + gcmoalpha->mode.reg.dst_global_alpha_mode + = gca->dst_global_alpha_mode; + + gcmoalpha->mode.reg.src_blend + = gca->srcconfig->factor_mode; + gcmoalpha->mode.reg.src_color_reverse + = gca->srcconfig->color_reverse; + + gcmoalpha->mode.reg.dst_blend + = gca->dstconfig->factor_mode; + gcmoalpha->mode.reg.dst_color_reverse + = gca->dstconfig->color_reverse; + + GCDBG(GCZONE_BLEND, "dst blend:\n"); + GCDBG(GCZONE_BLEND, " factor = %d\n", + gcmoalpha->mode.reg.dst_blend); + GCDBG(GCZONE_BLEND, " inverse = %d\n", + gcmoalpha->mode.reg.dst_color_reverse); + + GCDBG(GCZONE_BLEND, "src blend:\n"); + GCDBG(GCZONE_BLEND, " factor = %d\n", + gcmoalpha->mode.reg.src_blend); + GCDBG(GCZONE_BLEND, " inverse = %d\n", + gcmoalpha->mode.reg.src_color_reverse); + + if ((gca->src_global_alpha_mode + != GCREG_GLOBAL_ALPHA_MODE_NORMAL) || + (gca->dst_global_alpha_mode + != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) { + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoglobal), + (void **) &gcmoglobal); + if (bverror != BVERR_NONE) + goto exit; + + gcmoglobal->color_ldst = gcmoglobal_color_ldst; + gcmoglobal->srcglobal.raw = gca->src_global_color; + gcmoglobal->dstglobal.raw = gca->dst_global_color; + } + } + +exit: + GCEXITARG(GCZONE_BLEND, "bv%s = %d\n", + (bverror == BVERR_NONE) ? "result" : "error", bverror); + return bverror; +} + +enum bverror set_blending_index(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo, + unsigned int index) +{ + enum bverror bverror = BVERR_NONE; + struct gcmoalphaoff *gcmoalphaoff; + struct gcmoxsrcalpha *gcmoxsrcalpha; + struct gcmoxsrcglobal *gcmoxsrcglobal; + struct gcalpha *gca; + + GCENTER(GCZONE_BLEND); + + gca = srcinfo->gca; + if (gca == NULL) { + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoalphaoff), + (void **) &gcmoalphaoff); + if (bverror != BVERR_NONE) + goto exit; + + gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst[index]; + gcmoalphaoff->control.reg = gcregalpha_off; + + GCDBG(GCZONE_BLEND, "blending disabled.\n"); + } else { + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoxsrcalpha), + (void **) &gcmoxsrcalpha); + if (bverror != BVERR_NONE) + goto exit; + + gcmoxsrcalpha->control_ldst = gcmoxsrcalpha_control_ldst[index]; + gcmoxsrcalpha->control.reg = gcregalpha_on; + + gcmoxsrcalpha->mode_ldst = gcmoxsrcalpha_mode_ldst[index]; + gcmoxsrcalpha->mode.raw = 0; + gcmoxsrcalpha->mode.reg.src_global_alpha_mode + = gca->src_global_alpha_mode; + gcmoxsrcalpha->mode.reg.dst_global_alpha_mode + = gca->dst_global_alpha_mode; + + gcmoxsrcalpha->mode.reg.src_blend + = gca->srcconfig->factor_mode; + gcmoxsrcalpha->mode.reg.src_color_reverse + = gca->srcconfig->color_reverse; + + gcmoxsrcalpha->mode.reg.dst_blend + = gca->dstconfig->factor_mode; + gcmoxsrcalpha->mode.reg.dst_color_reverse + = gca->dstconfig->color_reverse; + + GCDBG(GCZONE_BLEND, "dst blend:\n"); + GCDBG(GCZONE_BLEND, " factor = %d\n", + gcmoxsrcalpha->mode.reg.dst_blend); + GCDBG(GCZONE_BLEND, " inverse = %d\n", + gcmoxsrcalpha->mode.reg.dst_color_reverse); + + GCDBG(GCZONE_BLEND, "src blend:\n"); + GCDBG(GCZONE_BLEND, " factor = %d\n", + gcmoxsrcalpha->mode.reg.src_blend); + GCDBG(GCZONE_BLEND, " inverse = %d\n", + gcmoxsrcalpha->mode.reg.src_color_reverse); + + if ((gca->src_global_alpha_mode + != GCREG_GLOBAL_ALPHA_MODE_NORMAL) || + (gca->dst_global_alpha_mode + != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) { + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoxsrcglobal), + (void **) &gcmoxsrcglobal); + if (bverror != BVERR_NONE) + goto exit; + + gcmoxsrcglobal->srcglobal_ldst + = gcmoxsrcglobal_srcglobal_ldst[index]; + gcmoxsrcglobal->srcglobal.raw = gca->src_global_color; + + gcmoxsrcglobal->dstglobal_ldst + = gcmoxsrcglobal_dstglobal_ldst[index]; + gcmoxsrcglobal->dstglobal.raw = gca->dst_global_color; + } + } + +exit: + GCEXITARG(GCZONE_BLEND, "bv%s = %d\n", + (bverror == BVERR_NONE) ? "result" : "error", bverror); + return bverror; +} + +/******************************************************************************* + * Program YUV source. + */ + +enum bverror set_yuvsrc(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo, + struct bvbuffmap *srcmap) +{ + enum bverror bverror = BVERR_NONE; + struct gcmoyuv1 *gcmoyuv1; + struct gcmoyuv2 *gcmoyuv2; + struct gcmoyuv3 *gcmoyuv3; + int ushift, vshift; + unsigned int srcheight; + + GCENTER(GCZONE_SRC); + + GCDBG(GCZONE_SRC, "plane count %d.\n", + srcinfo->format.cs.yuv.planecount); + + switch (srcinfo->format.cs.yuv.planecount) { + case 1: + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoyuv1), + (void **) &gcmoyuv1); + if (bverror != BVERR_NONE) + goto exit; + + gcmoyuv1->pectrl_ldst = gcmoyuv_pectrl_ldst; + gcmoyuv1->pectrl.raw = 0; + gcmoyuv1->pectrl.reg.standard + = srcinfo->format.cs.yuv.std; + gcmoyuv1->pectrl.reg.swizzle + = srcinfo->format.swizzle; + gcmoyuv1->pectrl.reg.convert + = GCREG_PE_CONTROL_YUVRGB_DISABLED; + break; + + case 2: + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoyuv2), + (void **) &gcmoyuv2); + if (bverror != BVERR_NONE) + goto exit; + + gcmoyuv2->pectrl_ldst = gcmoyuv_pectrl_ldst; + gcmoyuv2->pectrl.raw = 0; + gcmoyuv2->pectrl.reg.standard + = srcinfo->format.cs.yuv.std; + gcmoyuv2->pectrl.reg.swizzle + = srcinfo->format.swizzle; + gcmoyuv2->pectrl.reg.convert + = GCREG_PE_CONTROL_YUVRGB_DISABLED; + + srcheight = ((srcinfo->angle % 2) == 0) + ? srcinfo->geom->height + : srcinfo->geom->width; + + ushift = srcinfo->bytealign + + srcinfo->geom->virtstride + * srcheight; + GCDBG(GCZONE_SRC, "ushift = 0x%08X (%d)\n", + ushift, ushift); + + add_fixup(bvbltparams, batch, &gcmoyuv2->uplaneaddress, + ushift); + + gcmoyuv2->plane_ldst = gcmoyuv2_plane_ldst; + gcmoyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap); + gcmoyuv2->uplanestride = srcinfo->geom->virtstride; + break; + + case 3: + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoyuv3), + (void **) &gcmoyuv3); + if (bverror != BVERR_NONE) + goto exit; + + gcmoyuv3->pectrl_ldst = gcmoyuv_pectrl_ldst; + gcmoyuv3->pectrl.raw = 0; + gcmoyuv3->pectrl.reg.standard + = srcinfo->format.cs.yuv.std; + gcmoyuv3->pectrl.reg.swizzle + = srcinfo->format.swizzle; + gcmoyuv3->pectrl.reg.convert + = GCREG_PE_CONTROL_YUVRGB_DISABLED; + + srcheight = ((srcinfo->angle % 2) == 0) + ? srcinfo->geom->height + : srcinfo->geom->width; + + ushift = srcinfo->bytealign + + srcinfo->geom->virtstride + * srcheight; + vshift = ushift + + srcinfo->geom->virtstride + * srcheight / 4; + + GCDBG(GCZONE_SRC, "ushift = 0x%08X (%d)\n", + ushift, ushift); + GCDBG(GCZONE_SRC, "vshift = 0x%08X (%d)\n", + vshift, vshift); + + add_fixup(bvbltparams, batch, &gcmoyuv3->uplaneaddress, + ushift); + add_fixup(bvbltparams, batch, &gcmoyuv3->vplaneaddress, + vshift); + + gcmoyuv3->plane_ldst = gcmoyuv3_plane_ldst; + gcmoyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap); + gcmoyuv3->uplanestride = srcinfo->geom->virtstride / 2; + gcmoyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap); + gcmoyuv3->vplanestride = srcinfo->geom->virtstride / 2; + break; + + default: + GCERR("invlaid plane count %d.\n", + srcinfo->format.cs.yuv.planecount); + } + +exit: + GCEXITARG(GCZONE_SRC, "bv%s = %d\n", + (bverror == BVERR_NONE) ? "result" : "error", bverror); + return bverror; +} + +enum bverror set_yuvsrc_index(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo, + struct bvbuffmap *srcmap, + unsigned int index) +{ + enum bverror bverror = BVERR_NONE; + struct gcmoxsrcyuv1 *gcmoxsrcyuv1; + struct gcmoxsrcyuv2 *gcmoxsrcyuv2; + struct gcmoxsrcyuv3 *gcmoxsrcyuv3; + int ushift, vshift; + unsigned int srcheight; + + GCENTER(GCZONE_SRC); + + GCDBG(GCZONE_SRC, "plane count %d.\n", + srcinfo->format.cs.yuv.planecount); + + switch (srcinfo->format.cs.yuv.planecount) { + case 1: + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoxsrcyuv1), + (void **) &gcmoxsrcyuv1); + if (bverror != BVERR_NONE) + goto exit; + + gcmoxsrcyuv1->pectrl_ldst + = gcmoxsrcyuv_pectrl_ldst[index]; + gcmoxsrcyuv1->pectrl.raw = 0; + gcmoxsrcyuv1->pectrl.reg.standard + = srcinfo->format.cs.yuv.std; + gcmoxsrcyuv1->pectrl.reg.swizzle + = srcinfo->format.swizzle; + gcmoxsrcyuv1->pectrl.reg.convert + = GCREG_PE_CONTROL_YUVRGB_DISABLED; + break; + + case 2: + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoxsrcyuv2), + (void **) &gcmoxsrcyuv2); + if (bverror != BVERR_NONE) + goto exit; + + gcmoxsrcyuv2->pectrl_ldst + = gcmoxsrcyuv_pectrl_ldst[index]; + gcmoxsrcyuv2->pectrl.raw = 0; + gcmoxsrcyuv2->pectrl.reg.standard + = srcinfo->format.cs.yuv.std; + gcmoxsrcyuv2->pectrl.reg.swizzle + = srcinfo->format.swizzle; + gcmoxsrcyuv2->pectrl.reg.convert + = GCREG_PE_CONTROL_YUVRGB_DISABLED; + + srcheight = ((srcinfo->angle % 2) == 0) + ? srcinfo->geom->height + : srcinfo->geom->width; + + ushift = srcinfo->bytealign + + srcinfo->geom->virtstride + * srcheight; + GCDBG(GCZONE_SRC, "ushift = 0x%08X (%d)\n", + ushift, ushift); + + add_fixup(bvbltparams, batch, &gcmoxsrcyuv2->uplaneaddress, + ushift); + + gcmoxsrcyuv2->uplaneaddress_ldst + = gcmoxsrcyuv_uplaneaddress_ldst[index]; + gcmoxsrcyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap); + + gcmoxsrcyuv2->uplanestride_ldst + = gcmoxsrcyuv_uplanestride_ldst[index]; + gcmoxsrcyuv2->uplanestride = srcinfo->geom->virtstride; + break; + + case 3: + bverror = claim_buffer(bvbltparams, batch, + sizeof(struct gcmoxsrcyuv3), + (void **) &gcmoxsrcyuv3); + if (bverror != BVERR_NONE) + goto exit; + + gcmoxsrcyuv3->pectrl_ldst + = gcmoxsrcyuv_pectrl_ldst[index]; + gcmoxsrcyuv3->pectrl.raw = 0; + gcmoxsrcyuv3->pectrl.reg.standard + = srcinfo->format.cs.yuv.std; + gcmoxsrcyuv3->pectrl.reg.swizzle + = srcinfo->format.swizzle; + gcmoxsrcyuv3->pectrl.reg.convert + = GCREG_PE_CONTROL_YUVRGB_DISABLED; + + srcheight = ((srcinfo->angle % 2) == 0) + ? srcinfo->geom->height + : srcinfo->geom->width; + + ushift = srcinfo->bytealign + + srcinfo->geom->virtstride + * srcheight; + vshift = ushift + + srcinfo->geom->virtstride + * srcheight / 4; + + GCDBG(GCZONE_SRC, "ushift = 0x%08X (%d)\n", + ushift, ushift); + GCDBG(GCZONE_SRC, "vshift = 0x%08X (%d)\n", + vshift, vshift); + + add_fixup(bvbltparams, batch, &gcmoxsrcyuv3->uplaneaddress, + ushift); + add_fixup(bvbltparams, batch, &gcmoxsrcyuv3->vplaneaddress, + vshift); + + gcmoxsrcyuv3->uplaneaddress_ldst + = gcmoxsrcyuv_uplaneaddress_ldst[index]; + gcmoxsrcyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap); + + gcmoxsrcyuv3->uplanestride_ldst + = gcmoxsrcyuv_uplanestride_ldst[index]; + gcmoxsrcyuv3->uplanestride = srcinfo->geom->virtstride / 2; + + gcmoxsrcyuv3->vplaneaddress_ldst + = gcmoxsrcyuv_vplaneaddress_ldst[index]; + gcmoxsrcyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap); + + gcmoxsrcyuv3->vplanestride_ldst + = gcmoxsrcyuv_vplanestride_ldst[index]; + gcmoxsrcyuv3->vplanestride = srcinfo->geom->virtstride / 2; + break; + + default: + GCERR("invlaid plane count %d.\n", + srcinfo->format.cs.yuv.planecount); + } + +exit: + GCEXITARG(GCZONE_SRC, "bv%s = %d\n", + (bverror == BVERR_NONE) ? "result" : "error", bverror); + return bverror; +} /******************************************************************************* * Surface compare and validation. diff --git a/drivers/misc/gcx/gcbv/gcbv.h b/drivers/misc/gcx/gcbv/gcbv.h index decd739..bc82aec 100644 --- a/drivers/misc/gcx/gcbv/gcbv.h +++ b/drivers/misc/gcx/gcbv/gcbv.h @@ -380,9 +380,6 @@ struct gcblit { /* Multi source enable flag. */ unsigned int multisrc; - /* ROP code. */ - unsigned short rop; - /* Computed destination rectangle coordinates; in multi-source * setup can be modified to match new destination and source * geometry. */ @@ -573,6 +570,26 @@ enum bverror set_dst(struct bvbltparams *bltparams, struct gcbatch *batch, struct bvbuffmap *dstmap); +/* Program blending. */ +enum bverror set_blending(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo); +enum bverror set_blending_index(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo, + unsigned int index); + +/* Program YUV source. */ +enum bverror set_yuvsrc(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo, + struct bvbuffmap *srcmap); +enum bverror set_yuvsrc_index(struct bvbltparams *bvbltparams, + struct gcbatch *batch, + struct surfaceinfo *srcinfo, + struct bvbuffmap *srcmap, + unsigned int index); + /* Rendering entry points. */ enum bverror do_fill(struct bvbltparams *bltparams, struct gcbatch *gcbatch, diff --git a/drivers/misc/gcx/gcbv/gcfilter.c b/drivers/misc/gcx/gcbv/gcfilter.c index f9074b3..427f6f9 100644 --- a/drivers/misc/gcx/gcbv/gcfilter.c +++ b/drivers/misc/gcx/gcbv/gcfilter.c @@ -926,14 +926,10 @@ static enum bverror startvr(struct bvbltparams *bvbltparams, { enum bverror bverror; struct gccontext *gccontext = get_context(); - struct gcalpha *gca; struct gcfilter *gcfilter; struct gcmovrdst *gcmovrdst; struct gcmovrsrc *gcmovrsrc; - struct gcmoalphaoff *gcmoalphaoff; - struct gcmoalpha *gcmoalpha; - struct gcmoglobal *gcmoglobal; struct gcmostartvr *gcmostartvr; struct gcrect srcrect; @@ -1091,171 +1087,18 @@ static enum bverror startvr(struct bvbltparams *bvbltparams, /* Program YUV source. */ if (srcinfo->format.type == BVFMT_YUV) { - struct gcmoyuv1 *gcmoyuv1; - struct gcmoyuv2 *gcmoyuv2; - struct gcmoyuv3 *gcmoyuv3; - int ushift, vshift; - - switch (srcinfo->format.cs.yuv.planecount) { - case 1: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoyuv1), - (void **) &gcmoyuv1); - if (bverror != BVERR_NONE) - goto exit; - - gcmoyuv1->pectrl_ldst = gcmoyuv_pectrl_ldst; - gcmoyuv1->pectrl.raw = 0; - gcmoyuv1->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoyuv1->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoyuv1->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - break; - - case 2: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoyuv2), - (void **) &gcmoyuv2); - if (bverror != BVERR_NONE) - goto exit; - - gcmoyuv2->pectrl_ldst = gcmoyuv_pectrl_ldst; - gcmoyuv2->pectrl.raw = 0; - gcmoyuv2->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoyuv2->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoyuv2->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - - ushift = srcinfo->bytealign - + srcinfo->geom->virtstride - * srcinfo->physheight; - GCDBG(GCZONE_FILTER, "ushift = 0x%08X (%d)\n", - ushift, ushift); - - add_fixup(bvbltparams, batch, &gcmoyuv2->uplaneaddress, - ushift); - - gcmoyuv2->plane_ldst = gcmoyuv2_plane_ldst; - gcmoyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoyuv2->uplanestride = srcinfo->geom->virtstride; - break; - - case 3: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoyuv3), - (void **) &gcmoyuv3); - if (bverror != BVERR_NONE) - goto exit; - - gcmoyuv3->pectrl_ldst = gcmoyuv_pectrl_ldst; - gcmoyuv3->pectrl.raw = 0; - gcmoyuv3->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoyuv3->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoyuv3->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - - ushift = srcinfo->bytealign - + srcinfo->geom->virtstride - * srcinfo->physheight; - vshift = ushift - + srcinfo->geom->virtstride - * srcinfo->physheight / 4; - - GCDBG(GCZONE_FILTER, "ushift = 0x%08X (%d)\n", - ushift, ushift); - GCDBG(GCZONE_FILTER, "vshift = 0x%08X (%d)\n", - vshift, vshift); - - add_fixup(bvbltparams, batch, &gcmoyuv3->uplaneaddress, - ushift); - add_fixup(bvbltparams, batch, &gcmoyuv3->vplaneaddress, - vshift); - - gcmoyuv3->plane_ldst = gcmoyuv3_plane_ldst; - gcmoyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoyuv3->uplanestride = srcinfo->geom->virtstride / 2; - gcmoyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoyuv3->vplanestride = srcinfo->geom->virtstride / 2; - break; - } + bverror = set_yuvsrc(bvbltparams, batch, srcinfo, srcmap); + if (bverror != BVERR_NONE) + goto exit; } /*********************************************************************** * Program blending. */ - gca = srcinfo->gca; - if (gca == NULL) { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoalphaoff), - (void **) &gcmoalphaoff); - if (bverror != BVERR_NONE) - goto exit; - - gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst; - gcmoalphaoff->control.reg = gcregalpha_off; - - GCDBG(GCZONE_BLEND, "blending disabled.\n"); - } else { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoalpha), - (void **) &gcmoalpha); - if (bverror != BVERR_NONE) - goto exit; - - gcmoalpha->config_ldst = gcmoalpha_config_ldst; - gcmoalpha->control.reg = gcregalpha_on; - - gcmoalpha->mode.raw = 0; - gcmoalpha->mode.reg.src_global_alpha_mode - = gca->src_global_alpha_mode; - gcmoalpha->mode.reg.dst_global_alpha_mode - = gca->dst_global_alpha_mode; - - gcmoalpha->mode.reg.src_blend - = gca->srcconfig->factor_mode; - gcmoalpha->mode.reg.src_color_reverse - = gca->srcconfig->color_reverse; - - gcmoalpha->mode.reg.dst_blend - = gca->dstconfig->factor_mode; - gcmoalpha->mode.reg.dst_color_reverse - = gca->dstconfig->color_reverse; - - GCDBG(GCZONE_BLEND, "dst blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoalpha->mode.reg.dst_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoalpha->mode.reg.dst_color_reverse); - - GCDBG(GCZONE_BLEND, "src blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoalpha->mode.reg.src_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoalpha->mode.reg.src_color_reverse); - - if ((gca->src_global_alpha_mode - != GCREG_GLOBAL_ALPHA_MODE_NORMAL) || - (gca->dst_global_alpha_mode - != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoglobal), - (void **) &gcmoglobal); - if (bverror != BVERR_NONE) - goto exit; - - gcmoglobal->color_ldst = gcmoglobal_color_ldst; - gcmoglobal->srcglobal.raw = gca->src_global_color; - gcmoglobal->dstglobal.raw = gca->dst_global_color; - } - } - + bverror = set_blending(bvbltparams, batch, srcinfo); + if (bverror != BVERR_NONE) + goto exit; /*********************************************************************** * Start the operation. @@ -1822,8 +1665,8 @@ enum bverror do_filter(struct bvbltparams *bvbltparams, srcx, srcy, &dstrotated0, ROT_ANGLE_0, ROT_ANGLE_0, ((gcfilter->dstangle % 2) == 0) - ? GC_SCALE_HOR - : GC_SCALE_HOR_FLIPPED); + ? GC_SCALE_HOR + : GC_SCALE_HOR_FLIPPED); if (bverror != BVERR_NONE) goto exit; } else { |