psx_gpu: consolidate C code, implement exnhancement asm
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu / psx_gpu_4x.c
CommitLineData
59d15d23 1#ifndef NEON_BUILD\r
05e2e0c6
E
2void setup_sprite_16bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u,\r
3 s32 v, s32 width, s32 height, u32 color)\r
4{\r
5 u32 left_offset = u & 0x7;\r
6 u32 width_rounded = width + left_offset + 7;\r
7\r
fc6cef7d 8 u16 *fb_ptr = psx_gpu->vram_out_ptr + (y * 1024) + (s32)(x - left_offset * 2);\r
05e2e0c6
E
9 u32 right_width = width_rounded & 0x7;\r
10 u32 block_width = width_rounded / 8;\r
fc6cef7d 11 u32 fb_ptr_pitch = (2048 + 16) - (block_width * 16);\r
05e2e0c6
E
12\r
13 u32 left_mask_bits = ~(0xFFFF << (left_offset * 2));\r
fc6cef7d 14 u32 right_mask_bits = 0xFFFC << (right_width * 2);\r
05e2e0c6
E
15\r
16 u32 texture_offset_base = u + (v * 1024);\r
17 u32 texture_mask =\r
18 psx_gpu->texture_mask_width | (psx_gpu->texture_mask_height * 1024);\r
19\r
20 u32 blocks_remaining;\r
21 u32 num_blocks = psx_gpu->num_blocks;\r
22 block_struct *block = psx_gpu->blocks + num_blocks;\r
23\r
24 u16 *texture_page_ptr = psx_gpu->texture_page_ptr;\r
25 u16 *texture_block_ptr;\r
26\r
27 texture_offset_base &= ~0x7;\r
28\r
29 sprites_16bpp++;\r
30\r
31 if(block_width == 1)\r
32 {\r
33 u32 mask_bits = left_mask_bits | right_mask_bits;\r
34 u32 mask_bits_a = mask_bits & 0xFF;\r
35 u32 mask_bits_b = mask_bits >> 8;\r
36 \r
37 vec_8x16u texels;\r
38 vec_8x16u texels_wide;\r
39\r
40 while(height)\r
41 {\r
42 num_blocks += 4;\r
43 sprite_blocks += 4;\r
44\r
45 if(num_blocks > MAX_BLOCKS)\r
46 {\r
47 flush_render_block_buffer(psx_gpu);\r
48 num_blocks = 4;\r
49 block = psx_gpu->blocks;\r
50 }\r
51 \r
52 texture_block_ptr =\r
53 texture_page_ptr + (texture_offset_base & texture_mask);\r
54\r
55 load_128b(texels, texture_block_ptr);\r
56 \r
fc6cef7d 57 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
58 block->texels = texels_wide;\r
59 block->draw_mask_bits = mask_bits_a;\r
60 block->fb_ptr = fb_ptr; \r
61 block++;\r
62 \r
63 block->texels = texels_wide;\r
64 block->draw_mask_bits = mask_bits_a;\r
65 block->fb_ptr = fb_ptr + 1024; \r
66 block++;\r
67 \r
fc6cef7d 68 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
69 block->texels = texels_wide;\r
70 block->draw_mask_bits = mask_bits_b;\r
71 block->fb_ptr = fb_ptr + 8;\r
72 block++;\r
73 \r
74 block->texels = texels_wide;\r
75 block->draw_mask_bits = mask_bits_b;\r
76 block->fb_ptr = fb_ptr + 8 + 1024; \r
77 block++; \r
78\r
79 texture_offset_base += 1024;\r
80 fb_ptr += 2048;\r
81\r
82 height--;\r
83 psx_gpu->num_blocks = num_blocks;\r
84 }\r
85 }\r
86 else\r
87 {\r
88 u32 texture_offset;\r
89 \r
90 u32 left_mask_bits_a = left_mask_bits & 0xFF;\r
91 u32 left_mask_bits_b = left_mask_bits >> 8;\r
92 u32 right_mask_bits_a = right_mask_bits & 0xFF;\r
93 u32 right_mask_bits_b = right_mask_bits >> 8;\r
94 \r
95 vec_8x16u texels;\r
96 vec_8x16u texels_wide; \r
97\r
98 while(height)\r
99 {\r
100 blocks_remaining = block_width - 2;\r
101 num_blocks += block_width * 4;\r
102 sprite_blocks += block_width * 4;\r
103\r
104 if(num_blocks > MAX_BLOCKS)\r
105 {\r
106 flush_render_block_buffer(psx_gpu);\r
fc6cef7d 107 num_blocks = block_width * 4;\r
05e2e0c6
E
108 block = psx_gpu->blocks;\r
109 }\r
110\r
111 texture_offset = texture_offset_base;\r
112 texture_offset_base += 1024;\r
113\r
114 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
115 \r
116 load_128b(texels, texture_block_ptr);\r
117\r
fc6cef7d 118 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
119 block->texels = texels_wide;\r
120 block->draw_mask_bits = left_mask_bits_a;\r
121 block->fb_ptr = fb_ptr;\r
122 block++;\r
123 \r
124 block->texels = texels_wide;\r
125 block->draw_mask_bits = left_mask_bits_a;\r
126 block->fb_ptr = fb_ptr + 1024;\r
127 block++; \r
128\r
fc6cef7d 129 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
130 block->texels = texels_wide;\r
131 block->draw_mask_bits = left_mask_bits_b;\r
132 block->fb_ptr = fb_ptr + 8;\r
133 block++; \r
134 \r
135 block->texels = texels_wide;\r
136 block->draw_mask_bits = left_mask_bits_b;\r
137 block->fb_ptr = fb_ptr + 8 + 1024;\r
138 block++; \r
139 \r
140 texture_offset += 8;\r
141 fb_ptr += 16;\r
142\r
143 while(blocks_remaining)\r
144 {\r
145 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
146 load_128b(texels, texture_block_ptr);\r
147\r
fc6cef7d 148 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
149 block->texels = texels_wide;\r
150 block->draw_mask_bits = 0;\r
151 block->fb_ptr = fb_ptr;\r
152 block++;\r
153 \r
154 block->texels = texels_wide;\r
155 block->draw_mask_bits = 0;\r
156 block->fb_ptr = fb_ptr + 1024;\r
157 block++; \r
158\r
fc6cef7d 159 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
160 block->texels = texels_wide;\r
161 block->draw_mask_bits = 0;\r
162 block->fb_ptr = fb_ptr + 8;\r
163 block++;\r
164 \r
165 block->texels = texels_wide;\r
166 block->draw_mask_bits = 0;\r
167 block->fb_ptr = fb_ptr + 8 + 1024;\r
168 block++;\r
169 \r
170 texture_offset += 8;\r
fc6cef7d 171 fb_ptr += 16;\r
05e2e0c6
E
172\r
173 blocks_remaining--;\r
174 }\r
175\r
176 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
177 load_128b(texels, texture_block_ptr);\r
178 \r
fc6cef7d 179 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
180 block->texels = texels_wide;\r
181 block->draw_mask_bits = right_mask_bits_a;\r
182 block->fb_ptr = fb_ptr;\r
183 block++;\r
184 \r
185 block->texels = texels_wide;\r
186 block->draw_mask_bits = right_mask_bits_a;\r
187 block->fb_ptr = fb_ptr + 1024;\r
188 block++; \r
189\r
fc6cef7d 190 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
191 block->texels = texels_wide;\r
192 block->draw_mask_bits = right_mask_bits_b;\r
193 block->fb_ptr = fb_ptr + 8;\r
194 block++;\r
195\r
196 block->texels = texels_wide;\r
197 block->draw_mask_bits = right_mask_bits_b;\r
198 block->fb_ptr = fb_ptr + 8 + 1024; \r
199 block++;\r
200\r
201 fb_ptr += fb_ptr_pitch;\r
202\r
203 height--;\r
204 psx_gpu->num_blocks = num_blocks;\r
205 }\r
206 }\r
207}\r
208\r
209#endif\r
210\r
fc6cef7d 211static void setup_sprite_untextured_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y,\r
212 s32 u, s32 v, s32 width, s32 height, u32 color)\r
213{\r
214 setup_sprite_untextured(psx_gpu, x, y, u, v, width * 2, height * 2, color);\r
215}\r
216\r
05e2e0c6
E
217#define setup_sprite_blocks_switch_textured_4x(texture_mode) \\r
218 setup_sprite_##texture_mode##_4x \\r
219\r
220#define setup_sprite_blocks_switch_untextured_4x(texture_mode) \\r
fc6cef7d 221 setup_sprite_untextured_4x \\r
05e2e0c6
E
222\r
223#define setup_sprite_blocks_switch_4x(texturing, texture_mode) \\r
224 setup_sprite_blocks_switch_##texturing##_4x(texture_mode) \\r
225\r
226 \r
227#define render_sprite_blocks_switch_block_modulation_4x(texture_mode, \\r
228 blend_mode, mask_evaluate, shading, dithering, texturing, blending, \\r
229 modulation) \\r
230{ \\r
231 setup_sprite_blocks_switch_4x(texturing, texture_mode), \\r
232 texture_sprite_blocks_switch_##texturing(texture_mode), \\r
233 shade_blocks_switch(unshaded, texturing, modulation, undithered, blending, \\r
234 mask_evaluate), \\r
235 blend_blocks_switch(texturing, blending, blend_mode, mask_evaluate) \\r
236} \\r
237\r
238#define render_sprite_blocks_switch_block_blending_4x(texture_mode, \\r
239 blend_mode, mask_evaluate, shading, dithering, texturing, blending) \\r
240 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \\r
241 mask_evaluate, shading, dithering, texturing, blending, modulated), \\r
242 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \\r
243 mask_evaluate, shading, dithering, texturing, blending, unmodulated) \\r
244\r
245#define render_sprite_blocks_switch_block_texturing_4x(texture_mode, \\r
246 blend_mode, mask_evaluate, shading, dithering, texturing) \\r
247 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \\r
248 mask_evaluate, shading, dithering, texturing, unblended), \\r
249 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \\r
250 mask_evaluate, shading, dithering, texturing, blended) \\r
251\r
252#define render_sprite_blocks_switch_block_dithering_4x(texture_mode, \\r
253 blend_mode, mask_evaluate, shading, dithering) \\r
254 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \\r
255 mask_evaluate, shading, dithering, untextured), \\r
256 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \\r
257 mask_evaluate, shading, dithering, textured) \\r
258\r
259#define render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \\r
260 mask_evaluate, shading) \\r
261 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \\r
262 mask_evaluate, shading, undithered), \\r
263 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \\r
264 mask_evaluate, shading, dithered) \\r
265\r
266#define render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, \\r
267 blend_mode, mask_evaluate) \\r
268 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \\r
269 mask_evaluate, unshaded), \\r
270 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \\r
271 mask_evaluate, shaded) \\r
272\r
273#define render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, \\r
274 blend_mode) \\r
275 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \\r
276 off), \\r
277 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \\r
278 on) \\r
279\r
280#define render_sprite_blocks_switch_block_texture_mode_4x(texture_mode) \\r
281 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, average), \\r
282 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add), \\r
283 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, subtract), \\r
284 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add_fourth) \\r
285\r
286#define render_sprite_blocks_switch_block_4x() \\r
287 render_sprite_blocks_switch_block_texture_mode_4x(4bpp), \\r
288 render_sprite_blocks_switch_block_texture_mode_4x(8bpp), \\r
289 render_sprite_blocks_switch_block_texture_mode_4x(16bpp), \\r
290 render_sprite_blocks_switch_block_texture_mode_4x(4bpp) \\r
291\r
292\r
293render_block_handler_struct render_sprite_block_handlers_4x[] =\r
294{\r
295 render_sprite_blocks_switch_block_4x()\r
296};\r
297\r
298\r
299void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,\r
300 s32 width, s32 height, u32 flags, u32 color)\r
301{\r
05e2e0c6
E
302 s32 x_right = x + width - 1;\r
303 s32 y_bottom = y + height - 1;\r
304\r
305#ifdef PROFILE\r
306 sprites++;\r
307#endif\r
308\r
309 if(x < psx_gpu->viewport_start_x)\r
310 {\r
311 u32 clip = psx_gpu->viewport_start_x - x;\r
312 x += clip;\r
313 u += clip;\r
314 width -= clip;\r
315 }\r
316\r
317 if(y < psx_gpu->viewport_start_y)\r
318 {\r
319 s32 clip = psx_gpu->viewport_start_y - y;\r
320 y += clip;\r
321 v += clip;\r
322 height -= clip;\r
323 }\r
324\r
325 if(x_right > psx_gpu->viewport_end_x)\r
326 width -= x_right - psx_gpu->viewport_end_x;\r
327\r
328 if(y_bottom > psx_gpu->viewport_end_y)\r
329 height -= y_bottom - psx_gpu->viewport_end_y;\r
330\r
331 if((width <= 0) || (height <= 0))\r
332 return;\r
333\r
fc6cef7d 334 x *= 2;\r
335 y *= 2;\r
336\r
05e2e0c6
E
337#ifdef PROFILE\r
338 span_pixels += width * height;\r
339 spans += height;\r
340#endif\r
341\r
342 u32 render_state = flags &\r
343 (RENDER_FLAGS_MODULATE_TEXELS | RENDER_FLAGS_BLEND |\r
344 RENDER_FLAGS_TEXTURE_MAP);\r
345 render_state |=\r
346 (psx_gpu->render_state_base & ~RENDER_STATE_DITHER);\r
347\r
348 if((psx_gpu->render_state != render_state) ||\r
349 (psx_gpu->primitive_type != PRIMITIVE_TYPE_SPRITE))\r
350 {\r
351 psx_gpu->render_state = render_state;\r
352 flush_render_block_buffer(psx_gpu);\r
353#ifdef PROFILE\r
354 state_changes++;\r
355#endif\r
356 }\r
357\r
358 psx_gpu->primitive_type = PRIMITIVE_TYPE_SPRITE;\r
359\r
360 color &= 0xFFFFFF;\r
361\r
362 if(psx_gpu->triangle_color != color)\r
363 {\r
364 flush_render_block_buffer(psx_gpu);\r
365 psx_gpu->triangle_color = color;\r
366 }\r
367\r
368 if(color == 0x808080)\r
369 render_state |= RENDER_FLAGS_MODULATE_TEXELS;\r
370\r
371 render_block_handler_struct *render_block_handler =\r
372 &(render_sprite_block_handlers_4x[render_state]);\r
373 psx_gpu->render_block_handler = render_block_handler;\r
374\r
375 ((setup_sprite_function_type *)render_block_handler->setup_blocks)\r
376 (psx_gpu, x, y, u, v, width, height, color);\r
377}\r
378\r