aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorAlexei Shlychkov <x0177296@ti.com>2012-10-09 11:56:44 -0700
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:01:04 +0200
commit36383ebef70b9e962233f61b4fcff20d5c2b5969 (patch)
tree9e2151dcc004f065280a3e820d4eb40abcd2fc49 /drivers/misc
parentcfffef220d24e794b3c2f815387cee9b07d19a76 (diff)
downloadkernel_samsung_tuna-36383ebef70b9e962233f61b4fcff20d5c2b5969.tar.gz
kernel_samsung_tuna-36383ebef70b9e962233f61b4fcff20d5c2b5969.tar.bz2
kernel_samsung_tuna-36383ebef70b9e962233f61b4fcff20d5c2b5969.zip
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.c462
-rw-r--r--drivers/misc/gcx/gcbv/gcbv.c451
-rw-r--r--drivers/misc/gcx/gcbv/gcbv.h23
-rw-r--r--drivers/misc/gcx/gcbv/gcfilter.c173
4 files changed, 665 insertions, 444 deletions
diff --git a/drivers/misc/gcx/gcbv/gcblit.c b/drivers/misc/gcx/gcbv/gcblit.c
index 17aa2974a4a..04fa86a3e78 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 90ace0cea22..d86d5500bc5 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 decd7399f1e..bc82aecfc23 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 f9074b32e9c..427f6f9fbd4 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 {