Commit 272d7dee authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/pull-cirrus-20170316-1' into staging



cirrus: blitter fixes.

# gpg: Signature made Thu 16 Mar 2017 09:05:22 GMT
# gpg:                using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/pull-cirrus-20170316-1:
  cirrus: stop passing around src pointers in the blitter
  cirrus: stop passing around dst pointers in the blitter
  cirrus: fix cirrus_invalidate_region
  cirrus: add option to disable blitter
  cirrus: switch to 4 MB video memory by default
  cirrus/vnc: zap bitblit support from console code.
  fix :cirrus_vga fix OOB read case qemu Segmentation fault

# Conflicts:
#	include/hw/compat.h

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c5e737e5 ffaf8577
Loading
Loading
Loading
Loading
+72 −34
Original line number Diff line number Diff line
@@ -178,11 +178,12 @@

struct CirrusVGAState;
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
                                     uint8_t * dst, const uint8_t * src,
                                     uint32_t dstaddr, uint32_t srcaddr,
				     int dstpitch, int srcpitch,
				     int bltwidth, int bltheight);
typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
                              uint8_t *dst, int dst_pitch, int width, int height);
                              uint32_t dstaddr, int dst_pitch,
                              int width, int height);

typedef struct CirrusVGAState {
    VGACommonState vga;
@@ -205,6 +206,7 @@ typedef struct CirrusVGAState {
    uint32_t cirrus_bank_base[2];
    uint32_t cirrus_bank_limit[2];
    uint8_t cirrus_hidden_palette[48];
    bool enable_blitter;
    int cirrus_blt_pixelwidth;
    int cirrus_blt_width;
    int cirrus_blt_height;
@@ -320,18 +322,57 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
}

static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
                                  uint8_t *dst,const uint8_t *src,
                                  uint32_t dstaddr, uint32_t srcaddr,
                                  int dstpitch,int srcpitch,
                                  int bltwidth,int bltheight)
{
}

static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
                                   uint8_t *dst,
                                   uint32_t dstaddr,
                                   int dstpitch, int bltwidth,int bltheight)
{
}

static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr)
{
    if (s->cirrus_srccounter) {
        /* cputovideo */
        return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)];
    } else {
        /* videotovideo */
        return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask];
    }
}

static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr)
{
    uint16_t *src;

    if (s->cirrus_srccounter) {
        /* cputovideo */
        src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1];
    } else {
        /* videotovideo */
        src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1];
    }
    return *src;
}

static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr)
{
    uint32_t *src;

    if (s->cirrus_srccounter) {
        /* cputovideo */
        src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3];
    } else {
        /* videotovideo */
        src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3];
    }
    return *src;
}

#define ROP_NAME 0
#define ROP_FN(d, s) 0
#include "cirrus_vga_rop.h"
@@ -667,20 +708,17 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,

    for (y = 0; y < lines; y++) {
        off_cur = off_begin;
	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
        off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1;
        assert(off_cur_end >= off_cur);
        memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
        off_begin += off_pitch;
    }
}

static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s)
{
    uint32_t patternsize;
    uint8_t *dst;
    uint8_t *src;

    dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
    bool videosrc = !s->cirrus_srccounter;

    if (videosrc) {
        switch (s->vga.get_bpp(&s->vga)) {
@@ -701,16 +739,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
        if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
            return 0;
        }
        src = s->vga.vram_ptr + s->cirrus_blt_srcaddr;
    } else {
        src = s->cirrus_bltbuf;
    }

    if (blit_is_unsafe(s, true)) {
        return 0;
    }

    (*s->cirrus_rop) (s, dst, src,
    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
                      videosrc ? s->cirrus_blt_srcaddr : 0,
                      s->cirrus_blt_dstpitch, 0,
                      s->cirrus_blt_width, s->cirrus_blt_height);
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
@@ -729,7 +765,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
        return 0;
    }
    rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
    rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
    rop_func(s, s->cirrus_blt_dstaddr,
             s->cirrus_blt_dstpitch,
             s->cirrus_blt_width, s->cirrus_blt_height);
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
@@ -747,7 +783,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)

static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
{
    return cirrus_bitblt_common_patterncopy(s, true);
    return cirrus_bitblt_common_patterncopy(s);
}

static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
@@ -796,19 +832,13 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
        }
    }

    /* we have to flush all pending changes so that the copy
       is generated at the appropriate moment in time */
    if (notify)
        graphic_hw_update(s->vga.con);

    (*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
                      s->vga.vram_ptr + s->cirrus_blt_srcaddr,
    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
                      s->cirrus_blt_srcaddr,
		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
		      s->cirrus_blt_width, s->cirrus_blt_height);

    if (notify) {
        qemu_console_copy(s->vga.con,
			  sx, sy, dx, dy,
        dpy_gfx_update(s->vga.con, dx, dy,
                       s->cirrus_blt_width / depth,
                       s->cirrus_blt_height);
    }
@@ -846,15 +876,15 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)

    if (s->cirrus_srccounter > 0) {
        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
            cirrus_bitblt_common_patterncopy(s, false);
            cirrus_bitblt_common_patterncopy(s);
        the_end:
            s->cirrus_srccounter = 0;
            cirrus_bitblt_reset(s);
        } else {
            /* at least one scan line */
            do {
                (*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
                (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr,
                                 0, 0, 0, s->cirrus_blt_width, 1);
                cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
                                         s->cirrus_blt_width, 1);
                s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
@@ -966,6 +996,10 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
{
    uint8_t blt_rop;

    if (!s->enable_blitter) {
        goto bitblt_ignore;
    }

    s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;

    s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
@@ -3029,7 +3063,9 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)

static Property isa_cirrus_vga_properties[] = {
    DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState,
                       cirrus_vga.vga.vram_size_mb, 8),
                       cirrus_vga.vga.vram_size_mb, 4),
    DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState,
                       cirrus_vga.enable_blitter, true),
    DEFINE_PROP_END_OF_LIST(),
};

@@ -3098,7 +3134,9 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)

static Property pci_vga_cirrus_properties[] = {
    DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
                       cirrus_vga.vga.vram_size_mb, 8),
                       cirrus_vga.vga.vram_size_mb, 4),
    DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState,
                     cirrus_vga.enable_blitter, true),
    DEFINE_PROP_END_OF_LIST(),
};

+115 −76
Original line number Diff line number Diff line
@@ -22,29 +22,63 @@
 * THE SOFTWARE.
 */

static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src)
static inline void glue(rop_8_, ROP_NAME)(CirrusVGAState *s,
                                          uint32_t dstaddr, uint8_t src)
{
    uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
    *dst = ROP_FN(*dst, src);
}

static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src)
static inline void glue(rop_tr_8_, ROP_NAME)(CirrusVGAState *s,
                                             uint32_t dstaddr, uint8_t src,
                                             uint8_t transp)
{
    uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
    uint8_t pixel = ROP_FN(*dst, src);
    if (pixel != transp) {
        *dst = pixel;
    }
}

static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s,
                                           uint32_t dstaddr, uint16_t src)
{
    uint16_t *dst = (uint16_t *)
        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
    *dst = ROP_FN(*dst, src);
}

static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
static inline void glue(rop_tr_16_, ROP_NAME)(CirrusVGAState *s,
                                              uint32_t dstaddr, uint16_t src,
                                              uint16_t transp)
{
    uint16_t *dst = (uint16_t *)
        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
    uint16_t pixel = ROP_FN(*dst, src);
    if (pixel != transp) {
        *dst = pixel;
    }
}

static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s,
                                           uint32_t dstaddr, uint32_t src)
{
    uint32_t *dst = (uint32_t *)
        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]);
    *dst = ROP_FN(*dst, src);
}

#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s)
#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s)
#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s)
#define ROP_OP(st, d, s)           glue(rop_8_, ROP_NAME)(st, d, s)
#define ROP_OP_TR(st, d, s, t)     glue(rop_tr_8_, ROP_NAME)(st, d, s, t)
#define ROP_OP_16(st, d, s)        glue(rop_16_, ROP_NAME)(st, d, s)
#define ROP_OP_TR_16(st, d, s, t)  glue(rop_tr_16_, ROP_NAME)(st, d, s, t)
#define ROP_OP_32(st, d, s)        glue(rop_32_, ROP_NAME)(st, d, s)
#undef ROP_FN

static void
glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
                             uint8_t *dst,const uint8_t *src,
                                       uint32_t dstaddr,
                                       uint32_t srcaddr,
                                       int dstpitch, int srcpitch,
                                       int bltwidth, int bltheight)
{
@@ -58,18 +92,19 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,

    for (y = 0; y < bltheight; y++) {
        for (x = 0; x < bltwidth; x++) {
            ROP_OP(dst, *src);
            dst++;
            src++;
            ROP_OP(s, dstaddr, cirrus_src(s, srcaddr));
            dstaddr++;
            srcaddr++;
        }
        dst += dstpitch;
        src += srcpitch;
        dstaddr += dstpitch;
        srcaddr += srcpitch;
    }
}

static void
glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
                                        uint8_t *dst,const uint8_t *src,
                                        uint32_t dstaddr,
                                        uint32_t srcaddr,
                                        int dstpitch, int srcpitch,
                                        int bltwidth, int bltheight)
{
@@ -78,114 +113,118 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
    srcpitch += bltwidth;
    for (y = 0; y < bltheight; y++) {
        for (x = 0; x < bltwidth; x++) {
            ROP_OP(dst, *src);
            dst--;
            src--;
            ROP_OP(s, dstaddr, cirrus_src(s, srcaddr));
            dstaddr--;
            srcaddr--;
        }
        dst += dstpitch;
        src += srcpitch;
        dstaddr += dstpitch;
        srcaddr += srcpitch;
    }
}

static void
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
						       uint8_t *dst,const uint8_t *src,
						       int dstpitch,int srcpitch,
						       int bltwidth,int bltheight)
                                                       uint32_t dstaddr,
                                                       uint32_t srcaddr,
                                                       int dstpitch,
                                                       int srcpitch,
                                                       int bltwidth,
                                                       int bltheight)
{
    int x,y;
    uint8_t p;
    uint8_t transp = s->vga.gr[0x34];
    dstpitch -= bltwidth;
    srcpitch -= bltwidth;

    if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
        return;
    }

    for (y = 0; y < bltheight; y++) {
        for (x = 0; x < bltwidth; x++) {
	    p = *dst;
            ROP_OP(&p, *src);
	    if (p != s->vga.gr[0x34]) *dst = p;
            dst++;
            src++;
            ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp);
            dstaddr++;
            srcaddr++;
        }
        dst += dstpitch;
        src += srcpitch;
        dstaddr += dstpitch;
        srcaddr += srcpitch;
    }
}

static void
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
							uint8_t *dst,const uint8_t *src,
							int dstpitch,int srcpitch,
							int bltwidth,int bltheight)
                                                        uint32_t dstaddr,
                                                        uint32_t srcaddr,
                                                        int dstpitch,
                                                        int srcpitch,
                                                        int bltwidth,
                                                        int bltheight)
{
    int x,y;
    uint8_t p;
    uint8_t transp = s->vga.gr[0x34];
    dstpitch += bltwidth;
    srcpitch += bltwidth;
    for (y = 0; y < bltheight; y++) {
        for (x = 0; x < bltwidth; x++) {
	    p = *dst;
            ROP_OP(&p, *src);
	    if (p != s->vga.gr[0x34]) *dst = p;
            dst--;
            src--;
            ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp);
            dstaddr--;
            srcaddr--;
        }
        dst += dstpitch;
        src += srcpitch;
        dstaddr += dstpitch;
        srcaddr += srcpitch;
    }
}

static void
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
							uint8_t *dst,const uint8_t *src,
							int dstpitch,int srcpitch,
							int bltwidth,int bltheight)
                                                        uint32_t dstaddr,
                                                        uint32_t srcaddr,
                                                        int dstpitch,
                                                        int srcpitch,
                                                        int bltwidth,
                                                        int bltheight)
{
    int x,y;
    uint8_t p1, p2;
    uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
    dstpitch -= bltwidth;
    srcpitch -= bltwidth;

    if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
        return;
    }

    for (y = 0; y < bltheight; y++) {
        for (x = 0; x < bltwidth; x+=2) {
	    p1 = *dst;
	    p2 = *(dst+1);
            ROP_OP(&p1, *src);
            ROP_OP(&p2, *(src + 1));
	    if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
		*dst = p1;
		*(dst+1) = p2;
	    }
            dst+=2;
            src+=2;
            ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
            dstaddr += 2;
            srcaddr += 2;
        }
        dst += dstpitch;
        src += srcpitch;
        dstaddr += dstpitch;
        srcaddr += srcpitch;
    }
}

static void
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
							 uint8_t *dst,const uint8_t *src,
							 int dstpitch,int srcpitch,
							 int bltwidth,int bltheight)
                                                         uint32_t dstaddr,
                                                         uint32_t srcaddr,
                                                         int dstpitch,
                                                         int srcpitch,
                                                         int bltwidth,
                                                         int bltheight)
{
    int x,y;
    uint8_t p1, p2;
    uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
    dstpitch += bltwidth;
    srcpitch += bltwidth;
    for (y = 0; y < bltheight; y++) {
        for (x = 0; x < bltwidth; x+=2) {
	    p1 = *(dst-1);
	    p2 = *dst;
            ROP_OP(&p1, *(src - 1));
            ROP_OP(&p2, *src);
	    if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
		*(dst-1) = p1;
		*dst = p2;
	    }
            dst-=2;
            src-=2;
        }
        dst += dstpitch;
        src += srcpitch;
            ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
            dstaddr -= 2;
            srcaddr -= 2;
        }
        dstaddr += dstpitch;
        srcaddr += srcpitch;
    }
}

+64 −61
Original line number Diff line number Diff line
@@ -23,30 +23,32 @@
 */

#if DEPTH == 8
#define PUTPIXEL()    ROP_OP(&d[0], col)
#define PUTPIXEL(s, a, c)    ROP_OP(s, a, c)
#elif DEPTH == 16
#define PUTPIXEL()    ROP_OP_16((uint16_t *)&d[0], col)
#define PUTPIXEL(s, a, c)    ROP_OP_16(s, a, c)
#elif DEPTH == 24
#define PUTPIXEL()    ROP_OP(&d[0], col);        \
                      ROP_OP(&d[1], (col >> 8)); \
                      ROP_OP(&d[2], (col >> 16))
#define PUTPIXEL(s, a, c)    do {          \
        ROP_OP(s, a,     c);               \
        ROP_OP(s, a + 1, (col >> 8));      \
        ROP_OP(s, a + 2, (col >> 16));     \
    } while (0)
#elif DEPTH == 32
#define PUTPIXEL()    ROP_OP_32(((uint32_t *)&d[0]), col)
#define PUTPIXEL(s, a, c)    ROP_OP_32(s, a, c)
#else
#error unsupported DEPTH
#endif

static void
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
     (CirrusVGAState * s, uint8_t * dst,
      const uint8_t * src,
     (CirrusVGAState *s, uint32_t dstaddr,
      uint32_t srcaddr,
      int dstpitch, int srcpitch,
      int bltwidth, int bltheight)
{
    uint8_t *d;
    uint32_t addr;
    int x, y, pattern_y, pattern_pitch, pattern_x;
    unsigned int col;
    const uint8_t *src1;
    uint32_t src1addr;
#if DEPTH == 24
    int skipleft = s->vga.gr[0x2f] & 0x1f;
#else
@@ -63,42 +65,44 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
    pattern_y = s->cirrus_blt_srcaddr & 7;
    for(y = 0; y < bltheight; y++) {
        pattern_x = skipleft;
        d = dst + skipleft;
        src1 = src + pattern_y * pattern_pitch;
        addr = dstaddr + skipleft;
        src1addr = srcaddr + pattern_y * pattern_pitch;
        for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
#if DEPTH == 8
            col = src1[pattern_x];
            col = cirrus_src(s, src1addr + pattern_x);
            pattern_x = (pattern_x + 1) & 7;
#elif DEPTH == 16
            col = ((uint16_t *)(src1 + pattern_x))[0];
            col = cirrus_src16(s, src1addr + pattern_x);
            pattern_x = (pattern_x + 2) & 15;
#elif DEPTH == 24
            {
                const uint8_t *src2 = src1 + pattern_x * 3;
                col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
                uint32_t src2addr = src1addr + pattern_x * 3;
                col = cirrus_src(s, src2addr) |
                    (cirrus_src(s, src2addr + 1) << 8) |
                    (cirrus_src(s, src2addr + 2) << 16);
                pattern_x = (pattern_x + 1) & 7;
            }
#else
            col = ((uint32_t *)(src1 + pattern_x))[0];
            col = cirrus_src32(s, src1addr + pattern_x);
            pattern_x = (pattern_x + 4) & 31;
#endif
            PUTPIXEL();
            d += (DEPTH / 8);
            PUTPIXEL(s, addr, col);
            addr += (DEPTH / 8);
        }
        pattern_y = (pattern_y + 1) & 7;
        dst += dstpitch;
        dstaddr += dstpitch;
    }
}

/* NOTE: srcpitch is ignored */
static void
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
     (CirrusVGAState * s, uint8_t * dst,
      const uint8_t * src,
     (CirrusVGAState *s, uint32_t dstaddr,
      uint32_t srcaddr,
      int dstpitch, int srcpitch,
      int bltwidth, int bltheight)
{
    uint8_t *d;
    uint32_t addr;
    int x, y;
    unsigned bits, bits_xor;
    unsigned int col;
@@ -122,33 +126,33 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)

    for(y = 0; y < bltheight; y++) {
        bitmask = 0x80 >> srcskipleft;
        bits = *src++ ^ bits_xor;
        d = dst + dstskipleft;
        bits = cirrus_src(s, srcaddr++) ^ bits_xor;
        addr = dstaddr + dstskipleft;
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
            if ((bitmask & 0xff) == 0) {
                bitmask = 0x80;
                bits = *src++ ^ bits_xor;
                bits = cirrus_src(s, srcaddr++) ^ bits_xor;
            }
            index = (bits & bitmask);
            if (index) {
                PUTPIXEL();
                PUTPIXEL(s, addr, col);
            }
            d += (DEPTH / 8);
            addr += (DEPTH / 8);
            bitmask >>= 1;
        }
        dst += dstpitch;
        dstaddr += dstpitch;
    }
}

static void
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
     (CirrusVGAState * s, uint8_t * dst,
      const uint8_t * src,
     (CirrusVGAState *s, uint32_t dstaddr,
      uint32_t srcaddr,
      int dstpitch, int srcpitch,
      int bltwidth, int bltheight)
{
    uint32_t colors[2];
    uint8_t *d;
    uint32_t addr;
    int x, y;
    unsigned bits;
    unsigned int col;
@@ -160,30 +164,30 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
    colors[1] = s->cirrus_blt_fgcol;
    for(y = 0; y < bltheight; y++) {
        bitmask = 0x80 >> srcskipleft;
        bits = *src++;
        d = dst + dstskipleft;
        bits = cirrus_src(s, srcaddr++);
        addr = dstaddr + dstskipleft;
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
            if ((bitmask & 0xff) == 0) {
                bitmask = 0x80;
                bits = *src++;
                bits = cirrus_src(s, srcaddr++);
            }
            col = colors[!!(bits & bitmask)];
            PUTPIXEL();
            d += (DEPTH / 8);
            PUTPIXEL(s, addr, col);
            addr += (DEPTH / 8);
            bitmask >>= 1;
        }
        dst += dstpitch;
        dstaddr += dstpitch;
    }
}

static void
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
     (CirrusVGAState * s, uint8_t * dst,
      const uint8_t * src,
     (CirrusVGAState *s, uint32_t dstaddr,
      uint32_t srcaddr,
      int dstpitch, int srcpitch,
      int bltwidth, int bltheight)
{
    uint8_t *d;
    uint32_t addr;
    int x, y, bitpos, pattern_y;
    unsigned int bits, bits_xor;
    unsigned int col;
@@ -205,30 +209,30 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
    pattern_y = s->cirrus_blt_srcaddr & 7;

    for(y = 0; y < bltheight; y++) {
        bits = src[pattern_y] ^ bits_xor;
        bits = cirrus_src(s, srcaddr + pattern_y) ^ bits_xor;
        bitpos = 7 - srcskipleft;
        d = dst + dstskipleft;
        addr = dstaddr + dstskipleft;
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
            if ((bits >> bitpos) & 1) {
                PUTPIXEL();
                PUTPIXEL(s, addr, col);
            }
            d += (DEPTH / 8);
            addr += (DEPTH / 8);
            bitpos = (bitpos - 1) & 7;
        }
        pattern_y = (pattern_y + 1) & 7;
        dst += dstpitch;
        dstaddr += dstpitch;
    }
}

static void
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
     (CirrusVGAState * s, uint8_t * dst,
      const uint8_t * src,
     (CirrusVGAState *s, uint32_t dstaddr,
      uint32_t srcaddr,
      int dstpitch, int srcpitch,
      int bltwidth, int bltheight)
{
    uint32_t colors[2];
    uint8_t *d;
    uint32_t addr;
    int x, y, bitpos, pattern_y;
    unsigned int bits;
    unsigned int col;
@@ -240,40 +244,39 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
    pattern_y = s->cirrus_blt_srcaddr & 7;

    for(y = 0; y < bltheight; y++) {
        bits = src[pattern_y];
        bits = cirrus_src(s, srcaddr + pattern_y);
        bitpos = 7 - srcskipleft;
        d = dst + dstskipleft;
        addr = dstaddr + dstskipleft;
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
            col = colors[(bits >> bitpos) & 1];
            PUTPIXEL();
            d += (DEPTH / 8);
            PUTPIXEL(s, addr, col);
            addr += (DEPTH / 8);
            bitpos = (bitpos - 1) & 7;
        }
        pattern_y = (pattern_y + 1) & 7;
        dst += dstpitch;
        dstaddr += dstpitch;
    }
}

static void
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
     (CirrusVGAState *s,
      uint8_t *dst, int dst_pitch,
      uint32_t dstaddr, int dst_pitch,
      int width, int height)
{
    uint8_t *d, *d1;
    uint32_t addr;
    uint32_t col;
    int x, y;

    col = s->cirrus_blt_fgcol;

    d1 = dst;
    for(y = 0; y < height; y++) {
        d = d1;
        addr = dstaddr;
        for(x = 0; x < width; x += (DEPTH / 8)) {
            PUTPIXEL();
            d += (DEPTH / 8);
            PUTPIXEL(s, addr, col);
            addr += (DEPTH / 8);
        }
        d1 += dst_pitch;
        dstaddr += dst_pitch;
    }
}

+8 −0
Original line number Diff line number Diff line
@@ -34,6 +34,14 @@
        .driver   = "virtio-pci",\
        .property = "x-pcie-pm-init",\
        .value    = "off",\
    },{\
        .driver   = "cirrus-vga",\
        .property = "vgamem_mb",\
        .value    = "8",\
    },{\
        .driver   = "isa-cirrus-vga",\
        .property = "vgamem_mb",\
        .value    = "8",\
    },

#define HW_COMPAT_2_7 \
+0 −7

File changed.

Preview size limit exceeded, changes collapsed.

Loading