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 | 31 | |
| 32 | 32 | /* |
| 33 | 33 | * TODO: |
| 34 | - * - fix 24 bpp pattern fills (source is 32 bpp in that case) | |
| 35 | 34 | * - add support for WRITEMASK (GR2F) |
| 36 | - * - add support for scanline modulo in pattern fill | |
| 37 | 35 | * - optimize linear mappings |
| 38 | 36 | * - optimize bitblt functions |
| 39 | 37 | */ |
| ... | ... | @@ -420,6 +418,25 @@ static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { |
| 420 | 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 | 440 | static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { |
| 424 | 441 | ROP2(cirrus_colorexpand_transp_0), |
| 425 | 442 | ROP2(cirrus_colorexpand_transp_src_and_dst), |
| ... | ... | @@ -569,9 +586,6 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, |
| 569 | 586 | { |
| 570 | 587 | uint8_t work_colorexp[256]; |
| 571 | 588 | uint8_t *dst; |
| 572 | - uint8_t *dstc; | |
| 573 | - int x, y; | |
| 574 | - int tilewidth, tileheight; | |
| 575 | 589 | int patternbytes = s->cirrus_blt_pixelwidth * 8; |
| 576 | 590 | |
| 577 | 591 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { |
| ... | ... | @@ -592,21 +606,12 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, |
| 592 | 606 | } |
| 593 | 607 | |
| 594 | 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 | 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 | 615 | return 1; |
| 611 | 616 | } |
| 612 | 617 | |
| ... | ... | @@ -636,8 +641,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) |
| 636 | 641 | static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) |
| 637 | 642 | { |
| 638 | 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 | 648 | static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) |
| ... | ... | @@ -855,6 +860,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s) |
| 855 | 860 | cirrus_bitblt_bgcol(s); |
| 856 | 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 | 865 | } else { |
| 859 | 866 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { |
| 860 | 867 | s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; | ... | ... |
hw/cirrus_vga_rop2.h
| ... | ... | @@ -36,6 +36,49 @@ |
| 36 | 36 | #error unsupported DEPTH |
| 37 | 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 | 82 | /* NOTE: srcpitch is ignored */ |
| 40 | 83 | static void |
| 41 | 84 | glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) | ... | ... |