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
42 static bool trace = false;
43 static struct hash_table *trace_screens;
44
45 static const char *
trace_screen_get_name(struct pipe_screen * _screen)46 trace_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
66 static const char *
trace_screen_get_vendor(struct pipe_screen * _screen)67 trace_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
87 static const char *
trace_screen_get_device_vendor(struct pipe_screen * _screen)88 trace_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
108 static const void *
trace_screen_get_compiler_options(struct pipe_screen * _screen,enum pipe_shader_ir ir,enum pipe_shader_type shader)109 trace_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
120 static struct disk_cache *
trace_screen_get_disk_shader_cache(struct pipe_screen * _screen)121 trace_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
140 static int
trace_screen_get_param(struct pipe_screen * _screen,enum pipe_cap param)141 trace_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
163 static int
trace_screen_get_shader_param(struct pipe_screen * _screen,enum pipe_shader_type shader,enum pipe_shader_cap param)164 trace_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
188 static float
trace_screen_get_paramf(struct pipe_screen * _screen,enum pipe_capf param)189 trace_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
211 static int
trace_screen_get_compute_param(struct pipe_screen * _screen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * data)212 trace_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
237 static bool
trace_screen_is_format_supported(struct pipe_screen * _screen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned tex_usage)238 trace_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
267 static void
trace_context_replace_buffer_storage(struct pipe_context * _pipe,struct pipe_resource * dst,struct pipe_resource * src,unsigned num_rebinds,uint32_t rebind_mask,unsigned delete_buffer_id)268 trace_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
291 static struct pipe_fence_handle *
trace_context_create_fence(struct pipe_context * _pipe,struct tc_unflushed_batch_token * token)292 trace_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
309 static bool
trace_context_is_resource_busy(struct pipe_screen * _screen,struct pipe_resource * resource,unsigned usage)310 trace_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
333 struct pipe_context *
trace_context_create_threaded(struct pipe_screen * screen,struct pipe_context * pipe,tc_replace_buffer_storage_func * replace_buffer,struct threaded_context_options * options)334 trace_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
366 static struct pipe_context *
trace_screen_context_create(struct pipe_screen * _screen,void * priv,unsigned flags)367 trace_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
393 static void
trace_screen_flush_frontbuffer(struct pipe_screen * _screen,struct pipe_context * _pipe,struct pipe_resource * resource,unsigned level,unsigned layer,void * context_private,struct pipe_box * sub_box)394 trace_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
421 static void
trace_screen_get_driver_uuid(struct pipe_screen * _screen,char * uuid)422 trace_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
435 static void
trace_screen_get_device_uuid(struct pipe_screen * _screen,char * uuid)436 trace_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
454 static void *
trace_screen_map_memory(struct pipe_screen * _screen,struct pipe_memory_allocation * pmem)455 trace_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
476 static void
trace_screen_unmap_memory(struct pipe_screen * _screen,struct pipe_memory_allocation * pmem)477 trace_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
494 static struct pipe_memory_allocation *
trace_screen_allocate_memory(struct pipe_screen * _screen,uint64_t size)495 trace_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
516 static void
trace_screen_free_memory(struct pipe_screen * _screen,struct pipe_memory_allocation * pmem)517 trace_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
534 static bool
trace_screen_resource_bind_backing(struct pipe_screen * _screen,struct pipe_resource * resource,struct pipe_memory_allocation * pmem,uint64_t offset)535 trace_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
560 static struct pipe_resource *
trace_screen_resource_create_unbacked(struct pipe_screen * _screen,const struct pipe_resource * templat,uint64_t * size_required)561 trace_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
588 static struct pipe_resource *
trace_screen_resource_create(struct pipe_screen * _screen,const struct pipe_resource * templat)589 trace_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
612 static struct pipe_resource *
trace_screen_resource_create_with_modifiers(struct pipe_screen * _screen,const struct pipe_resource * templat,const uint64_t * modifiers,int modifiers_count)613 trace_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
637 static struct pipe_resource *
trace_screen_resource_from_handle(struct pipe_screen * _screen,const struct pipe_resource * templ,struct winsys_handle * handle,unsigned usage)638 trace_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
656 static bool
trace_screen_check_resource_capability(struct pipe_screen * _screen,struct pipe_resource * resource,unsigned bind)657 trace_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
666 static bool
trace_screen_resource_get_handle(struct pipe_screen * _screen,struct pipe_context * _pipe,struct pipe_resource * resource,struct winsys_handle * handle,unsigned usage)667 trace_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
683 static bool
trace_screen_resource_get_param(struct pipe_screen * _screen,struct pipe_context * _pipe,struct pipe_resource * resource,unsigned plane,unsigned layer,unsigned level,enum pipe_resource_param param,unsigned handle_usage,uint64_t * value)684 trace_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
705 static void
trace_screen_resource_get_info(struct pipe_screen * _screen,struct pipe_resource * resource,unsigned * stride,unsigned * offset)706 trace_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
719 static struct pipe_resource *
trace_screen_resource_from_memobj(struct pipe_screen * _screen,const struct pipe_resource * templ,struct pipe_memory_object * memobj,uint64_t offset)720 trace_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
745 static void
trace_screen_resource_changed(struct pipe_screen * _screen,struct pipe_resource * resource)746 trace_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
763 static void
trace_screen_resource_destroy(struct pipe_screen * _screen,struct pipe_resource * resource)764 trace_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
783 static void
trace_screen_fence_reference(struct pipe_screen * _screen,struct pipe_fence_handle ** pdst,struct pipe_fence_handle * src)784 trace_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
807 static int
trace_screen_fence_get_fd(struct pipe_screen * _screen,struct pipe_fence_handle * fence)808 trace_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
830 static bool
trace_screen_fence_finish(struct pipe_screen * _screen,struct pipe_context * _ctx,struct pipe_fence_handle * fence,uint64_t timeout)831 trace_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
863 static struct pipe_memory_object *
trace_screen_memobj_create_from_handle(struct pipe_screen * _screen,struct winsys_handle * handle,bool dedicated)864 trace_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
884 static void
trace_screen_memobj_destroy(struct pipe_screen * _screen,struct pipe_memory_object * memobj)885 trace_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
903 static uint64_t
trace_screen_get_timestamp(struct pipe_screen * _screen)904 trace_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
921 static char *
trace_screen_finalize_nir(struct pipe_screen * _screen,void * nir)922 trace_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
929 static void
trace_screen_destroy(struct pipe_screen * _screen)930 trace_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
955 static void
trace_screen_query_memory_info(struct pipe_screen * _screen,struct pipe_memory_info * info)956 trace_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
972 static void
trace_screen_query_dmabuf_modifiers(struct pipe_screen * _screen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)973 trace_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
998 static bool
trace_screen_is_dmabuf_modifier_supported(struct pipe_screen * _screen,uint64_t modifier,enum pipe_format format,bool * external_only)999 trace_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
1022 static unsigned int
trace_screen_get_dmabuf_modifier_planes(struct pipe_screen * _screen,uint64_t modifier,enum pipe_format format)1023 trace_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
1042 static struct pipe_vertex_state *
trace_screen_create_vertex_state(struct pipe_screen * _screen,struct pipe_vertex_buffer * buffer,const struct pipe_vertex_element * elements,unsigned num_elements,struct pipe_resource * indexbuf,uint32_t full_velem_mask)1043 trace_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
trace_screen_vertex_state_destroy(struct pipe_screen * _screen,struct pipe_vertex_state * state)1073 static 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
1087 bool
trace_enabled(void)1088 trace_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
1104 struct pipe_screen *
trace_screen_create(struct pipe_screen * screen)1105 trace_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
1198 error2:
1199 trace_dump_ret(ptr, screen);
1200 trace_dump_call_end();
1201 error1:
1202 return screen;
1203 }
1204
1205
1206 struct trace_screen *
trace_screen(struct pipe_screen * screen)1207 trace_screen(struct pipe_screen *screen)
1208 {
1209 assert(screen);
1210 assert(screen->destroy == trace_screen_destroy);
1211 return (struct trace_screen *)screen;
1212 }
1213