@@ -92,6 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
92
92
switch (s -> regs .dp_mix & GMC_ROP3_MASK ) {
93
93
case ROP3_SRCCOPY :
94
94
{
95
+ bool fallback = false;
95
96
unsigned src_x = (s -> regs .dp_cntl & DST_X_LEFT_TO_RIGHT ?
96
97
s -> regs .src_x : s -> regs .src_x + 1 - s -> regs .dst_width );
97
98
unsigned src_y = (s -> regs .dp_cntl & DST_Y_TOP_TO_BOTTOM ?
@@ -122,27 +123,50 @@ void ati_2d_blt(ATIVGAState *s)
122
123
src_bits , dst_bits , src_stride , dst_stride , bpp , bpp ,
123
124
src_x , src_y , dst_x , dst_y ,
124
125
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 &&
126
128
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 )) {
132
134
/* FIXME: We only really need a temporary if src and dst overlap */
133
135
int llb = s -> regs .dst_width * (bpp / 8 );
134
136
int tmp_stride = DIV_ROUND_UP (llb , sizeof (uint32_t ));
135
137
uint32_t * tmp = g_malloc (tmp_stride * sizeof (uint32_t ) *
136
138
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
+ }
145
149
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
+ }
146
170
}
147
171
if (dst_bits >= s -> vga .vram_ptr + s -> vga .vbe_start_addr &&
148
172
dst_bits < s -> vga .vram_ptr + s -> vga .vbe_start_addr +
@@ -180,14 +204,21 @@ void ati_2d_blt(ATIVGAState *s)
180
204
181
205
dst_stride /= sizeof (uint32_t );
182
206
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
+ }
191
222
if (dst_bits >= s -> vga .vram_ptr + s -> vga .vbe_start_addr &&
192
223
dst_bits < s -> vga .vram_ptr + s -> vga .vbe_start_addr +
193
224
s -> vga .vbe_regs [VBE_DISPI_INDEX_YRES ] * s -> vga .vbe_line_offset ) {
0 commit comments