st/mesa: Add rgbx handling for fp formats
[mesa.git] / src / gallium / drivers / panfrost / pan_trace.c
1 /*
2 * Copyright (C) 2019 Alyssa Rosenzweig
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdbool.h>
28 #include <panfrost-job.h>
29 #include "pan_trace.h"
30 #include "util/list.h"
31
32 /* The pandecode utility is capable of parsing a command stream trace and
33 * disassembling any referenced shaders. Traces themselves are glorified memory
34 * dumps, a directory consisting of .bin's for each memory segment, and a
35 * simple plain-text description of the interesting kernel activity.
36 * Historically, these dumps have been produced via panwrap, an LD_PRELOAD shim
37 * sitting between the driver and the kernel. However, for modern Panfrost, we
38 * can just produce the dumps ourselves, which is rather less fragile. This
39 * file (pantrace) implements this functionality. */
40
41 static FILE *pan_control_log;
42 static const char *pan_control_base;
43
44 /* Represent the abstraction for a single mmap chunk */
45
46 static unsigned pantrace_memory_count = 0;
47
48 struct pantrace_memory {
49 struct list_head node;
50
51 mali_ptr gpu;
52 void *cpu;
53 size_t sz;
54 char *full_filename;
55 };
56
57 static struct pantrace_memory mmaps;
58
59 void
60 pantrace_initialize(const char *base)
61 {
62 /* Open the control.log */
63 char fn[128];
64 snprintf(fn, 128, "%s/control.log", base);
65 pan_control_log = fopen(fn, "w+");
66 assert(pan_control_log);
67
68 /* Save the base for later */
69 pan_control_base = base;
70
71 /* Initialize the mmap list */
72 list_inithead(&mmaps.node);
73 }
74
75 static bool
76 pantrace_is_initialized(void)
77 {
78 return pan_control_log && pan_control_base;
79 }
80
81 /* Traces a submitted job with a given job chain, core requirements, and
82 * platform */
83
84 void
85 pantrace_submit_job(mali_ptr jc, unsigned core_req, unsigned is_bifrost)
86 {
87 if (!pantrace_is_initialized())
88 return;
89
90 fprintf(pan_control_log, "JS %" PRIx64 " %x %x\n",
91 jc, core_req, is_bifrost);
92 fflush(pan_control_log);
93 }
94
95 /* Dumps a given mapped memory buffer with the given label. If no label
96 * is given (label == NULL), one is created */
97
98 void
99 pantrace_mmap(mali_ptr gpu, void *cpu, size_t sz, char *label)
100 {
101 if (!pantrace_is_initialized())
102 return;
103
104 char *filename = NULL;
105 char *full_filename = NULL;
106
107 /* Create a filename based on the label or count */
108
109 if (label) {
110 asprintf(&filename, "%s.bin", label);
111 } else {
112 asprintf(&filename, "memory_%d.bin", pantrace_memory_count++);
113 }
114
115 /* Emit an mmap for it */
116 fprintf(pan_control_log, "MMAP %" PRIx64 " %s\n", gpu, filename);
117 fflush(pan_control_log);
118
119 /* Dump the memory itself */
120 asprintf(&full_filename, "%s/%s", pan_control_base, filename);
121 free(filename);
122
123 struct pantrace_memory *mem = malloc(sizeof(*mem));
124 list_inithead(&mem->node);
125 mem->gpu = gpu;
126 mem->cpu = cpu;
127 mem->sz = sz;
128 mem->full_filename = full_filename;
129 list_add(&mem->node, &mmaps.node);
130 }
131
132 /* Dump all memory at once, once everything has been written */
133
134 void
135 pantrace_dump_memory(void)
136 {
137 if (!pantrace_is_initialized())
138 return;
139
140 list_for_each_entry(struct pantrace_memory, pos, &mmaps.node, node) {
141 /* Save the mapping */
142 FILE *fp = fopen(pos->full_filename, "wb");
143 fwrite(pos->cpu, 1, pos->sz, fp);
144 fclose(fp);
145 }
146 }