Commit e69390cee7c7a0526eac5189fc98a05c0a39ce85
1 parent
7f647cf6
pattern fill fixes and optimization
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@917 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
71 additions
and
21 deletions
hw/cirrus_vga.c
| @@ -31,9 +31,7 @@ | @@ -31,9 +31,7 @@ | ||
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | * TODO: | 33 | * TODO: |
| 34 | - * - fix 24 bpp pattern fills (source is 32 bpp in that case) | ||
| 35 | * - add support for WRITEMASK (GR2F) | 34 | * - add support for WRITEMASK (GR2F) |
| 36 | - * - add support for scanline modulo in pattern fill | ||
| 37 | * - optimize linear mappings | 35 | * - optimize linear mappings |
| 38 | * - optimize bitblt functions | 36 | * - optimize bitblt functions |
| 39 | */ | 37 | */ |
| @@ -420,6 +418,25 @@ static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { | @@ -420,6 +418,25 @@ static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { | ||
| 420 | func,\ | 418 | func,\ |
| 421 | } | 419 | } |
| 422 | 420 | ||
| 421 | +static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = { | ||
| 422 | + ROP2(cirrus_patternfill_0), | ||
| 423 | + ROP2(cirrus_patternfill_src_and_dst), | ||
| 424 | + ROP_NOP2(cirrus_bitblt_rop_nop), | ||
| 425 | + ROP2(cirrus_patternfill_src_and_notdst), | ||
| 426 | + ROP2(cirrus_patternfill_notdst), | ||
| 427 | + ROP2(cirrus_patternfill_src), | ||
| 428 | + ROP2(cirrus_patternfill_1), | ||
| 429 | + ROP2(cirrus_patternfill_notsrc_and_dst), | ||
| 430 | + ROP2(cirrus_patternfill_src_xor_dst), | ||
| 431 | + ROP2(cirrus_patternfill_src_or_dst), | ||
| 432 | + ROP2(cirrus_patternfill_notsrc_or_notdst), | ||
| 433 | + ROP2(cirrus_patternfill_src_notxor_dst), | ||
| 434 | + ROP2(cirrus_patternfill_src_or_notdst), | ||
| 435 | + ROP2(cirrus_patternfill_notsrc), | ||
| 436 | + ROP2(cirrus_patternfill_notsrc_or_dst), | ||
| 437 | + ROP2(cirrus_patternfill_notsrc_and_notdst), | ||
| 438 | +}; | ||
| 439 | + | ||
| 423 | static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { | 440 | static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { |
| 424 | ROP2(cirrus_colorexpand_transp_0), | 441 | ROP2(cirrus_colorexpand_transp_0), |
| 425 | ROP2(cirrus_colorexpand_transp_src_and_dst), | 442 | ROP2(cirrus_colorexpand_transp_src_and_dst), |
| @@ -569,9 +586,6 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, | @@ -569,9 +586,6 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, | ||
| 569 | { | 586 | { |
| 570 | uint8_t work_colorexp[256]; | 587 | uint8_t work_colorexp[256]; |
| 571 | uint8_t *dst; | 588 | uint8_t *dst; |
| 572 | - uint8_t *dstc; | ||
| 573 | - int x, y; | ||
| 574 | - int tilewidth, tileheight; | ||
| 575 | int patternbytes = s->cirrus_blt_pixelwidth * 8; | 589 | int patternbytes = s->cirrus_blt_pixelwidth * 8; |
| 576 | 590 | ||
| 577 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { | 591 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { |
| @@ -592,21 +606,12 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, | @@ -592,21 +606,12 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, | ||
| 592 | } | 606 | } |
| 593 | 607 | ||
| 594 | dst = s->vram_ptr + s->cirrus_blt_dstaddr; | 608 | dst = s->vram_ptr + s->cirrus_blt_dstaddr; |
| 595 | - for (y = 0; y < s->cirrus_blt_height; y += 8) { | ||
| 596 | - dstc = dst; | ||
| 597 | - tileheight = qemu_MIN(8, s->cirrus_blt_height - y); | ||
| 598 | - for (x = 0; x < s->cirrus_blt_width; x += patternbytes) { | ||
| 599 | - tilewidth = qemu_MIN(patternbytes, s->cirrus_blt_width - x); | ||
| 600 | - (*s->cirrus_rop) (s, dstc, src, | ||
| 601 | - s->cirrus_blt_dstpitch, patternbytes, | ||
| 602 | - tilewidth, tileheight); | ||
| 603 | - dstc += patternbytes; | ||
| 604 | - } | ||
| 605 | - dst += s->cirrus_blt_dstpitch * 8; | ||
| 606 | - } | 609 | + (*s->cirrus_rop) (s, dst, src, |
| 610 | + s->cirrus_blt_dstpitch, 0, | ||
| 611 | + s->cirrus_blt_width, s->cirrus_blt_height); | ||
| 607 | cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, | 612 | cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, |
| 608 | - s->cirrus_blt_dstpitch, s->cirrus_blt_width, | ||
| 609 | - s->cirrus_blt_height); | 613 | + s->cirrus_blt_dstpitch, s->cirrus_blt_width, |
| 614 | + s->cirrus_blt_height); | ||
| 610 | return 1; | 615 | return 1; |
| 611 | } | 616 | } |
| 612 | 617 | ||
| @@ -636,8 +641,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) | @@ -636,8 +641,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) | ||
| 636 | static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) | 641 | static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) |
| 637 | { | 642 | { |
| 638 | return cirrus_bitblt_common_patterncopy(s, | 643 | return cirrus_bitblt_common_patterncopy(s, |
| 639 | - s->vram_ptr + | ||
| 640 | - s->cirrus_blt_srcaddr); | 644 | + s->vram_ptr + |
| 645 | + (s->cirrus_blt_srcaddr & ~7)); | ||
| 641 | } | 646 | } |
| 642 | 647 | ||
| 643 | static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) | 648 | static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) |
| @@ -855,6 +860,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s) | @@ -855,6 +860,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s) | ||
| 855 | cirrus_bitblt_bgcol(s); | 860 | cirrus_bitblt_bgcol(s); |
| 856 | s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | 861 | s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; |
| 857 | } | 862 | } |
| 863 | + } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { | ||
| 864 | + s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | ||
| 858 | } else { | 865 | } else { |
| 859 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { | 866 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { |
| 860 | s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; | 867 | s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; |
hw/cirrus_vga_rop2.h
| @@ -36,6 +36,49 @@ | @@ -36,6 +36,49 @@ | ||
| 36 | #error unsupported DEPTH | 36 | #error unsupported DEPTH |
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | +static void | ||
| 40 | +glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) | ||
| 41 | + (CirrusVGAState * s, uint8_t * dst, | ||
| 42 | + const uint8_t * src, | ||
| 43 | + int dstpitch, int srcpitch, | ||
| 44 | + int bltwidth, int bltheight) | ||
| 45 | +{ | ||
| 46 | + uint8_t *d; | ||
| 47 | + int x, y, pattern_y, pattern_pitch, pattern_x; | ||
| 48 | + unsigned int col; | ||
| 49 | + const uint8_t *src1; | ||
| 50 | + | ||
| 51 | +#if DEPTH == 8 | ||
| 52 | + pattern_pitch = 8; | ||
| 53 | +#elif DEPTH == 16 | ||
| 54 | + pattern_pitch = 16; | ||
| 55 | +#else | ||
| 56 | + pattern_pitch = 32; | ||
| 57 | +#endif | ||
| 58 | + pattern_y = s->cirrus_blt_srcaddr & 7; | ||
| 59 | + pattern_x = 0; | ||
| 60 | + for(y = 0; y < bltheight; y++) { | ||
| 61 | + d = dst; | ||
| 62 | + src1 = src + pattern_y * pattern_pitch; | ||
| 63 | + for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | ||
| 64 | +#if DEPTH == 8 | ||
| 65 | + col = src1[pattern_x]; | ||
| 66 | + pattern_x = (pattern_x + 1) & 7; | ||
| 67 | +#elif DEPTH == 16 | ||
| 68 | + col = ((uint16_t *)(src1 + pattern_x))[0]; | ||
| 69 | + pattern_x = (pattern_x + 2) & 15; | ||
| 70 | +#else | ||
| 71 | + col = ((uint32_t *)(src1 + pattern_x))[0]; | ||
| 72 | + pattern_x = (pattern_x + 4) & 31; | ||
| 73 | +#endif | ||
| 74 | + PUTPIXEL(); | ||
| 75 | + d += (DEPTH / 8); | ||
| 76 | + } | ||
| 77 | + pattern_y = (pattern_y + 1) & 7; | ||
| 78 | + dst += dstpitch; | ||
| 79 | + } | ||
| 80 | +} | ||
| 81 | + | ||
| 39 | /* NOTE: srcpitch is ignored */ | 82 | /* NOTE: srcpitch is ignored */ |
| 40 | static void | 83 | static void |
| 41 | glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) | 84 | glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) |