1/**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include "util/u_memory.h"
30#include "util/u_debug.h"
31#include "util/u_dump.h"
32#include "util/u_math.h"
33
34
35#if 0
36static const char *
37util_dump_strip_prefix(const char *name,
38                        const char *prefix)
39{
40   const char *stripped;
41   assert(name);
42   assert(prefix);
43   stripped = name;
44   while(*prefix) {
45      if(*stripped != *prefix)
46	 return name;
47
48      ++stripped;
49      ++prefix;
50   }
51   return stripped;
52}
53#endif
54
55static const char *
56util_dump_enum_continuous(unsigned value,
57                           unsigned num_names,
58                           const char **names)
59{
60   if (value >= num_names)
61      return UTIL_DUMP_INVALID_NAME;
62   return names[value];
63}
64
65
66#define DEFINE_UTIL_STR_CONTINUOUS(_name) \
67   const char * \
68   util_str_##_name(unsigned value, boolean shortened) \
69   { \
70      if(shortened) \
71         return util_dump_enum_continuous(value, ARRAY_SIZE(util_##_name##_short_names), util_##_name##_short_names); \
72      else \
73         return util_dump_enum_continuous(value, ARRAY_SIZE(util_##_name##_names), util_##_name##_names); \
74   }
75
76
77/**
78 * Same as DEFINE_UTIL_STR_CONTINUOUS but with static assertions to detect
79 * failures to update lists.
80 */
81#define DEFINE_UTIL_STR_CONTINUOUS_COUNT(_name, _count) \
82   const char * \
83   util_str_##_name(unsigned value, boolean shortened) \
84   { \
85      STATIC_ASSERT(ARRAY_SIZE(util_##_name##_names) == _count); \
86      STATIC_ASSERT(ARRAY_SIZE(util_##_name##_short_names) == _count); \
87      if(shortened) \
88         return util_dump_enum_continuous(value, ARRAY_SIZE(util_##_name##_short_names), util_##_name##_short_names); \
89      else \
90         return util_dump_enum_continuous(value, ARRAY_SIZE(util_##_name##_names), util_##_name##_names); \
91   }
92
93static void
94util_dump_flags_continuous(FILE *stream, unsigned value, unsigned num_names,
95                           const char * const *names)
96{
97   unsigned unknown = 0;
98   bool first = true;
99
100   while (value) {
101      int i = u_bit_scan(&value);
102      if (i >= (int)num_names || !names[i])
103         unknown |= 1u << i;
104      if (!first)
105         fputs("|", stream);
106      fputs(names[i], stream);
107      first = false;
108   }
109
110   if (unknown) {
111      if (!first)
112         fputs("|", stream);
113      fprintf(stream, "%x", unknown);
114      first = false;
115   }
116
117   if (first)
118      fputs("0", stream);
119}
120
121#define DEFINE_UTIL_DUMP_FLAGS_CONTINUOUS(_name) \
122void \
123util_dump_##_name(FILE *stream, unsigned value) \
124{ \
125   util_dump_flags_continuous(stream, value, ARRAY_SIZE(util_##_name##_names), \
126                              util_##_name##_names); \
127}
128
129static const char *
130util_blend_factor_names[] = {
131   UTIL_DUMP_INVALID_NAME, /* 0x0 */
132   "PIPE_BLENDFACTOR_ONE",
133   "PIPE_BLENDFACTOR_SRC_COLOR",
134   "PIPE_BLENDFACTOR_SRC_ALPHA",
135   "PIPE_BLENDFACTOR_DST_ALPHA",
136   "PIPE_BLENDFACTOR_DST_COLOR",
137   "PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE",
138   "PIPE_BLENDFACTOR_CONST_COLOR",
139   "PIPE_BLENDFACTOR_CONST_ALPHA",
140   "PIPE_BLENDFACTOR_SRC1_COLOR",
141   "PIPE_BLENDFACTOR_SRC1_ALPHA",
142   UTIL_DUMP_INVALID_NAME, /* 0x0b */
143   UTIL_DUMP_INVALID_NAME, /* 0x0c */
144   UTIL_DUMP_INVALID_NAME, /* 0x0d */
145   UTIL_DUMP_INVALID_NAME, /* 0x0e */
146   UTIL_DUMP_INVALID_NAME, /* 0x0f */
147   UTIL_DUMP_INVALID_NAME, /* 0x10 */
148   "PIPE_BLENDFACTOR_ZERO",
149   "PIPE_BLENDFACTOR_INV_SRC_COLOR",
150   "PIPE_BLENDFACTOR_INV_SRC_ALPHA",
151   "PIPE_BLENDFACTOR_INV_DST_ALPHA",
152   "PIPE_BLENDFACTOR_INV_DST_COLOR",
153   UTIL_DUMP_INVALID_NAME, /* 0x16 */
154   "PIPE_BLENDFACTOR_INV_CONST_COLOR",
155   "PIPE_BLENDFACTOR_INV_CONST_ALPHA",
156   "PIPE_BLENDFACTOR_INV_SRC1_COLOR",
157   "PIPE_BLENDFACTOR_INV_SRC1_ALPHA"
158};
159
160static const char *
161util_blend_factor_short_names[] = {
162   UTIL_DUMP_INVALID_NAME, /* 0x0 */
163   "one",
164   "src_color",
165   "src_alpha",
166   "dst_alpha",
167   "dst_color",
168   "src_alpha_saturate",
169   "const_color",
170   "const_alpha",
171   "src1_color",
172   "src1_alpha",
173   UTIL_DUMP_INVALID_NAME, /* 0x0b */
174   UTIL_DUMP_INVALID_NAME, /* 0x0c */
175   UTIL_DUMP_INVALID_NAME, /* 0x0d */
176   UTIL_DUMP_INVALID_NAME, /* 0x0e */
177   UTIL_DUMP_INVALID_NAME, /* 0x0f */
178   UTIL_DUMP_INVALID_NAME, /* 0x10 */
179   "zero",
180   "inv_src_color",
181   "inv_src_alpha",
182   "inv_dst_alpha",
183   "inv_dst_color",
184   UTIL_DUMP_INVALID_NAME, /* 0x16 */
185   "inv_const_color",
186   "inv_const_alpha",
187   "inv_src1_color",
188   "inv_src1_alpha"
189};
190
191DEFINE_UTIL_STR_CONTINUOUS(blend_factor)
192
193
194static const char *
195util_blend_func_names[] = {
196   "PIPE_BLEND_ADD",
197   "PIPE_BLEND_SUBTRACT",
198   "PIPE_BLEND_REVERSE_SUBTRACT",
199   "PIPE_BLEND_MIN",
200   "PIPE_BLEND_MAX"
201};
202
203static const char *
204util_blend_func_short_names[] = {
205   "add",
206   "sub",
207   "rev_sub",
208   "min",
209   "max"
210};
211
212DEFINE_UTIL_STR_CONTINUOUS(blend_func)
213
214
215static const char *
216util_logicop_names[] = {
217   "PIPE_LOGICOP_CLEAR",
218   "PIPE_LOGICOP_NOR",
219   "PIPE_LOGICOP_AND_INVERTED",
220   "PIPE_LOGICOP_COPY_INVERTED",
221   "PIPE_LOGICOP_AND_REVERSE",
222   "PIPE_LOGICOP_INVERT",
223   "PIPE_LOGICOP_XOR",
224   "PIPE_LOGICOP_NAND",
225   "PIPE_LOGICOP_AND",
226   "PIPE_LOGICOP_EQUIV",
227   "PIPE_LOGICOP_NOOP",
228   "PIPE_LOGICOP_OR_INVERTED",
229   "PIPE_LOGICOP_COPY",
230   "PIPE_LOGICOP_OR_REVERSE",
231   "PIPE_LOGICOP_OR",
232   "PIPE_LOGICOP_SET"
233};
234
235static const char *
236util_logicop_short_names[] = {
237   "clear",
238   "nor",
239   "and_inverted",
240   "copy_inverted",
241   "and_reverse",
242   "invert",
243   "xor",
244   "nand",
245   "and",
246   "equiv",
247   "noop",
248   "or_inverted",
249   "copy",
250   "or_reverse",
251   "or",
252   "set"
253};
254
255DEFINE_UTIL_STR_CONTINUOUS(logicop)
256
257
258static const char *
259util_func_names[] = {
260   "PIPE_FUNC_NEVER",
261   "PIPE_FUNC_LESS",
262   "PIPE_FUNC_EQUAL",
263   "PIPE_FUNC_LEQUAL",
264   "PIPE_FUNC_GREATER",
265   "PIPE_FUNC_NOTEQUAL",
266   "PIPE_FUNC_GEQUAL",
267   "PIPE_FUNC_ALWAYS"
268};
269
270static const char *
271util_func_short_names[] = {
272   "never",
273   "less",
274   "equal",
275   "less_equal",
276   "greater",
277   "not_equal",
278   "greater_equal",
279   "always"
280};
281
282DEFINE_UTIL_STR_CONTINUOUS(func)
283
284
285static const char *
286util_stencil_op_names[] = {
287   "PIPE_STENCIL_OP_KEEP",
288   "PIPE_STENCIL_OP_ZERO",
289   "PIPE_STENCIL_OP_REPLACE",
290   "PIPE_STENCIL_OP_INCR",
291   "PIPE_STENCIL_OP_DECR",
292   "PIPE_STENCIL_OP_INCR_WRAP",
293   "PIPE_STENCIL_OP_DECR_WRAP",
294   "PIPE_STENCIL_OP_INVERT"
295};
296
297static const char *
298util_stencil_op_short_names[] = {
299   "keep",
300   "zero",
301   "replace",
302   "incr",
303   "decr",
304   "incr_wrap",
305   "decr_wrap",
306   "invert"
307};
308
309DEFINE_UTIL_STR_CONTINUOUS(stencil_op)
310
311
312static const char *
313util_tex_target_names[] = {
314   "PIPE_BUFFER",
315   "PIPE_TEXTURE_1D",
316   "PIPE_TEXTURE_2D",
317   "PIPE_TEXTURE_3D",
318   "PIPE_TEXTURE_CUBE",
319   "PIPE_TEXTURE_RECT",
320   "PIPE_TEXTURE_1D_ARRAY",
321   "PIPE_TEXTURE_2D_ARRAY",
322   "PIPE_TEXTURE_CUBE_ARRAY",
323};
324
325static const char *
326util_tex_target_short_names[] = {
327   "buffer",
328   "1d",
329   "2d",
330   "3d",
331   "cube",
332   "rect",
333   "1d_array",
334   "2d_array",
335   "cube_array",
336};
337
338DEFINE_UTIL_STR_CONTINUOUS_COUNT(tex_target, PIPE_MAX_TEXTURE_TYPES)
339
340
341static const char *
342util_tex_wrap_names[] = {
343   "PIPE_TEX_WRAP_REPEAT",
344   "PIPE_TEX_WRAP_CLAMP",
345   "PIPE_TEX_WRAP_CLAMP_TO_EDGE",
346   "PIPE_TEX_WRAP_CLAMP_TO_BORDER",
347   "PIPE_TEX_WRAP_MIRROR_REPEAT",
348   "PIPE_TEX_WRAP_MIRROR_CLAMP",
349   "PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE",
350   "PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER"
351};
352
353static const char *
354util_tex_wrap_short_names[] = {
355   "repeat",
356   "clamp",
357   "clamp_to_edge",
358   "clamp_to_border",
359   "mirror_repeat",
360   "mirror_clamp",
361   "mirror_clamp_to_edge",
362   "mirror_clamp_to_border"
363};
364
365DEFINE_UTIL_STR_CONTINUOUS(tex_wrap)
366
367
368static const char *
369util_tex_mipfilter_names[] = {
370   "PIPE_TEX_MIPFILTER_NEAREST",
371   "PIPE_TEX_MIPFILTER_LINEAR",
372   "PIPE_TEX_MIPFILTER_NONE"
373};
374
375static const char *
376util_tex_mipfilter_short_names[] = {
377   "nearest",
378   "linear",
379   "none"
380};
381
382DEFINE_UTIL_STR_CONTINUOUS(tex_mipfilter)
383
384
385static const char *
386util_tex_filter_names[] = {
387   "PIPE_TEX_FILTER_NEAREST",
388   "PIPE_TEX_FILTER_LINEAR"
389};
390
391static const char *
392util_tex_filter_short_names[] = {
393   "nearest",
394   "linear"
395};
396
397DEFINE_UTIL_STR_CONTINUOUS(tex_filter)
398
399
400static const char *
401util_query_type_names[] = {
402   "PIPE_QUERY_OCCLUSION_COUNTER",
403   "PIPE_QUERY_OCCLUSION_PREDICATE",
404   "PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE",
405   "PIPE_QUERY_TIMESTAMP",
406   "PIPE_QUERY_TIMESTAMP_DISJOINT",
407   "PIPE_QUERY_TIME_ELAPSED",
408   "PIPE_QUERY_PRIMITIVES_GENERATED",
409   "PIPE_QUERY_PRIMITIVES_EMITTED",
410   "PIPE_QUERY_SO_STATISTICS",
411   "PIPE_QUERY_SO_OVERFLOW_PREDICATE",
412   "PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE",
413   "PIPE_QUERY_GPU_FINISHED",
414   "PIPE_QUERY_PIPELINE_STATISTICS",
415};
416
417static const char *
418util_query_type_short_names[] = {
419   "occlusion_counter",
420   "occlusion_predicate",
421   "occlusion_predicate_conservative",
422   "timestamp",
423   "timestamp_disjoint",
424   "time_elapsed",
425   "primitives_generated",
426   "primitives_emitted",
427   "so_statistics",
428   "so_overflow_predicate",
429   "so_overflow_any_predicate",
430   "gpu_finished",
431   "pipeline_statistics",
432};
433
434DEFINE_UTIL_STR_CONTINUOUS(query_type)
435
436
437static const char *
438util_query_value_type_names[] = {
439   "PIPE_QUERY_TYPE_I32",
440   "PIPE_QUERY_TYPE_U32",
441   "PIPE_QUERY_TYPE_I64",
442   "PIPE_QUERY_TYPE_U64",
443};
444
445static const char *
446util_query_value_type_short_names[] = {
447   "i32",
448   "u32",
449   "i64",
450   "u64",
451};
452
453DEFINE_UTIL_STR_CONTINUOUS(query_value_type)
454
455
456static const char *
457util_prim_mode_names[] = {
458   "PIPE_PRIM_POINTS",
459   "PIPE_PRIM_LINES",
460   "PIPE_PRIM_LINE_LOOP",
461   "PIPE_PRIM_LINE_STRIP",
462   "PIPE_PRIM_TRIANGLES",
463   "PIPE_PRIM_TRIANGLE_STRIP",
464   "PIPE_PRIM_TRIANGLE_FAN",
465   "PIPE_PRIM_QUADS",
466   "PIPE_PRIM_QUAD_STRIP",
467   "PIPE_PRIM_POLYGON",
468   "PIPE_PRIM_LINES_ADJACENCY",
469   "PIPE_PRIM_LINE_STRIP_ADJACENCY",
470   "PIPE_PRIM_TRIANGLES_ADJACENCY",
471   "PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY",
472   "PIPE_PRIM_PATCHES",
473};
474
475static const char *
476util_prim_mode_short_names[] = {
477   "points",
478   "lines",
479   "line_loop",
480   "line_strip",
481   "triangles",
482   "triangle_strip",
483   "triangle_fan",
484   "quads",
485   "quad_strip",
486   "polygon",
487   "lines_adjacency",
488   "line_strip_adjacency",
489   "triangles_adjacency",
490   "triangle_strip_adjacency",
491   "patches",
492};
493
494DEFINE_UTIL_STR_CONTINUOUS(prim_mode)
495
496void
497util_dump_query_type(FILE *stream, unsigned value)
498{
499   if (value >= PIPE_QUERY_DRIVER_SPECIFIC)
500      fprintf(stream, "PIPE_QUERY_DRIVER_SPECIFIC + %i",
501              value - PIPE_QUERY_DRIVER_SPECIFIC);
502   else
503      fprintf(stream, "%s", util_str_query_type(value, false));
504}
505
506void
507util_dump_query_value_type(FILE *stream, unsigned value)
508{
509   fprintf(stream, "%s", util_str_query_value_type(value, false));
510}
511
512void
513util_dump_query_flags(FILE *stream, unsigned value)
514{
515   fprintf(stream, "%s", util_str_query_value_type(value, false));
516}
517
518
519static const char * const
520util_transfer_usage_names[] = {
521      "PIPE_MAP_READ",
522      "PIPE_MAP_WRITE",
523      "PIPE_MAP_DIRECTLY",
524      "PIPE_MAP_DISCARD_RANGE",
525      "PIPE_MAP_DONTBLOCK",
526      "PIPE_MAP_UNSYNCHRONIZED",
527      "PIPE_MAP_FLUSH_EXPLICIT",
528      "PIPE_MAP_DISCARD_WHOLE_RESOURCE",
529      "PIPE_MAP_PERSISTENT",
530      "PIPE_MAP_COHERENT",
531};
532
533DEFINE_UTIL_DUMP_FLAGS_CONTINUOUS(transfer_usage)
534