@@ -92,6 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
9292 switch (s -> regs .dp_mix & GMC_ROP3_MASK ) {
9393 case ROP3_SRCCOPY :
9494 {
95+ bool fallback = false;
9596 unsigned src_x = (s -> regs .dp_cntl & DST_X_LEFT_TO_RIGHT ?
9697 s -> regs .src_x : s -> regs .src_x + 1 - s -> regs .dst_width );
9798 unsigned src_y = (s -> regs .dp_cntl & DST_Y_TOP_TO_BOTTOM ?
@@ -122,27 +123,50 @@ void ati_2d_blt(ATIVGAState *s)
122123 src_bits , dst_bits , src_stride , dst_stride , bpp , bpp ,
123124 src_x , src_y , dst_x , dst_y ,
124125 s -> regs .dst_width , s -> regs .dst_height );
125- if (s -> regs .dp_cntl & DST_X_LEFT_TO_RIGHT &&
126+ if ((s -> use_pixman & BIT (1 )) &&
127+ s -> regs .dp_cntl & DST_X_LEFT_TO_RIGHT &&
126128 s -> regs .dp_cntl & DST_Y_TOP_TO_BOTTOM ) {
127- pixman_blt ((uint32_t * )src_bits , (uint32_t * )dst_bits ,
128- src_stride , dst_stride , bpp , bpp ,
129- src_x , src_y , dst_x , dst_y ,
130- s -> regs .dst_width , s -> regs .dst_height );
131- } else {
129+ fallback = ! pixman_blt ((uint32_t * )src_bits , (uint32_t * )dst_bits ,
130+ src_stride , dst_stride , bpp , bpp ,
131+ src_x , src_y , dst_x , dst_y ,
132+ s -> regs .dst_width , s -> regs .dst_height );
133+ } else if ( s -> use_pixman & BIT ( 1 )) {
132134 /* FIXME: We only really need a temporary if src and dst overlap */
133135 int llb = s -> regs .dst_width * (bpp / 8 );
134136 int tmp_stride = DIV_ROUND_UP (llb , sizeof (uint32_t ));
135137 uint32_t * tmp = g_malloc (tmp_stride * sizeof (uint32_t ) *
136138 s -> regs .dst_height );
137- pixman_blt ((uint32_t * )src_bits , tmp ,
138- src_stride , tmp_stride , bpp , bpp ,
139- src_x , src_y , 0 , 0 ,
140- s -> regs .dst_width , s -> regs .dst_height );
141- pixman_blt (tmp , (uint32_t * )dst_bits ,
142- tmp_stride , dst_stride , bpp , bpp ,
143- 0 , 0 , dst_x , dst_y ,
144- s -> regs .dst_width , s -> regs .dst_height );
139+ fallback = !pixman_blt ((uint32_t * )src_bits , tmp ,
140+ src_stride , tmp_stride , bpp , bpp ,
141+ src_x , src_y , 0 , 0 ,
142+ s -> regs .dst_width , s -> regs .dst_height );
143+ if (!fallback ) {
144+ fallback = !pixman_blt (tmp , (uint32_t * )dst_bits ,
145+ tmp_stride , dst_stride , bpp , bpp ,
146+ 0 , 0 , dst_x , dst_y ,
147+ s -> regs .dst_width , s -> regs .dst_height );
148+ }
145149 g_free (tmp );
150+ } else {
151+ fallback = true;
152+ }
153+ if (fallback ) {
154+ unsigned int y , i , j , bypp = bpp / 8 ;
155+ unsigned int src_pitch = src_stride * sizeof (uint32_t );
156+ unsigned int dst_pitch = dst_stride * sizeof (uint32_t );
157+
158+ for (y = 0 ; y < s -> regs .dst_height ; y ++ ) {
159+ i = dst_x * bypp ;
160+ j = src_x * bypp ;
161+ if (s -> regs .dp_cntl & DST_Y_TOP_TO_BOTTOM ) {
162+ i += (dst_y + y ) * dst_pitch ;
163+ j += (src_y + y ) * src_pitch ;
164+ } else {
165+ i += (dst_y + s -> regs .dst_height - 1 - y ) * dst_pitch ;
166+ j += (src_y + s -> regs .dst_height - 1 - y ) * src_pitch ;
167+ }
168+ memmove (& dst_bits [i ], & src_bits [j ], s -> regs .dst_width * bypp );
169+ }
146170 }
147171 if (dst_bits >= s -> vga .vram_ptr + s -> vga .vbe_start_addr &&
148172 dst_bits < s -> vga .vram_ptr + s -> vga .vbe_start_addr +
@@ -180,14 +204,21 @@ void ati_2d_blt(ATIVGAState *s)
180204
181205 dst_stride /= sizeof (uint32_t );
182206 DPRINTF ("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n" ,
183- dst_bits , dst_stride , bpp ,
184- dst_x , dst_y ,
185- s -> regs .dst_width , s -> regs .dst_height ,
186- filler );
187- pixman_fill ((uint32_t * )dst_bits , dst_stride , bpp ,
188- dst_x , dst_y ,
189- s -> regs .dst_width , s -> regs .dst_height ,
190- filler );
207+ dst_bits , dst_stride , bpp , dst_x , dst_y ,
208+ s -> regs .dst_width , s -> regs .dst_height , filler );
209+ if (!(s -> use_pixman & BIT (0 )) ||
210+ !pixman_fill ((uint32_t * )dst_bits , dst_stride , bpp , dst_x , dst_y ,
211+ s -> regs .dst_width , s -> regs .dst_height , filler )) {
212+ /* fallback when pixman failed or we don't want to call it */
213+ unsigned int x , y , i , bypp = bpp / 8 ;
214+ unsigned int dst_pitch = dst_stride * sizeof (uint32_t );
215+ for (y = 0 ; y < s -> regs .dst_height ; y ++ ) {
216+ i = dst_x * bypp + (dst_y + y ) * dst_pitch ;
217+ for (x = 0 ; x < s -> regs .dst_width ; x ++ , i += bypp ) {
218+ stn_he_p (& dst_bits [i ], bypp , filler );
219+ }
220+ }
221+ }
191222 if (dst_bits >= s -> vga .vram_ptr + s -> vga .vbe_start_addr &&
192223 dst_bits < s -> vga .vram_ptr + s -> vga .vbe_start_addr +
193224 s -> vga .vbe_regs [VBE_DISPI_INDEX_YRES ] * s -> vga .vbe_line_offset ) {
0 commit comments