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