psx_gpu: 2x sprite renderer
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu / psx_gpu_4x.c
CommitLineData
05e2e0c6
E
1#define setup_sprite_tiled_initialize_4bpp_4x() \\r
2 u16 *clut_ptr = psx_gpu->clut_ptr; \\r
3 vec_8x16u clut_a, clut_b; \\r
4 vec_16x8u clut_low, clut_high; \\r
5 \\r
6 load_8x16b(clut_a, clut_ptr); \\r
7 load_8x16b(clut_b, clut_ptr + 8); \\r
8 unzip_16x8b(clut_low, clut_high, clut_a, clut_b) \\r
9\r
10\r
11#define setup_sprite_tiled_initialize_8bpp_4x() \\r
12\r
13\r
14#define setup_sprite_tile_fetch_texel_block_8bpp_4x(offset) \\r
15 texture_block_ptr = psx_gpu->texture_page_ptr + \\r
16 ((texture_offset + offset) & texture_mask); \\r
17 \\r
18 load_64b(texels, texture_block_ptr) \\r
19\r
20\r
21#define setup_sprite_tile_setup_block_yes_4x(side, offset, texture_mode) \\r
22\r
23#define setup_sprite_tile_setup_block_no_4x(side, offset, texture_mode) \\r
24\r
25#define setup_sprite_tile_add_blocks_4x(tile_num_blocks) \\r
26 num_blocks += tile_num_blocks * 4; \\r
27 sprite_blocks += tile_num_blocks * 4; \\r
28 \\r
29 if(num_blocks > MAX_BLOCKS) \\r
30 { \\r
31 flush_render_block_buffer(psx_gpu); \\r
32 num_blocks = tile_num_blocks * 4; \\r
33 block = psx_gpu->blocks; \\r
34 } \\r
35\r
36#define setup_sprite_tile_full_4bpp_4x(edge) \\r
37{ \\r
38 vec_8x8u texels_low, texels_high; \\r
39 vec_8x16u pixels, pixels_wide; \\r
40 setup_sprite_tile_add_blocks_4x(sub_tile_height * 2); \\r
41 u32 left_mask_bits_a = left_mask_bits & 0xFF; \\r
42 u32 left_mask_bits_b = left_mask_bits >> 8; \\r
43 u32 right_mask_bits_a = right_mask_bits & 0xFF; \\r
44 u32 right_mask_bits_b = right_mask_bits >> 8; \\r
45 \\r
46 while(sub_tile_height) \\r
47 { \\r
48 setup_sprite_tile_fetch_texel_block_8bpp_4x(0); \\r
49 tbl_16(texels_low, texels, clut_low); \\r
50 tbl_16(texels_high, texels, clut_high); \\r
51 zip_8x16b(pixels, texels_low, texels_high); \\r
52 \\r
53 zip_4x32b(vector_cast(vec_4x32u, pixels_wide), pixels.low, pixels.low); \\r
54 block->texels = pixels_wide; \\r
55 block->draw_mask_bits = left_mask_bits_a; \\r
56 block->fb_ptr = fb_ptr; \\r
57 block++; \\r
58 \\r
59 block->texels = pixels_wide; \\r
60 block->draw_mask_bits = left_mask_bits_a; \\r
61 block->fb_ptr = fb_ptr + 1024; \\r
62 block++; \\r
63 \\r
64 zip_4x32b(vector_cast(vec_4x32u, pixels_wide), pixels.high, pixels.high); \\r
65 block->texels = pixels_wide; \\r
66 block->draw_mask_bits = left_mask_bits_b; \\r
67 block->fb_ptr = fb_ptr + 8; \\r
68 block++; \\r
69 \\r
70 block->texels = pixels_wide; \\r
71 block->draw_mask_bits = left_mask_bits_b; \\r
72 block->fb_ptr = fb_ptr + 1024 + 8; \\r
73 block++; \\r
74 \\r
75 setup_sprite_tile_fetch_texel_block_8bpp_4x(8); \\r
76 tbl_16(texels_low, texels, clut_low); \\r
77 tbl_16(texels_high, texels, clut_high); \\r
78 zip_8x16b(pixels, texels_low, texels_high); \\r
79 \\r
80 zip_4x32b(vector_cast(vec_4x32u, pixels_wide), pixels.low, pixels.low); \\r
81 block->texels = pixels_wide; \\r
82 block->draw_mask_bits = right_mask_bits_a; \\r
83 block->fb_ptr = fb_ptr + 16; \\r
84 block++; \\r
85 \\r
86 block->texels = pixels_wide; \\r
87 block->draw_mask_bits = right_mask_bits_a; \\r
88 block->fb_ptr = fb_ptr + 1024 + 16; \\r
89 block++; \\r
90 \\r
91 zip_4x32b(vector_cast(vec_4x32u, pixels_wide), pixels.high, pixels.high); \\r
92 block->texels = pixels_wide; \\r
93 block->draw_mask_bits = right_mask_bits_b; \\r
94 block->fb_ptr = fb_ptr + 24; \\r
95 block++; \\r
96 \\r
97 block->texels = pixels_wide; \\r
98 block->draw_mask_bits = right_mask_bits_b; \\r
99 block->fb_ptr = fb_ptr + 1024 + 24; \\r
100 block++; \\r
101 \\r
102 fb_ptr += 2048; \\r
103 texture_offset += 0x10; \\r
104 sub_tile_height--; \\r
105 } \\r
106 texture_offset += 0xF00; \\r
107 psx_gpu->num_blocks = num_blocks; \\r
108} \\r
109\r
110#define setup_sprite_tile_half_4bpp_4x(edge) \\r
111{ \\r
112 vec_8x8u texels_low, texels_high; \\r
113 vec_8x16u pixels, pixels_wide; \\r
114 setup_sprite_tile_add_blocks(sub_tile_height); \\r
115 u32 edge##_mask_bits_a = edge##_mask_bits & 0xFF; \\r
116 u32 edge##_mask_bits_b = edge##_mask_bits >> 8; \\r
117 \\r
118 while(sub_tile_height) \\r
119 { \\r
120 setup_sprite_tile_fetch_texel_block_8bpp_4x(0); \\r
121 tbl_16(texels_low, texels, clut_low); \\r
122 tbl_16(texels_high, texels, clut_high); \\r
123 zip_8x16b(pixels, texels_low, texels_high); \\r
124 \\r
125 zip_4x32b(vector_cast(vec_4x32u, pixels_wide), pixels.low, pixels.low); \\r
126 block->texels = pixels_wide; \\r
127 block->draw_mask_bits = edge##_mask_bits_a; \\r
128 block->fb_ptr = fb_ptr; \\r
129 block++; \\r
130 \\r
131 block->texels = pixels_wide; \\r
132 block->draw_mask_bits = edge##_mask_bits_a; \\r
133 block->fb_ptr = fb_ptr + 1024; \\r
134 block++; \\r
135 \\r
136 zip_4x32b(vector_cast(vec_4x32u, pixels_wide), pixels.high, pixels.high); \\r
137 block->texels = pixels_wide; \\r
138 block->draw_mask_bits = edge##_mask_bits_b; \\r
139 block->fb_ptr = fb_ptr + 8; \\r
140 block++; \\r
141 \\r
142 block->texels = pixels_wide; \\r
143 block->draw_mask_bits = edge##_mask_bits_b; \\r
144 block->fb_ptr = fb_ptr + 1024 + 8; \\r
145 block++; \\r
146 \\r
147 fb_ptr += 2048; \\r
148 texture_offset += 0x10; \\r
149 sub_tile_height--; \\r
150 } \\r
151 texture_offset += 0xF00; \\r
152 psx_gpu->num_blocks = num_blocks; \\r
153} \\r
154\r
155 \r
156#define setup_sprite_tile_full_8bpp_4x(edge) \\r
157{ \\r
158 setup_sprite_tile_add_blocks_4x(sub_tile_height * 2); \\r
159 vec_16x8u texels_wide; \\r
160 u32 left_mask_bits_a = left_mask_bits & 0xFF; \\r
161 u32 left_mask_bits_b = left_mask_bits >> 8; \\r
162 u32 right_mask_bits_a = right_mask_bits & 0xFF; \\r
163 u32 right_mask_bits_b = right_mask_bits >> 8; \\r
164 \\r
165 while(sub_tile_height) \\r
166 { \\r
167 setup_sprite_tile_fetch_texel_block_8bpp_4x(0); \\r
168 zip_8x16b(vector_cast(vec_8x16u, texels_wide), texels, texels); \\r
169 block->r = texels_wide.low; \\r
170 block->draw_mask_bits = left_mask_bits_a; \\r
171 block->fb_ptr = fb_ptr; \\r
172 block++; \\r
173 \\r
174 block->r = texels_wide.low; \\r
175 block->draw_mask_bits = left_mask_bits_a; \\r
176 block->fb_ptr = fb_ptr + 1024; \\r
177 block++; \\r
178 \\r
179 block->r = texels_wide.high; \\r
180 block->draw_mask_bits = left_mask_bits_b; \\r
181 block->fb_ptr = fb_ptr + 8; \\r
182 block++; \\r
183 \\r
184 block->r = texels_wide.high; \\r
185 block->draw_mask_bits = left_mask_bits_b; \\r
186 block->fb_ptr = fb_ptr + 1024 + 8; \\r
187 block++; \\r
188 \\r
189 setup_sprite_tile_fetch_texel_block_8bpp_4x(8); \\r
190 zip_8x16b(vector_cast(vec_8x16u, texels_wide), texels, texels); \\r
191 block->r = texels_wide.low; \\r
192 block->draw_mask_bits = right_mask_bits_a; \\r
193 block->fb_ptr = fb_ptr + 16; \\r
194 block++; \\r
195 \\r
196 block->r = texels_wide.low; \\r
197 block->draw_mask_bits = right_mask_bits_a; \\r
198 block->fb_ptr = fb_ptr + 1024; \\r
199 block++; \\r
200 \\r
201 block->r = texels_wide.high; \\r
202 block->draw_mask_bits = right_mask_bits_b; \\r
203 block->fb_ptr = fb_ptr + 24 + 1024; \\r
204 block++; \\r
205 \\r
206 block->r = texels_wide.high; \\r
207 block->draw_mask_bits = right_mask_bits_b; \\r
208 block->fb_ptr = fb_ptr + 24 + 1024; \\r
209 block++; \\r
210 \\r
211 fb_ptr += 2048; \\r
212 texture_offset += 0x10; \\r
213 sub_tile_height--; \\r
214 } \\r
215 texture_offset += 0xF00; \\r
216 psx_gpu->num_blocks = num_blocks; \\r
217} \\r
218\r
219#define setup_sprite_tile_half_8bpp_4x(edge) \\r
220{ \\r
221 setup_sprite_tile_add_blocks_4x(sub_tile_height * 2); \\r
222 vec_16x8u texels_wide; \\r
223 u32 edge##_mask_bits_a = edge##_mask_bits & 0xFF; \\r
224 u32 edge##_mask_bits_b = edge##_mask_bits >> 8; \\r
225 \\r
226 while(sub_tile_height) \\r
227 { \\r
228 setup_sprite_tile_fetch_texel_block_8bpp_4x(0); \\r
229 zip_8x16b(vector_cast(vec_8x16u, texels_wide), texels, texels); \\r
230 block->r = texels_wide.low; \\r
231 block->draw_mask_bits = edge##_mask_bits_a; \\r
232 block->fb_ptr = fb_ptr; \\r
233 block++; \\r
234 \\r
235 block->r = texels_wide.low; \\r
236 block->draw_mask_bits = edge##_mask_bits_a; \\r
237 block->fb_ptr = fb_ptr + 1024; \\r
238 block++; \\r
239 \\r
240 block->r = texels_wide.high; \\r
241 block->draw_mask_bits = edge##_mask_bits_b; \\r
242 block->fb_ptr = fb_ptr + 8; \\r
243 block++; \\r
244 \\r
245 block->r = texels_wide.high; \\r
246 block->draw_mask_bits = edge##_mask_bits_b; \\r
247 block->fb_ptr = fb_ptr + 8 + 1024; \\r
248 block++; \\r
249 \\r
250 fb_ptr += 2048; \\r
251 texture_offset += 0x10; \\r
252 sub_tile_height--; \\r
253 } \\r
254 texture_offset += 0xF00; \\r
255 psx_gpu->num_blocks = num_blocks; \\r
256} \\r
257\r
258 \r
259#define setup_sprite_tile_column_edge_pre_adjust_half_right_4x() \\r
260 texture_offset = texture_offset_base + 8; \\r
261 fb_ptr += 16 \\r
262\r
263#define setup_sprite_tile_column_edge_pre_adjust_half_left_4x() \\r
264 texture_offset = texture_offset_base \\r
265\r
266#define setup_sprite_tile_column_edge_pre_adjust_half_4x(edge) \\r
267 setup_sprite_tile_column_edge_pre_adjust_half_##edge##_4x() \\r
268\r
269#define setup_sprite_tile_column_edge_pre_adjust_full_4x(edge) \\r
270 texture_offset = texture_offset_base \\r
271\r
272#define setup_sprite_tile_column_edge_post_adjust_half_right_4x() \\r
273 fb_ptr -= 16 \\r
274\r
275#define setup_sprite_tile_column_edge_post_adjust_half_left_4x() \\r
276\r
277#define setup_sprite_tile_column_edge_post_adjust_half_4x(edge) \\r
278 setup_sprite_tile_column_edge_post_adjust_half_##edge##_4x() \\r
279\r
280#define setup_sprite_tile_column_edge_post_adjust_full_4x(edge) \\r
281\r
282\r
283#define setup_sprite_tile_column_height_single_4x(edge_mode, edge, \\r
284 texture_mode) \\r
285do \\r
286{ \\r
287 sub_tile_height = column_data; \\r
288 setup_sprite_tile_column_edge_pre_adjust_##edge_mode##_4x(edge); \\r
289 setup_sprite_tile_##edge_mode##_##texture_mode##_4x(edge); \\r
290 setup_sprite_tile_column_edge_post_adjust_##edge_mode##_4x(edge); \\r
291} while(0) \\r
292\r
293#define setup_sprite_tile_column_height_multi_4x(edge_mode, edge, \\r
294 texture_mode) \\r
295do \\r
296{ \\r
297 u32 tiles_remaining = column_data >> 16; \\r
298 sub_tile_height = column_data & 0xFF; \\r
299 setup_sprite_tile_column_edge_pre_adjust_##edge_mode##_4x(edge); \\r
300 setup_sprite_tile_##edge_mode##_##texture_mode##_4x(edge); \\r
301 tiles_remaining -= 1; \\r
302 \\r
303 while(tiles_remaining) \\r
304 { \\r
305 sub_tile_height = 16; \\r
306 setup_sprite_tile_##edge_mode##_##texture_mode##_4x(edge); \\r
307 tiles_remaining--; \\r
308 } \\r
309 \\r
310 sub_tile_height = (column_data >> 8) & 0xFF; \\r
311 setup_sprite_tile_##edge_mode##_##texture_mode##_4x(edge); \\r
312 setup_sprite_tile_column_edge_post_adjust_##edge_mode##_4x(edge); \\r
313} while(0) \\r
314\r
315\r
316#define setup_sprite_column_data_single_4x() \\r
317 column_data = height \\r
318\r
319#define setup_sprite_column_data_multi_4x() \\r
320 column_data = 16 - offset_v; \\r
321 column_data |= ((height_rounded & 0xF) + 1) << 8; \\r
322 column_data |= (tile_height - 1) << 16 \\r
323\r
324\r
325#define setup_sprite_tile_column_width_single_4x(texture_mode, multi_height, \\r
326 edge_mode, edge) \\r
327{ \\r
328 setup_sprite_column_data_##multi_height##_4x(); \\r
329 left_mask_bits = left_block_mask | right_block_mask; \\r
330 right_mask_bits = left_mask_bits >> 16; \\r
331 \\r
332 setup_sprite_tile_column_height_##multi_height##_4x(edge_mode, edge, \\r
333 texture_mode); \\r
334} \\r
335\r
336#define setup_sprite_tiled_advance_column_4x() \\r
337 texture_offset_base += 0x100; \\r
338 if((texture_offset_base & 0xF00) == 0) \\r
339 texture_offset_base -= (0x100 + 0xF00) \\r
340\r
341#define setup_sprite_tile_column_width_multi_4x(texture_mode, multi_height, \\r
342 left_mode, right_mode) \\r
343{ \\r
344 setup_sprite_column_data_##multi_height##_4x(); \\r
345 s32 fb_ptr_advance_column = 32 - (2048 * height); \\r
346 \\r
347 tile_width -= 2; \\r
348 left_mask_bits = left_block_mask; \\r
349 right_mask_bits = left_mask_bits >> 16; \\r
350 \\r
351 setup_sprite_tile_column_height_##multi_height##_4x(left_mode, right, \\r
352 texture_mode); \\r
353 fb_ptr += fb_ptr_advance_column; \\r
354 \\r
355 left_mask_bits = 0x00; \\r
356 right_mask_bits = 0x00; \\r
357 \\r
358 while(tile_width) \\r
359 { \\r
360 setup_sprite_tiled_advance_column_4x(); \\r
361 setup_sprite_tile_column_height_##multi_height##_4x(full, none, \\r
362 texture_mode); \\r
363 fb_ptr += fb_ptr_advance_column; \\r
364 tile_width--; \\r
365 } \\r
366 \\r
367 left_mask_bits = right_block_mask; \\r
368 right_mask_bits = left_mask_bits >> 16; \\r
369 \\r
370 setup_sprite_tiled_advance_column(); \\r
371 setup_sprite_tile_column_height_##multi_height##_4x(right_mode, left, \\r
372 texture_mode); \\r
373} \\r
374\r
375\r
376#define setup_sprite_tiled_builder_4x(texture_mode) \\r
377void setup_sprite_##texture_mode##_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, \\r
378 s32 u, s32 v, s32 width, s32 height, u32 color) \\r
379{ \\r
380 s32 offset_u = u & 0xF; \\r
381 s32 offset_v = v & 0xF; \\r
382 \\r
383 s32 width_rounded = offset_u + width + 15; \\r
384 s32 height_rounded = offset_v + height + 15; \\r
385 s32 tile_height = height_rounded / 16; \\r
386 s32 tile_width = width_rounded / 16; \\r
387 u32 offset_u_right = width_rounded & 0xF; \\r
388 \\r
389 u32 left_block_mask = ~(0xFFFFFFFF << (offset_u * 2)); \\r
390 u32 right_block_mask = 0xFFFFFFFE << (offset_u_right * 2); \\r
391 \\r
392 u32 left_mask_bits; \\r
393 u32 right_mask_bits; \\r
394 \\r
395 u32 sub_tile_height; \\r
396 u32 column_data; \\r
397 \\r
398 u32 texture_mask = (psx_gpu->texture_mask_width & 0xF) | \\r
399 ((psx_gpu->texture_mask_height & 0xF) << 4) | \\r
400 ((psx_gpu->texture_mask_width >> 4) << 8) | \\r
401 ((psx_gpu->texture_mask_height >> 4) << 12); \\r
402 u32 texture_offset = ((v & 0xF) << 4) | ((u & 0xF0) << 4) | \\r
403 ((v & 0xF0) << 8); \\r
404 u32 texture_offset_base = texture_offset; \\r
405 u32 control_mask; \\r
406 \\r
407 u16 *fb_ptr = psx_gpu->vram_ptr + (y * 1024) + (x - offset_u); \\r
408 u32 num_blocks = psx_gpu->num_blocks; \\r
409 block_struct *block = psx_gpu->blocks + num_blocks; \\r
410 \\r
411 u16 *texture_block_ptr; \\r
412 vec_8x8u texels; \\r
413 \\r
414 setup_sprite_tiled_initialize_##texture_mode##_4x(); \\r
415 \\r
416 control_mask = tile_width == 1; \\r
417 control_mask |= (tile_height == 1) << 1; \\r
418 control_mask |= ((left_block_mask & 0xFFFF) == 0xFFFF) << 2; \\r
419 control_mask |= (((right_block_mask >> 8) & 0xFFFF) == 0xFFFF) << 3; \\r
420 \\r
421 sprites_##texture_mode++; \\r
422 \\r
423 switch(control_mask) \\r
424 { \\r
425 default: \\r
426 case 0x0: \\r
427 setup_sprite_tile_column_width_multi_4x(texture_mode, multi, full, \\r
428 full); \\r
429 break; \\r
430 \\r
431 case 0x1: \\r
432 setup_sprite_tile_column_width_single_4x(texture_mode, multi, full, \\r
433 none); \\r
434 break; \\r
435 \\r
436 case 0x2: \\r
437 setup_sprite_tile_column_width_multi_4x(texture_mode, single, full, \\r
438 full); \\r
439 break; \\r
440 \\r
441 case 0x3: \\r
442 setup_sprite_tile_column_width_single_4x(texture_mode, single, full, \\r
443 none); \\r
444 break; \\r
445 \\r
446 case 0x4: \\r
447 setup_sprite_tile_column_width_multi_4x(texture_mode, multi, half, \\r
448 full); \\r
449 break; \\r
450 \\r
451 case 0x5: \\r
452 setup_sprite_tile_column_width_single_4x(texture_mode, multi, half, \\r
453 right); \\r
454 break; \\r
455 \\r
456 case 0x6: \\r
457 setup_sprite_tile_column_width_multi_4x(texture_mode, single, half, \\r
458 full); \\r
459 break; \\r
460 \\r
461 case 0x7: \\r
462 setup_sprite_tile_column_width_single_4x(texture_mode, single, half, \\r
463 right); \\r
464 break; \\r
465 \\r
466 case 0x8: \\r
467 setup_sprite_tile_column_width_multi_4x(texture_mode, multi, full, \\r
468 half); \\r
469 break; \\r
470 \\r
471 case 0x9: \\r
472 setup_sprite_tile_column_width_single_4x(texture_mode, multi, half, \\r
473 left); \\r
474 break; \\r
475 \\r
476 case 0xA: \\r
477 setup_sprite_tile_column_width_multi_4x(texture_mode, single, full, \\r
478 half); \\r
479 break; \\r
480 \\r
481 case 0xB: \\r
482 setup_sprite_tile_column_width_single_4x(texture_mode, single, half, \\r
483 left); \\r
484 break; \\r
485 \\r
486 case 0xC: \\r
487 setup_sprite_tile_column_width_multi_4x(texture_mode, multi, half, \\r
488 half); \\r
489 break; \\r
490 \\r
491 case 0xE: \\r
492 setup_sprite_tile_column_width_multi_4x(texture_mode, single, half, \\r
493 half); \\r
494 break; \\r
495 } \\r
496} \\r
497\r
498\r
499void setup_sprite_4bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u, s32 v,\r
500 s32 width, s32 height, u32 color);\r
501void setup_sprite_8bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u, s32 v,\r
502 s32 width, s32 height, u32 color);\r
503void setup_sprite_16bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u, s32 v,\r
504 s32 width, s32 height, u32 color);\r
505\r
506//#ifndef NEON_BUILD\r
507#if 1\r
508setup_sprite_tiled_builder_4x(4bpp);\r
509setup_sprite_tiled_builder_4x(8bpp);\r
510\r
511void setup_sprite_16bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u,\r
512 s32 v, s32 width, s32 height, u32 color)\r
513{\r
514 u32 left_offset = u & 0x7;\r
515 u32 width_rounded = width + left_offset + 7;\r
516\r
517 u16 *fb_ptr = psx_gpu->vram_ptr + (y * 1024) + (s32)(x - left_offset);\r
518 u32 right_width = width_rounded & 0x7;\r
519 u32 block_width = width_rounded / 8;\r
520 u32 fb_ptr_pitch = (1024 + 8) - (block_width * 8);\r
521\r
522 u32 left_mask_bits = ~(0xFFFF << (left_offset * 2));\r
523 u32 right_mask_bits = 0xFE << (right_width * 2);\r
524\r
525 u32 texture_offset_base = u + (v * 1024);\r
526 u32 texture_mask =\r
527 psx_gpu->texture_mask_width | (psx_gpu->texture_mask_height * 1024);\r
528\r
529 u32 blocks_remaining;\r
530 u32 num_blocks = psx_gpu->num_blocks;\r
531 block_struct *block = psx_gpu->blocks + num_blocks;\r
532\r
533 u16 *texture_page_ptr = psx_gpu->texture_page_ptr;\r
534 u16 *texture_block_ptr;\r
535\r
536 texture_offset_base &= ~0x7;\r
537\r
538 sprites_16bpp++;\r
539\r
540 if(block_width == 1)\r
541 {\r
542 u32 mask_bits = left_mask_bits | right_mask_bits;\r
543 u32 mask_bits_a = mask_bits & 0xFF;\r
544 u32 mask_bits_b = mask_bits >> 8;\r
545 \r
546 vec_8x16u texels;\r
547 vec_8x16u texels_wide;\r
548\r
549 while(height)\r
550 {\r
551 num_blocks += 4;\r
552 sprite_blocks += 4;\r
553\r
554 if(num_blocks > MAX_BLOCKS)\r
555 {\r
556 flush_render_block_buffer(psx_gpu);\r
557 num_blocks = 4;\r
558 block = psx_gpu->blocks;\r
559 }\r
560 \r
561 texture_block_ptr =\r
562 texture_page_ptr + (texture_offset_base & texture_mask);\r
563\r
564 load_128b(texels, texture_block_ptr);\r
565 \r
566 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
567 block->texels = texels_wide;\r
568 block->draw_mask_bits = mask_bits_a;\r
569 block->fb_ptr = fb_ptr; \r
570 block++;\r
571 \r
572 block->texels = texels_wide;\r
573 block->draw_mask_bits = mask_bits_a;\r
574 block->fb_ptr = fb_ptr + 1024; \r
575 block++;\r
576 \r
577 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
578 block->texels = texels_wide;\r
579 block->draw_mask_bits = mask_bits_b;\r
580 block->fb_ptr = fb_ptr + 8;\r
581 block++;\r
582 \r
583 block->texels = texels_wide;\r
584 block->draw_mask_bits = mask_bits_b;\r
585 block->fb_ptr = fb_ptr + 8 + 1024; \r
586 block++; \r
587\r
588 texture_offset_base += 1024;\r
589 fb_ptr += 2048;\r
590\r
591 height--;\r
592 psx_gpu->num_blocks = num_blocks;\r
593 }\r
594 }\r
595 else\r
596 {\r
597 u32 texture_offset;\r
598 \r
599 u32 left_mask_bits_a = left_mask_bits & 0xFF;\r
600 u32 left_mask_bits_b = left_mask_bits >> 8;\r
601 u32 right_mask_bits_a = right_mask_bits & 0xFF;\r
602 u32 right_mask_bits_b = right_mask_bits >> 8;\r
603 \r
604 vec_8x16u texels;\r
605 vec_8x16u texels_wide; \r
606\r
607 while(height)\r
608 {\r
609 blocks_remaining = block_width - 2;\r
610 num_blocks += block_width * 4;\r
611 sprite_blocks += block_width * 4;\r
612\r
613 if(num_blocks > MAX_BLOCKS)\r
614 {\r
615 flush_render_block_buffer(psx_gpu);\r
616 num_blocks = block_width;\r
617 block = psx_gpu->blocks;\r
618 }\r
619\r
620 texture_offset = texture_offset_base;\r
621 texture_offset_base += 1024;\r
622\r
623 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
624 \r
625 load_128b(texels, texture_block_ptr);\r
626\r
627 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
628 block->texels = texels_wide;\r
629 block->draw_mask_bits = left_mask_bits_a;\r
630 block->fb_ptr = fb_ptr;\r
631 block++;\r
632 \r
633 block->texels = texels_wide;\r
634 block->draw_mask_bits = left_mask_bits_a;\r
635 block->fb_ptr = fb_ptr + 1024;\r
636 block++; \r
637\r
638 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
639 block->texels = texels_wide;\r
640 block->draw_mask_bits = left_mask_bits_b;\r
641 block->fb_ptr = fb_ptr + 8;\r
642 block++; \r
643 \r
644 block->texels = texels_wide;\r
645 block->draw_mask_bits = left_mask_bits_b;\r
646 block->fb_ptr = fb_ptr + 8 + 1024;\r
647 block++; \r
648 \r
649 texture_offset += 8;\r
650 fb_ptr += 16;\r
651\r
652 while(blocks_remaining)\r
653 {\r
654 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
655 load_128b(texels, texture_block_ptr);\r
656\r
657 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
658 block->texels = texels_wide;\r
659 block->draw_mask_bits = 0;\r
660 block->fb_ptr = fb_ptr;\r
661 block++;\r
662 \r
663 block->texels = texels_wide;\r
664 block->draw_mask_bits = 0;\r
665 block->fb_ptr = fb_ptr + 1024;\r
666 block++; \r
667\r
668 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
669 block->texels = texels_wide;\r
670 block->draw_mask_bits = 0;\r
671 block->fb_ptr = fb_ptr + 8;\r
672 block++;\r
673 \r
674 block->texels = texels_wide;\r
675 block->draw_mask_bits = 0;\r
676 block->fb_ptr = fb_ptr + 8 + 1024;\r
677 block++;\r
678 \r
679 texture_offset += 8;\r
680 fb_ptr += 8;\r
681\r
682 blocks_remaining--;\r
683 }\r
684\r
685 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
686 load_128b(texels, texture_block_ptr);\r
687 \r
688 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
689 block->texels = texels_wide;\r
690 block->draw_mask_bits = right_mask_bits_a;\r
691 block->fb_ptr = fb_ptr;\r
692 block++;\r
693 \r
694 block->texels = texels_wide;\r
695 block->draw_mask_bits = right_mask_bits_a;\r
696 block->fb_ptr = fb_ptr + 1024;\r
697 block++; \r
698\r
699 zip4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
700 block->texels = texels_wide;\r
701 block->draw_mask_bits = right_mask_bits_b;\r
702 block->fb_ptr = fb_ptr + 8;\r
703 block++;\r
704\r
705 block->texels = texels_wide;\r
706 block->draw_mask_bits = right_mask_bits_b;\r
707 block->fb_ptr = fb_ptr + 8 + 1024; \r
708 block++;\r
709\r
710 fb_ptr += fb_ptr_pitch;\r
711\r
712 height--;\r
713 psx_gpu->num_blocks = num_blocks;\r
714 }\r
715 }\r
716}\r
717\r
718#endif\r
719\r
720#define setup_sprite_blocks_switch_textured_4x(texture_mode) \\r
721 setup_sprite_##texture_mode##_4x \\r
722\r
723#define setup_sprite_blocks_switch_untextured_4x(texture_mode) \\r
724 setup_sprite_untextured \\r
725\r
726#define setup_sprite_blocks_switch_4x(texturing, texture_mode) \\r
727 setup_sprite_blocks_switch_##texturing##_4x(texture_mode) \\r
728\r
729 \r
730#define render_sprite_blocks_switch_block_modulation_4x(texture_mode, \\r
731 blend_mode, mask_evaluate, shading, dithering, texturing, blending, \\r
732 modulation) \\r
733{ \\r
734 setup_sprite_blocks_switch_4x(texturing, texture_mode), \\r
735 texture_sprite_blocks_switch_##texturing(texture_mode), \\r
736 shade_blocks_switch(unshaded, texturing, modulation, undithered, blending, \\r
737 mask_evaluate), \\r
738 blend_blocks_switch(texturing, blending, blend_mode, mask_evaluate) \\r
739} \\r
740\r
741#define render_sprite_blocks_switch_block_blending_4x(texture_mode, \\r
742 blend_mode, mask_evaluate, shading, dithering, texturing, blending) \\r
743 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \\r
744 mask_evaluate, shading, dithering, texturing, blending, modulated), \\r
745 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \\r
746 mask_evaluate, shading, dithering, texturing, blending, unmodulated) \\r
747\r
748#define render_sprite_blocks_switch_block_texturing_4x(texture_mode, \\r
749 blend_mode, mask_evaluate, shading, dithering, texturing) \\r
750 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \\r
751 mask_evaluate, shading, dithering, texturing, unblended), \\r
752 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \\r
753 mask_evaluate, shading, dithering, texturing, blended) \\r
754\r
755#define render_sprite_blocks_switch_block_dithering_4x(texture_mode, \\r
756 blend_mode, mask_evaluate, shading, dithering) \\r
757 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \\r
758 mask_evaluate, shading, dithering, untextured), \\r
759 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \\r
760 mask_evaluate, shading, dithering, textured) \\r
761\r
762#define render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \\r
763 mask_evaluate, shading) \\r
764 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \\r
765 mask_evaluate, shading, undithered), \\r
766 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \\r
767 mask_evaluate, shading, dithered) \\r
768\r
769#define render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, \\r
770 blend_mode, mask_evaluate) \\r
771 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \\r
772 mask_evaluate, unshaded), \\r
773 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \\r
774 mask_evaluate, shaded) \\r
775\r
776#define render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, \\r
777 blend_mode) \\r
778 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \\r
779 off), \\r
780 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \\r
781 on) \\r
782\r
783#define render_sprite_blocks_switch_block_texture_mode_4x(texture_mode) \\r
784 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, average), \\r
785 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add), \\r
786 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, subtract), \\r
787 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add_fourth) \\r
788\r
789#define render_sprite_blocks_switch_block_4x() \\r
790 render_sprite_blocks_switch_block_texture_mode_4x(4bpp), \\r
791 render_sprite_blocks_switch_block_texture_mode_4x(8bpp), \\r
792 render_sprite_blocks_switch_block_texture_mode_4x(16bpp), \\r
793 render_sprite_blocks_switch_block_texture_mode_4x(4bpp) \\r
794\r
795\r
796render_block_handler_struct render_sprite_block_handlers_4x[] =\r
797{\r
798 render_sprite_blocks_switch_block_4x()\r
799};\r
800\r
801\r
802void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,\r
803 s32 width, s32 height, u32 flags, u32 color)\r
804{\r
805 x *= 2;\r
806 y *= 2;\r
807\r
808 s32 x_right = x + width - 1;\r
809 s32 y_bottom = y + height - 1;\r
810\r
811#ifdef PROFILE\r
812 sprites++;\r
813#endif\r
814\r
815 if(x < psx_gpu->viewport_start_x)\r
816 {\r
817 u32 clip = psx_gpu->viewport_start_x - x;\r
818 x += clip;\r
819 u += clip;\r
820 width -= clip;\r
821 }\r
822\r
823 if(y < psx_gpu->viewport_start_y)\r
824 {\r
825 s32 clip = psx_gpu->viewport_start_y - y;\r
826 y += clip;\r
827 v += clip;\r
828 height -= clip;\r
829 }\r
830\r
831 if(x_right > psx_gpu->viewport_end_x)\r
832 width -= x_right - psx_gpu->viewport_end_x;\r
833\r
834 if(y_bottom > psx_gpu->viewport_end_y)\r
835 height -= y_bottom - psx_gpu->viewport_end_y;\r
836\r
837 if((width <= 0) || (height <= 0))\r
838 return;\r
839\r
840#ifdef PROFILE\r
841 span_pixels += width * height;\r
842 spans += height;\r
843#endif\r
844\r
845 u32 render_state = flags &\r
846 (RENDER_FLAGS_MODULATE_TEXELS | RENDER_FLAGS_BLEND |\r
847 RENDER_FLAGS_TEXTURE_MAP);\r
848 render_state |=\r
849 (psx_gpu->render_state_base & ~RENDER_STATE_DITHER);\r
850\r
851 if((psx_gpu->render_state != render_state) ||\r
852 (psx_gpu->primitive_type != PRIMITIVE_TYPE_SPRITE))\r
853 {\r
854 psx_gpu->render_state = render_state;\r
855 flush_render_block_buffer(psx_gpu);\r
856#ifdef PROFILE\r
857 state_changes++;\r
858#endif\r
859 }\r
860\r
861 psx_gpu->primitive_type = PRIMITIVE_TYPE_SPRITE;\r
862\r
863 color &= 0xFFFFFF;\r
864\r
865 if(psx_gpu->triangle_color != color)\r
866 {\r
867 flush_render_block_buffer(psx_gpu);\r
868 psx_gpu->triangle_color = color;\r
869 }\r
870\r
871 if(color == 0x808080)\r
872 render_state |= RENDER_FLAGS_MODULATE_TEXELS;\r
873\r
874 render_block_handler_struct *render_block_handler =\r
875 &(render_sprite_block_handlers_4x[render_state]);\r
876 psx_gpu->render_block_handler = render_block_handler;\r
877\r
878 ((setup_sprite_function_type *)render_block_handler->setup_blocks)\r
879 (psx_gpu, x, y, u, v, width, height, color);\r
880}\r
881\r