1 #if !defined(NEON_BUILD) || defined(SIMD_BUILD)
\r
5 #define vector_cast(vec_to, source) source
\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
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
19 u32 left_offset = u & 0x7;
\r
20 u32 width_rounded = width + left_offset + 7;
\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
27 u32 left_mask_bits = ~(0xFFFF << (left_offset * 2));
\r
28 u32 right_mask_bits = 0xFFFC << (right_width * 2);
\r
30 u32 texture_offset_base = u + (v * 1024);
\r
32 psx_gpu->texture_mask_width | (psx_gpu->texture_mask_height * 1024);
\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
38 u16 *texture_page_ptr = psx_gpu->texture_page_ptr;
\r
39 u16 *texture_block_ptr;
\r
41 texture_offset_base &= ~0x7;
\r
45 if(block_width == 1)
\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
52 vec_8x16u texels_wide;
\r
59 if(num_blocks > MAX_BLOCKS)
\r
61 flush_render_block_buffer(psx_gpu);
\r
63 block = psx_gpu->blocks;
\r
67 texture_page_ptr + (texture_offset_base & texture_mask);
\r
69 //load_128b(texels, texture_block_ptr);
\r
70 texels = *(vec_8x16u *)texture_block_ptr;
\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
78 block->texels = texels_wide;
\r
79 block->draw_mask_bits = mask_bits_a;
\r
80 block->fb_ptr = fb_ptr + 1024;
\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
89 block->texels = texels_wide;
\r
90 block->draw_mask_bits = mask_bits_b;
\r
91 block->fb_ptr = fb_ptr + 8 + 1024;
\r
94 texture_offset_base += 1024;
\r
98 psx_gpu->num_blocks = num_blocks;
\r
103 u32 texture_offset;
\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
111 vec_8x16u texels_wide;
\r
115 blocks_remaining = block_width - 2;
\r
116 num_blocks += block_width * 4;
\r
117 sprite_blocks += block_width * 4;
\r
119 if(num_blocks > MAX_BLOCKS)
\r
121 flush_render_block_buffer(psx_gpu);
\r
122 num_blocks = block_width * 4;
\r
123 block = psx_gpu->blocks;
\r
126 texture_offset = texture_offset_base;
\r
127 texture_offset_base += 1024;
\r
129 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
131 //load_128b(texels, texture_block_ptr);
\r
132 texels = *(vec_8x16u *)texture_block_ptr;
\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
140 block->texels = texels_wide;
\r
141 block->draw_mask_bits = left_mask_bits_a;
\r
142 block->fb_ptr = fb_ptr + 1024;
\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
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
156 texture_offset += 8;
\r
159 while(blocks_remaining)
\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
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
171 block->texels = texels_wide;
\r
172 block->draw_mask_bits = 0;
\r
173 block->fb_ptr = fb_ptr + 1024;
\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
182 block->texels = texels_wide;
\r
183 block->draw_mask_bits = 0;
\r
184 block->fb_ptr = fb_ptr + 8 + 1024;
\r
187 texture_offset += 8;
\r
190 blocks_remaining--;
\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
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
203 block->texels = texels_wide;
\r
204 block->draw_mask_bits = right_mask_bits_a;
\r
205 block->fb_ptr = fb_ptr + 1024;
\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
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
219 fb_ptr += fb_ptr_pitch;
\r
222 psx_gpu->num_blocks = num_blocks;
\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
236 setup_sprite_untextured(psx_gpu, x, y, u, v, width, height, color);
\r
239 #define setup_sprite_blocks_switch_textured_4x(texture_mode) \
\r
240 setup_sprite_##texture_mode##_4x \
\r
242 #define setup_sprite_blocks_switch_untextured_4x(texture_mode) \
\r
243 setup_sprite_untextured_4x \
\r
245 #define setup_sprite_blocks_switch_4x(texturing, texture_mode) \
\r
246 setup_sprite_blocks_switch_##texturing##_4x(texture_mode) \
\r
249 #define render_sprite_blocks_switch_block_modulation_4x(texture_mode, \
\r
250 blend_mode, mask_evaluate, shading, dithering, texturing, blending, \
\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
257 blend_blocks_switch(texturing, blending, blend_mode, mask_evaluate) \
\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
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
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
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
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
295 #define render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, \
\r
297 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \
\r
299 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \
\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
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
315 render_block_handler_struct render_sprite_block_handlers_4x[] =
\r
317 render_sprite_blocks_switch_block_4x()
\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
323 s32 x_right = x + width - 1;
\r
324 s32 y_bottom = y + height - 1;
\r
331 if(x < psx_gpu->viewport_start_x)
\r
333 u32 clip = psx_gpu->viewport_start_x - x;
\r
339 if(y < psx_gpu->viewport_start_y)
\r
341 s32 clip = psx_gpu->viewport_start_y - y;
\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
351 if(x_right > end_x)
\r
352 width -= x_right - end_x;
\r
354 if(y_bottom > psx_gpu->viewport_end_y)
\r
355 height -= y_bottom - psx_gpu->viewport_end_y;
\r
357 if((width <= 0) || (height <= 0))
\r
360 if (!psx_gpu->enhancement_current_buf_ptr)
\r
362 psx_gpu->vram_out_ptr = psx_gpu->enhancement_current_buf_ptr;
\r
368 span_pixels += width * height;
\r
372 u32 render_state = flags &
\r
373 (RENDER_FLAGS_MODULATE_TEXELS | RENDER_FLAGS_BLEND |
\r
374 RENDER_FLAGS_TEXTURE_MAP);
\r
376 (psx_gpu->render_state_base & ~RENDER_STATE_DITHER);
\r
378 if((psx_gpu->render_state != render_state) ||
\r
379 (psx_gpu->primitive_type != PRIMITIVE_TYPE_SPRITE))
\r
381 psx_gpu->render_state = render_state;
\r
382 flush_render_block_buffer(psx_gpu);
\r
388 psx_gpu->primitive_type = PRIMITIVE_TYPE_SPRITE;
\r
392 if(psx_gpu->triangle_color != color)
\r
394 flush_render_block_buffer(psx_gpu);
\r
395 psx_gpu->triangle_color = color;
\r
398 if(color == 0x808080)
\r
399 render_state |= RENDER_FLAGS_MODULATE_TEXELS;
\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
405 ((setup_sprite_function_type *)render_block_handler->setup_blocks)
\r
406 (psx_gpu, x, y, u, v, width, height, color);
\r