Implement read and write operations on SC_TOP_LEFT, SC_BOTTOM_RIGHT, and SRC_SC_BOTTOM_RIGHT registers. These registers are also updated when the src and/or dst clipping fields on DP_GUI_MASTER_CNTL are set to default clipping.
Scissor clipping is used when rendering text in X.org. The r128 driver sends host data much wider than is necessary to draw a glyph and cuts it down to size using clipping before rendering. The actual clipping implementation follows in a future patch. Signed-off-by: Chad Jablonski <[email protected]> --- hw/display/ati.c | 26 ++++++++++++++++++++++++++ hw/display/ati_int.h | 3 +++ hw/display/ati_regs.h | 12 ++++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/hw/display/ati.c b/hw/display/ati.c index 0b4298d078..eb9b30672f 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -510,6 +510,15 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size) case DEFAULT_SC_BOTTOM_RIGHT: val = s->regs.default_sc_bottom_right; break; + case SC_TOP_LEFT: + val = s->regs.sc_top_left; + break; + case SC_BOTTOM_RIGHT: + val = s->regs.sc_bottom_right; + break; + case SRC_SC_BOTTOM_RIGHT: + val = s->regs.src_sc_bottom_right; + break; default: break; } @@ -862,6 +871,14 @@ static void ati_mm_write(void *opaque, hwaddr addr, s->regs.dp_datatype = (data & 0x0f00) >> 8 | (data & 0x30f0) << 4 | (data & 0x4000) << 16; s->regs.dp_mix = (data & GMC_ROP3_MASK) | (data & 0x7000000) >> 16; + + if ((data & GMC_SRC_CLIPPING_MASK) == GMC_SRC_CLIP_DEFAULT) { + s->regs.src_sc_bottom_right = s->regs.default_sc_bottom_right; + } + if ((data & GMC_DST_CLIPPING_MASK) == GMC_DST_CLIP_DEFAULT) { + s->regs.sc_top_left = 0; + s->regs.sc_bottom_right = s->regs.default_sc_bottom_right; + } break; case DST_WIDTH_X: s->regs.dst_x = data & 0x3fff; @@ -937,6 +954,15 @@ static void ati_mm_write(void *opaque, hwaddr addr, case DEFAULT_SC_BOTTOM_RIGHT: s->regs.default_sc_bottom_right = data & 0x3fff3fff; break; + case SC_TOP_LEFT: + s->regs.sc_top_left = data; + break; + case SC_BOTTOM_RIGHT: + s->regs.sc_bottom_right = data; + break; + case SRC_SC_BOTTOM_RIGHT: + s->regs.src_sc_bottom_right = data; + break; default: break; } diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h index 708cc1dd3a..aab3cbf81a 100644 --- a/hw/display/ati_int.h +++ b/hw/display/ati_int.h @@ -86,6 +86,9 @@ typedef struct ATIVGARegs { uint32_t default_pitch; uint32_t default_tile; uint32_t default_sc_bottom_right; + uint32_t sc_top_left; + uint32_t sc_bottom_right; + uint32_t src_sc_bottom_right; } ATIVGARegs; struct ATIVGAState { diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h index d7127748ff..2b56b9fb66 100644 --- a/hw/display/ati_regs.h +++ b/hw/display/ati_regs.h @@ -392,8 +392,6 @@ /* DP_GUI_MASTER_CNTL bit constants */ #define GMC_SRC_PITCH_OFFSET_CNTL 0x00000001 #define GMC_DST_PITCH_OFFSET_CNTL 0x00000002 -#define GMC_SRC_CLIP_DEFAULT 0x00000000 -#define GMC_DST_CLIP_DEFAULT 0x00000000 #define GMC_BRUSH_SOLIDCOLOR 0x000000d0 #define GMC_SRC_DSTCOLOR 0x00003000 #define GMC_BYTE_ORDER_MSB_TO_LSB 0x00000000 @@ -404,6 +402,16 @@ #define GMC_WRITE_MASK_SET 0x40000000 #define GMC_DP_CONVERSION_TEMP_6500 0x00000000 +/* DP_GUI_MASTER_CNTL DP_SRC_CLIPPING named constants */ +#define GMC_SRC_CLIPPING_MASK 0x00000004 +#define GMC_SRC_CLIP_DEFAULT 0x00000000 +#define GMC_SRC_CLIP_LEAVE_ALONE 0x00000004 + +/* DP_GUI_MASTER_CNTL DP_DST_CLIPPING named constants */ +#define GMC_DST_CLIPPING_MASK 0x00000008 +#define GMC_DST_CLIP_DEFAULT 0x00000000 +#define GMC_DST_CLIP_LEAVE_ALONE 0x00000008 + /* DP_GUI_MASTER_CNTL ROP3 named constants */ #define GMC_ROP3_MASK 0x00ff0000 #define ROP3_BLACKNESS 0x00000000 -- 2.51.0
