e585611e22394f82309d1160d08f846713aa6802
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu / psx_gpu.h
1 /*
2  * Copyright (C) 2011 Gilead Kutnick "Exophase" <exophase@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #ifndef PSX_GPU_H
16 #define PSX_GPU_H
17
18 #define MAX_SPANS             512
19 #define MAX_BLOCKS            64
20 #define MAX_BLOCKS_PER_ROW    128
21
22 #define SPAN_DATA_BLOCKS_SIZE 32
23
24 #define AHACK_TEXTURE_ADJ_U   (1 << 0)
25 #define AHACK_TEXTURE_ADJ_V   (1 << 1)
26
27 #ifndef __ASSEMBLER__
28
29 #include "vector_types.h"
30
31 #ifndef unlikely
32 #define unlikely(x) __builtin_expect((x), 0)
33 #endif
34
35 #define sign_extend_11bit(value) \
36   (((s32)((value) << 21)) >> 21)
37
38 typedef enum
39 {
40   PRIMITIVE_TYPE_TRIANGLE = 0,
41   PRIMITIVE_TYPE_SPRITE = 1,
42   PRIMITIVE_TYPE_LINE = 2,
43   PRIMITIVE_TYPE_UNKNOWN = 3
44 } primitive_type_enum;
45
46 typedef enum
47 {
48   TEXTURE_MODE_4BPP  = 0,
49   TEXTURE_MODE_8BPP  = 1,
50   TEXTURE_MODE_16BPP = 2
51 } texture_mode_enum;
52
53 typedef enum
54 {
55   BLEND_MODE_AVERAGE    = 0,
56   BLEND_MODE_ADD        = 1,
57   BLEND_MODE_SUBTRACT   = 2,
58   BLEND_MODE_ADD_FOURTH = 3
59 } blend_mode_enum;
60
61 typedef enum
62 {
63   RENDER_FLAGS_MODULATE_TEXELS = 0x1,
64   RENDER_FLAGS_BLEND           = 0x2,
65   RENDER_FLAGS_TEXTURE_MAP     = 0x4,
66   RENDER_FLAGS_QUAD            = 0x8,
67   RENDER_FLAGS_SHADE           = 0x10,
68 } render_flags_enum;
69
70 typedef enum
71 {
72   RENDER_STATE_DITHER          = 0x8,
73   RENDER_STATE_MASK_EVALUATE   = 0x20,
74 } render_state_enum;
75
76 typedef enum
77 {
78   RENDER_INTERLACE_ENABLED     = 0x1,
79   RENDER_INTERLACE_ODD         = 0x2,
80 } render_mode_enum;
81
82 typedef struct
83 {
84   u16 left_x;
85   u16 num_blocks;
86   u16 right_mask;
87   u16 y;
88 } edge_data_struct;
89
90 // 64 (72) bytes total
91 typedef struct
92 {
93   // 16 bytes
94   union
95   {
96     vec_8x16u uv;
97     vec_8x16u texels;
98     vec_8x16u draw_mask;
99   };
100
101   // 24 bytes
102   union
103   {
104     struct
105     {
106       vec_8x8u r;
107       vec_8x8u g;
108       vec_8x8u b;
109     };
110
111     vec_8x16u pixels;
112   };
113
114   // 8 (16) bytes
115   u32 draw_mask_bits;
116   u16 *fb_ptr;
117
118   // 16 bytes
119   vec_8x16u dither_offsets;  
120 } block_struct;
121
122 typedef struct render_block_handler_struct render_block_handler_struct;
123
124 typedef struct
125 {
126   // 144 bytes
127   vec_8x16u test_mask;
128
129   vec_4x32u uvrg;
130   vec_4x32u uvrg_dx;
131   vec_4x32u uvrg_dy;
132
133   vec_4x32u u_block_span;
134   vec_4x32u v_block_span;
135   vec_4x32u r_block_span;
136   vec_4x32u g_block_span;
137   vec_4x32u b_block_span;
138
139   u32 b;
140   u32 b_dy;
141
142   u32 triangle_area;
143
144   u32 texture_window_settings;
145   u32 current_texture_mask;
146   u32 viewport_mask;
147   u32 dirty_textures_4bpp_mask;
148   u32 dirty_textures_8bpp_mask;
149   u32 dirty_textures_8bpp_alternate_mask;
150
151   u32 triangle_color;
152   u32 dither_table[4];
153
154   struct render_block_handler_struct *render_block_handler;
155   void *texture_page_ptr;
156   void *texture_page_base;
157   u16 *clut_ptr;
158   u16 *vram_ptr;
159   u16 *vram_out_ptr;
160
161   u32 uvrgb_phase;
162
163   u16 render_state_base;
164   u16 render_state;
165
166   u16 num_spans;
167   u16 num_blocks;
168
169   s16 viewport_start_x;
170   s16 viewport_start_y;
171   s16 viewport_end_x;
172   s16 viewport_end_y;
173
174   u16 mask_msb;
175
176   u8 triangle_winding;
177
178   u8 display_area_draw_enable;
179
180   u8 current_texture_page;
181   u8 last_8bpp_texture_page;
182
183   u8 texture_mask_width;
184   u8 texture_mask_height;
185   u8 texture_window_x;
186   u8 texture_window_y;
187
188   u8 primitive_type;
189   u8 render_mode;
190
191   s16 offset_x;
192   s16 offset_y;
193
194   u16 clut_settings;
195   u16 texture_settings;
196
197   u32 *reciprocal_table_ptr;
198
199   // enhancement stuff
200   u16 *enhancement_buf_ptr;          // main alloc
201   u16 *enhancement_current_buf_ptr;  // offset into above, 4 bufs
202   u32 hacks_active;                  // AHACK_TEXTURE_ADJ_U ...
203   u32 saved_hres;
204   s16 saved_viewport_start_x;
205   s16 saved_viewport_start_y;
206   s16 saved_viewport_end_x;
207   s16 saved_viewport_end_y;
208   struct psx_gpu_scanout {
209     u16 x, y, w, h;
210   } enhancement_scanouts[4];         // 0-3 specifying which buf to use
211   u16 enhancement_scanout_eselect;   // eviction selector
212   u16 enhancement_current_buf;
213
214   u32 allow_dithering:1;
215   u32 force_dithering:1;
216   u32 hack_disable_main:1;
217   u32 hack_texture_adj:1;
218
219   // Align up to 64 byte boundary to keep the upcoming buffers cache line
220   // aligned, also make reachable with single immediate addition
221   u8 reserved_a[68 + 9*4 - 9*sizeof(void *)];
222
223   // space for saving regs on c call to flush_render_block_buffer() and asm
224   u32 saved_tmp[48 / sizeof(u32)];
225   u32 saved_q4_q7[64 / sizeof(u32)];
226
227   // 8KB
228   block_struct blocks[MAX_BLOCKS_PER_ROW];
229
230   // 14336 bytes
231   vec_4x32u span_uvrg_offset[MAX_SPANS];
232   edge_data_struct span_edge_data[MAX_SPANS];
233   u32 span_b_offset[MAX_SPANS];
234
235   u8 texture_4bpp_cache[32][256 * 256];
236   u8 texture_8bpp_even_cache[16][256 * 256];
237   u8 texture_8bpp_odd_cache[16][256 * 256];
238 } psx_gpu_struct;
239
240 typedef struct __attribute__((aligned(16)))
241 {
242   u8 u;
243   u8 v;
244
245   u8 r;
246   u8 g;
247   u8 b;
248
249   u8 reserved[3];
250
251   s16 x;
252   s16 y;
253
254   u32 padding;
255 } vertex_struct;
256
257 typedef struct
258 {
259   vertex_struct *vertexes[3];
260   s16 offset_x;
261   s16 offset_y;
262 } prepared_triangle;
263
264 void render_block_fill(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y,
265  u32 width, u32 height);
266 void render_block_copy(psx_gpu_struct *psx_gpu, u16 *source, u32 x, u32 y,
267  u32 width, u32 height, u32 pitch);
268 void render_block_move(psx_gpu_struct *psx_gpu, u32 source_x, u32 source_y,
269  u32 dest_x, u32 dest_y, u32 width, u32 height);
270
271 void render_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes,
272  u32 flags);
273 void render_sprite(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,
274  s32 *width, s32 *height, u32 flags, u32 color);
275 void render_line(psx_gpu_struct *gpu, vertex_struct *vertexes, u32 flags,
276  u32 color, int double_resolution);
277
278 u32 texture_region_mask(s32 x1, s32 y1, s32 x2, s32 y2);
279
280 void update_texture_8bpp_cache(psx_gpu_struct *psx_gpu);
281 void flush_render_block_buffer(psx_gpu_struct *psx_gpu);
282
283 void setup_blocks_uv_adj_hack(psx_gpu_struct *psx_gpu, block_struct *block,
284     edge_data_struct *span_edge_data, vec_4x32u *span_uvrg_offset);
285
286 void initialize_psx_gpu(psx_gpu_struct *psx_gpu, u16 *vram);
287 u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
288  s32 *cpu_cycles_sum_out, s32 *cpu_cycles_last, u32 *last_command);
289
290 void triangle_benchmark(psx_gpu_struct *psx_gpu);
291
292 void compute_all_gradients(psx_gpu_struct * __restrict__ psx_gpu,
293  const vertex_struct * __restrict__ a, const vertex_struct * __restrict__ b,
294  const vertex_struct * __restrict__ c);
295
296 #endif // __ASSEMBLER__
297 #endif // PSX_GPU_H