1/************************************************************************** 2 * 3 * Copyright 2008 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#include "util/format/u_format.h" 29#include "util/u_memory.h" 30#include "util/hash_table.h" 31#include "util/simple_list.h" 32 33#include "tr_dump.h" 34#include "tr_dump_defines.h" 35#include "tr_dump_state.h" 36#include "tr_texture.h" 37#include "tr_context.h" 38#include "tr_screen.h" 39#include "tr_public.h" 40 41 42static bool trace = false; 43static struct hash_table *trace_screens; 44 45static const char * 46trace_screen_get_name(struct pipe_screen *_screen) 47{ 48 struct trace_screen *tr_scr = trace_screen(_screen); 49 struct pipe_screen *screen = tr_scr->screen; 50 const char *result; 51 52 trace_dump_call_begin("pipe_screen", "get_name"); 53 54 trace_dump_arg(ptr, screen); 55 56 result = screen->get_name(screen); 57 58 trace_dump_ret(string, result); 59 60 trace_dump_call_end(); 61 62 return result; 63} 64 65 66static const char * 67trace_screen_get_vendor(struct pipe_screen *_screen) 68{ 69 struct trace_screen *tr_scr = trace_screen(_screen); 70 struct pipe_screen *screen = tr_scr->screen; 71 const char *result; 72 73 trace_dump_call_begin("pipe_screen", "get_vendor"); 74 75 trace_dump_arg(ptr, screen); 76 77 result = screen->get_vendor(screen); 78 79 trace_dump_ret(string, result); 80 81 trace_dump_call_end(); 82 83 return result; 84} 85 86 87static const char * 88trace_screen_get_device_vendor(struct pipe_screen *_screen) 89{ 90 struct trace_screen *tr_scr = trace_screen(_screen); 91 struct pipe_screen *screen = tr_scr->screen; 92 const char *result; 93 94 trace_dump_call_begin("pipe_screen", "get_device_vendor"); 95 96 trace_dump_arg(ptr, screen); 97 98 result = screen->get_device_vendor(screen); 99 100 trace_dump_ret(string, result); 101 102 trace_dump_call_end(); 103 104 return result; 105} 106 107 108static const void * 109trace_screen_get_compiler_options(struct pipe_screen *_screen, 110 enum pipe_shader_ir ir, 111 enum pipe_shader_type shader) 112{ 113 struct trace_screen *tr_scr = trace_screen(_screen); 114 struct pipe_screen *screen = tr_scr->screen; 115 116 return screen->get_compiler_options(screen, ir, shader); 117} 118 119 120static struct disk_cache * 121trace_screen_get_disk_shader_cache(struct pipe_screen *_screen) 122{ 123 struct trace_screen *tr_scr = trace_screen(_screen); 124 struct pipe_screen *screen = tr_scr->screen; 125 126 trace_dump_call_begin("pipe_screen", "get_disk_shader_cache"); 127 128 trace_dump_arg(ptr, screen); 129 130 struct disk_cache *result = screen->get_disk_shader_cache(screen); 131 132 trace_dump_ret(ptr, result); 133 134 trace_dump_call_end(); 135 136 return result; 137} 138 139 140static int 141trace_screen_get_param(struct pipe_screen *_screen, 142 enum pipe_cap param) 143{ 144 struct trace_screen *tr_scr = trace_screen(_screen); 145 struct pipe_screen *screen = tr_scr->screen; 146 int result; 147 148 trace_dump_call_begin("pipe_screen", "get_param"); 149 150 trace_dump_arg(ptr, screen); 151 trace_dump_arg(int, param); 152 153 result = screen->get_param(screen, param); 154 155 trace_dump_ret(int, result); 156 157 trace_dump_call_end(); 158 159 return result; 160} 161 162 163static int 164trace_screen_get_shader_param(struct pipe_screen *_screen, 165 enum pipe_shader_type shader, 166 enum pipe_shader_cap param) 167{ 168 struct trace_screen *tr_scr = trace_screen(_screen); 169 struct pipe_screen *screen = tr_scr->screen; 170 int result; 171 172 trace_dump_call_begin("pipe_screen", "get_shader_param"); 173 174 trace_dump_arg(ptr, screen); 175 trace_dump_arg(uint, shader); 176 trace_dump_arg(int, param); 177 178 result = screen->get_shader_param(screen, shader, param); 179 180 trace_dump_ret(int, result); 181 182 trace_dump_call_end(); 183 184 return result; 185} 186 187 188static float 189trace_screen_get_paramf(struct pipe_screen *_screen, 190 enum pipe_capf param) 191{ 192 struct trace_screen *tr_scr = trace_screen(_screen); 193 struct pipe_screen *screen = tr_scr->screen; 194 float result; 195 196 trace_dump_call_begin("pipe_screen", "get_paramf"); 197 198 trace_dump_arg(ptr, screen); 199 trace_dump_arg(int, param); 200 201 result = screen->get_paramf(screen, param); 202 203 trace_dump_ret(float, result); 204 205 trace_dump_call_end(); 206 207 return result; 208} 209 210 211static int 212trace_screen_get_compute_param(struct pipe_screen *_screen, 213 enum pipe_shader_ir ir_type, 214 enum pipe_compute_cap param, void *data) 215{ 216 struct trace_screen *tr_scr = trace_screen(_screen); 217 struct pipe_screen *screen = tr_scr->screen; 218 int result; 219 220 trace_dump_call_begin("pipe_screen", "get_compute_param"); 221 222 trace_dump_arg(ptr, screen); 223 trace_dump_arg(int, ir_type); 224 trace_dump_arg(int, param); 225 trace_dump_arg(ptr, data); 226 227 result = screen->get_compute_param(screen, ir_type, param, data); 228 229 trace_dump_ret(int, result); 230 231 trace_dump_call_end(); 232 233 return result; 234} 235 236 237static bool 238trace_screen_is_format_supported(struct pipe_screen *_screen, 239 enum pipe_format format, 240 enum pipe_texture_target target, 241 unsigned sample_count, 242 unsigned storage_sample_count, 243 unsigned tex_usage) 244{ 245 struct trace_screen *tr_scr = trace_screen(_screen); 246 struct pipe_screen *screen = tr_scr->screen; 247 bool result; 248 249 trace_dump_call_begin("pipe_screen", "is_format_supported"); 250 251 trace_dump_arg(ptr, screen); 252 trace_dump_arg(format, format); 253 trace_dump_arg(int, target); 254 trace_dump_arg(uint, sample_count); 255 trace_dump_arg(uint, tex_usage); 256 257 result = screen->is_format_supported(screen, format, target, sample_count, 258 storage_sample_count, tex_usage); 259 260 trace_dump_ret(bool, result); 261 262 trace_dump_call_end(); 263 264 return result; 265} 266 267static void 268trace_context_replace_buffer_storage(struct pipe_context *_pipe, 269 struct pipe_resource *dst, 270 struct pipe_resource *src, 271 unsigned num_rebinds, 272 uint32_t rebind_mask, 273 unsigned delete_buffer_id) 274{ 275 struct trace_context *tr_ctx = trace_context(_pipe); 276 struct pipe_context *pipe = tr_ctx->pipe; 277 278 trace_dump_call_begin("pipe_context", "replace_buffer_storage"); 279 280 trace_dump_arg(ptr, pipe); 281 trace_dump_arg(ptr, dst); 282 trace_dump_arg(ptr, src); 283 trace_dump_arg(uint, num_rebinds); 284 trace_dump_arg(uint, rebind_mask); 285 trace_dump_arg(uint, delete_buffer_id); 286 trace_dump_call_end(); 287 288 tr_ctx->replace_buffer_storage(pipe, dst, src, num_rebinds, rebind_mask, delete_buffer_id); 289} 290 291static struct pipe_fence_handle * 292trace_context_create_fence(struct pipe_context *_pipe, struct tc_unflushed_batch_token *token) 293{ 294 struct trace_context *tr_ctx = trace_context(_pipe); 295 struct pipe_context *pipe = tr_ctx->pipe; 296 297 trace_dump_call_begin("pipe_context", "create_fence"); 298 299 trace_dump_arg(ptr, pipe); 300 trace_dump_arg(ptr, token); 301 302 struct pipe_fence_handle *ret = tr_ctx->create_fence(pipe, token); 303 trace_dump_ret(ptr, ret); 304 trace_dump_call_end(); 305 306 return ret; 307} 308 309static bool 310trace_context_is_resource_busy(struct pipe_screen *_screen, 311 struct pipe_resource *resource, 312 unsigned usage) 313{ 314 struct trace_screen *tr_scr = trace_screen(_screen); 315 struct pipe_screen *screen = tr_scr->screen; 316 bool result; 317 318 trace_dump_call_begin("pipe_screen", "is_resource_busy"); 319 320 trace_dump_arg(ptr, screen); 321 trace_dump_arg(ptr, resource); 322 trace_dump_arg(uint, usage); 323 324 result = tr_scr->is_resource_busy(screen, resource, usage); 325 326 trace_dump_ret(bool, result); 327 328 trace_dump_call_end(); 329 330 return result; 331} 332 333struct pipe_context * 334trace_context_create_threaded(struct pipe_screen *screen, struct pipe_context *pipe, 335 tc_replace_buffer_storage_func *replace_buffer, 336 struct threaded_context_options *options) 337{ 338 if (!trace_screens) 339 return pipe; 340 341 struct hash_entry *he = _mesa_hash_table_search(trace_screens, screen); 342 if (!he) 343 return pipe; 344 struct trace_screen *tr_scr = trace_screen(he->data); 345 346 if (tr_scr->trace_tc) 347 return pipe; 348 349 struct pipe_context *ctx = trace_context_create(tr_scr, pipe); 350 if (!ctx) 351 return pipe; 352 353 struct trace_context *tr_ctx = trace_context(ctx); 354 tr_ctx->replace_buffer_storage = *replace_buffer; 355 tr_ctx->create_fence = options->create_fence; 356 tr_scr->is_resource_busy = options->is_resource_busy; 357 tr_ctx->threaded = true; 358 *replace_buffer = trace_context_replace_buffer_storage; 359 if (options->create_fence) 360 options->create_fence = trace_context_create_fence; 361 if (options->is_resource_busy) 362 options->is_resource_busy = trace_context_is_resource_busy; 363 return ctx; 364} 365 366static struct pipe_context * 367trace_screen_context_create(struct pipe_screen *_screen, void *priv, 368 unsigned flags) 369{ 370 struct trace_screen *tr_scr = trace_screen(_screen); 371 struct pipe_screen *screen = tr_scr->screen; 372 struct pipe_context *result; 373 374 result = screen->context_create(screen, priv, flags); 375 376 trace_dump_call_begin("pipe_screen", "context_create"); 377 378 trace_dump_arg(ptr, screen); 379 trace_dump_arg(ptr, priv); 380 trace_dump_arg(uint, flags); 381 382 trace_dump_ret(ptr, result); 383 384 trace_dump_call_end(); 385 386 if (result && (tr_scr->trace_tc || result->draw_vbo != tc_draw_vbo)) 387 result = trace_context_create(tr_scr, result); 388 389 return result; 390} 391 392 393static void 394trace_screen_flush_frontbuffer(struct pipe_screen *_screen, 395 struct pipe_context *_pipe, 396 struct pipe_resource *resource, 397 unsigned level, unsigned layer, 398 void *context_private, 399 struct pipe_box *sub_box) 400{ 401 struct trace_screen *tr_scr = trace_screen(_screen); 402 struct pipe_screen *screen = tr_scr->screen; 403 struct pipe_context *pipe = _pipe ? trace_get_possibly_threaded_context(_pipe) : NULL; 404 405 trace_dump_call_begin("pipe_screen", "flush_frontbuffer"); 406 407 trace_dump_arg(ptr, screen); 408 trace_dump_arg(ptr, resource); 409 trace_dump_arg(uint, level); 410 trace_dump_arg(uint, layer); 411 /* XXX: hide, as there is nothing we can do with this 412 trace_dump_arg(ptr, context_private); 413 */ 414 415 trace_dump_call_end(); 416 417 screen->flush_frontbuffer(screen, pipe, resource, level, layer, context_private, sub_box); 418} 419 420 421static void 422trace_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid) 423{ 424 struct pipe_screen *screen = trace_screen(_screen)->screen; 425 426 trace_dump_call_begin("pipe_screen", "get_driver_uuid"); 427 trace_dump_arg(ptr, screen); 428 429 screen->get_driver_uuid(screen, uuid); 430 431 trace_dump_ret(string, uuid); 432 trace_dump_call_end(); 433} 434 435static void 436trace_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid) 437{ 438 struct pipe_screen *screen = trace_screen(_screen)->screen; 439 440 trace_dump_call_begin("pipe_screen", "get_device_uuid"); 441 trace_dump_arg(ptr, screen); 442 443 screen->get_device_uuid(screen, uuid); 444 445 trace_dump_ret(string, uuid); 446 trace_dump_call_end(); 447} 448 449 450/******************************************************************** 451 * texture 452 */ 453 454static void * 455trace_screen_map_memory(struct pipe_screen *_screen, 456 struct pipe_memory_allocation *pmem) 457{ 458 struct trace_screen *tr_scr = trace_screen(_screen); 459 struct pipe_screen *screen = tr_scr->screen; 460 void *result; 461 462 trace_dump_call_begin("pipe_screen", "map_memory"); 463 464 trace_dump_arg(ptr, screen); 465 trace_dump_arg(ptr, pmem); 466 467 result = screen->map_memory(screen, pmem); 468 469 trace_dump_ret(ptr, result); 470 471 trace_dump_call_end(); 472 473 return result; 474} 475 476static void 477trace_screen_unmap_memory(struct pipe_screen *_screen, 478 struct pipe_memory_allocation *pmem) 479{ 480 struct trace_screen *tr_scr = trace_screen(_screen); 481 struct pipe_screen *screen = tr_scr->screen; 482 483 trace_dump_call_begin("pipe_screen", "unmap_memory"); 484 485 trace_dump_arg(ptr, screen); 486 trace_dump_arg(ptr, pmem); 487 488 screen->unmap_memory(screen, pmem); 489 490 491 trace_dump_call_end(); 492} 493 494static struct pipe_memory_allocation * 495trace_screen_allocate_memory(struct pipe_screen *_screen, 496 uint64_t size) 497{ 498 struct trace_screen *tr_scr = trace_screen(_screen); 499 struct pipe_screen *screen = tr_scr->screen; 500 struct pipe_memory_allocation *result; 501 502 trace_dump_call_begin("pipe_screen", "allocate_memory"); 503 504 trace_dump_arg(ptr, screen); 505 trace_dump_arg(uint, size); 506 507 result = screen->allocate_memory(screen, size); 508 509 trace_dump_ret(ptr, result); 510 511 trace_dump_call_end(); 512 513 return result; 514} 515 516static void 517trace_screen_free_memory(struct pipe_screen *_screen, 518 struct pipe_memory_allocation *pmem) 519{ 520 struct trace_screen *tr_scr = trace_screen(_screen); 521 struct pipe_screen *screen = tr_scr->screen; 522 523 trace_dump_call_begin("pipe_screen", "free_memory"); 524 525 trace_dump_arg(ptr, screen); 526 trace_dump_arg(ptr, pmem); 527 528 screen->free_memory(screen, pmem); 529 530 531 trace_dump_call_end(); 532} 533 534static bool 535trace_screen_resource_bind_backing(struct pipe_screen *_screen, 536 struct pipe_resource *resource, 537 struct pipe_memory_allocation *pmem, 538 uint64_t offset) 539{ 540 struct trace_screen *tr_scr = trace_screen(_screen); 541 struct pipe_screen *screen = tr_scr->screen; 542 bool result; 543 544 trace_dump_call_begin("pipe_screen", "resource_bind_backing"); 545 546 trace_dump_arg(ptr, screen); 547 trace_dump_arg(ptr, resource); 548 trace_dump_arg(ptr, pmem); 549 trace_dump_arg(uint, offset); 550 551 result = screen->resource_bind_backing(screen, resource, pmem, offset); 552 553 trace_dump_ret(bool, result); 554 555 trace_dump_call_end(); 556 557 return result; 558} 559 560static struct pipe_resource * 561trace_screen_resource_create_unbacked(struct pipe_screen *_screen, 562 const struct pipe_resource *templat, 563 uint64_t *size_required) 564{ 565 struct trace_screen *tr_scr = trace_screen(_screen); 566 struct pipe_screen *screen = tr_scr->screen; 567 struct pipe_resource *result; 568 569 trace_dump_call_begin("pipe_screen", "resource_create_unbacked"); 570 571 trace_dump_arg(ptr, screen); 572 trace_dump_arg(resource_template, templat); 573 574 result = screen->resource_create_unbacked(screen, templat, size_required); 575 576 trace_dump_ret_begin(); 577 trace_dump_uint(*size_required); 578 trace_dump_ret_end(); 579 trace_dump_ret(ptr, result); 580 581 trace_dump_call_end(); 582 583 if (result) 584 result->screen = _screen; 585 return result; 586} 587 588static struct pipe_resource * 589trace_screen_resource_create(struct pipe_screen *_screen, 590 const struct pipe_resource *templat) 591{ 592 struct trace_screen *tr_scr = trace_screen(_screen); 593 struct pipe_screen *screen = tr_scr->screen; 594 struct pipe_resource *result; 595 596 trace_dump_call_begin("pipe_screen", "resource_create"); 597 598 trace_dump_arg(ptr, screen); 599 trace_dump_arg(resource_template, templat); 600 601 result = screen->resource_create(screen, templat); 602 603 trace_dump_ret(ptr, result); 604 605 trace_dump_call_end(); 606 607 if (result) 608 result->screen = _screen; 609 return result; 610} 611 612static struct pipe_resource * 613trace_screen_resource_create_with_modifiers(struct pipe_screen *_screen, const struct pipe_resource *templat, 614 const uint64_t *modifiers, int modifiers_count) 615{ 616 struct trace_screen *tr_scr = trace_screen(_screen); 617 struct pipe_screen *screen = tr_scr->screen; 618 struct pipe_resource *result; 619 620 trace_dump_call_begin("pipe_screen", "resource_create_with_modifiers"); 621 622 trace_dump_arg(ptr, screen); 623 trace_dump_arg(resource_template, templat); 624 trace_dump_arg_array(uint, modifiers, modifiers_count); 625 626 result = screen->resource_create_with_modifiers(screen, templat, modifiers, modifiers_count); 627 628 trace_dump_ret(ptr, result); 629 630 trace_dump_call_end(); 631 632 if (result) 633 result->screen = _screen; 634 return result; 635} 636 637static struct pipe_resource * 638trace_screen_resource_from_handle(struct pipe_screen *_screen, 639 const struct pipe_resource *templ, 640 struct winsys_handle *handle, 641 unsigned usage) 642{ 643 struct trace_screen *tr_screen = trace_screen(_screen); 644 struct pipe_screen *screen = tr_screen->screen; 645 struct pipe_resource *result; 646 647 /* TODO trace call */ 648 649 result = screen->resource_from_handle(screen, templ, handle, usage); 650 651 if (result) 652 result->screen = _screen; 653 return result; 654} 655 656static bool 657trace_screen_check_resource_capability(struct pipe_screen *_screen, 658 struct pipe_resource *resource, 659 unsigned bind) 660{ 661 struct pipe_screen *screen = trace_screen(_screen)->screen; 662 663 return screen->check_resource_capability(screen, resource, bind); 664} 665 666static bool 667trace_screen_resource_get_handle(struct pipe_screen *_screen, 668 struct pipe_context *_pipe, 669 struct pipe_resource *resource, 670 struct winsys_handle *handle, 671 unsigned usage) 672{ 673 struct trace_screen *tr_screen = trace_screen(_screen); 674 struct pipe_context *pipe = _pipe ? trace_get_possibly_threaded_context(_pipe) : NULL; 675 struct pipe_screen *screen = tr_screen->screen; 676 677 /* TODO trace call */ 678 679 return screen->resource_get_handle(screen, pipe, 680 resource, handle, usage); 681} 682 683static bool 684trace_screen_resource_get_param(struct pipe_screen *_screen, 685 struct pipe_context *_pipe, 686 struct pipe_resource *resource, 687 unsigned plane, 688 unsigned layer, 689 unsigned level, 690 enum pipe_resource_param param, 691 unsigned handle_usage, 692 uint64_t *value) 693{ 694 struct trace_screen *tr_screen = trace_screen(_screen); 695 struct pipe_context *pipe = _pipe ? trace_get_possibly_threaded_context(_pipe) : NULL; 696 struct pipe_screen *screen = tr_screen->screen; 697 698 /* TODO trace call */ 699 700 return screen->resource_get_param(screen, pipe, 701 resource, plane, layer, level, param, 702 handle_usage, value); 703} 704 705static void 706trace_screen_resource_get_info(struct pipe_screen *_screen, 707 struct pipe_resource *resource, 708 unsigned *stride, 709 unsigned *offset) 710{ 711 struct trace_screen *tr_screen = trace_screen(_screen); 712 struct pipe_screen *screen = tr_screen->screen; 713 714 /* TODO trace call */ 715 716 screen->resource_get_info(screen, resource, stride, offset); 717} 718 719static struct pipe_resource * 720trace_screen_resource_from_memobj(struct pipe_screen *_screen, 721 const struct pipe_resource *templ, 722 struct pipe_memory_object *memobj, 723 uint64_t offset) 724{ 725 struct pipe_screen *screen = trace_screen(_screen)->screen; 726 727 trace_dump_call_begin("pipe_screen", "resource_from_memobj"); 728 trace_dump_arg(ptr, screen); 729 trace_dump_arg(resource_template, templ); 730 trace_dump_arg(ptr, memobj); 731 trace_dump_arg(uint, offset); 732 733 struct pipe_resource *res = 734 screen->resource_from_memobj(screen, templ, memobj, offset); 735 736 if (!res) 737 return NULL; 738 res->screen = _screen; 739 740 trace_dump_ret(ptr, res); 741 trace_dump_call_end(); 742 return res; 743} 744 745static void 746trace_screen_resource_changed(struct pipe_screen *_screen, 747 struct pipe_resource *resource) 748{ 749 struct trace_screen *tr_scr = trace_screen(_screen); 750 struct pipe_screen *screen = tr_scr->screen; 751 752 trace_dump_call_begin("pipe_screen", "resource_changed"); 753 754 trace_dump_arg(ptr, screen); 755 trace_dump_arg(ptr, resource); 756 757 if (screen->resource_changed) 758 screen->resource_changed(screen, resource); 759 760 trace_dump_call_end(); 761} 762 763static void 764trace_screen_resource_destroy(struct pipe_screen *_screen, 765 struct pipe_resource *resource) 766{ 767 struct trace_screen *tr_scr = trace_screen(_screen); 768 struct pipe_screen *screen = tr_scr->screen; 769 770 /* Don't trace this, because due to the lack of pipe_resource wrapping, 771 * we can get this call from inside of driver calls, which would try 772 * to lock an already-locked mutex. 773 */ 774 screen->resource_destroy(screen, resource); 775} 776 777 778/******************************************************************** 779 * fence 780 */ 781 782 783static void 784trace_screen_fence_reference(struct pipe_screen *_screen, 785 struct pipe_fence_handle **pdst, 786 struct pipe_fence_handle *src) 787{ 788 struct trace_screen *tr_scr = trace_screen(_screen); 789 struct pipe_screen *screen = tr_scr->screen; 790 struct pipe_fence_handle *dst; 791 792 assert(pdst); 793 dst = *pdst; 794 795 trace_dump_call_begin("pipe_screen", "fence_reference"); 796 797 trace_dump_arg(ptr, screen); 798 trace_dump_arg(ptr, dst); 799 trace_dump_arg(ptr, src); 800 801 screen->fence_reference(screen, pdst, src); 802 803 trace_dump_call_end(); 804} 805 806 807static int 808trace_screen_fence_get_fd(struct pipe_screen *_screen, 809 struct pipe_fence_handle *fence) 810{ 811 struct trace_screen *tr_scr = trace_screen(_screen); 812 struct pipe_screen *screen = tr_scr->screen; 813 int result; 814 815 trace_dump_call_begin("pipe_screen", "fence_get_fd"); 816 817 trace_dump_arg(ptr, screen); 818 trace_dump_arg(ptr, fence); 819 820 result = screen->fence_get_fd(screen, fence); 821 822 trace_dump_ret(int, result); 823 824 trace_dump_call_end(); 825 826 return result; 827} 828 829 830static bool 831trace_screen_fence_finish(struct pipe_screen *_screen, 832 struct pipe_context *_ctx, 833 struct pipe_fence_handle *fence, 834 uint64_t timeout) 835{ 836 struct trace_screen *tr_scr = trace_screen(_screen); 837 struct pipe_screen *screen = tr_scr->screen; 838 struct pipe_context *ctx = _ctx ? trace_get_possibly_threaded_context(_ctx) : NULL; 839 int result; 840 841 result = screen->fence_finish(screen, ctx, fence, timeout); 842 843 844 trace_dump_call_begin("pipe_screen", "fence_finish"); 845 846 trace_dump_arg(ptr, screen); 847 trace_dump_arg(ptr, ctx); 848 trace_dump_arg(ptr, fence); 849 trace_dump_arg(uint, timeout); 850 851 trace_dump_ret(bool, result); 852 853 trace_dump_call_end(); 854 855 return result; 856} 857 858 859/******************************************************************** 860 * memobj 861 */ 862 863static struct pipe_memory_object * 864trace_screen_memobj_create_from_handle(struct pipe_screen *_screen, 865 struct winsys_handle *handle, 866 bool dedicated) 867{ 868 struct pipe_screen *screen = trace_screen(_screen)->screen; 869 870 trace_dump_call_begin("pipe_screen", "memobj_create_from_handle"); 871 trace_dump_arg(ptr, screen); 872 trace_dump_arg(ptr, handle); 873 trace_dump_arg(bool, dedicated); 874 875 struct pipe_memory_object *res = 876 screen->memobj_create_from_handle(screen, handle, dedicated); 877 878 trace_dump_ret(ptr, res); 879 trace_dump_call_end(); 880 881 return res; 882} 883 884static void 885trace_screen_memobj_destroy(struct pipe_screen *_screen, 886 struct pipe_memory_object *memobj) 887{ 888 struct pipe_screen *screen = trace_screen(_screen)->screen; 889 890 trace_dump_call_begin("pipe_screen", "memobj_destroy"); 891 trace_dump_arg(ptr, screen); 892 trace_dump_arg(ptr, memobj); 893 trace_dump_call_end(); 894 895 screen->memobj_destroy(screen, memobj); 896} 897 898 899/******************************************************************** 900 * screen 901 */ 902 903static uint64_t 904trace_screen_get_timestamp(struct pipe_screen *_screen) 905{ 906 struct trace_screen *tr_scr = trace_screen(_screen); 907 struct pipe_screen *screen = tr_scr->screen; 908 uint64_t result; 909 910 trace_dump_call_begin("pipe_screen", "get_timestamp"); 911 trace_dump_arg(ptr, screen); 912 913 result = screen->get_timestamp(screen); 914 915 trace_dump_ret(uint, result); 916 trace_dump_call_end(); 917 918 return result; 919} 920 921static char * 922trace_screen_finalize_nir(struct pipe_screen *_screen, void *nir) 923{ 924 struct pipe_screen *screen = trace_screen(_screen)->screen; 925 926 return screen->finalize_nir(screen, nir); 927} 928 929static void 930trace_screen_destroy(struct pipe_screen *_screen) 931{ 932 struct trace_screen *tr_scr = trace_screen(_screen); 933 struct pipe_screen *screen = tr_scr->screen; 934 935 trace_dump_call_begin("pipe_screen", "destroy"); 936 trace_dump_arg(ptr, screen); 937 trace_dump_call_end(); 938 939 if (trace_screens) { 940 struct hash_entry *he = _mesa_hash_table_search(trace_screens, screen); 941 if (he) { 942 _mesa_hash_table_remove(trace_screens, he); 943 if (!_mesa_hash_table_num_entries(trace_screens)) { 944 _mesa_hash_table_destroy(trace_screens, NULL); 945 trace_screens = NULL; 946 } 947 } 948 } 949 950 screen->destroy(screen); 951 952 FREE(tr_scr); 953} 954 955static void 956trace_screen_query_memory_info(struct pipe_screen *_screen, struct pipe_memory_info *info) 957{ 958 struct trace_screen *tr_scr = trace_screen(_screen); 959 struct pipe_screen *screen = tr_scr->screen; 960 961 trace_dump_call_begin("pipe_screen", "query_memory_info"); 962 963 trace_dump_arg(ptr, screen); 964 965 screen->query_memory_info(screen, info); 966 967 trace_dump_ret(memory_info, info); 968 969 trace_dump_call_end(); 970} 971 972static void 973trace_screen_query_dmabuf_modifiers(struct pipe_screen *_screen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count) 974{ 975 struct trace_screen *tr_scr = trace_screen(_screen); 976 struct pipe_screen *screen = tr_scr->screen; 977 978 trace_dump_call_begin("pipe_screen", "query_dmabuf_modifiers"); 979 980 trace_dump_arg(ptr, screen); 981 trace_dump_arg(format, format); 982 trace_dump_arg(int, max); 983 984 screen->query_dmabuf_modifiers(screen, format, max, modifiers, external_only, count); 985 986 if (max) 987 trace_dump_arg_array(uint, modifiers, *count); 988 else 989 trace_dump_arg_array(uint, modifiers, max); 990 trace_dump_arg_array(uint, external_only, max); 991 trace_dump_ret_begin(); 992 trace_dump_uint(*count); 993 trace_dump_ret_end(); 994 995 trace_dump_call_end(); 996} 997 998static bool 999trace_screen_is_dmabuf_modifier_supported(struct pipe_screen *_screen, uint64_t modifier, enum pipe_format format, bool *external_only) 1000{ 1001 struct trace_screen *tr_scr = trace_screen(_screen); 1002 struct pipe_screen *screen = tr_scr->screen; 1003 1004 trace_dump_call_begin("pipe_screen", "is_dmabuf_modifier_supported"); 1005 1006 trace_dump_arg(ptr, screen); 1007 trace_dump_arg(uint, modifier); 1008 trace_dump_arg(format, format); 1009 1010 bool ret = screen->is_dmabuf_modifier_supported(screen, modifier, format, external_only); 1011 1012 trace_dump_arg_begin("external_only"); 1013 trace_dump_bool(external_only ? *external_only : false); 1014 trace_dump_arg_end(); 1015 1016 trace_dump_ret(bool, ret); 1017 1018 trace_dump_call_end(); 1019 return ret; 1020} 1021 1022static unsigned int 1023trace_screen_get_dmabuf_modifier_planes(struct pipe_screen *_screen, uint64_t modifier, enum pipe_format format) 1024{ 1025 struct trace_screen *tr_scr = trace_screen(_screen); 1026 struct pipe_screen *screen = tr_scr->screen; 1027 1028 trace_dump_call_begin("pipe_screen", "get_dmabuf_modifier_planes"); 1029 1030 trace_dump_arg(ptr, screen); 1031 trace_dump_arg(uint, modifier); 1032 trace_dump_arg(format, format); 1033 1034 unsigned ret = screen->get_dmabuf_modifier_planes(screen, modifier, format); 1035 1036 trace_dump_ret(uint, ret); 1037 1038 trace_dump_call_end(); 1039 return ret; 1040} 1041 1042static struct pipe_vertex_state * 1043trace_screen_create_vertex_state(struct pipe_screen *_screen, 1044 struct pipe_vertex_buffer *buffer, 1045 const struct pipe_vertex_element *elements, 1046 unsigned num_elements, 1047 struct pipe_resource *indexbuf, 1048 uint32_t full_velem_mask) 1049{ 1050 struct trace_screen *tr_scr = trace_screen(_screen); 1051 struct pipe_screen *screen = tr_scr->screen; 1052 1053 trace_dump_call_begin("pipe_screen", "create_vertex_state"); 1054 1055 trace_dump_arg(ptr, screen); 1056 trace_dump_arg(ptr, buffer->buffer.resource); 1057 trace_dump_arg(vertex_buffer, buffer); 1058 trace_dump_arg_begin("elements"); 1059 trace_dump_struct_array(vertex_element, elements, num_elements); 1060 trace_dump_arg_end(); 1061 trace_dump_arg(uint, num_elements); 1062 trace_dump_arg(ptr, indexbuf); 1063 trace_dump_arg(uint, full_velem_mask); 1064 1065 struct pipe_vertex_state *vstate = 1066 screen->create_vertex_state(screen, buffer, elements, num_elements, 1067 indexbuf, full_velem_mask); 1068 trace_dump_ret(ptr, vstate); 1069 trace_dump_call_end(); 1070 return vstate; 1071} 1072 1073static void trace_screen_vertex_state_destroy(struct pipe_screen *_screen, 1074 struct pipe_vertex_state *state) 1075{ 1076 struct trace_screen *tr_scr = trace_screen(_screen); 1077 struct pipe_screen *screen = tr_scr->screen; 1078 1079 trace_dump_call_begin("pipe_screen", "vertex_state_destroy"); 1080 trace_dump_arg(ptr, screen); 1081 trace_dump_arg(ptr, state); 1082 trace_dump_call_end(); 1083 1084 screen->vertex_state_destroy(screen, state); 1085} 1086 1087bool 1088trace_enabled(void) 1089{ 1090 static bool firstrun = true; 1091 1092 if (!firstrun) 1093 return trace; 1094 firstrun = false; 1095 1096 if(trace_dump_trace_begin()) { 1097 trace_dumping_start(); 1098 trace = true; 1099 } 1100 1101 return trace; 1102} 1103 1104struct pipe_screen * 1105trace_screen_create(struct pipe_screen *screen) 1106{ 1107 struct trace_screen *tr_scr; 1108 1109#ifdef ZINK_WITH_SWRAST_VK 1110 /* if zink+lavapipe is enabled, ensure that only one driver is traced */ 1111 const char *driver = debug_get_option("MESA_LOADER_DRIVER_OVERRIDE", NULL); 1112 if (driver && !strcmp(driver, "zink")) { 1113 /* the user wants zink: check whether they want to trace zink or lavapipe */ 1114 bool trace_lavapipe = debug_get_bool_option("ZINK_TRACE_LAVAPIPE", false); 1115 if (!strncmp(screen->get_name(screen), "zink", 4)) { 1116 /* this is the zink screen: only trace if lavapipe tracing is disabled */ 1117 if (trace_lavapipe) 1118 return screen; 1119 } else { 1120 /* this is the llvmpipe screen: only trace if lavapipe tracing is enabled */ 1121 if (!trace_lavapipe) 1122 return screen; 1123 } 1124 } 1125#endif 1126 if (!trace_enabled()) 1127 goto error1; 1128 1129 trace_dump_call_begin("", "pipe_screen_create"); 1130 1131 tr_scr = CALLOC_STRUCT(trace_screen); 1132 if (!tr_scr) 1133 goto error2; 1134 1135#define SCR_INIT(_member) \ 1136 tr_scr->base._member = screen->_member ? trace_screen_##_member : NULL 1137 1138 tr_scr->base.destroy = trace_screen_destroy; 1139 tr_scr->base.get_name = trace_screen_get_name; 1140 tr_scr->base.get_vendor = trace_screen_get_vendor; 1141 tr_scr->base.get_device_vendor = trace_screen_get_device_vendor; 1142 SCR_INIT(get_compiler_options); 1143 SCR_INIT(get_disk_shader_cache); 1144 tr_scr->base.get_param = trace_screen_get_param; 1145 tr_scr->base.get_shader_param = trace_screen_get_shader_param; 1146 tr_scr->base.get_paramf = trace_screen_get_paramf; 1147 tr_scr->base.get_compute_param = trace_screen_get_compute_param; 1148 tr_scr->base.is_format_supported = trace_screen_is_format_supported; 1149 assert(screen->context_create); 1150 tr_scr->base.context_create = trace_screen_context_create; 1151 tr_scr->base.resource_create = trace_screen_resource_create; 1152 SCR_INIT(resource_create_with_modifiers); 1153 tr_scr->base.resource_create_unbacked = trace_screen_resource_create_unbacked; 1154 tr_scr->base.resource_bind_backing = trace_screen_resource_bind_backing; 1155 tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; 1156 tr_scr->base.allocate_memory = trace_screen_allocate_memory; 1157 tr_scr->base.free_memory = trace_screen_free_memory; 1158 tr_scr->base.map_memory = trace_screen_map_memory; 1159 tr_scr->base.unmap_memory = trace_screen_unmap_memory; 1160 SCR_INIT(query_memory_info); 1161 SCR_INIT(query_dmabuf_modifiers); 1162 SCR_INIT(is_dmabuf_modifier_supported); 1163 SCR_INIT(get_dmabuf_modifier_planes); 1164 SCR_INIT(check_resource_capability); 1165 tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; 1166 SCR_INIT(resource_get_param); 1167 SCR_INIT(resource_get_info); 1168 SCR_INIT(resource_from_memobj); 1169 SCR_INIT(resource_changed); 1170 tr_scr->base.resource_destroy = trace_screen_resource_destroy; 1171 tr_scr->base.fence_reference = trace_screen_fence_reference; 1172 SCR_INIT(fence_get_fd); 1173 tr_scr->base.fence_finish = trace_screen_fence_finish; 1174 SCR_INIT(memobj_create_from_handle); 1175 SCR_INIT(memobj_destroy); 1176 tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; 1177 tr_scr->base.get_timestamp = trace_screen_get_timestamp; 1178 SCR_INIT(get_driver_uuid); 1179 SCR_INIT(get_device_uuid); 1180 SCR_INIT(finalize_nir); 1181 SCR_INIT(create_vertex_state); 1182 SCR_INIT(vertex_state_destroy); 1183 tr_scr->base.transfer_helper = screen->transfer_helper; 1184 1185 tr_scr->screen = screen; 1186 1187 trace_dump_ret(ptr, screen); 1188 trace_dump_call_end(); 1189 1190 if (!trace_screens) 1191 trace_screens = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); 1192 _mesa_hash_table_insert(trace_screens, screen, tr_scr); 1193 1194 tr_scr->trace_tc = debug_get_bool_option("GALLIUM_TRACE_TC", false); 1195 1196 return &tr_scr->base; 1197 1198error2: 1199 trace_dump_ret(ptr, screen); 1200 trace_dump_call_end(); 1201error1: 1202 return screen; 1203} 1204 1205 1206struct trace_screen * 1207trace_screen(struct pipe_screen *screen) 1208{ 1209 assert(screen); 1210 assert(screen->destroy == trace_screen_destroy); 1211 return (struct trace_screen *)screen; 1212} 1213