Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
#include   /* for PRIu64 macro */
2
#include "util/u_math.h"
3
#include "lp_rast_priv.h"
4
#include "lp_state_fs.h"
5
 
6
struct tile {
7
   int coverage;
8
   int overdraw;
9
   const struct lp_rast_state *state;
10
   char data[TILE_SIZE][TILE_SIZE];
11
};
12
 
13
static char get_label( int i )
14
{
15
   static const char *cmd_labels = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
16
   unsigned max_label = (2*26+10);
17
 
18
   if (i < max_label)
19
      return cmd_labels[i];
20
   else
21
      return '?';
22
}
23
 
24
 
25
 
26
static const char *cmd_names[LP_RAST_OP_MAX] =
27
{
28
   "clear_color",
29
   "clear_zstencil",
30
   "triangle_1",
31
   "triangle_2",
32
   "triangle_3",
33
   "triangle_4",
34
   "triangle_5",
35
   "triangle_6",
36
   "triangle_7",
37
   "triangle_8",
38
   "triangle_3_4",
39
   "triangle_3_16",
40
   "triangle_4_16",
41
   "shade_tile",
42
   "shade_tile_opaque",
43
   "begin_query",
44
   "end_query",
45
   "set_state",
46
};
47
 
48
static const char *cmd_name(unsigned cmd)
49
{
50
   assert(Elements(cmd_names) > cmd);
51
   return cmd_names[cmd];
52
}
53
 
54
static const struct lp_fragment_shader_variant *
55
get_variant( const struct lp_rast_state *state,
56
             const struct cmd_block *block,
57
             int k )
58
{
59
   if (!state)
60
      return NULL;
61
 
62
   if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
63
       block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE ||
64
       block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
65
       block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
66
       block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
67
       block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
68
       block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
69
       block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
70
       block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
71
      return state->variant;
72
 
73
   return NULL;
74
}
75
 
76
 
77
static boolean
78
is_blend( const struct lp_rast_state *state,
79
          const struct cmd_block *block,
80
          int k )
81
{
82
   const struct lp_fragment_shader_variant *variant = get_variant(state, block, k);
83
 
84
   if (variant)
85
      return  variant->key.blend.rt[0].blend_enable;
86
 
87
   return FALSE;
88
}
89
 
90
 
91
 
92
static void
93
debug_bin( const struct cmd_bin *bin, int x, int y )
94
{
95
   const struct lp_rast_state *state = NULL;
96
   const struct cmd_block *head = bin->head;
97
   int i, j = 0;
98
 
99
   debug_printf("bin %d,%d:\n", x, y);
100
 
101
   while (head) {
102
      for (i = 0; i < head->count; i++, j++) {
103
         if (head->cmd[i] == LP_RAST_OP_SET_STATE)
104
            state = head->arg[i].state;
105
 
106
         debug_printf("%d: %s %s\n", j,
107
                      cmd_name(head->cmd[i]),
108
                      is_blend(state, head, i) ? "blended" : "");
109
      }
110
      head = head->next;
111
   }
112
}
113
 
114
 
115
static void plot(struct tile *tile,
116
                 int x, int y,
117
                 char val,
118
                 boolean blend)
119
{
120
   if (tile->data[x][y] == ' ')
121
      tile->coverage++;
122
   else
123
      tile->overdraw++;
124
 
125
   tile->data[x][y] = val;
126
}
127
 
128
 
129
 
130
 
131
 
132
 
133
static int
134
debug_shade_tile(int x, int y,
135
                 const union lp_rast_cmd_arg arg,
136
                 struct tile *tile,
137
                 char val)
138
{
139
   const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
140
   boolean blend;
141
   unsigned i,j;
142
 
143
   if (!tile->state)
144
      return 0;
145
 
146
   blend = tile->state->variant->key.blend.rt[0].blend_enable;
147
 
148
   if (inputs->disable)
149
      return 0;
150
 
151
   for (i = 0; i < TILE_SIZE; i++)
152
      for (j = 0; j < TILE_SIZE; j++)
153
         plot(tile, i, j, val, blend);
154
 
155
   return TILE_SIZE * TILE_SIZE;
156
}
157
 
158
static int
159
debug_clear_tile(int x, int y,
160
                 const union lp_rast_cmd_arg arg,
161
                 struct tile *tile,
162
                 char val)
163
{
164
   unsigned i,j;
165
 
166
   for (i = 0; i < TILE_SIZE; i++)
167
      for (j = 0; j < TILE_SIZE; j++)
168
         plot(tile, i, j, val, FALSE);
169
 
170
   return TILE_SIZE * TILE_SIZE;
171
 
172
}
173
 
174
 
175
static int
176
debug_triangle(int tilex, int tiley,
177
               const union lp_rast_cmd_arg arg,
178
               struct tile *tile,
179
               char val)
180
{
181
   const struct lp_rast_triangle *tri = arg.triangle.tri;
182
   unsigned plane_mask = arg.triangle.plane_mask;
183
   const struct lp_rast_plane *tri_plane = GET_PLANES(tri);
184
   struct lp_rast_plane plane[8];
185
   int x, y;
186
   int count = 0;
187
   unsigned i, nr_planes = 0;
188
   boolean blend = tile->state->variant->key.blend.rt[0].blend_enable;
189
 
190
   if (tri->inputs.disable) {
191
      /* This triangle was partially binned and has been disabled */
192
      return 0;
193
   }
194
 
195
   while (plane_mask) {
196
      plane[nr_planes] = tri_plane[u_bit_scan(&plane_mask)];
197
      plane[nr_planes].c = (plane[nr_planes].c +
198
                            plane[nr_planes].dcdy * tiley -
199
                            plane[nr_planes].dcdx * tilex);
200
      nr_planes++;
201
   }
202
 
203
   for(y = 0; y < TILE_SIZE; y++)
204
   {
205
      for(x = 0; x < TILE_SIZE; x++)
206
      {
207
         for (i = 0; i < nr_planes; i++)
208
            if (plane[i].c <= 0)
209
               goto out;
210
 
211
         plot(tile, x, y, val, blend);
212
         count++;
213
 
214
      out:
215
         for (i = 0; i < nr_planes; i++)
216
            plane[i].c -= plane[i].dcdx;
217
      }
218
 
219
      for (i = 0; i < nr_planes; i++) {
220
         plane[i].c += plane[i].dcdx * TILE_SIZE;
221
         plane[i].c += plane[i].dcdy;
222
      }
223
   }
224
   return count;
225
}
226
 
227
 
228
 
229
 
230
 
231
static void
232
do_debug_bin( struct tile *tile,
233
              const struct cmd_bin *bin,
234
              int x, int y,
235
              boolean print_cmds)
236
{
237
   unsigned k, j = 0;
238
   const struct cmd_block *block;
239
 
240
   int tx = x * TILE_SIZE;
241
   int ty = y * TILE_SIZE;
242
 
243
   memset(tile->data, ' ', sizeof tile->data);
244
   tile->coverage = 0;
245
   tile->overdraw = 0;
246
   tile->state = NULL;
247
 
248
   for (block = bin->head; block; block = block->next) {
249
      for (k = 0; k < block->count; k++, j++) {
250
         boolean blend = is_blend(tile->state, block, k);
251
         char val = get_label(j);
252
         int count = 0;
253
 
254
         if (print_cmds)
255
            debug_printf("%c: %15s", val, cmd_name(block->cmd[k]));
256
 
257
         if (block->cmd[k] == LP_RAST_OP_SET_STATE)
258
            tile->state = block->arg[k].state;
259
 
260
         if (block->cmd[k] == LP_RAST_OP_CLEAR_COLOR ||
261
             block->cmd[k] == LP_RAST_OP_CLEAR_ZSTENCIL)
262
            count = debug_clear_tile(tx, ty, block->arg[k], tile, val);
263
 
264
         if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
265
             block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE)
266
            count = debug_shade_tile(tx, ty, block->arg[k], tile, val);
267
 
268
         if (block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
269
             block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
270
             block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
271
             block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
272
             block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
273
             block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
274
             block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
275
            count = debug_triangle(tx, ty, block->arg[k], tile, val);
276
 
277
         if (print_cmds) {
278
            debug_printf(" % 5d", count);
279
 
280
            if (blend)
281
               debug_printf(" blended");
282
 
283
            debug_printf("\n");
284
         }
285
      }
286
   }
287
}
288
 
289
void
290
lp_debug_bin( const struct cmd_bin *bin, int i, int j)
291
{
292
   struct tile tile;
293
   int x,y;
294
 
295
   if (bin->head) {
296
      do_debug_bin(&tile, bin, i, j, TRUE);
297
 
298
      debug_printf("------------------------------------------------------------------\n");
299
      for (y = 0; y < TILE_SIZE; y++) {
300
         for (x = 0; x < TILE_SIZE; x++) {
301
            debug_printf("%c", tile.data[y][x]);
302
         }
303
         debug_printf("|\n");
304
      }
305
      debug_printf("------------------------------------------------------------------\n");
306
 
307
      debug_printf("each pixel drawn avg %f times\n",
308
                   ((float)tile.overdraw + tile.coverage)/(float)tile.coverage);
309
   }
310
}
311
 
312
 
313
 
314
 
315
 
316
 
317
/** Return number of bytes used for a single bin */
318
static unsigned
319
lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y )
320
{
321
   struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y);
322
   const struct cmd_block *cmd;
323
   unsigned size = 0;
324
   for (cmd = bin->head; cmd; cmd = cmd->next) {
325
      size += (cmd->count *
326
               (sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg)));
327
   }
328
   return size;
329
}
330
 
331
 
332
 
333
void
334
lp_debug_draw_bins_by_coverage( struct lp_scene *scene )
335
{
336
   unsigned x, y;
337
   unsigned total = 0;
338
   unsigned possible = 0;
339
   static uint64_t _total = 0;
340
   static uint64_t _possible = 0;
341
 
342
   for (x = 0; x < scene->tiles_x; x++)
343
      debug_printf("-");
344
   debug_printf("\n");
345
 
346
   for (y = 0; y < scene->tiles_y; y++) {
347
      for (x = 0; x < scene->tiles_x; x++) {
348
         struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
349
         const char *bits = "0123456789";
350
         struct tile tile;
351
 
352
         if (bin->head) {
353
            //lp_debug_bin(bin, x, y);
354
 
355
            do_debug_bin(&tile, bin, x, y, FALSE);
356
 
357
            total += tile.coverage;
358
            possible += 64*64;
359
 
360
            if (tile.coverage == 64*64)
361
               debug_printf("*");
362
            else if (tile.coverage) {
363
               int bit = tile.coverage/(64.0*64.0)*10;
364
               debug_printf("%c", bits[MIN2(bit,10)]);
365
            }
366
            else
367
               debug_printf("?");
368
         }
369
         else {
370
            debug_printf(" ");
371
         }
372
      }
373
      debug_printf("|\n");
374
   }
375
 
376
   for (x = 0; x < scene->tiles_x; x++)
377
      debug_printf("-");
378
   debug_printf("\n");
379
 
380
   debug_printf("this tile total: %u possible %u: percentage: %f\n",
381
                total,
382
                possible,
383
                total * 100.0 / (float)possible);
384
 
385
   _total += total;
386
   _possible += possible;
387
 
388
 
389
   debug_printf("overall   total: %" PRIu64
390
                " possible %" PRIu64 ": percentage: %f\n",
391
                _total,
392
                _possible,
393
                (double) _total * 100.0 / (double)_possible);
394
}
395
 
396
 
397
void
398
lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene )
399
{
400
   unsigned x, y;
401
 
402
   for (y = 0; y < scene->tiles_y; y++) {
403
      for (x = 0; x < scene->tiles_x; x++) {
404
         const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW";
405
         unsigned sz = lp_scene_bin_size(scene, x, y);
406
         unsigned sz2 = util_logbase2(sz);
407
         debug_printf("%c", bits[MIN2(sz2,32)]);
408
      }
409
      debug_printf("\n");
410
   }
411
}
412
 
413
 
414
void
415
lp_debug_bins( struct lp_scene *scene )
416
{
417
   unsigned x, y;
418
 
419
   for (y = 0; y < scene->tiles_y; y++) {
420
      for (x = 0; x < scene->tiles_x; x++) {
421
         struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
422
         if (bin->head) {
423
            debug_bin(bin, x, y);
424
         }
425
      }
426
   }
427
}