1/*
2 * Copyright © 2021 Intel Corporation
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#ifndef INTEL_DRIVER_DS_H
25#define INTEL_DRIVER_DS_H
26
27#include <stdint.h>
28
29#include "util/macros.h"
30#include "util/perf/u_trace.h"
31#include "util/u_vector.h"
32
33#include "dev/intel_device_info.h"
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39enum intel_ds_api {
40   INTEL_DS_API_OPENGL,
41   INTEL_DS_API_VULKAN,
42};
43
44enum intel_ds_stall_flag {
45   INTEL_DS_DEPTH_CACHE_FLUSH_BIT         = BITFIELD_BIT(0),
46   INTEL_DS_DATA_CACHE_FLUSH_BIT          = BITFIELD_BIT(1),
47   INTEL_DS_HDC_PIPELINE_FLUSH_BIT        = BITFIELD_BIT(2),
48   INTEL_DS_RENDER_TARGET_CACHE_FLUSH_BIT = BITFIELD_BIT(3),
49   INTEL_DS_TILE_CACHE_FLUSH_BIT          = BITFIELD_BIT(4),
50   INTEL_DS_STATE_CACHE_INVALIDATE_BIT    = BITFIELD_BIT(5),
51   INTEL_DS_CONST_CACHE_INVALIDATE_BIT    = BITFIELD_BIT(6),
52   INTEL_DS_VF_CACHE_INVALIDATE_BIT       = BITFIELD_BIT(7),
53   INTEL_DS_TEXTURE_CACHE_INVALIDATE_BIT  = BITFIELD_BIT(8),
54   INTEL_DS_INST_CACHE_INVALIDATE_BIT     = BITFIELD_BIT(9),
55   INTEL_DS_STALL_AT_SCOREBOARD_BIT       = BITFIELD_BIT(10),
56   INTEL_DS_DEPTH_STALL_BIT               = BITFIELD_BIT(11),
57   INTEL_DS_CS_STALL_BIT                  = BITFIELD_BIT(12),
58};
59
60/* Convert internal driver PIPE_CONTROL stall bits to intel_ds_stall_flag. */
61typedef enum intel_ds_stall_flag (*intel_ds_stall_cb_t)(uint32_t flags);
62
63enum intel_ds_queue_stage {
64   INTEL_DS_QUEUE_STAGE_CMD_BUFFER,
65   INTEL_DS_QUEUE_STAGE_STALL,
66   INTEL_DS_QUEUE_STAGE_COMPUTE,
67   INTEL_DS_QUEUE_STAGE_RENDER_PASS,
68   INTEL_DS_QUEUE_STAGE_BLORP,
69   INTEL_DS_QUEUE_STAGE_DRAW,
70   INTEL_DS_QUEUE_STAGE_N_STAGES,
71};
72
73struct intel_ds_device {
74   struct intel_device_info info;
75
76   /* DRM fd */
77   int fd;
78
79   /* API of this device */
80   enum intel_ds_api api;
81
82   /* GPU identifier (minor number) */
83   uint32_t gpu_id;
84
85   /* Clock identifier for this device. */
86   uint32_t gpu_clock_id;
87
88   /* The timestamp at the point where we first emitted the clock_sync..
89    * this  will be a *later* timestamp that the first GPU traces (since
90    * we capture the first clock_sync from the CPU *after* the first GPU
91    * tracepoints happen).  To avoid confusing perfetto we need to drop
92    * the GPU traces with timestamps before this.
93    */
94   uint64_t sync_gpu_ts;
95
96   /* Next timestamp after which we should resend a clock correlation. */
97   uint64_t next_clock_sync_ns;
98
99   /* Unique perfetto identifier for the context */
100   uint64_t iid;
101
102   /* Event ID generator */
103   uint64_t event_id;
104
105   struct u_trace_context trace_context;
106
107   /* List of intel_ds_queue */
108   struct u_vector queues;
109};
110
111struct intel_ds_stage {
112   /* Unique hw_queue IID */
113   uint64_t queue_iid;
114
115   /* Unique stage IID */
116   uint64_t stage_iid;
117
118   /* Start timestamp of the last work element */
119   uint64_t start_ns;
120};
121
122struct intel_ds_queue {
123   /* Device this queue belongs to */
124   struct intel_ds_device *device;
125
126   /* Unique queue ID across the device */
127   uint32_t queue_id;
128
129   /* Unique name of the queue */
130   char name[80];
131
132   /* Counter incremented on each intel_ds_end_submit() call */
133   uint64_t submission_id;
134
135   struct intel_ds_stage stages[INTEL_DS_QUEUE_STAGE_N_STAGES];
136};
137
138struct intel_ds_flush_data {
139   struct intel_ds_queue *queue;
140
141   /* u_trace element in which we copy other traces in case we deal with
142    * reusable command buffers.
143    */
144   struct u_trace trace;
145
146   /* Unique submission ID associated with the trace */
147   uint64_t submission_id;
148};
149
150void intel_driver_ds_init(void);
151
152void intel_ds_device_init(struct intel_ds_device *device,
153                          struct intel_device_info *devinfo,
154                          int drm_fd,
155                          uint32_t gpu_id,
156                          enum intel_ds_api api);
157void intel_ds_device_fini(struct intel_ds_device *device);
158
159struct intel_ds_queue *intel_ds_device_add_queue(struct intel_ds_device *device,
160                                                 const char *fmt_name,
161                                                 ...);
162
163void intel_ds_flush_data_init(struct intel_ds_flush_data *data,
164                              struct intel_ds_queue *queue,
165                              uint64_t submission_id);
166
167void intel_ds_flush_data_fini(struct intel_ds_flush_data *data);
168
169#ifdef HAVE_PERFETTO
170
171uint64_t intel_ds_begin_submit(struct intel_ds_queue *queue);
172void intel_ds_end_submit(struct intel_ds_queue *queue,
173                         uint64_t start_ts);
174
175#else
176
177static inline uint64_t intel_ds_begin_submit(struct intel_ds_queue *queue)
178{
179   return 0;
180}
181
182static inline void intel_ds_end_submit(struct intel_ds_queue *queue,
183                                       uint64_t start_ts)
184{
185}
186
187#endif /* HAVE_PERFETTO */
188
189#ifdef __cplusplus
190}
191#endif
192
193#endif /* INTEL_DRIVER_DS_H */
194