summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Crouse <jordan.crouse@amd.com>2007-06-01 18:32:28 -0600
committerJordan Crouse <jordan.crouse@amd.com>2007-07-06 17:00:26 -0600
commitdc23a3168df78424108e8609b250e88c3dd16775 (patch)
treed43f8e963ff2cc3b077e2df69e5079ddd4728bfc
parent167d9dcfe6c13f37590b26bd544ae225cb7934ac (diff)
Fix A8 masks
We were using the wrong operation for A8 masks, resulting in badness. Also, clean up the mask blt to be much simpler.
-rw-r--r--src/amd_lx_exa.c10
-rw-r--r--src/cim/cim_gp.c140
-rw-r--r--src/cim/cim_rtns.h2
3 files changed, 24 insertions, 128 deletions
diff --git a/src/amd_lx_exa.c b/src/amd_lx_exa.c
index 5f56f22..eec6a7c 100644
--- a/src/amd_lx_exa.c
+++ b/src/amd_lx_exa.c
@@ -408,9 +408,11 @@ struct blend_ops_t {
/* PictOpDst */
{ CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_DEST }, { },
/* PictOpOver*/
- { CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { },
+ { CIMGP_ALPHA_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE },
+ { },
/* PictOpOverReverse */
- { CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, { },
+ { CIMGP_ALPHA_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST },
+ { },
/* PictOpIn */
{ CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { },
/* PictOpInReverse */
@@ -880,8 +882,8 @@ lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset,
gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
gp_set_solid_source (exaScratch.srcColor);
- gp_blend_mask_blt(dstOffset, 0, width, height, data,
- exaScratch.srcPitch, opPtr->operation,
+ gp_blend_mask_blt(dstOffset, 0, width, height, maskOffset,
+ exaScratch.srcPitch, opPtr->operation,
exaScratch.fourBpp);
}
diff --git a/src/cim/cim_gp.c b/src/cim/cim_gp.c
index 6579f12..6aad40f 100644
--- a/src/cim/cim_gp.c
+++ b/src/cim/cim_gp.c
@@ -3399,14 +3399,11 @@ gp_restore_state(GP_SAVE_RESTORE * gp_state)
void
gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx,
unsigned long width, unsigned long height,
- unsigned char *data, long stride, int operation,
+ unsigned long dataoffset, long stride, int operation,
int fourbpp)
{
- unsigned long indent, temp;
- unsigned long total_dwords, size_dwords;
- unsigned long dword_count, byte_count;
+ unsigned long indent;
unsigned long size = ((width << 16) | height);
- unsigned long ch3_offset, srcoffset;
unsigned long base, depth_flag;
base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
@@ -3430,27 +3427,14 @@ gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx,
if (fourbpp) {
depth_flag = GP3_CH3_SRC_4BPP_ALPHA;
- indent = (srcx >> 1);
- srcoffset = (indent & ~3L);
- indent &= 3;
- ch3_offset = indent | ((srcx & 1) << 25);
-
- temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+ indent = (srcx >> 1) & 3;
+ dataoffset += indent | ((srcx & 1) << 25);
} else {
depth_flag = GP3_CH3_SRC_8BPP_ALPHA;
- indent = srcx;
- srcoffset = (indent & ~3L);
- indent &= 3;
- ch3_offset = indent;
-
- temp = width + indent;
+ indent = srcx & 3;
+ dataoffset += indent;
}
- total_dwords = (temp + 3) >> 2;
- size_dwords = (total_dwords << 2) + 8;
- dword_count = (temp >> 2);
- byte_count = (temp & 3);
-
/* SET RASTER MODE REGISTER */
/* Alpha blending will only apply to RGB when no alpha component is present. */
/* As 8BPP is not supported for this routine, the only alpha-less mode is */
@@ -3460,24 +3444,28 @@ gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx,
WRITE_COMMAND32(GP3_BLT_RASTER_MODE,
gp3_bpp |
GP3_RM_ALPHA_TO_RGB |
- ((unsigned long) operation << 20) | GP3_RM_SELECT_ALPHA_CHAN_3);
+ ((unsigned long) (operation << 20)) | GP3_RM_SELECT_ALPHA_CHAN_3);
} else {
WRITE_COMMAND32(GP3_BLT_RASTER_MODE,
gp3_bpp |
- GP3_RM_ALPHA_ALL |
- ((unsigned long) operation << 20) | GP3_RM_SELECT_ALPHA_CHAN_3);
+ GP3_RM_ALPHA_ALL | ((unsigned long) (operation << 20)) |
+ GP3_RM_SELECT_ALPHA_CHAN_3);
}
/* WRITE ALL REMAINING REGISTERS */
WRITE_COMMAND32(GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
- WRITE_COMMAND32(GP3_BLT_CH3_OFFSET, ch3_offset);
+
+ /* Set the offset of the CH3 data in memory */
+ WRITE_COMMAND32(GP3_BLT_CH3_OFFSET, dataoffset & 0xFFFFFFF);
+
WRITE_COMMAND32(GP3_BLT_WID_HEIGHT, size);
WRITE_COMMAND32(GP3_BLT_CH3_WIDHI, size);
WRITE_COMMAND32(GP3_BLT_BASE_OFFSET, base);
- WRITE_COMMAND32(GP3_BLT_CH3_MODE_STR, GP3_CH3_C3EN |
- GP3_CH3_HST_SRC_ENABLE |
- depth_flag | ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+
+ WRITE_COMMAND32(GP3_BLT_CH3_MODE_STR, GP3_CH3_C3EN | (stride & 0xFFFF) |
+ depth_flag | ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+
WRITE_COMMAND32(GP3_BLT_MODE, GP3_BM_DST_REQ);
/* START THE BLT */
@@ -3485,98 +3473,4 @@ gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx,
WRITE_COMMAND32(GP3_BLT_CMD_HEADER, gp3_cmd_header);
WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
-
- /* WRITE DATA LINE BY LINE
- * Each line will be created as a separate command buffer entry to allow
- * line-by-line wrapping and to allow simultaneous rendering by the HW.
- */
-
- if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
- (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72)) {
- /* UPDATE THE COMMAND POINTER */
-
- cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
-
- /* CHECK IF A WRAP WILL BE NEEDED */
-
- gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
-
- if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE) {
- gp3_cmd_next = gp3_cmd_top;
-
- GP3_WAIT_WRAP(temp);
- WRITE_COMMAND32(0,
- GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
- GP3_DATA_LOAD_HDR_ENABLE);
- } else {
- GP3_WAIT_PRIMITIVE(temp);
- WRITE_COMMAND32(0,
- GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
- }
-
- /* WRITE DWORD COUNT */
-
- WRITE_COMMAND32(4,
- GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
-
- while (height--) {
- /* WRITE DATA */
-
- WRITE_COMMAND_STRING32(8, data, srcoffset, dword_count);
- WRITE_COMMAND_STRING8(8 + (dword_count << 2), data,
- srcoffset + (dword_count << 2), byte_count);
-
- srcoffset += stride;
- cim_cmd_ptr += total_dwords << 2;
- }
-
- WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next);
- gp3_cmd_current = gp3_cmd_next;
- } else {
- while (height--) {
- /* UPDATE THE COMMAND POINTER
- * The WRITE_COMMANDXX macros use a pointer to the current buffer
- * space. This is created by adding gp3_cmd_current to the base
- * pointer.
- */
-
- cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
-
- /* CHECK IF A WRAP WILL BE NEEDED */
-
- gp3_cmd_next = gp3_cmd_current + size_dwords;
- if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE) {
- gp3_cmd_next = gp3_cmd_top;
-
- /* WAIT FOR HARDWARE */
-
- GP3_WAIT_WRAP(temp);
- WRITE_COMMAND32(0,
- GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
- GP3_DATA_LOAD_HDR_ENABLE);
- } else {
- /* WAIT FOR AVAILABLE SPACE */
-
- GP3_WAIT_PRIMITIVE(temp);
- WRITE_COMMAND32(0,
- GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
- }
-
- /* WRITE DWORD COUNT */
-
- WRITE_COMMAND32(4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
-
- /* WRITE DATA */
-
- WRITE_COMMAND_STRING32(8, data, srcoffset, dword_count);
- WRITE_COMMAND_STRING8(8 + (dword_count << 2), data,
- srcoffset + (dword_count << 2), byte_count);
-
- /* UPDATE POINTERS */
-
- srcoffset += stride;
- WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next);
- gp3_cmd_current = gp3_cmd_next;
- }
- }
}
diff --git a/src/cim/cim_rtns.h b/src/cim/cim_rtns.h
index 6fecb4b..60bdcd1 100644
--- a/src/cim/cim_rtns.h
+++ b/src/cim/cim_rtns.h
@@ -126,7 +126,7 @@ extern "C"
unsigned long width, unsigned long height, unsigned char *data,
long stride, int fourbpp);
void gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx,
- unsigned long width, unsigned long height, unsigned char *data,
+ unsigned long width, unsigned long height, unsigned long,
long stride, int operation, int fourbpp);
void gp_masked_blt(unsigned long dstoffset, unsigned long width,
unsigned long height, unsigned long mono_srcx,