gpu_neon: merge cmd size tables
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu / psx_gpu_main.c
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 #include <stdio.h>
16 #include <stdlib.h>
17
18 #include "SDL.h"
19 #include "common.h"
20
21 extern u32 span_pixels;
22 extern u32 span_pixel_blocks;
23 extern u32 spans;
24 extern u32 triangles;
25 extern u32 sprites;
26 extern u32 sprites_4bpp;
27 extern u32 sprites_8bpp;
28 extern u32 sprites_16bpp;
29 extern u32 sprites_untextured;
30 extern u32 sprite_blocks;
31 extern u32 lines;
32 extern u32 texels_4bpp;
33 extern u32 texels_8bpp;
34 extern u32 texels_16bpp;
35 extern u32 texel_blocks_4bpp;
36 extern u32 texel_blocks_8bpp;
37 extern u32 texel_blocks_16bpp;
38 extern u32 texel_blocks_untextured;
39 extern u32 blend_blocks;
40 extern u32 render_buffer_flushes;
41 extern u32 state_changes;
42 extern u32 trivial_rejects;
43 extern u32 left_split_triangles;
44 extern u32 flat_triangles;
45 extern u32 clipped_triangles;
46 extern u32 zero_block_spans;
47 extern u32 texture_cache_loads;
48 extern u32 false_modulated_blocks;
49
50 static u32 mismatches;
51
52 typedef struct
53 {
54         u16 vram[1024 * 512];
55         u32 gpu_register[15];
56         u32 status;
57 } gpu_dump_struct;
58
59 static gpu_dump_struct state;
60
61 psx_gpu_struct __attribute__((aligned(256))) _psx_gpu;
62 u16 __attribute__((aligned(256))) _vram[(1024 * 512) + 1024];
63
64 #define percent_of(numerator, denominator)                                     \
65   ((((double)(numerator)) / (denominator)) * 100.0)                            \
66
67 void clear_stats(void)
68 {
69   triangles = 0;
70   sprites = 0;
71   sprites_4bpp = 0;
72   sprites_8bpp = 0;
73   sprites_16bpp = 0;
74   sprites_untextured = 0;
75   sprite_blocks = 0;
76   lines = 0;
77   span_pixels = 0;
78   span_pixel_blocks = 0;
79   spans = 0;
80   texels_4bpp = 0;
81   texels_8bpp = 0;
82   texels_16bpp = 0;
83   texel_blocks_untextured = 0;
84   texel_blocks_4bpp = 0;
85   texel_blocks_8bpp = 0;
86   texel_blocks_16bpp = 0;
87   blend_blocks = 0;
88   render_buffer_flushes = 0;
89   state_changes = 0;
90   trivial_rejects = 0;
91   left_split_triangles = 0;
92   flat_triangles = 0;
93   clipped_triangles = 0;
94   zero_block_spans = 0;
95   texture_cache_loads = 0;
96   false_modulated_blocks = 0;
97 }
98
99 void update_screen(psx_gpu_struct *psx_gpu, SDL_Surface *screen)
100 {
101   u32 x, y;
102
103   for(y = 0; y < 512; y++)
104   {
105     for(x = 0; x < 1024; x++)
106     {
107       u32 pixel = psx_gpu->vram_ptr[(y * 1024) + x];
108       ((u32 *)screen->pixels)[(y * 1024) + x] =
109        ((pixel & 0x1F) << (16 + 3)) |
110        (((pixel >> 5) & 0x1F) << (8 + 3)) |
111        (((pixel >> 10) & 0x1F) << 3);
112     }
113   }
114
115   SDL_Flip(screen);
116 }
117
118 #ifdef NEON_BUILD
119
120 #include <fcntl.h>
121 #include <linux/fb.h>
122 #include <sys/mman.h>
123 #include <sys/ioctl.h>
124   
125 #endif
126
127 int main(int argc, char *argv[])
128 {
129   psx_gpu_struct *psx_gpu = &_psx_gpu;
130   SDL_Surface *screen;
131   SDL_Event event;
132
133   u32 *list;
134   int size;
135   FILE *state_file;
136   FILE *list_file;
137   u32 no_display = 0;
138
139   if((argc != 3) && (argc != 4))
140   {
141     printf("usage:\n%s <state> <list>\n", argv[0]);
142     return 1;
143   }
144
145   if((argc == 4) && !strcmp(argv[3], "-n"))
146     no_display = 1;
147   
148   state_file = fopen(argv[1], "rb");
149   fread(&state, 1, sizeof(gpu_dump_struct), state_file);
150   fclose(state_file);
151   
152   list_file = fopen(argv[2], "rb");
153   
154   fseek(list_file, 0, SEEK_END);
155   size = ftell(list_file);
156   fseek(list_file, 0, SEEK_SET);
157   //size = 0;
158
159   list = malloc(size);
160   fread(list, 1, size, list_file);
161   fclose(list_file);
162  
163   if(no_display == 0) 
164   {
165     SDL_Init(SDL_INIT_EVERYTHING);
166     screen = SDL_SetVideoMode(1024, 512, 32, 0);
167   }
168
169 #ifdef NEON_BUILD
170   system("ofbset -fb /dev/fb1 -mem 6291456 -en 0");
171   u32 fbdev_handle = open("/dev/fb1", O_RDWR);
172   u16 *vram_ptr =
173   vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
174    MAP_SHARED | 0xA0000000, fbdev_handle, 0));
175   vram_ptr += 64;
176
177   initialize_psx_gpu(psx_gpu, vram_ptr);
178 #else
179   initialize_psx_gpu(psx_gpu, _vram + 64);
180 #endif
181
182 #ifdef NEON_BUILD
183   //triangle_benchmark(psx_gpu);
184   //return 0;
185 #endif
186
187   memcpy(psx_gpu->vram_ptr, state.vram, 1024 * 512 * 2);
188
189   clear_stats();
190
191 #ifdef NEON_BUILD
192   init_counter();
193 #endif
194
195   gpu_parse(psx_gpu, list, size);
196   flush_render_block_buffer(psx_gpu);
197
198   clear_stats();
199
200 #ifdef NEON_BUILD
201   u32 cycles = get_counter();
202 #endif
203
204   gpu_parse(psx_gpu, list, size);
205   flush_render_block_buffer(psx_gpu);
206
207 #ifdef NEON_BUILD
208   u32 cycles_elapsed = get_counter() - cycles;
209
210   printf("%-64s: %d\n", argv[1], cycles_elapsed);
211 #else
212   printf("%-64s: ", argv[1]);
213 #endif
214
215 #if 1
216   u32 i;
217
218   for(i = 0; i < 1024 * 512; i++)
219   {
220     if((psx_gpu->vram_ptr[i] & 0x7FFF) != (state.vram[i] & 0x7FFF))
221     {
222       printf("(%d %d %d) vs (%d %d %d) at (%d %d)\n",
223        psx_gpu->vram_ptr[i] & 0x1F,
224        (psx_gpu->vram_ptr[i] >> 5) & 0x1F,
225        (psx_gpu->vram_ptr[i] >> 10) & 0x1F,
226        state.vram[i] & 0x1F,
227        (state.vram[i] >> 5) & 0x1F,
228        (state.vram[i] >> 10) & 0x1F, i % 1024, i / 1024);
229
230       mismatches++;
231     }
232     else
233     {
234       psx_gpu->vram_ptr[i] =
235        ((psx_gpu->vram_ptr[i] & 0x1F) / 4) |
236        ((((psx_gpu->vram_ptr[i] >> 5) & 0x1F) / 4) << 5) |
237        ((((psx_gpu->vram_ptr[i] >> 10) & 0x1F) / 4) << 10);
238     }
239   }
240 #endif
241
242 #if 0
243   printf("\n");
244   printf("  %d pixels, %d pixel blocks, %d spans\n"
245    "   (%lf pixels per block, %lf pixels per span),\n"
246    "   %lf blocks per span (%lf per non-zero span), %lf overdraw)\n\n",
247    span_pixels, span_pixel_blocks, spans,
248    (double)span_pixels / span_pixel_blocks,
249    (double)span_pixels / spans,
250    (double)span_pixel_blocks / spans, 
251    (double)span_pixel_blocks / (spans - zero_block_spans),
252    (double)span_pixels / 
253    ((psx_gpu->viewport_end_x - psx_gpu->viewport_start_x) * 
254    (psx_gpu->viewport_end_y - psx_gpu->viewport_start_y)));
255
256   printf("  %d triangles\n"
257    "   (%d trivial rejects, %lf%% flat, %lf%% left split, %lf%% clipped)\n"
258    "   (%lf pixels per triangle, %lf rows per triangle)\n\n",
259    triangles, trivial_rejects,
260    percent_of(flat_triangles, triangles),
261    percent_of(left_split_triangles, triangles),
262    percent_of(clipped_triangles, triangles),
263    (double)span_pixels / triangles,
264    (double)spans / triangles);
265
266   printf("  Block data:\n");
267   printf("   %7d 4bpp texel blocks  (%lf%%)\n", texel_blocks_4bpp,
268    percent_of(texel_blocks_4bpp, span_pixel_blocks));
269   printf("   %7d 8bpp texel blocks  (%lf%%)\n", texel_blocks_8bpp,
270    percent_of(texel_blocks_8bpp, span_pixel_blocks));
271   printf("   %7d 16bpp texel blocks (%lf%%)\n", texel_blocks_16bpp,
272    percent_of(texel_blocks_16bpp, span_pixel_blocks));
273   printf("   %7d untextured blocks  (%lf%%)\n", texel_blocks_untextured,
274    percent_of(texel_blocks_untextured, span_pixel_blocks));
275   printf("   %7d sprite blocks      (%lf%%)\n", sprite_blocks,  
276    percent_of(sprite_blocks, span_pixel_blocks));
277   printf("   %7d blended blocks     (%lf%%)\n", blend_blocks,
278    percent_of(blend_blocks, span_pixel_blocks));
279   printf("   %7d false-mod blocks   (%lf%%)\n", false_modulated_blocks,
280    percent_of(false_modulated_blocks, span_pixel_blocks));
281   printf("\n");
282   printf("  %lf blocks per render buffer flush\n", (double)span_pixel_blocks /
283    render_buffer_flushes);
284   printf("  %d zero block spans\n", zero_block_spans);
285   printf("  %d state changes, %d texture cache loads\n", state_changes,
286    texture_cache_loads);
287   if(sprites)
288   {
289     printf("  %d sprites\n"
290      "    4bpp:       %lf%%\n"
291      "    8bpp:       %lf%%\n"
292      "    16bpp:      %lf%%\n"
293      "    untextured: %lf%%\n",
294      sprites, percent_of(sprites_4bpp, sprites),
295      percent_of(sprites_8bpp, sprites), percent_of(sprites_16bpp, sprites),
296      percent_of(sprites_untextured, sprites));
297   }
298   printf("  %d lines\n", lines);
299   printf("\n");
300   printf("  %d mismatches\n\n\n", mismatches);
301 #endif
302
303   fflush(stdout);
304
305   if(no_display == 0)
306   {
307     while(1)
308     {
309       update_screen(psx_gpu, screen);
310   
311       if(SDL_PollEvent(&event))
312       {
313         if((event.type == SDL_QUIT) ||
314          ((event.type == SDL_KEYDOWN) &&
315          (event.key.keysym.sym == SDLK_ESCAPE)))
316         {
317           break;
318         }      
319       }
320   
321       SDL_Delay(20);
322     }
323   }
324
325   return (mismatches != 0);
326 }