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