ati-vga: Use local variables for register values in ati_2d_blt
ati_2d_blt uses a mixture of locals and direct register access of needed state. This assigns all values derived from register state to local variables. It prepares the function for a larger refactor that removes the dependency on the full device and direct register access entirely. 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: <2c7f8fdc527e8c5bad237933a1c8a7a8e5068a3d.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
67f074bf24ea0426facb06827a76cac2850757e9
1 file changed
+48
-44
hw/display/ati_2d.c
+48
-44
@@ -66,10 +66,18 @@ void ati_2d_blt(ATIVGAState *s)
66
{
67
/* FIXME it is probably more complex than this and may need to be */
68
/* rewritten but for now as a start just to get some output: */
69
- unsigned dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
70
- s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
71
- unsigned dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
72
- s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
69
+ uint32_t rop3 = s->regs.dp_mix & GMC_ROP3_MASK;
70
+ bool left_to_right = s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT;
71
+ bool top_to_bottom = s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM;
72
+ uint32_t frgd_clr = s->regs.dp_brush_frgd_clr;
73
+ uint8_t *palette = s->vga.palette;
74
+ unsigned dst_offset = s->regs.dst_offset;
75
+ unsigned dst_width = s->regs.dst_width;
76
+ unsigned dst_height = s->regs.dst_height;
77
+ unsigned dst_x = (left_to_right ?
78
+ s->regs.dst_x : s->regs.dst_x + 1 - dst_width);
79
+ unsigned dst_y = (top_to_bottom ?
80
+ s->regs.dst_y : s->regs.dst_y + 1 - dst_height);
81
int bpp = ati_bpp_from_datatype(s);
82
if (!bpp) {
83
qemu_log_mask(LOG_GUEST_ERROR, "Invalid bpp\n");
@@ -80,7 +88,7 @@ void ati_2d_blt(ATIVGAState *s)
88
qemu_log_mask(LOG_GUEST_ERROR, "Zero dest pitch\n");
89
return;
90
}
83
- uint8_t *dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
91
+ uint8_t *dst_bits = s->vga.vram_ptr + dst_offset;
92
93
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
94
dst_bits += s->regs.crtc_offset & 0x07ffffff;
@@ -88,26 +96,25 @@ void ati_2d_blt(ATIVGAState *s)
96
}
97
uint8_t *end = s->vga.vram_ptr + s->vga.vram_size;
98
if (dst_x > 0x3fff || dst_y > 0x3fff || dst_bits >= end
91
- || dst_bits + dst_x
92
- + (dst_y + s->regs.dst_height) * dst_stride >= end) {
99
+ || dst_bits + dst_x + (dst_y + dst_height) * dst_stride >= end) {
100
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
101
return;
102
}
103
DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n",
97
- s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset,
98
- s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch,
104
+ s->regs.src_offset, dst_offset, s->regs.default_offset,
105
+ s->regs.src_pitch, dst_stride, s->regs.default_pitch,
106
s->regs.src_x, s->regs.src_y, dst_x, dst_y,
100
- s->regs.dst_width, s->regs.dst_height,
101
- (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? '>' : '<'),
102
- (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? 'v' : '^'));
103
- switch (s->regs.dp_mix & GMC_ROP3_MASK) {
107
+ dst_width, dst_height,
108
+ (left_to_right ? '>' : '<'),
109
+ (top_to_bottom ? 'v' : '^'));
110
+ switch (rop3) {
111
case ROP3_SRCCOPY:
112
{
113
bool fallback = false;
107
- unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
108
- s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
109
- unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
110
- s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
114
+ unsigned src_x = (left_to_right ?
115
+ s->regs.src_x : s->regs.src_x + 1 - dst_width);
116
+ unsigned src_y = (top_to_bottom ?
117
+ s->regs.src_y : s->regs.src_y + 1 - dst_height);
118
int src_stride = s->regs.src_pitch;
119
if (!src_stride) {
120
qemu_log_mask(LOG_GUEST_ERROR, "Zero source pitch\n");
@@ -121,7 +128,7 @@ void ati_2d_blt(ATIVGAState *s)
128
}
129
if (src_x > 0x3fff || src_y > 0x3fff || src_bits >= end
130
|| src_bits + src_x
124
- + (src_y + s->regs.dst_height) * src_stride >= end) {
131
+ + (src_y + dst_height) * src_stride >= end) {
132
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
133
return;
134
}
@@ -129,32 +136,30 @@ void ati_2d_blt(ATIVGAState *s)
136
DPRINTF("pixman_blt(%p, %p, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d)\n",
137
src_bits, dst_bits, src_stride / sizeof(uint32_t),
138
dst_stride / sizeof(uint32_t), bpp, bpp, src_x, src_y, dst_x,
132
- dst_y, s->regs.dst_width, s->regs.dst_height);
139
+ dst_y, dst_width, dst_height);
140
#ifdef CONFIG_PIXMAN
141
int src_stride_words = src_stride / sizeof(uint32_t);
142
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) {
143
+ if ((s->use_pixman & BIT(1)) && left_to_right && top_to_bottom) {
144
fallback = !pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
145
src_stride_words, dst_stride_words, bpp, bpp,
146
src_x, src_y, dst_x, dst_y,
142
- s->regs.dst_width, s->regs.dst_height);
147
+ dst_width, dst_height);
148
} else if (s->use_pixman & BIT(1)) {
149
/* FIXME: We only really need a temporary if src and dst overlap */
145
- int llb = s->regs.dst_width * (bpp / 8);
150
+ int llb = dst_width * (bpp / 8);
151
int tmp_stride_words = DIV_ROUND_UP(llb, sizeof(uint32_t));
152
uint32_t *tmp = g_malloc(tmp_stride_words * sizeof(uint32_t) *
148
- s->regs.dst_height);
153
+ dst_height);
154
fallback = !pixman_blt((uint32_t *)src_bits, tmp,
155
src_stride_words, tmp_stride_words, bpp, bpp,
156
src_x, src_y, 0, 0,
152
- s->regs.dst_width, s->regs.dst_height);
157
+ dst_width, dst_height);
158
if (!fallback) {
159
fallback = !pixman_blt(tmp, (uint32_t *)dst_bits,
160
tmp_stride_words, dst_stride_words,
161
bpp, bpp, 0, 0, dst_x, dst_y,
157
- s->regs.dst_width, s->regs.dst_height);
162
+ dst_width, dst_height);
163
}
164
g_free(tmp);
165
} else
@@ -164,17 +169,17 @@ void ati_2d_blt(ATIVGAState *s)
169
}
170
if (fallback) {
171
unsigned int y, i, j, bypp = bpp / 8;
167
- for (y = 0; y < s->regs.dst_height; y++) {
172
+ for (y = 0; y < dst_height; y++) {
173
i = dst_x * bypp;
174
j = src_x * bypp;
170
- if (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
175
+ if (top_to_bottom) {
176
i += (dst_y + y) * dst_stride;
177
j += (src_y + y) * src_stride;
178
} else {
174
- i += (dst_y + s->regs.dst_height - 1 - y) * dst_stride;
175
- j += (src_y + s->regs.dst_height - 1 - y) * src_stride;
179
+ i += (dst_y + dst_height - 1 - y) * dst_stride;
180
+ j += (src_y + dst_height - 1 - y) * src_stride;
181
}
177
- memmove(&dst_bits[i], &src_bits[j], s->regs.dst_width * bypp);
182
+ memmove(&dst_bits[i], &src_bits[j], dst_width * bypp);
183
}
184
}
185
break;
@@ -185,35 +190,34 @@ void ati_2d_blt(ATIVGAState *s)
190
{
191
uint32_t filler = 0;
192
188
- switch (s->regs.dp_mix & GMC_ROP3_MASK) {
193
+ switch (rop3) {
194
case ROP3_PATCOPY:
190
- filler = s->regs.dp_brush_frgd_clr;
195
+ filler = frgd_clr;
196
break;
197
case ROP3_BLACKNESS:
193
- filler = 0xffUL << 24 | rgb_to_pixel32(s->vga.palette[0],
194
- s->vga.palette[1], s->vga.palette[2]);
198
+ filler = 0xffUL << 24 | rgb_to_pixel32(palette[0], palette[1],
199
+ palette[2]);
200
break;
201
case ROP3_WHITENESS:
197
- filler = 0xffUL << 24 | rgb_to_pixel32(s->vga.palette[3],
198
- s->vga.palette[4], s->vga.palette[5]);
202
+ filler = 0xffUL << 24 | rgb_to_pixel32(palette[3], palette[4],
203
+ palette[5]);
204
break;
205
}
206
207
DPRINTF("pixman_fill(%p, %ld, %d, %d, %d, %d, %d, %x)\n",
208
dst_bits, dst_stride / sizeof(uint32_t), bpp, dst_x, dst_y,
204
- s->regs.dst_width, s->regs.dst_height, filler);
209
+ dst_width, dst_height, filler);
210
#ifdef CONFIG_PIXMAN
211
if (!(s->use_pixman & BIT(0)) ||
212
!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))
213
+ bpp, dst_x, dst_y, dst_width, dst_height, filler))
214
#endif
215
{
216
/* fallback when pixman failed or we don't want to call it */
217
unsigned int x, y, i, bypp = bpp / 8;
214
- for (y = 0; y < s->regs.dst_height; y++) {
218
+ for (y = 0; y < dst_height; y++) {
219
i = dst_x * bypp + (dst_y + y) * dst_stride;
216
- for (x = 0; x < s->regs.dst_width; x++, i += bypp) {
220
+ for (x = 0; x < dst_width; x++, i += bypp) {
221
stn_he_p(&dst_bits[i], bypp, filler);
222
}
223
}
@@ -222,7 +226,7 @@ void ati_2d_blt(ATIVGAState *s)
226
}
227
default:
228
qemu_log_mask(LOG_UNIMP, "Unimplemented ati_2d blt op %x\n",
225
- (s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
229
+ rop3 >> 16);
230
return;
231
}
232