2 * Copyright (C) 2011 Gilead Kutnick "Exophase" <exophase@gmail.com>
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.
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.
21 extern u32 span_pixels;
22 extern u32 span_pixel_blocks;
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;
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;
50 static u32 mismatches;
59 static gpu_dump_struct state;
61 psx_gpu_struct __attribute__((aligned(256))) _psx_gpu;
62 u16 __attribute__((aligned(256))) _vram[(1024 * 512) + 1024];
64 #define percent_of(numerator, denominator) \
65 ((((double)(numerator)) / (denominator)) * 100.0) \
67 void clear_stats(void)
74 sprites_untextured = 0;
78 span_pixel_blocks = 0;
83 texel_blocks_untextured = 0;
84 texel_blocks_4bpp = 0;
85 texel_blocks_8bpp = 0;
86 texel_blocks_16bpp = 0;
88 render_buffer_flushes = 0;
91 left_split_triangles = 0;
93 clipped_triangles = 0;
95 texture_cache_loads = 0;
96 false_modulated_blocks = 0;
99 void update_screen(psx_gpu_struct *psx_gpu, SDL_Surface *screen)
103 for(y = 0; y < 512; y++)
105 for(x = 0; x < 1024; x++)
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);
121 #include <linux/fb.h>
122 #include <sys/mman.h>
123 #include <sys/ioctl.h>
127 int main(int argc, char *argv[])
129 psx_gpu_struct *psx_gpu = &_psx_gpu;
130 SDL_Surface *screen = NULL;
141 if((argc != 3) && (argc != 4))
143 printf("usage:\n%s <state> <list>\n", argv[0]);
147 if((argc == 4) && !strcmp(argv[3], "-n"))
150 state_file = fopen(argv[1], "rb");
151 fread(&state, 1, sizeof(gpu_dump_struct), state_file);
154 list_file = fopen(argv[2], "rb");
156 fseek(list_file, 0, SEEK_END);
157 size = ftell(list_file);
158 fseek(list_file, 0, SEEK_SET);
162 fread(list, 1, size, list_file);
167 SDL_Init(SDL_INIT_EVERYTHING);
168 screen = SDL_SetVideoMode(1024, 512, 32, 0);
171 printf("can't set video mode: %s\n", SDL_GetError());
179 system("ofbset -fb /dev/fb1 -mem 6291456 -en 0");
180 u32 fbdev_handle = open("/dev/fb1", O_RDWR);
181 vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
182 MAP_SHARED | 0xA0000000, fbdev_handle, 0));
185 #define MAP_HUGETLB 0x40000 /* arch specific */
187 vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
188 MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB, -1, 0));
190 vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
191 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
193 if (vram_ptr == MAP_FAILED)
200 initialize_psx_gpu(psx_gpu, vram_ptr);
202 initialize_psx_gpu(psx_gpu, _vram + 64);
206 //triangle_benchmark(psx_gpu);
210 memcpy(psx_gpu->vram_ptr, state.vram, 1024 * 512 * 2);
218 gpu_parse(psx_gpu, list, size, &dummy0, &dummy1);
219 flush_render_block_buffer(psx_gpu);
224 u32 cycles = get_counter();
227 gpu_parse(psx_gpu, list, size, &dummy0, &dummy1);
228 flush_render_block_buffer(psx_gpu);
231 u32 cycles_elapsed = get_counter() - cycles;
233 printf("%-64s: %d\n", argv[1], cycles_elapsed);
235 printf("%-64s: ", argv[1]);
241 for(i = 0; i < 1024 * 512; i++)
243 if((psx_gpu->vram_ptr[i] & 0x7FFF) != (state.vram[i] & 0x7FFF))
245 printf("(%d %d %d) vs (%d %d %d) at (%d %d)\n",
246 psx_gpu->vram_ptr[i] & 0x1F,
247 (psx_gpu->vram_ptr[i] >> 5) & 0x1F,
248 (psx_gpu->vram_ptr[i] >> 10) & 0x1F,
249 state.vram[i] & 0x1F,
250 (state.vram[i] >> 5) & 0x1F,
251 (state.vram[i] >> 10) & 0x1F, i % 1024, i / 1024);
257 psx_gpu->vram_ptr[i] =
258 ((psx_gpu->vram_ptr[i] & 0x1F) / 4) |
259 ((((psx_gpu->vram_ptr[i] >> 5) & 0x1F) / 4) << 5) |
260 ((((psx_gpu->vram_ptr[i] >> 10) & 0x1F) / 4) << 10);
267 printf(" %d pixels, %d pixel blocks, %d spans\n"
268 " (%lf pixels per block, %lf pixels per span),\n"
269 " %lf blocks per span (%lf per non-zero span), %lf overdraw)\n\n",
270 span_pixels, span_pixel_blocks, spans,
271 (double)span_pixels / span_pixel_blocks,
272 (double)span_pixels / spans,
273 (double)span_pixel_blocks / spans,
274 (double)span_pixel_blocks / (spans - zero_block_spans),
275 (double)span_pixels /
276 ((psx_gpu->viewport_end_x - psx_gpu->viewport_start_x) *
277 (psx_gpu->viewport_end_y - psx_gpu->viewport_start_y)));
279 printf(" %d triangles\n"
280 " (%d trivial rejects, %lf%% flat, %lf%% left split, %lf%% clipped)\n"
281 " (%lf pixels per triangle, %lf rows per triangle)\n\n",
282 triangles, trivial_rejects,
283 percent_of(flat_triangles, triangles),
284 percent_of(left_split_triangles, triangles),
285 percent_of(clipped_triangles, triangles),
286 (double)span_pixels / triangles,
287 (double)spans / triangles);
289 printf(" Block data:\n");
290 printf(" %7d 4bpp texel blocks (%lf%%)\n", texel_blocks_4bpp,
291 percent_of(texel_blocks_4bpp, span_pixel_blocks));
292 printf(" %7d 8bpp texel blocks (%lf%%)\n", texel_blocks_8bpp,
293 percent_of(texel_blocks_8bpp, span_pixel_blocks));
294 printf(" %7d 16bpp texel blocks (%lf%%)\n", texel_blocks_16bpp,
295 percent_of(texel_blocks_16bpp, span_pixel_blocks));
296 printf(" %7d untextured blocks (%lf%%)\n", texel_blocks_untextured,
297 percent_of(texel_blocks_untextured, span_pixel_blocks));
298 printf(" %7d sprite blocks (%lf%%)\n", sprite_blocks,
299 percent_of(sprite_blocks, span_pixel_blocks));
300 printf(" %7d blended blocks (%lf%%)\n", blend_blocks,
301 percent_of(blend_blocks, span_pixel_blocks));
302 printf(" %7d false-mod blocks (%lf%%)\n", false_modulated_blocks,
303 percent_of(false_modulated_blocks, span_pixel_blocks));
305 printf(" %lf blocks per render buffer flush\n", (double)span_pixel_blocks /
306 render_buffer_flushes);
307 printf(" %d zero block spans\n", zero_block_spans);
308 printf(" %d state changes, %d texture cache loads\n", state_changes,
309 texture_cache_loads);
312 printf(" %d sprites\n"
316 " untextured: %lf%%\n",
317 sprites, percent_of(sprites_4bpp, sprites),
318 percent_of(sprites_8bpp, sprites), percent_of(sprites_16bpp, sprites),
319 percent_of(sprites_untextured, sprites));
321 printf(" %d lines\n", lines);
323 printf(" %d mismatches\n\n\n", mismatches);
332 update_screen(psx_gpu, screen);
334 if(SDL_PollEvent(&event))
336 if((event.type == SDL_QUIT) ||
337 ((event.type == SDL_KEYDOWN) &&
338 (event.key.keysym.sym == SDLK_ESCAPE)))
348 return (mismatches != 0);