1/************************************************************************** 2 * 3 * Copyright 2008-2010 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 "pipe/p_compiler.h" 30#include "util/u_memory.h" 31#include "util/u_string.h" 32#include "util/u_format.h" 33#include "tgsi/tgsi_dump.h" 34 35#include "u_dump.h" 36 37 38/* 39 * Dump primitives 40 */ 41 42static INLINE void 43util_stream_writef(FILE *stream, const char *format, ...) 44{ 45 static char buf[1024]; 46 unsigned len; 47 va_list ap; 48 va_start(ap, format); 49 len = util_vsnprintf(buf, sizeof(buf), format, ap); 50 va_end(ap); 51 fwrite(buf, len, 1, stream); 52} 53 54static void 55util_dump_bool(FILE *stream, int value) 56{ 57 util_stream_writef(stream, "%c", value ? '1' : '0'); 58} 59 60static void 61util_dump_int(FILE *stream, long long int value) 62{ 63 util_stream_writef(stream, "%lli", value); 64} 65 66static void 67util_dump_uint(FILE *stream, long long unsigned value) 68{ 69 util_stream_writef(stream, "%llu", value); 70} 71 72static void 73util_dump_float(FILE *stream, double value) 74{ 75 util_stream_writef(stream, "%g", value); 76} 77 78static void 79util_dump_string(FILE *stream, const char *str) 80{ 81 fputs("\"", stream); 82 fputs(str, stream); 83 fputs("\"", stream); 84} 85 86static void 87util_dump_enum(FILE *stream, const char *value) 88{ 89 fputs(value, stream); 90} 91 92static void 93util_dump_array_begin(FILE *stream) 94{ 95 fputs("{", stream); 96} 97 98static void 99util_dump_array_end(FILE *stream) 100{ 101 fputs("}", stream); 102} 103 104static void 105util_dump_elem_begin(FILE *stream) 106{ 107} 108 109static void 110util_dump_elem_end(FILE *stream) 111{ 112 fputs(", ", stream); 113} 114 115static void 116util_dump_struct_begin(FILE *stream, const char *name) 117{ 118 fputs("{", stream); 119} 120 121static void 122util_dump_struct_end(FILE *stream) 123{ 124 fputs("}", stream); 125} 126 127static void 128util_dump_member_begin(FILE *stream, const char *name) 129{ 130 util_stream_writef(stream, "%s = ", name); 131} 132 133static void 134util_dump_member_end(FILE *stream) 135{ 136 fputs(", ", stream); 137} 138 139static void 140util_dump_null(FILE *stream) 141{ 142 fputs("NULL", stream); 143} 144 145static void 146util_dump_ptr(FILE *stream, const void *value) 147{ 148 if(value) 149 util_stream_writef(stream, "0x%08lx", (unsigned long)(uintptr_t)value); 150 else 151 util_dump_null(stream); 152} 153 154 155/* 156 * Code saving macros. 157 */ 158 159#define util_dump_arg(_stream, _type, _arg) \ 160 do { \ 161 util_dump_arg_begin(_stream, #_arg); \ 162 util_dump_##_type(_stream, _arg); \ 163 util_dump_arg_end(_stream); \ 164 } while(0) 165 166#define util_dump_ret(_stream, _type, _arg) \ 167 do { \ 168 util_dump_ret_begin(_stream); \ 169 util_dump_##_type(_stream, _arg); \ 170 util_dump_ret_end(_stream); \ 171 } while(0) 172 173#define util_dump_array(_stream, _type, _obj, _size) \ 174 do { \ 175 size_t idx; \ 176 util_dump_array_begin(_stream); \ 177 for(idx = 0; idx < (_size); ++idx) { \ 178 util_dump_elem_begin(_stream); \ 179 util_dump_##_type(_stream, (_obj)[idx]); \ 180 util_dump_elem_end(_stream); \ 181 } \ 182 util_dump_array_end(_stream); \ 183 } while(0) 184 185#define util_dump_struct_array(_stream, _type, _obj, _size) \ 186 do { \ 187 size_t idx; \ 188 util_dump_array_begin(_stream); \ 189 for(idx = 0; idx < (_size); ++idx) { \ 190 util_dump_elem_begin(_stream); \ 191 util_dump_##_type(_stream, &(_obj)[idx]); \ 192 util_dump_elem_end(_stream); \ 193 } \ 194 util_dump_array_end(_stream); \ 195 } while(0) 196 197#define util_dump_member(_stream, _type, _obj, _member) \ 198 do { \ 199 util_dump_member_begin(_stream, #_member); \ 200 util_dump_##_type(_stream, (_obj)->_member); \ 201 util_dump_member_end(_stream); \ 202 } while(0) 203 204#define util_dump_arg_array(_stream, _type, _arg, _size) \ 205 do { \ 206 util_dump_arg_begin(_stream, #_arg); \ 207 util_dump_array(_stream, _type, _arg, _size); \ 208 util_dump_arg_end(_stream); \ 209 } while(0) 210 211#define util_dump_member_array(_stream, _type, _obj, _member) \ 212 do { \ 213 util_dump_member_begin(_stream, #_member); \ 214 util_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ 215 util_dump_member_end(_stream); \ 216 } while(0) 217 218 219 220/* 221 * Wrappers for enum -> string dumpers. 222 */ 223 224 225static void 226util_dump_format(FILE *stream, enum pipe_format format) 227{ 228 util_dump_enum(stream, util_format_name(format)); 229} 230 231 232static void 233util_dump_enum_blend_factor(FILE *stream, unsigned value) 234{ 235 util_dump_enum(stream, util_dump_blend_factor(value, TRUE)); 236} 237 238static void 239util_dump_enum_blend_func(FILE *stream, unsigned value) 240{ 241 util_dump_enum(stream, util_dump_blend_func(value, TRUE)); 242} 243 244static void 245util_dump_enum_func(FILE *stream, unsigned value) 246{ 247 util_dump_enum(stream, util_dump_func(value, TRUE)); 248} 249 250 251/* 252 * Public functions 253 */ 254 255 256void 257util_dump_template(FILE *stream, const struct pipe_resource *templat) 258{ 259 if(!templat) { 260 util_dump_null(stream); 261 return; 262 } 263 264 util_dump_struct_begin(stream, "pipe_resource"); 265 266 util_dump_member(stream, int, templat, target); 267 util_dump_member(stream, format, templat, format); 268 269 util_dump_member_begin(stream, "width"); 270 util_dump_uint(stream, templat->width0); 271 util_dump_member_end(stream); 272 273 util_dump_member_begin(stream, "height"); 274 util_dump_uint(stream, templat->height0); 275 util_dump_member_end(stream); 276 277 util_dump_member_begin(stream, "depth"); 278 util_dump_uint(stream, templat->depth0); 279 util_dump_member_end(stream); 280 281 util_dump_member_begin(stream, "array_size"); 282 util_dump_uint(stream, templat->array_size); 283 util_dump_member_end(stream); 284 285 util_dump_member(stream, uint, templat, last_level); 286 util_dump_member(stream, uint, templat, usage); 287 util_dump_member(stream, uint, templat, bind); 288 util_dump_member(stream, uint, templat, flags); 289 290 util_dump_struct_end(stream); 291} 292 293 294void 295util_dump_rasterizer_state(FILE *stream, const struct pipe_rasterizer_state *state) 296{ 297 if(!state) { 298 util_dump_null(stream); 299 return; 300 } 301 302 util_dump_struct_begin(stream, "pipe_rasterizer_state"); 303 304 util_dump_member(stream, bool, state, flatshade); 305 util_dump_member(stream, bool, state, light_twoside); 306 util_dump_member(stream, bool, state, clamp_vertex_color); 307 util_dump_member(stream, bool, state, clamp_fragment_color); 308 util_dump_member(stream, uint, state, front_ccw); 309 util_dump_member(stream, uint, state, cull_face); 310 util_dump_member(stream, uint, state, fill_front); 311 util_dump_member(stream, uint, state, fill_back); 312 util_dump_member(stream, bool, state, offset_point); 313 util_dump_member(stream, bool, state, offset_line); 314 util_dump_member(stream, bool, state, offset_tri); 315 util_dump_member(stream, bool, state, scissor); 316 util_dump_member(stream, bool, state, poly_smooth); 317 util_dump_member(stream, bool, state, poly_stipple_enable); 318 util_dump_member(stream, bool, state, point_smooth); 319 util_dump_member(stream, uint, state, sprite_coord_enable); 320 util_dump_member(stream, bool, state, sprite_coord_mode); 321 util_dump_member(stream, bool, state, point_quad_rasterization); 322 util_dump_member(stream, bool, state, point_size_per_vertex); 323 util_dump_member(stream, bool, state, multisample); 324 util_dump_member(stream, bool, state, line_smooth); 325 util_dump_member(stream, bool, state, line_stipple_enable); 326 util_dump_member(stream, uint, state, line_stipple_factor); 327 util_dump_member(stream, uint, state, line_stipple_pattern); 328 util_dump_member(stream, bool, state, line_last_pixel); 329 util_dump_member(stream, bool, state, flatshade_first); 330 util_dump_member(stream, bool, state, gl_rasterization_rules); 331 util_dump_member(stream, bool, state, rasterizer_discard); 332 util_dump_member(stream, bool, state, depth_clip); 333 util_dump_member(stream, uint, state, clip_plane_enable); 334 335 util_dump_member(stream, float, state, line_width); 336 util_dump_member(stream, float, state, point_size); 337 util_dump_member(stream, float, state, offset_units); 338 util_dump_member(stream, float, state, offset_scale); 339 util_dump_member(stream, float, state, offset_clamp); 340 341 util_dump_struct_end(stream); 342} 343 344 345void 346util_dump_poly_stipple(FILE *stream, const struct pipe_poly_stipple *state) 347{ 348 if(!state) { 349 util_dump_null(stream); 350 return; 351 } 352 353 util_dump_struct_begin(stream, "pipe_poly_stipple"); 354 355 util_dump_member_begin(stream, "stipple"); 356 util_dump_member_array(stream, uint, state, stipple); 357 util_dump_member_end(stream); 358 359 util_dump_struct_end(stream); 360} 361 362 363void 364util_dump_viewport_state(FILE *stream, const struct pipe_viewport_state *state) 365{ 366 if(!state) { 367 util_dump_null(stream); 368 return; 369 } 370 371 util_dump_struct_begin(stream, "pipe_viewport_state"); 372 373 util_dump_member_array(stream, float, state, scale); 374 util_dump_member_array(stream, float, state, translate); 375 376 util_dump_struct_end(stream); 377} 378 379 380void 381util_dump_scissor_state(FILE *stream, const struct pipe_scissor_state *state) 382{ 383 if(!state) { 384 util_dump_null(stream); 385 return; 386 } 387 388 util_dump_struct_begin(stream, "pipe_scissor_state"); 389 390 util_dump_member(stream, uint, state, minx); 391 util_dump_member(stream, uint, state, miny); 392 util_dump_member(stream, uint, state, maxx); 393 util_dump_member(stream, uint, state, maxy); 394 395 util_dump_struct_end(stream); 396} 397 398 399void 400util_dump_clip_state(FILE *stream, const struct pipe_clip_state *state) 401{ 402 unsigned i; 403 404 if(!state) { 405 util_dump_null(stream); 406 return; 407 } 408 409 util_dump_struct_begin(stream, "pipe_clip_state"); 410 411 util_dump_member_begin(stream, "ucp"); 412 util_dump_array_begin(stream); 413 for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { 414 util_dump_elem_begin(stream); 415 util_dump_array(stream, float, state->ucp[i], 4); 416 util_dump_elem_end(stream); 417 } 418 util_dump_array_end(stream); 419 util_dump_member_end(stream); 420 421 util_dump_struct_end(stream); 422} 423 424 425void 426util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state) 427{ 428 char str[8192]; 429 unsigned i; 430 431 if(!state) { 432 util_dump_null(stream); 433 return; 434 } 435 436 tgsi_dump_str(state->tokens, 0, str, sizeof(str)); 437 438 util_dump_struct_begin(stream, "pipe_shader_state"); 439 440 util_dump_member_begin(stream, "tokens"); 441 util_dump_string(stream, str); 442 util_dump_member_end(stream); 443 444 util_dump_member_begin(stream, "stream_output"); 445 util_dump_struct_begin(stream, "pipe_stream_output_info"); 446 util_dump_member(stream, uint, &state->stream_output, num_outputs); 447 util_dump_array(stream, uint, state->stream_output.stride, 448 Elements(state->stream_output.stride)); 449 util_dump_array_begin(stream); 450 for(i = 0; i < state->stream_output.num_outputs; ++i) { 451 util_dump_elem_begin(stream); 452 util_dump_struct_begin(stream, ""); /* anonymous */ 453 util_dump_member(stream, uint, &state->stream_output.output[i], register_index); 454 util_dump_member(stream, uint, &state->stream_output.output[i], start_component); 455 util_dump_member(stream, uint, &state->stream_output.output[i], num_components); 456 util_dump_member(stream, uint, &state->stream_output.output[i], output_buffer); 457 util_dump_struct_end(stream); 458 util_dump_elem_end(stream); 459 } 460 util_dump_array_end(stream); 461 util_dump_struct_end(stream); 462 util_dump_member_end(stream); 463 464 util_dump_struct_end(stream); 465} 466 467 468void 469util_dump_depth_stencil_alpha_state(FILE *stream, const struct pipe_depth_stencil_alpha_state *state) 470{ 471 unsigned i; 472 473 if(!state) { 474 util_dump_null(stream); 475 return; 476 } 477 478 util_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); 479 480 util_dump_member_begin(stream, "depth"); 481 util_dump_struct_begin(stream, "pipe_depth_state"); 482 util_dump_member(stream, bool, &state->depth, enabled); 483 if (state->depth.enabled) { 484 util_dump_member(stream, bool, &state->depth, writemask); 485 util_dump_member(stream, enum_func, &state->depth, func); 486 } 487 util_dump_struct_end(stream); 488 util_dump_member_end(stream); 489 490 util_dump_member_begin(stream, "stencil"); 491 util_dump_array_begin(stream); 492 for(i = 0; i < Elements(state->stencil); ++i) { 493 util_dump_elem_begin(stream); 494 util_dump_struct_begin(stream, "pipe_stencil_state"); 495 util_dump_member(stream, bool, &state->stencil[i], enabled); 496 if (state->stencil[i].enabled) { 497 util_dump_member(stream, enum_func, &state->stencil[i], func); 498 util_dump_member(stream, uint, &state->stencil[i], fail_op); 499 util_dump_member(stream, uint, &state->stencil[i], zpass_op); 500 util_dump_member(stream, uint, &state->stencil[i], zfail_op); 501 util_dump_member(stream, uint, &state->stencil[i], valuemask); 502 util_dump_member(stream, uint, &state->stencil[i], writemask); 503 } 504 util_dump_struct_end(stream); 505 util_dump_elem_end(stream); 506 } 507 util_dump_array_end(stream); 508 util_dump_member_end(stream); 509 510 util_dump_member_begin(stream, "alpha"); 511 util_dump_struct_begin(stream, "pipe_alpha_state"); 512 util_dump_member(stream, bool, &state->alpha, enabled); 513 if (state->alpha.enabled) { 514 util_dump_member(stream, enum_func, &state->alpha, func); 515 util_dump_member(stream, float, &state->alpha, ref_value); 516 } 517 util_dump_struct_end(stream); 518 util_dump_member_end(stream); 519 520 util_dump_struct_end(stream); 521} 522 523void 524util_dump_rt_blend_state(FILE *stream, const struct pipe_rt_blend_state *state) 525{ 526 util_dump_struct_begin(stream, "pipe_rt_blend_state"); 527 528 util_dump_member(stream, uint, state, blend_enable); 529 if (state->blend_enable) { 530 util_dump_member(stream, enum_blend_func, state, rgb_func); 531 util_dump_member(stream, enum_blend_factor, state, rgb_src_factor); 532 util_dump_member(stream, enum_blend_factor, state, rgb_dst_factor); 533 534 util_dump_member(stream, enum_blend_func, state, alpha_func); 535 util_dump_member(stream, enum_blend_factor, state, alpha_src_factor); 536 util_dump_member(stream, enum_blend_factor, state, alpha_dst_factor); 537 } 538 539 util_dump_member(stream, uint, state, colormask); 540 541 util_dump_struct_end(stream); 542} 543 544void 545util_dump_blend_state(FILE *stream, const struct pipe_blend_state *state) 546{ 547 unsigned valid_entries = 1; 548 549 if(!state) { 550 util_dump_null(stream); 551 return; 552 } 553 554 util_dump_struct_begin(stream, "pipe_blend_state"); 555 556 util_dump_member(stream, bool, state, dither); 557 558 util_dump_member(stream, bool, state, logicop_enable); 559 if (state->logicop_enable) { 560 util_dump_member(stream, enum_func, state, logicop_func); 561 } 562 else { 563 util_dump_member(stream, bool, state, independent_blend_enable); 564 565 util_dump_member_begin(stream, "rt"); 566 if (state->independent_blend_enable) 567 valid_entries = PIPE_MAX_COLOR_BUFS; 568 util_dump_struct_array(stream, rt_blend_state, state->rt, valid_entries); 569 util_dump_member_end(stream); 570 } 571 572 util_dump_struct_end(stream); 573} 574 575 576void 577util_dump_blend_color(FILE *stream, const struct pipe_blend_color *state) 578{ 579 if(!state) { 580 util_dump_null(stream); 581 return; 582 } 583 584 util_dump_struct_begin(stream, "pipe_blend_color"); 585 586 util_dump_member_array(stream, float, state, color); 587 588 util_dump_struct_end(stream); 589} 590 591void 592util_dump_stencil_ref(FILE *stream, const struct pipe_stencil_ref *state) 593{ 594 if(!state) { 595 util_dump_null(stream); 596 return; 597 } 598 599 util_dump_struct_begin(stream, "pipe_stencil_ref"); 600 601 util_dump_member_array(stream, uint, state, ref_value); 602 603 util_dump_struct_end(stream); 604} 605 606void 607util_dump_framebuffer_state(FILE *stream, const struct pipe_framebuffer_state *state) 608{ 609 util_dump_struct_begin(stream, "pipe_framebuffer_state"); 610 611 util_dump_member(stream, uint, state, width); 612 util_dump_member(stream, uint, state, height); 613 util_dump_member(stream, uint, state, nr_cbufs); 614 util_dump_member_array(stream, ptr, state, cbufs); 615 util_dump_member(stream, ptr, state, zsbuf); 616 617 util_dump_struct_end(stream); 618} 619 620 621void 622util_dump_sampler_state(FILE *stream, const struct pipe_sampler_state *state) 623{ 624 if(!state) { 625 util_dump_null(stream); 626 return; 627 } 628 629 util_dump_struct_begin(stream, "pipe_sampler_state"); 630 631 util_dump_member(stream, uint, state, wrap_s); 632 util_dump_member(stream, uint, state, wrap_t); 633 util_dump_member(stream, uint, state, wrap_r); 634 util_dump_member(stream, uint, state, min_img_filter); 635 util_dump_member(stream, uint, state, min_mip_filter); 636 util_dump_member(stream, uint, state, mag_img_filter); 637 util_dump_member(stream, uint, state, compare_mode); 638 util_dump_member(stream, enum_func, state, compare_func); 639 util_dump_member(stream, bool, state, normalized_coords); 640 util_dump_member(stream, uint, state, max_anisotropy); 641 util_dump_member(stream, float, state, lod_bias); 642 util_dump_member(stream, float, state, min_lod); 643 util_dump_member(stream, float, state, max_lod); 644 util_dump_member_array(stream, float, state, border_color.f); 645 646 util_dump_struct_end(stream); 647} 648 649 650void 651util_dump_surface(FILE *stream, const struct pipe_surface *state) 652{ 653 if(!state) { 654 util_dump_null(stream); 655 return; 656 } 657 658 util_dump_struct_begin(stream, "pipe_surface"); 659 660 util_dump_member(stream, format, state, format); 661 util_dump_member(stream, uint, state, width); 662 util_dump_member(stream, uint, state, height); 663 664 util_dump_member(stream, uint, state, usage); 665 666 util_dump_member(stream, ptr, state, texture); 667 util_dump_member(stream, uint, state, u.tex.level); 668 util_dump_member(stream, uint, state, u.tex.first_layer); 669 util_dump_member(stream, uint, state, u.tex.last_layer); 670 671 util_dump_struct_end(stream); 672} 673 674 675void 676util_dump_transfer(FILE *stream, const struct pipe_transfer *state) 677{ 678 if(!state) { 679 util_dump_null(stream); 680 return; 681 } 682 683 util_dump_struct_begin(stream, "pipe_transfer"); 684 685 util_dump_member(stream, ptr, state, resource); 686 /*util_dump_member(stream, uint, state, box);*/ 687 688 util_dump_member(stream, uint, state, stride); 689 util_dump_member(stream, uint, state, layer_stride); 690 691 /*util_dump_member(stream, ptr, state, data);*/ 692 693 util_dump_struct_end(stream); 694} 695 696 697void 698util_dump_vertex_buffer(FILE *stream, const struct pipe_vertex_buffer *state) 699{ 700 if(!state) { 701 util_dump_null(stream); 702 return; 703 } 704 705 util_dump_struct_begin(stream, "pipe_vertex_buffer"); 706 707 util_dump_member(stream, uint, state, stride); 708 util_dump_member(stream, uint, state, buffer_offset); 709 util_dump_member(stream, ptr, state, buffer); 710 711 util_dump_struct_end(stream); 712} 713 714 715void 716util_dump_vertex_element(FILE *stream, const struct pipe_vertex_element *state) 717{ 718 if(!state) { 719 util_dump_null(stream); 720 return; 721 } 722 723 util_dump_struct_begin(stream, "pipe_vertex_element"); 724 725 util_dump_member(stream, uint, state, src_offset); 726 727 util_dump_member(stream, uint, state, vertex_buffer_index); 728 729 util_dump_member(stream, format, state, src_format); 730 731 util_dump_struct_end(stream); 732} 733 734 735void 736util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) 737{ 738 if(!state) { 739 util_dump_null(stream); 740 return; 741 } 742 743 util_dump_struct_begin(stream, "pipe_draw_info"); 744 745 util_dump_member(stream, bool, state, indexed); 746 747 util_dump_member(stream, uint, state, mode); 748 util_dump_member(stream, uint, state, start); 749 util_dump_member(stream, uint, state, count); 750 751 util_dump_member(stream, uint, state, start_instance); 752 util_dump_member(stream, uint, state, instance_count); 753 754 util_dump_member(stream, int, state, index_bias); 755 util_dump_member(stream, uint, state, min_index); 756 util_dump_member(stream, uint, state, max_index); 757 758 util_dump_member(stream, bool, state, primitive_restart); 759 util_dump_member(stream, uint, state, restart_index); 760 761 util_dump_member(stream, ptr, state, count_from_stream_output); 762 763 util_dump_struct_end(stream); 764} 765