psx_gpu: improve fills
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu / psx_gpu_main.c
CommitLineData
75e28f62
E
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
21extern u32 span_pixels;
22extern u32 span_pixel_blocks;
75e28f62
E
23extern u32 spans;
24extern u32 triangles;
25extern u32 sprites;
26extern u32 sprites_4bpp;
27extern u32 sprites_8bpp;
28extern u32 sprites_16bpp;
29extern u32 sprites_untextured;
30extern u32 sprite_blocks;
31extern u32 lines;
32extern u32 texels_4bpp;
33extern u32 texels_8bpp;
34extern u32 texels_16bpp;
35extern u32 texel_blocks_4bpp;
36extern u32 texel_blocks_8bpp;
37extern u32 texel_blocks_16bpp;
38extern u32 texel_blocks_untextured;
39extern u32 blend_blocks;
75e28f62
E
40extern u32 render_buffer_flushes;
41extern u32 state_changes;
42extern u32 trivial_rejects;
43extern u32 left_split_triangles;
44extern u32 flat_triangles;
45extern u32 clipped_triangles;
46extern u32 zero_block_spans;
47extern u32 texture_cache_loads;
3867c6ef 48extern u32 false_modulated_blocks;
75e28f62
E
49
50static u32 mismatches;
51
52typedef struct
53{
54 u16 vram[1024 * 512];
55 u32 gpu_register[15];
56 u32 status;
57} gpu_dump_struct;
58
59static gpu_dump_struct state;
60
61psx_gpu_struct __attribute__((aligned(256))) _psx_gpu;
3867c6ef 62u16 __attribute__((aligned(256))) _vram[(1024 * 512) + 1024];
75e28f62
E
63
64#define percent_of(numerator, denominator) \
65 ((((double)(numerator)) / (denominator)) * 100.0) \
66
67void 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;
75e28f62
E
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;
75e28f62
E
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;
3867c6ef 96 false_modulated_blocks = 0;
75e28f62
E
97}
98
99void 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
2bbbb7af 118#ifdef NEON_BUILD
75e28f62
E
119
120#include <fcntl.h>
121#include <linux/fb.h>
122#include <sys/mman.h>
123#include <sys/ioctl.h>
124
125#endif
126
127int 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;
3867c6ef 158
75e28f62
E
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 }
75e28f62 168
2bbbb7af 169#ifdef NEON_BUILD
75e28f62
E
170 system("ofbset -fb /dev/fb1 -mem 6291456 -en 0");
171 u32 fbdev_handle = open("/dev/fb1", O_RDWR);
3867c6ef
E
172 u16 *vram_ptr =
173 vram_ptr = (mmap((void *)0x50000000, 1024 * 1024 * 2, PROT_READ | PROT_WRITE,
75e28f62 174 MAP_SHARED | 0xA0000000, fbdev_handle, 0));
3867c6ef 175 vram_ptr += 64;
75e28f62 176
87c45ad1 177 initialize_psx_gpu(psx_gpu, vram_ptr);
3867c6ef
E
178#else
179 initialize_psx_gpu(psx_gpu, _vram + 64);
180#endif
75e28f62 181
2bbbb7af 182#ifdef NEON_BUILD
75e28f62
E
183 //triangle_benchmark(psx_gpu);
184 //return 0;
185#endif
186
75e28f62 187 memcpy(psx_gpu->vram_ptr, state.vram, 1024 * 512 * 2);
75e28f62
E
188
189 clear_stats();
190
2bbbb7af 191#ifdef NEON_BUILD
75e28f62
E
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
2bbbb7af 200#ifdef NEON_BUILD
75e28f62
E
201 u32 cycles = get_counter();
202#endif
203
204 gpu_parse(psx_gpu, list, size);
205 flush_render_block_buffer(psx_gpu);
206
2bbbb7af 207#ifdef NEON_BUILD
75e28f62
E
208 u32 cycles_elapsed = get_counter() - cycles;
209
87c45ad1
E
210 printf("%-64s: %d\n", argv[1], cycles_elapsed);
211#else
212 printf("%-64s: ", argv[1]);
75e28f62
E
213#endif
214
87c45ad1 215#if 1
75e28f62
E
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
75e28f62 241
87c45ad1 242#if 0
75e28f62 243 printf("\n");
3867c6ef
E
244 printf(" %d pixels, %d pixel blocks, %d spans\n"
245 " (%lf pixels per block, %lf pixels per span),\n"
75e28f62 246 " %lf blocks per span (%lf per non-zero span), %lf overdraw)\n\n",
3867c6ef 247 span_pixels, span_pixel_blocks, spans,
75e28f62 248 (double)span_pixels / span_pixel_blocks,
75e28f62
E
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
3867c6ef 256 printf(" %d triangles\n"
75e28f62
E
257 " (%d trivial rejects, %lf%% flat, %lf%% left split, %lf%% clipped)\n"
258 " (%lf pixels per triangle, %lf rows per triangle)\n\n",
3867c6ef 259 triangles, trivial_rejects,
75e28f62
E
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));
3867c6ef
E
279 printf(" %7d false-mod blocks (%lf%%)\n", false_modulated_blocks,
280 percent_of(false_modulated_blocks, span_pixel_blocks));
75e28f62
E
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 }
f9248bbf 298 printf(" %d lines\n", lines);
75e28f62
E
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}