• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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