@samitouri / QOSamiQemu / commits / 8239517393

ati-vga: Remove src and dst stride mutation in ati_2d_blt

Pixman requires stride in words. So over the course of the ati_2d_blt function both src and dst stride were mutated before being passed to pixman and then back afterwards. This creates local variables holding src and dst stride in words avoiding the potentially confusing mutation. Signed-off-by: Chad Jablonski <chad@jablonski.xyz> Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu> [balaton: Fix build without pixman] Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Message-ID: <7ab2227b96b73a63cb4fc61d0e6921e01900a4ee.1773020351.git.balaton@eik.bme.hu> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Chad Jablonski committed Mar 9, 2026 at 02:47 UTC 82395173935a15868561e604ffd1d4a60eec4689
1 file changed +22 -26
hw/display/ati_2d.c
+22 -26
@@ -126,34 +126,34 @@ void ati_2d_blt(ATIVGAState *s)
126 return;
127 }
128
129 - src_stride /= sizeof(uint32_t);
130 - dst_stride /= sizeof(uint32_t);
131 - DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
132 - src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
133 - src_x, src_y, dst_x, dst_y,
134 - s->regs.dst_width, s->regs.dst_height);
129 + DPRINTF("pixman_blt(%p, %p, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d)\n",
130 + src_bits, dst_bits, src_stride / sizeof(uint32_t),
131 + dst_stride / sizeof(uint32_t), bpp, bpp, src_x, src_y, dst_x,
132 + dst_y, s->regs.dst_width, s->regs.dst_height);
133 #ifdef CONFIG_PIXMAN
134 + int src_stride_words = src_stride / sizeof(uint32_t);
135 + int dst_stride_words = dst_stride / sizeof(uint32_t);
136 if ((s->use_pixman & BIT(1)) &&
137 s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT &&
138 s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
139 fallback = !pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
140 - src_stride, dst_stride, bpp, bpp,
140 + src_stride_words, dst_stride_words, bpp, bpp,
141 src_x, src_y, dst_x, dst_y,
142 s->regs.dst_width, s->regs.dst_height);
143 } else if (s->use_pixman & BIT(1)) {
144 /* FIXME: We only really need a temporary if src and dst overlap */
145 int llb = s->regs.dst_width * (bpp / 8);
146 - int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
147 - uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) *
146 + int tmp_stride_words = DIV_ROUND_UP(llb, sizeof(uint32_t));
147 + uint32_t *tmp = g_malloc(tmp_stride_words * sizeof(uint32_t) *
148 s->regs.dst_height);
149 fallback = !pixman_blt((uint32_t *)src_bits, tmp,
150 - src_stride, tmp_stride, bpp, bpp,
150 + src_stride_words, tmp_stride_words, bpp, bpp,
151 src_x, src_y, 0, 0,
152 s->regs.dst_width, s->regs.dst_height);
153 if (!fallback) {
154 fallback = !pixman_blt(tmp, (uint32_t *)dst_bits,
155 - tmp_stride, dst_stride, bpp, bpp,
156 - 0, 0, dst_x, dst_y,
155 + tmp_stride_words, dst_stride_words,
156 + bpp, bpp, 0, 0, dst_x, dst_y,
157 s->regs.dst_width, s->regs.dst_height);
158 }
159 g_free(tmp);
@@ -164,18 +164,15 @@ void ati_2d_blt(ATIVGAState *s)
164 }
165 if (fallback) {
166 unsigned int y, i, j, bypp = bpp / 8;
167 - unsigned int src_pitch = src_stride * sizeof(uint32_t);
168 - unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
169 -
167 for (y = 0; y < s->regs.dst_height; y++) {
168 i = dst_x * bypp;
169 j = src_x * bypp;
170 if (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
174 - i += (dst_y + y) * dst_pitch;
175 - j += (src_y + y) * src_pitch;
171 + i += (dst_y + y) * dst_stride;
172 + j += (src_y + y) * src_stride;
173 } else {
177 - i += (dst_y + s->regs.dst_height - 1 - y) * dst_pitch;
178 - j += (src_y + s->regs.dst_height - 1 - y) * src_pitch;
174 + i += (dst_y + s->regs.dst_height - 1 - y) * dst_stride;
175 + j += (src_y + s->regs.dst_height - 1 - y) * src_stride;
176 }
177 memmove(&dst_bits[i], &src_bits[j], s->regs.dst_width * bypp);
178 }
@@ -202,21 +199,20 @@ void ati_2d_blt(ATIVGAState *s)
199 break;
200 }
201
205 - dst_stride /= sizeof(uint32_t);
206 - DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
207 - dst_bits, dst_stride, bpp, dst_x, dst_y,
202 + DPRINTF("pixman_fill(%p, %ld, %d, %d, %d, %d, %d, %x)\n",
203 + dst_bits, dst_stride / sizeof(uint32_t), bpp, dst_x, dst_y,
204 s->regs.dst_width, s->regs.dst_height, filler);
205 #ifdef CONFIG_PIXMAN
206 if (!(s->use_pixman & BIT(0)) ||
211 - !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
212 - s->regs.dst_width, s->regs.dst_height, filler))
207 + !pixman_fill((uint32_t *)dst_bits, dst_stride / sizeof(uint32_t),
208 + bpp, dst_x, dst_y, s->regs.dst_width,
209 + s->regs.dst_height, filler))
210 #endif
211 {
212 /* fallback when pixman failed or we don't want to call it */
213 unsigned int x, y, i, bypp = bpp / 8;
217 - unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
214 for (y = 0; y < s->regs.dst_height; y++) {
219 - i = dst_x * bypp + (dst_y + y) * dst_pitch;
215 + i = dst_x * bypp + (dst_y + y) * dst_stride;
216 for (x = 0; x < s->regs.dst_width; x++, i += bypp) {
217 stn_he_p(&dst_bits[i], bypp, filler);
218 }