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
36 static const char *
37 util_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 
55 static const char *
util_dump_enum_continuous(unsigned value,unsigned num_names,const char ** names)56 util_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 
93 static void
util_dump_flags_continuous(FILE * stream,unsigned value,unsigned num_names,const char * const * names)94 util_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) \
122 void \
123 util_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 
129 static const char *
130 util_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 
160 static const char *
161 util_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 
191 DEFINE_UTIL_STR_CONTINUOUS(blend_factor)
192 
193 
194 static const char *
195 util_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 
203 static const char *
204 util_blend_func_short_names[] = {
205    "add",
206    "sub",
207    "rev_sub",
208    "min",
209    "max"
210 };
211 
212 DEFINE_UTIL_STR_CONTINUOUS(blend_func)
213 
214 
215 static const char *
216 util_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 
235 static const char *
236 util_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 
255 DEFINE_UTIL_STR_CONTINUOUS(logicop)
256 
257 
258 static const char *
259 util_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 
270 static const char *
271 util_func_short_names[] = {
272    "never",
273    "less",
274    "equal",
275    "less_equal",
276    "greater",
277    "not_equal",
278    "greater_equal",
279    "always"
280 };
281 
282 DEFINE_UTIL_STR_CONTINUOUS(func)
283 
284 
285 static const char *
286 util_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 
297 static const char *
298 util_stencil_op_short_names[] = {
299    "keep",
300    "zero",
301    "replace",
302    "incr",
303    "decr",
304    "incr_wrap",
305    "decr_wrap",
306    "invert"
307 };
308 
309 DEFINE_UTIL_STR_CONTINUOUS(stencil_op)
310 
311 
312 static const char *
313 util_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 
325 static const char *
326 util_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 
338 DEFINE_UTIL_STR_CONTINUOUS_COUNT(tex_target, PIPE_MAX_TEXTURE_TYPES)
339 
340 
341 static const char *
342 util_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 
353 static const char *
354 util_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 
365 DEFINE_UTIL_STR_CONTINUOUS(tex_wrap)
366 
367 
368 static const char *
369 util_tex_mipfilter_names[] = {
370    "PIPE_TEX_MIPFILTER_NEAREST",
371    "PIPE_TEX_MIPFILTER_LINEAR",
372    "PIPE_TEX_MIPFILTER_NONE"
373 };
374 
375 static const char *
376 util_tex_mipfilter_short_names[] = {
377    "nearest",
378    "linear",
379    "none"
380 };
381 
382 DEFINE_UTIL_STR_CONTINUOUS(tex_mipfilter)
383 
384 
385 static const char *
386 util_tex_filter_names[] = {
387    "PIPE_TEX_FILTER_NEAREST",
388    "PIPE_TEX_FILTER_LINEAR"
389 };
390 
391 static const char *
392 util_tex_filter_short_names[] = {
393    "nearest",
394    "linear"
395 };
396 
397 DEFINE_UTIL_STR_CONTINUOUS(tex_filter)
398 
399 
400 static const char *
401 util_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 
417 static const char *
418 util_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 
434 DEFINE_UTIL_STR_CONTINUOUS(query_type)
435 
436 
437 static const char *
438 util_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 
445 static const char *
446 util_query_value_type_short_names[] = {
447    "i32",
448    "u32",
449    "i64",
450    "u64",
451 };
452 
453 DEFINE_UTIL_STR_CONTINUOUS(query_value_type)
454 
455 
456 static const char *
457 util_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 
475 static const char *
476 util_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 
DEFINE_UTIL_STR_CONTINUOUS(prim_mode)494 DEFINE_UTIL_STR_CONTINUOUS(prim_mode)
495 
496 void
497 util_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 
506 void
util_dump_query_value_type(FILE * stream,unsigned value)507 util_dump_query_value_type(FILE *stream, unsigned value)
508 {
509    fprintf(stream, "%s", util_str_query_value_type(value, false));
510 }
511 
512 
513 static const char * const
514 util_transfer_usage_names[] = {
515       "PIPE_MAP_READ",
516       "PIPE_MAP_WRITE",
517       "PIPE_MAP_DIRECTLY",
518       "PIPE_MAP_DISCARD_RANGE",
519       "PIPE_MAP_DONTBLOCK",
520       "PIPE_MAP_UNSYNCHRONIZED",
521       "PIPE_MAP_FLUSH_EXPLICIT",
522       "PIPE_MAP_DISCARD_WHOLE_RESOURCE",
523       "PIPE_MAP_PERSISTENT",
524       "PIPE_MAP_COHERENT",
525 };
526 
527 DEFINE_UTIL_DUMP_FLAGS_CONTINUOUS(transfer_usage)
528