Commit b30d4608dae994cf57cab4824f3307de026fd373
1 parent
81ca7991
24 bpp fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@984 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
129 additions
and
69 deletions
hw/cirrus_vga.c
... | ... | @@ -456,25 +456,6 @@ static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { |
456 | 456 | ROP2(cirrus_colorexpand_transp_notsrc_and_notdst), |
457 | 457 | }; |
458 | 458 | |
459 | -static const cirrus_bitblt_rop_t cirrus_colorexpand_transp_inv[16][4] = { | |
460 | - ROP2(cirrus_colorexpand_transp_inv_0), | |
461 | - ROP2(cirrus_colorexpand_transp_inv_src_and_dst), | |
462 | - ROP_NOP2(cirrus_bitblt_rop_nop), | |
463 | - ROP2(cirrus_colorexpand_transp_inv_src_and_notdst), | |
464 | - ROP2(cirrus_colorexpand_transp_inv_notdst), | |
465 | - ROP2(cirrus_colorexpand_transp_inv_src), | |
466 | - ROP2(cirrus_colorexpand_transp_inv_1), | |
467 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_and_dst), | |
468 | - ROP2(cirrus_colorexpand_transp_inv_src_xor_dst), | |
469 | - ROP2(cirrus_colorexpand_transp_inv_src_or_dst), | |
470 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_or_notdst), | |
471 | - ROP2(cirrus_colorexpand_transp_inv_src_notxor_dst), | |
472 | - ROP2(cirrus_colorexpand_transp_inv_src_or_notdst), | |
473 | - ROP2(cirrus_colorexpand_transp_inv_notsrc), | |
474 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_or_dst), | |
475 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_and_notdst), | |
476 | -}; | |
477 | - | |
478 | 459 | static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { |
479 | 460 | ROP2(cirrus_colorexpand_0), |
480 | 461 | ROP2(cirrus_colorexpand_src_and_dst), |
... | ... | @@ -494,6 +475,44 @@ static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { |
494 | 475 | ROP2(cirrus_colorexpand_notsrc_and_notdst), |
495 | 476 | }; |
496 | 477 | |
478 | +static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = { | |
479 | + ROP2(cirrus_colorexpand_pattern_transp_0), | |
480 | + ROP2(cirrus_colorexpand_pattern_transp_src_and_dst), | |
481 | + ROP_NOP2(cirrus_bitblt_rop_nop), | |
482 | + ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst), | |
483 | + ROP2(cirrus_colorexpand_pattern_transp_notdst), | |
484 | + ROP2(cirrus_colorexpand_pattern_transp_src), | |
485 | + ROP2(cirrus_colorexpand_pattern_transp_1), | |
486 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst), | |
487 | + ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst), | |
488 | + ROP2(cirrus_colorexpand_pattern_transp_src_or_dst), | |
489 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst), | |
490 | + ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst), | |
491 | + ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst), | |
492 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc), | |
493 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst), | |
494 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst), | |
495 | +}; | |
496 | + | |
497 | +static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = { | |
498 | + ROP2(cirrus_colorexpand_pattern_0), | |
499 | + ROP2(cirrus_colorexpand_pattern_src_and_dst), | |
500 | + ROP_NOP2(cirrus_bitblt_rop_nop), | |
501 | + ROP2(cirrus_colorexpand_pattern_src_and_notdst), | |
502 | + ROP2(cirrus_colorexpand_pattern_notdst), | |
503 | + ROP2(cirrus_colorexpand_pattern_src), | |
504 | + ROP2(cirrus_colorexpand_pattern_1), | |
505 | + ROP2(cirrus_colorexpand_pattern_notsrc_and_dst), | |
506 | + ROP2(cirrus_colorexpand_pattern_src_xor_dst), | |
507 | + ROP2(cirrus_colorexpand_pattern_src_or_dst), | |
508 | + ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst), | |
509 | + ROP2(cirrus_colorexpand_pattern_src_notxor_dst), | |
510 | + ROP2(cirrus_colorexpand_pattern_src_or_notdst), | |
511 | + ROP2(cirrus_colorexpand_pattern_notsrc), | |
512 | + ROP2(cirrus_colorexpand_pattern_notsrc_or_dst), | |
513 | + ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst), | |
514 | +}; | |
515 | + | |
497 | 516 | static const cirrus_fill_t cirrus_fill[16][4] = { |
498 | 517 | ROP2(cirrus_fill_0), |
499 | 518 | ROP2(cirrus_fill_src_and_dst), |
... | ... | @@ -584,27 +603,8 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, |
584 | 603 | static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, |
585 | 604 | const uint8_t * src) |
586 | 605 | { |
587 | - uint8_t work_colorexp[256]; | |
588 | 606 | uint8_t *dst; |
589 | - int patternbytes = s->cirrus_blt_pixelwidth * 8; | |
590 | 607 | |
591 | - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { | |
592 | - cirrus_bitblt_rop_t rop_func; | |
593 | - cirrus_bitblt_fgcol(s); | |
594 | - cirrus_bitblt_bgcol(s); | |
595 | - rop_func = cirrus_colorexpand[CIRRUS_ROP_SRC_INDEX][s->cirrus_blt_pixelwidth - 1]; | |
596 | - rop_func(s, work_colorexp, src, patternbytes, 1, patternbytes, 8); | |
597 | - src = work_colorexp; | |
598 | - s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_COLOREXPAND; | |
599 | - } | |
600 | - if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_PATTERNCOPY) { | |
601 | -#ifdef DEBUG_BITBLT | |
602 | - printf("cirrus: blt mode %02x (pattercopy) - unimplemented\n", | |
603 | - s->cirrus_blt_mode); | |
604 | -#endif | |
605 | - return 0; | |
606 | - } | |
607 | - | |
608 | 608 | dst = s->vram_ptr + s->cirrus_blt_dstaddr; |
609 | 609 | (*s->cirrus_rop) (s, dst, src, |
610 | 610 | s->cirrus_blt_dstpitch, 0, |
... | ... | @@ -728,6 +728,7 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) |
728 | 728 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { |
729 | 729 | s->cirrus_blt_srcpitch = 8; |
730 | 730 | } else { |
731 | + /* XXX: check for 24 bpp */ | |
731 | 732 | s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; |
732 | 733 | } |
733 | 734 | s->cirrus_srccounter = s->cirrus_blt_srcpitch; |
... | ... | @@ -848,20 +849,32 @@ static void cirrus_bitblt_start(CirrusVGAState * s) |
848 | 849 | CIRRUS_BLTMODE_COLOREXPAND) { |
849 | 850 | |
850 | 851 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { |
851 | - if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
852 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) | |
852 | 853 | cirrus_bitblt_bgcol(s); |
853 | - s->cirrus_rop = cirrus_colorexpand_transp_inv[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
854 | - } else { | |
854 | + else | |
855 | 855 | cirrus_bitblt_fgcol(s); |
856 | - s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
857 | - } | |
856 | + s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
858 | 857 | } else { |
859 | 858 | cirrus_bitblt_fgcol(s); |
860 | 859 | cirrus_bitblt_bgcol(s); |
861 | 860 | s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; |
862 | 861 | } |
863 | 862 | } 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]; | |
863 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { | |
864 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { | |
865 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) | |
866 | + cirrus_bitblt_bgcol(s); | |
867 | + else | |
868 | + cirrus_bitblt_fgcol(s); | |
869 | + s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
870 | + } else { | |
871 | + cirrus_bitblt_fgcol(s); | |
872 | + cirrus_bitblt_bgcol(s); | |
873 | + s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
874 | + } | |
875 | + } else { | |
876 | + s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
877 | + } | |
865 | 878 | } else { |
866 | 879 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { |
867 | 880 | s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; |
... | ... | @@ -2793,9 +2806,10 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) |
2793 | 2806 | vga_io_memory); |
2794 | 2807 | |
2795 | 2808 | s->sr[0x06] = 0x0f; |
2796 | - s->sr[0x1F] = 0x22; // MemClock | |
2797 | 2809 | if (device_id == CIRRUS_ID_CLGD5446) { |
2798 | 2810 | /* 4MB 64 bit memory config, always PCI */ |
2811 | + s->sr[0x1F] = 0x2d; // MemClock | |
2812 | + s->gr[0x18] = 0x0f; // fastest memory configuration | |
2799 | 2813 | #if 1 |
2800 | 2814 | s->sr[0x0f] = 0x98; |
2801 | 2815 | s->sr[0x17] = 0x20; |
... | ... | @@ -2808,6 +2822,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) |
2808 | 2822 | s->real_vram_size = 2048 * 1024; |
2809 | 2823 | #endif |
2810 | 2824 | } else { |
2825 | + s->sr[0x1F] = 0x22; // MemClock | |
2811 | 2826 | s->sr[0x0F] = CIRRUS_MEMSIZE_2M; |
2812 | 2827 | if (is_pci) |
2813 | 2828 | s->sr[0x17] = CIRRUS_BUSTYPE_PCI; | ... | ... |
hw/cirrus_vga_rop2.h
... | ... | @@ -67,6 +67,12 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) |
67 | 67 | #elif DEPTH == 16 |
68 | 68 | col = ((uint16_t *)(src1 + pattern_x))[0]; |
69 | 69 | pattern_x = (pattern_x + 2) & 15; |
70 | +#elif DEPTH == 24 | |
71 | + { | |
72 | + const uint8_t *src2 = src1 + pattern_x * 3; | |
73 | + col = src2[0] | (src2[1] << 8) | (src2[2] << 16); | |
74 | + pattern_x = (pattern_x + 1) & 7; | |
75 | + } | |
70 | 76 | #else |
71 | 77 | col = ((uint32_t *)(src1 + pattern_x))[0]; |
72 | 78 | pattern_x = (pattern_x + 4) & 31; |
... | ... | @@ -89,21 +95,28 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) |
89 | 95 | { |
90 | 96 | uint8_t *d; |
91 | 97 | int x, y; |
92 | - unsigned bits; | |
98 | + unsigned bits, bits_xor; | |
93 | 99 | unsigned int col; |
94 | 100 | unsigned bitmask; |
95 | 101 | unsigned index; |
96 | 102 | int srcskipleft = 0; |
97 | 103 | |
98 | - col = s->cirrus_blt_fgcol; | |
104 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
105 | + bits_xor = 0xff; | |
106 | + col = s->cirrus_blt_bgcol; | |
107 | + } else { | |
108 | + bits_xor = 0x00; | |
109 | + col = s->cirrus_blt_fgcol; | |
110 | + } | |
111 | + | |
99 | 112 | for(y = 0; y < bltheight; y++) { |
100 | 113 | bitmask = 0x80 >> srcskipleft; |
101 | - bits = *src++; | |
114 | + bits = *src++ ^ bits_xor; | |
102 | 115 | d = dst; |
103 | 116 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { |
104 | 117 | if ((bitmask & 0xff) == 0) { |
105 | 118 | bitmask = 0x80; |
106 | - bits = *src++; | |
119 | + bits = *src++ ^ bits_xor; | |
107 | 120 | } |
108 | 121 | index = (bits & bitmask); |
109 | 122 | if (index) { |
... | ... | @@ -116,23 +129,23 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) |
116 | 129 | } |
117 | 130 | } |
118 | 131 | |
119 | -/* NOTE: srcpitch is ignored */ | |
120 | 132 | static void |
121 | -glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH) | |
133 | +glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) | |
122 | 134 | (CirrusVGAState * s, uint8_t * dst, |
123 | 135 | const uint8_t * src, |
124 | 136 | int dstpitch, int srcpitch, |
125 | 137 | int bltwidth, int bltheight) |
126 | 138 | { |
139 | + uint32_t colors[2]; | |
127 | 140 | uint8_t *d; |
128 | 141 | int x, y; |
129 | 142 | unsigned bits; |
130 | 143 | unsigned int col; |
131 | 144 | unsigned bitmask; |
132 | - unsigned index; | |
133 | 145 | int srcskipleft = 0; |
134 | 146 | |
135 | - col = s->cirrus_blt_bgcol; | |
147 | + colors[0] = s->cirrus_blt_bgcol; | |
148 | + colors[1] = s->cirrus_blt_fgcol; | |
136 | 149 | for(y = 0; y < bltheight; y++) { |
137 | 150 | bitmask = 0x80 >> srcskipleft; |
138 | 151 | bits = *src++; |
... | ... | @@ -142,19 +155,54 @@ glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH) |
142 | 155 | bitmask = 0x80; |
143 | 156 | bits = *src++; |
144 | 157 | } |
145 | - index = (bits & bitmask); | |
146 | - if (!index) { | |
158 | + col = colors[!!(bits & bitmask)]; | |
159 | + PUTPIXEL(); | |
160 | + d += (DEPTH / 8); | |
161 | + bitmask >>= 1; | |
162 | + } | |
163 | + dst += dstpitch; | |
164 | + } | |
165 | +} | |
166 | + | |
167 | +static void | |
168 | +glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) | |
169 | + (CirrusVGAState * s, uint8_t * dst, | |
170 | + const uint8_t * src, | |
171 | + int dstpitch, int srcpitch, | |
172 | + int bltwidth, int bltheight) | |
173 | +{ | |
174 | + uint8_t *d; | |
175 | + int x, y, bitpos, pattern_y; | |
176 | + unsigned int bits, bits_xor; | |
177 | + unsigned int col; | |
178 | + | |
179 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
180 | + bits_xor = 0xff; | |
181 | + col = s->cirrus_blt_bgcol; | |
182 | + } else { | |
183 | + bits_xor = 0x00; | |
184 | + col = s->cirrus_blt_fgcol; | |
185 | + } | |
186 | + pattern_y = s->cirrus_blt_srcaddr & 7; | |
187 | + | |
188 | + for(y = 0; y < bltheight; y++) { | |
189 | + bits = src[pattern_y] ^ bits_xor; | |
190 | + bitpos = 7; | |
191 | + d = dst; | |
192 | + for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | |
193 | + if ((bits >> bitpos) & 1) { | |
147 | 194 | PUTPIXEL(); |
148 | 195 | } |
149 | 196 | d += (DEPTH / 8); |
150 | - bitmask >>= 1; | |
197 | + bitpos = (bitpos - 1) & 7; | |
151 | 198 | } |
199 | + pattern_y = (pattern_y + 1) & 7; | |
152 | 200 | dst += dstpitch; |
153 | 201 | } |
154 | 202 | } |
155 | 203 | |
156 | 204 | static void |
157 | -glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) | |
205 | +glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) | |
158 | 206 | (CirrusVGAState * s, uint8_t * dst, |
159 | 207 | const uint8_t * src, |
160 | 208 | int dstpitch, int srcpitch, |
... | ... | @@ -162,28 +210,25 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) |
162 | 210 | { |
163 | 211 | uint32_t colors[2]; |
164 | 212 | uint8_t *d; |
165 | - int x, y; | |
166 | - unsigned bits; | |
213 | + int x, y, bitpos, pattern_y; | |
214 | + unsigned int bits; | |
167 | 215 | unsigned int col; |
168 | - unsigned bitmask; | |
169 | - int srcskipleft = 0; | |
170 | 216 | |
171 | 217 | colors[0] = s->cirrus_blt_bgcol; |
172 | 218 | colors[1] = s->cirrus_blt_fgcol; |
219 | + pattern_y = s->cirrus_blt_srcaddr & 7; | |
220 | + | |
173 | 221 | for(y = 0; y < bltheight; y++) { |
174 | - bitmask = 0x80 >> srcskipleft; | |
175 | - bits = *src++; | |
222 | + bits = src[pattern_y]; | |
223 | + bitpos = 7; | |
176 | 224 | d = dst; |
177 | 225 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { |
178 | - if ((bitmask & 0xff) == 0) { | |
179 | - bitmask = 0x80; | |
180 | - bits = *src++; | |
181 | - } | |
182 | - col = colors[!!(bits & bitmask)]; | |
226 | + col = colors[(bits >> bitpos) & 1]; | |
183 | 227 | PUTPIXEL(); |
184 | 228 | d += (DEPTH / 8); |
185 | - bitmask >>= 1; | |
229 | + bitpos = (bitpos - 1) & 7; | |
186 | 230 | } |
231 | + pattern_y = (pattern_y + 1) & 7; | |
187 | 232 | dst += dstpitch; |
188 | 233 | } |
189 | 234 | } | ... | ... |