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/u_format.h" 29#include "util/u_memory.h" 30#include "util/simple_list.h" 31 32#include "tr_dump.h" 33#include "tr_dump_defines.h" 34#include "tr_dump_state.h" 35#include "tr_texture.h" 36#include "tr_context.h" 37#include "tr_screen.h" 38#include "tr_public.h" 39 40 41static boolean trace = FALSE; 42 43static const char * 44trace_screen_get_name(struct pipe_screen *_screen) 45{ 46 struct trace_screen *tr_scr = trace_screen(_screen); 47 struct pipe_screen *screen = tr_scr->screen; 48 const char *result; 49 50 trace_dump_call_begin("pipe_screen", "get_name"); 51 52 trace_dump_arg(ptr, screen); 53 54 result = screen->get_name(screen); 55 56 trace_dump_ret(string, result); 57 58 trace_dump_call_end(); 59 60 return result; 61} 62 63 64static const char * 65trace_screen_get_vendor(struct pipe_screen *_screen) 66{ 67 struct trace_screen *tr_scr = trace_screen(_screen); 68 struct pipe_screen *screen = tr_scr->screen; 69 const char *result; 70 71 trace_dump_call_begin("pipe_screen", "get_vendor"); 72 73 trace_dump_arg(ptr, screen); 74 75 result = screen->get_vendor(screen); 76 77 trace_dump_ret(string, result); 78 79 trace_dump_call_end(); 80 81 return result; 82} 83 84 85static const char * 86trace_screen_get_device_vendor(struct pipe_screen *_screen) 87{ 88 struct trace_screen *tr_scr = trace_screen(_screen); 89 struct pipe_screen *screen = tr_scr->screen; 90 const char *result; 91 92 trace_dump_call_begin("pipe_screen", "get_device_vendor"); 93 94 trace_dump_arg(ptr, screen); 95 96 result = screen->get_device_vendor(screen); 97 98 trace_dump_ret(string, result); 99 100 trace_dump_call_end(); 101 102 return result; 103} 104 105 106static struct disk_cache * 107trace_screen_get_disk_shader_cache(struct pipe_screen *_screen) 108{ 109 struct trace_screen *tr_scr = trace_screen(_screen); 110 struct pipe_screen *screen = tr_scr->screen; 111 112 trace_dump_call_begin("pipe_screen", "get_disk_shader_cache"); 113 114 trace_dump_arg(ptr, screen); 115 116 struct disk_cache *result = screen->get_disk_shader_cache(screen); 117 118 trace_dump_ret(ptr, result); 119 120 trace_dump_call_end(); 121 122 return result; 123} 124 125 126static int 127trace_screen_get_param(struct pipe_screen *_screen, 128 enum pipe_cap param) 129{ 130 struct trace_screen *tr_scr = trace_screen(_screen); 131 struct pipe_screen *screen = tr_scr->screen; 132 int result; 133 134 trace_dump_call_begin("pipe_screen", "get_param"); 135 136 trace_dump_arg(ptr, screen); 137 trace_dump_arg(int, param); 138 139 result = screen->get_param(screen, param); 140 141 trace_dump_ret(int, result); 142 143 trace_dump_call_end(); 144 145 return result; 146} 147 148 149static int 150trace_screen_get_shader_param(struct pipe_screen *_screen, 151 enum pipe_shader_type shader, 152 enum pipe_shader_cap param) 153{ 154 struct trace_screen *tr_scr = trace_screen(_screen); 155 struct pipe_screen *screen = tr_scr->screen; 156 int result; 157 158 trace_dump_call_begin("pipe_screen", "get_shader_param"); 159 160 trace_dump_arg(ptr, screen); 161 trace_dump_arg(uint, shader); 162 trace_dump_arg(int, param); 163 164 result = screen->get_shader_param(screen, shader, param); 165 166 trace_dump_ret(int, result); 167 168 trace_dump_call_end(); 169 170 return result; 171} 172 173 174static float 175trace_screen_get_paramf(struct pipe_screen *_screen, 176 enum pipe_capf param) 177{ 178 struct trace_screen *tr_scr = trace_screen(_screen); 179 struct pipe_screen *screen = tr_scr->screen; 180 float result; 181 182 trace_dump_call_begin("pipe_screen", "get_paramf"); 183 184 trace_dump_arg(ptr, screen); 185 trace_dump_arg(int, param); 186 187 result = screen->get_paramf(screen, param); 188 189 trace_dump_ret(float, result); 190 191 trace_dump_call_end(); 192 193 return result; 194} 195 196 197static int 198trace_screen_get_compute_param(struct pipe_screen *_screen, 199 enum pipe_shader_ir ir_type, 200 enum pipe_compute_cap param, void *data) 201{ 202 struct trace_screen *tr_scr = trace_screen(_screen); 203 struct pipe_screen *screen = tr_scr->screen; 204 int result; 205 206 trace_dump_call_begin("pipe_screen", "get_compute_param"); 207 208 trace_dump_arg(ptr, screen); 209 trace_dump_arg(int, ir_type); 210 trace_dump_arg(int, param); 211 trace_dump_arg(ptr, data); 212 213 result = screen->get_compute_param(screen, ir_type, param, data); 214 215 trace_dump_ret(int, result); 216 217 trace_dump_call_end(); 218 219 return result; 220} 221 222 223static boolean 224trace_screen_is_format_supported(struct pipe_screen *_screen, 225 enum pipe_format format, 226 enum pipe_texture_target target, 227 unsigned sample_count, 228 unsigned storage_sample_count, 229 unsigned tex_usage) 230{ 231 struct trace_screen *tr_scr = trace_screen(_screen); 232 struct pipe_screen *screen = tr_scr->screen; 233 boolean result; 234 235 trace_dump_call_begin("pipe_screen", "is_format_supported"); 236 237 trace_dump_arg(ptr, screen); 238 trace_dump_arg(format, format); 239 trace_dump_arg(int, target); 240 trace_dump_arg(uint, sample_count); 241 trace_dump_arg(uint, tex_usage); 242 243 result = screen->is_format_supported(screen, format, target, sample_count, 244 storage_sample_count, tex_usage); 245 246 trace_dump_ret(bool, result); 247 248 trace_dump_call_end(); 249 250 return result; 251} 252 253 254static struct pipe_context * 255trace_screen_context_create(struct pipe_screen *_screen, void *priv, 256 unsigned flags) 257{ 258 struct trace_screen *tr_scr = trace_screen(_screen); 259 struct pipe_screen *screen = tr_scr->screen; 260 struct pipe_context *result; 261 262 trace_dump_call_begin("pipe_screen", "context_create"); 263 264 trace_dump_arg(ptr, screen); 265 trace_dump_arg(ptr, priv); 266 trace_dump_arg(uint, flags); 267 268 result = screen->context_create(screen, priv, flags); 269 270 trace_dump_ret(ptr, result); 271 272 trace_dump_call_end(); 273 274 result = trace_context_create(tr_scr, result); 275 276 return result; 277} 278 279 280static void 281trace_screen_flush_frontbuffer(struct pipe_screen *_screen, 282 struct pipe_resource *resource, 283 unsigned level, unsigned layer, 284 void *context_private, 285 struct pipe_box *sub_box) 286{ 287 struct trace_screen *tr_scr = trace_screen(_screen); 288 struct pipe_screen *screen = tr_scr->screen; 289 290 trace_dump_call_begin("pipe_screen", "flush_frontbuffer"); 291 292 trace_dump_arg(ptr, screen); 293 trace_dump_arg(ptr, resource); 294 trace_dump_arg(uint, level); 295 trace_dump_arg(uint, layer); 296 /* XXX: hide, as there is nothing we can do with this 297 trace_dump_arg(ptr, context_private); 298 */ 299 300 screen->flush_frontbuffer(screen, resource, level, layer, context_private, sub_box); 301 302 trace_dump_call_end(); 303} 304 305 306static void 307trace_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid) 308{ 309 struct pipe_screen *screen = trace_screen(_screen)->screen; 310 311 trace_dump_call_begin("pipe_screen", "get_driver_uuid"); 312 trace_dump_arg(ptr, screen); 313 314 screen->get_driver_uuid(screen, uuid); 315 316 trace_dump_ret(string, uuid); 317 trace_dump_call_end(); 318} 319 320static void 321trace_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid) 322{ 323 struct pipe_screen *screen = trace_screen(_screen)->screen; 324 325 trace_dump_call_begin("pipe_screen", "get_device_uuid"); 326 trace_dump_arg(ptr, screen); 327 328 screen->get_device_uuid(screen, uuid); 329 330 trace_dump_ret(string, uuid); 331 trace_dump_call_end(); 332} 333 334 335/******************************************************************** 336 * texture 337 */ 338 339 340static struct pipe_resource * 341trace_screen_resource_create(struct pipe_screen *_screen, 342 const struct pipe_resource *templat) 343{ 344 struct trace_screen *tr_scr = trace_screen(_screen); 345 struct pipe_screen *screen = tr_scr->screen; 346 struct pipe_resource *result; 347 348 trace_dump_call_begin("pipe_screen", "resource_create"); 349 350 trace_dump_arg(ptr, screen); 351 trace_dump_arg(resource_template, templat); 352 353 result = screen->resource_create(screen, templat); 354 355 trace_dump_ret(ptr, result); 356 357 trace_dump_call_end(); 358 359 if (result) 360 result->screen = _screen; 361 return result; 362} 363 364static struct pipe_resource * 365trace_screen_resource_from_handle(struct pipe_screen *_screen, 366 const struct pipe_resource *templ, 367 struct winsys_handle *handle, 368 unsigned usage) 369{ 370 struct trace_screen *tr_screen = trace_screen(_screen); 371 struct pipe_screen *screen = tr_screen->screen; 372 struct pipe_resource *result; 373 374 /* TODO trace call */ 375 376 result = screen->resource_from_handle(screen, templ, handle, usage); 377 378 if (result) 379 result->screen = _screen; 380 return result; 381} 382 383static bool 384trace_screen_check_resource_capability(struct pipe_screen *_screen, 385 struct pipe_resource *resource, 386 unsigned bind) 387{ 388 struct pipe_screen *screen = trace_screen(_screen)->screen; 389 390 return screen->check_resource_capability(screen, resource, bind); 391} 392 393static boolean 394trace_screen_resource_get_handle(struct pipe_screen *_screen, 395 struct pipe_context *_pipe, 396 struct pipe_resource *resource, 397 struct winsys_handle *handle, 398 unsigned usage) 399{ 400 struct trace_screen *tr_screen = trace_screen(_screen); 401 struct trace_context *tr_pipe = _pipe ? trace_context(_pipe) : NULL; 402 struct pipe_screen *screen = tr_screen->screen; 403 404 /* TODO trace call */ 405 406 return screen->resource_get_handle(screen, tr_pipe ? tr_pipe->pipe : NULL, 407 resource, handle, usage); 408} 409 410static void 411trace_screen_resource_get_info(struct pipe_screen *_screen, 412 struct pipe_resource *resource, 413 unsigned *stride, 414 unsigned *offset) 415{ 416 struct trace_screen *tr_screen = trace_screen(_screen); 417 struct pipe_screen *screen = tr_screen->screen; 418 419 /* TODO trace call */ 420 421 screen->resource_get_info(screen, resource, stride, offset); 422} 423 424static struct pipe_resource * 425trace_screen_resource_from_memobj(struct pipe_screen *_screen, 426 const struct pipe_resource *templ, 427 struct pipe_memory_object *memobj, 428 uint64_t offset) 429{ 430 struct pipe_screen *screen = trace_screen(_screen)->screen; 431 432 trace_dump_call_begin("pipe_screen", "resource_from_memobj"); 433 trace_dump_arg(ptr, screen); 434 trace_dump_arg(resource_template, templ); 435 trace_dump_arg(ptr, memobj); 436 trace_dump_arg(uint, offset); 437 438 struct pipe_resource *res = 439 screen->resource_from_memobj(screen, templ, memobj, offset); 440 441 if (!res) 442 return NULL; 443 res->screen = _screen; 444 445 trace_dump_ret(ptr, res); 446 trace_dump_call_end(); 447 return res; 448} 449 450static void 451trace_screen_resource_changed(struct pipe_screen *_screen, 452 struct pipe_resource *resource) 453{ 454 struct trace_screen *tr_scr = trace_screen(_screen); 455 struct pipe_screen *screen = tr_scr->screen; 456 457 trace_dump_call_begin("pipe_screen", "resource_changed"); 458 459 trace_dump_arg(ptr, screen); 460 trace_dump_arg(ptr, resource); 461 462 if (screen->resource_changed) 463 screen->resource_changed(screen, resource); 464 465 trace_dump_call_end(); 466} 467 468static void 469trace_screen_resource_destroy(struct pipe_screen *_screen, 470 struct pipe_resource *resource) 471{ 472 struct trace_screen *tr_scr = trace_screen(_screen); 473 struct pipe_screen *screen = tr_scr->screen; 474 475 /* Don't trace this, because due to the lack of pipe_resource wrapping, 476 * we can get this call from inside of driver calls, which would try 477 * to lock an already-locked mutex. 478 */ 479 screen->resource_destroy(screen, resource); 480} 481 482 483/******************************************************************** 484 * fence 485 */ 486 487 488static void 489trace_screen_fence_reference(struct pipe_screen *_screen, 490 struct pipe_fence_handle **pdst, 491 struct pipe_fence_handle *src) 492{ 493 struct trace_screen *tr_scr = trace_screen(_screen); 494 struct pipe_screen *screen = tr_scr->screen; 495 struct pipe_fence_handle *dst; 496 497 assert(pdst); 498 dst = *pdst; 499 500 trace_dump_call_begin("pipe_screen", "fence_reference"); 501 502 trace_dump_arg(ptr, screen); 503 trace_dump_arg(ptr, dst); 504 trace_dump_arg(ptr, src); 505 506 screen->fence_reference(screen, pdst, src); 507 508 trace_dump_call_end(); 509} 510 511 512static int 513trace_screen_fence_get_fd(struct pipe_screen *_screen, 514 struct pipe_fence_handle *fence) 515{ 516 struct trace_screen *tr_scr = trace_screen(_screen); 517 struct pipe_screen *screen = tr_scr->screen; 518 int result; 519 520 trace_dump_call_begin("pipe_screen", "fence_get_fd"); 521 522 trace_dump_arg(ptr, screen); 523 trace_dump_arg(ptr, fence); 524 525 result = screen->fence_get_fd(screen, fence); 526 527 trace_dump_ret(int, result); 528 529 trace_dump_call_end(); 530 531 return result; 532} 533 534 535static boolean 536trace_screen_fence_finish(struct pipe_screen *_screen, 537 struct pipe_context *_ctx, 538 struct pipe_fence_handle *fence, 539 uint64_t timeout) 540{ 541 struct trace_screen *tr_scr = trace_screen(_screen); 542 struct pipe_screen *screen = tr_scr->screen; 543 struct pipe_context *ctx = _ctx ? trace_context(_ctx)->pipe : NULL; 544 int result; 545 546 trace_dump_call_begin("pipe_screen", "fence_finish"); 547 548 trace_dump_arg(ptr, screen); 549 trace_dump_arg(ptr, ctx); 550 trace_dump_arg(ptr, fence); 551 trace_dump_arg(uint, timeout); 552 553 result = screen->fence_finish(screen, ctx, fence, timeout); 554 555 trace_dump_ret(bool, result); 556 557 trace_dump_call_end(); 558 559 return result; 560} 561 562 563/******************************************************************** 564 * memobj 565 */ 566 567static struct pipe_memory_object * 568trace_screen_memobj_create_from_handle(struct pipe_screen *_screen, 569 struct winsys_handle *handle, 570 bool dedicated) 571{ 572 struct pipe_screen *screen = trace_screen(_screen)->screen; 573 574 trace_dump_call_begin("pipe_screen", "memobj_create_from_handle"); 575 trace_dump_arg(ptr, screen); 576 trace_dump_arg(ptr, handle); 577 trace_dump_arg(bool, dedicated); 578 579 struct pipe_memory_object *res = 580 screen->memobj_create_from_handle(screen, handle, dedicated); 581 582 trace_dump_ret(ptr, res); 583 trace_dump_call_end(); 584 585 return res; 586} 587 588static void 589trace_screen_memobj_destroy(struct pipe_screen *_screen, 590 struct pipe_memory_object *memobj) 591{ 592 struct pipe_screen *screen = trace_screen(_screen)->screen; 593 594 trace_dump_call_begin("pipe_screen", "memobj_destroy"); 595 trace_dump_arg(ptr, screen); 596 trace_dump_arg(ptr, memobj); 597 trace_dump_call_end(); 598 599 screen->memobj_destroy(screen, memobj); 600} 601 602 603/******************************************************************** 604 * screen 605 */ 606 607static uint64_t 608trace_screen_get_timestamp(struct pipe_screen *_screen) 609{ 610 struct trace_screen *tr_scr = trace_screen(_screen); 611 struct pipe_screen *screen = tr_scr->screen; 612 uint64_t result; 613 614 trace_dump_call_begin("pipe_screen", "get_timestamp"); 615 trace_dump_arg(ptr, screen); 616 617 result = screen->get_timestamp(screen); 618 619 trace_dump_ret(uint, result); 620 trace_dump_call_end(); 621 622 return result; 623} 624 625static void 626trace_screen_destroy(struct pipe_screen *_screen) 627{ 628 struct trace_screen *tr_scr = trace_screen(_screen); 629 struct pipe_screen *screen = tr_scr->screen; 630 631 trace_dump_call_begin("pipe_screen", "destroy"); 632 trace_dump_arg(ptr, screen); 633 trace_dump_call_end(); 634 635 screen->destroy(screen); 636 637 FREE(tr_scr); 638} 639 640boolean 641trace_enabled(void) 642{ 643 static boolean firstrun = TRUE; 644 645 if (!firstrun) 646 return trace; 647 firstrun = FALSE; 648 649 if(trace_dump_trace_begin()) { 650 trace_dumping_start(); 651 trace = TRUE; 652 } 653 654 return trace; 655} 656 657struct pipe_screen * 658trace_screen_create(struct pipe_screen *screen) 659{ 660 struct trace_screen *tr_scr; 661 662 if (!trace_enabled()) 663 goto error1; 664 665 trace_dump_call_begin("", "pipe_screen_create"); 666 667 tr_scr = CALLOC_STRUCT(trace_screen); 668 if (!tr_scr) 669 goto error2; 670 671#define SCR_INIT(_member) \ 672 tr_scr->base._member = screen->_member ? trace_screen_##_member : NULL 673 674 tr_scr->base.destroy = trace_screen_destroy; 675 tr_scr->base.get_name = trace_screen_get_name; 676 tr_scr->base.get_vendor = trace_screen_get_vendor; 677 tr_scr->base.get_device_vendor = trace_screen_get_device_vendor; 678 SCR_INIT(get_disk_shader_cache); 679 tr_scr->base.get_param = trace_screen_get_param; 680 tr_scr->base.get_shader_param = trace_screen_get_shader_param; 681 tr_scr->base.get_paramf = trace_screen_get_paramf; 682 tr_scr->base.get_compute_param = trace_screen_get_compute_param; 683 tr_scr->base.is_format_supported = trace_screen_is_format_supported; 684 assert(screen->context_create); 685 tr_scr->base.context_create = trace_screen_context_create; 686 tr_scr->base.resource_create = trace_screen_resource_create; 687 tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; 688 SCR_INIT(check_resource_capability); 689 tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; 690 SCR_INIT(resource_get_info); 691 SCR_INIT(resource_from_memobj); 692 SCR_INIT(resource_changed); 693 tr_scr->base.resource_destroy = trace_screen_resource_destroy; 694 tr_scr->base.fence_reference = trace_screen_fence_reference; 695 SCR_INIT(fence_get_fd); 696 tr_scr->base.fence_finish = trace_screen_fence_finish; 697 SCR_INIT(memobj_create_from_handle); 698 SCR_INIT(memobj_destroy); 699 tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; 700 tr_scr->base.get_timestamp = trace_screen_get_timestamp; 701 SCR_INIT(get_driver_uuid); 702 SCR_INIT(get_device_uuid); 703 704 tr_scr->screen = screen; 705 706 trace_dump_ret(ptr, screen); 707 trace_dump_call_end(); 708 709 return &tr_scr->base; 710 711error2: 712 trace_dump_ret(ptr, screen); 713 trace_dump_call_end(); 714error1: 715 return screen; 716} 717 718 719struct trace_screen * 720trace_screen(struct pipe_screen *screen) 721{ 722 assert(screen); 723 assert(screen->destroy == trace_screen_destroy); 724 return (struct trace_screen *)screen; 725} 726