cdrom: change pause timing again
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu / psx_gpu_4x.c
CommitLineData
a2cb152a 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
05e2e0c6
E
16void 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
fc6cef7d 22 u16 *fb_ptr = psx_gpu->vram_out_ptr + (y * 1024) + (s32)(x - left_offset * 2);\r
05e2e0c6
E
23 u32 right_width = width_rounded & 0x7;\r
24 u32 block_width = width_rounded / 8;\r
fc6cef7d 25 u32 fb_ptr_pitch = (2048 + 16) - (block_width * 16);\r
05e2e0c6
E
26\r
27 u32 left_mask_bits = ~(0xFFFF << (left_offset * 2));\r
fc6cef7d 28 u32 right_mask_bits = 0xFFFC << (right_width * 2);\r
05e2e0c6
E
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
a2cb152a 69 //load_128b(texels, texture_block_ptr);\r
70 texels = *(vec_8x16u *)texture_block_ptr;\r
05e2e0c6 71 \r
fc6cef7d 72 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
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
fc6cef7d 83 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
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
fc6cef7d 122 num_blocks = block_width * 4;\r
05e2e0c6
E
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
a2cb152a 131 //load_128b(texels, texture_block_ptr);\r
132 texels = *(vec_8x16u *)texture_block_ptr;\r
05e2e0c6 133\r
fc6cef7d 134 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
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
fc6cef7d 145 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
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
a2cb152a 162 //load_128b(texels, texture_block_ptr);\r
163 texels = *(vec_8x16u *)texture_block_ptr;\r
05e2e0c6 164\r
fc6cef7d 165 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
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
fc6cef7d 176 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
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
fc6cef7d 188 fb_ptr += 16;\r
05e2e0c6
E
189\r
190 blocks_remaining--;\r
191 }\r
192\r
193 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);\r
a2cb152a 194 //load_128b(texels, texture_block_ptr);\r
195 texels = *(vec_8x16u *)texture_block_ptr;\r
05e2e0c6 196 \r
fc6cef7d 197 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);\r
05e2e0c6
E
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
fc6cef7d 208 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);\r
05e2e0c6
E
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
fc6cef7d 229static 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
2d658c89 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
fc6cef7d 237}\r
238\r
05e2e0c6
E
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
fc6cef7d 243 setup_sprite_untextured_4x \\r
05e2e0c6
E
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
b7f5c059 312 render_sprite_blocks_switch_block_texture_mode_4x(16bpp) \\r
05e2e0c6
E
313\r
314\r
315render_block_handler_struct render_sprite_block_handlers_4x[] =\r
316{\r
317 render_sprite_blocks_switch_block_4x()\r
318};\r
319\r
05e2e0c6
E
320void 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
05e2e0c6
E
323 s32 x_right = x + width - 1;\r
324 s32 y_bottom = y + height - 1;\r
2da2fc76 325 s16 end_x;\r
05e2e0c6
E
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
2da2fc76 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
05e2e0c6
E
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
2da2fc76 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
7956599f 363\r
fc6cef7d 364 x *= 2;\r
365 y *= 2;\r
366\r
05e2e0c6
E
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