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