1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2020 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * on the rights to use, copy, modify, merge, publish, distribute, sub
8*61046927SAndroid Build Coastguard Worker * license, and/or sell copies of the Software, and to permit persons to whom
9*61046927SAndroid Build Coastguard Worker * the Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19*61046927SAndroid Build Coastguard Worker * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20*61046927SAndroid Build Coastguard Worker * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21*61046927SAndroid Build Coastguard Worker * USE OR OTHER DEALINGS IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "anv_measure.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
27*61046927SAndroid Build Coastguard Worker #include <sys/stat.h>
28*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker #include "common/intel_measure.h"
31*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker struct anv_measure_batch {
34*61046927SAndroid Build Coastguard Worker struct anv_bo *bo;
35*61046927SAndroid Build Coastguard Worker struct intel_measure_batch base;
36*61046927SAndroid Build Coastguard Worker };
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker void
anv_measure_device_init(struct anv_physical_device * device)39*61046927SAndroid Build Coastguard Worker anv_measure_device_init(struct anv_physical_device *device)
40*61046927SAndroid Build Coastguard Worker {
41*61046927SAndroid Build Coastguard Worker /* initialise list of measure structures that await rendering */
42*61046927SAndroid Build Coastguard Worker struct intel_measure_device *measure_device = &device->measure_device;
43*61046927SAndroid Build Coastguard Worker intel_measure_init(measure_device);
44*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = measure_device->config;
45*61046927SAndroid Build Coastguard Worker if (config == NULL)
46*61046927SAndroid Build Coastguard Worker return;
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker /* the final member of intel_measure_ringbuffer is a zero-length array of
49*61046927SAndroid Build Coastguard Worker * intel_measure_buffered_result objects. Allocate additional space for
50*61046927SAndroid Build Coastguard Worker * the buffered objects based on the run-time configurable buffer_size
51*61046927SAndroid Build Coastguard Worker */
52*61046927SAndroid Build Coastguard Worker const size_t rb_bytes = sizeof(struct intel_measure_ringbuffer) +
53*61046927SAndroid Build Coastguard Worker config->buffer_size * sizeof(struct intel_measure_buffered_result);
54*61046927SAndroid Build Coastguard Worker struct intel_measure_ringbuffer * rb =
55*61046927SAndroid Build Coastguard Worker vk_zalloc(&device->instance->vk.alloc,
56*61046927SAndroid Build Coastguard Worker rb_bytes, 8,
57*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
58*61046927SAndroid Build Coastguard Worker measure_device->ringbuffer = rb;
59*61046927SAndroid Build Coastguard Worker }
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker static struct intel_measure_config*
config_from_command_buffer(struct anv_cmd_buffer * cmd_buffer)62*61046927SAndroid Build Coastguard Worker config_from_command_buffer(struct anv_cmd_buffer *cmd_buffer)
63*61046927SAndroid Build Coastguard Worker {
64*61046927SAndroid Build Coastguard Worker return cmd_buffer->device->physical->measure_device.config;
65*61046927SAndroid Build Coastguard Worker }
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker void
anv_measure_init(struct anv_cmd_buffer * cmd_buffer)68*61046927SAndroid Build Coastguard Worker anv_measure_init(struct anv_cmd_buffer *cmd_buffer)
69*61046927SAndroid Build Coastguard Worker {
70*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
71*61046927SAndroid Build Coastguard Worker struct anv_device *device = cmd_buffer->device;
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker if (!config || !config->enabled) {
74*61046927SAndroid Build Coastguard Worker cmd_buffer->measure = NULL;
75*61046927SAndroid Build Coastguard Worker return;
76*61046927SAndroid Build Coastguard Worker }
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker /* the final member of anv_measure is a zero-length array of
79*61046927SAndroid Build Coastguard Worker * intel_measure_snapshot objects. Create additional space for the
80*61046927SAndroid Build Coastguard Worker * snapshot objects based on the run-time configurable batch_size
81*61046927SAndroid Build Coastguard Worker */
82*61046927SAndroid Build Coastguard Worker const size_t batch_bytes = sizeof(struct anv_measure_batch) +
83*61046927SAndroid Build Coastguard Worker config->batch_size * sizeof(struct intel_measure_snapshot);
84*61046927SAndroid Build Coastguard Worker struct anv_measure_batch * measure =
85*61046927SAndroid Build Coastguard Worker vk_alloc(&cmd_buffer->vk.pool->alloc,
86*61046927SAndroid Build Coastguard Worker batch_bytes, 8,
87*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker memset(measure, 0, batch_bytes);
90*61046927SAndroid Build Coastguard Worker cmd_buffer->measure = measure;
91*61046927SAndroid Build Coastguard Worker if(config->cpu_measure)
92*61046927SAndroid Build Coastguard Worker return;
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker ASSERTED VkResult result =
95*61046927SAndroid Build Coastguard Worker anv_device_alloc_bo(device, "measure data",
96*61046927SAndroid Build Coastguard Worker config->batch_size * sizeof(uint64_t),
97*61046927SAndroid Build Coastguard Worker ANV_BO_ALLOC_MAPPED |
98*61046927SAndroid Build Coastguard Worker ANV_BO_ALLOC_HOST_CACHED_COHERENT |
99*61046927SAndroid Build Coastguard Worker ANV_BO_ALLOC_INTERNAL,
100*61046927SAndroid Build Coastguard Worker 0,
101*61046927SAndroid Build Coastguard Worker (struct anv_bo**)&measure->bo);
102*61046927SAndroid Build Coastguard Worker measure->base.timestamps = measure->bo->map;
103*61046927SAndroid Build Coastguard Worker assert(result == VK_SUCCESS);
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker static void
anv_measure_start_snapshot(struct anv_cmd_buffer * cmd_buffer,enum intel_measure_snapshot_type type,const char * event_name,uint32_t count)107*61046927SAndroid Build Coastguard Worker anv_measure_start_snapshot(struct anv_cmd_buffer *cmd_buffer,
108*61046927SAndroid Build Coastguard Worker enum intel_measure_snapshot_type type,
109*61046927SAndroid Build Coastguard Worker const char *event_name,
110*61046927SAndroid Build Coastguard Worker uint32_t count)
111*61046927SAndroid Build Coastguard Worker {
112*61046927SAndroid Build Coastguard Worker struct anv_batch *batch = &cmd_buffer->batch;
113*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
114*61046927SAndroid Build Coastguard Worker struct anv_physical_device *device = cmd_buffer->device->physical;
115*61046927SAndroid Build Coastguard Worker struct intel_measure_device *measure_device = &device->measure_device;
116*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
117*61046927SAndroid Build Coastguard Worker enum anv_timestamp_capture_type capture_type;
118*61046927SAndroid Build Coastguard Worker unsigned index = measure->base.index++;
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker if (event_name == NULL)
121*61046927SAndroid Build Coastguard Worker event_name = intel_measure_snapshot_string(type);
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker if (config->cpu_measure) {
124*61046927SAndroid Build Coastguard Worker intel_measure_print_cpu_result(measure_device->frame,
125*61046927SAndroid Build Coastguard Worker measure->base.batch_count,
126*61046927SAndroid Build Coastguard Worker measure->base.batch_size,
127*61046927SAndroid Build Coastguard Worker index/2,
128*61046927SAndroid Build Coastguard Worker measure->base.event_count,
129*61046927SAndroid Build Coastguard Worker count,
130*61046927SAndroid Build Coastguard Worker event_name);
131*61046927SAndroid Build Coastguard Worker return;
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker if ((batch->engine_class == INTEL_ENGINE_CLASS_COPY) ||
136*61046927SAndroid Build Coastguard Worker (batch->engine_class == INTEL_ENGINE_CLASS_VIDEO))
137*61046927SAndroid Build Coastguard Worker capture_type = ANV_TIMESTAMP_CAPTURE_TOP_OF_PIPE;
138*61046927SAndroid Build Coastguard Worker else
139*61046927SAndroid Build Coastguard Worker capture_type = ANV_TIMESTAMP_CAPTURE_AT_CS_STALL;
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker (*device->cmd_emit_timestamp)(batch, cmd_buffer->device,
142*61046927SAndroid Build Coastguard Worker (struct anv_address) {
143*61046927SAndroid Build Coastguard Worker .bo = measure->bo,
144*61046927SAndroid Build Coastguard Worker .offset = index * sizeof(uint64_t) },
145*61046927SAndroid Build Coastguard Worker capture_type,
146*61046927SAndroid Build Coastguard Worker NULL);
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker struct intel_measure_snapshot *snapshot = &(measure->base.snapshots[index]);
149*61046927SAndroid Build Coastguard Worker memset(snapshot, 0, sizeof(*snapshot));
150*61046927SAndroid Build Coastguard Worker snapshot->type = type;
151*61046927SAndroid Build Coastguard Worker snapshot->count = (unsigned) count;
152*61046927SAndroid Build Coastguard Worker snapshot->event_count = measure->base.event_count;
153*61046927SAndroid Build Coastguard Worker snapshot->event_name = event_name;
154*61046927SAndroid Build Coastguard Worker snapshot->renderpass = (type == INTEL_SNAPSHOT_COMPUTE) ? 0
155*61046927SAndroid Build Coastguard Worker : measure->base.renderpass;
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker if (type == INTEL_SNAPSHOT_COMPUTE && cmd_buffer->state.compute.base.pipeline) {
158*61046927SAndroid Build Coastguard Worker const struct anv_compute_pipeline *pipeline =
159*61046927SAndroid Build Coastguard Worker anv_pipeline_to_compute(cmd_buffer->state.compute.base.pipeline);
160*61046927SAndroid Build Coastguard Worker snapshot->cs = pipeline->source_hash;
161*61046927SAndroid Build Coastguard Worker } else if (type == INTEL_SNAPSHOT_DRAW && cmd_buffer->state.gfx.base.pipeline) {
162*61046927SAndroid Build Coastguard Worker const struct anv_graphics_pipeline *pipeline =
163*61046927SAndroid Build Coastguard Worker anv_pipeline_to_graphics(cmd_buffer->state.gfx.base.pipeline);
164*61046927SAndroid Build Coastguard Worker snapshot->vs = pipeline->base.source_hashes[MESA_SHADER_VERTEX];
165*61046927SAndroid Build Coastguard Worker snapshot->tcs = pipeline->base.source_hashes[MESA_SHADER_TESS_CTRL];
166*61046927SAndroid Build Coastguard Worker snapshot->tes = pipeline->base.source_hashes[MESA_SHADER_TESS_EVAL];
167*61046927SAndroid Build Coastguard Worker snapshot->gs = pipeline->base.source_hashes[MESA_SHADER_GEOMETRY];
168*61046927SAndroid Build Coastguard Worker snapshot->fs = pipeline->base.source_hashes[MESA_SHADER_FRAGMENT];
169*61046927SAndroid Build Coastguard Worker snapshot->ms = pipeline->base.source_hashes[MESA_SHADER_MESH];
170*61046927SAndroid Build Coastguard Worker snapshot->ts = pipeline->base.source_hashes[MESA_SHADER_TASK];
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker static void
anv_measure_end_snapshot(struct anv_cmd_buffer * cmd_buffer,uint32_t event_count)175*61046927SAndroid Build Coastguard Worker anv_measure_end_snapshot(struct anv_cmd_buffer *cmd_buffer,
176*61046927SAndroid Build Coastguard Worker uint32_t event_count)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker struct anv_batch *batch = &cmd_buffer->batch;
179*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
180*61046927SAndroid Build Coastguard Worker struct anv_physical_device *device = cmd_buffer->device->physical;
181*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
182*61046927SAndroid Build Coastguard Worker enum anv_timestamp_capture_type capture_type;
183*61046927SAndroid Build Coastguard Worker unsigned index = measure->base.index++;
184*61046927SAndroid Build Coastguard Worker assert(index % 2 == 1);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker if (config->cpu_measure)
187*61046927SAndroid Build Coastguard Worker return;
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker if ((batch->engine_class == INTEL_ENGINE_CLASS_COPY) ||
190*61046927SAndroid Build Coastguard Worker (batch->engine_class == INTEL_ENGINE_CLASS_VIDEO))
191*61046927SAndroid Build Coastguard Worker capture_type = ANV_TIMESTAMP_CAPTURE_END_OF_PIPE;
192*61046927SAndroid Build Coastguard Worker else
193*61046927SAndroid Build Coastguard Worker capture_type = ANV_TIMESTAMP_CAPTURE_AT_CS_STALL;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker (*device->cmd_emit_timestamp)(batch, cmd_buffer->device,
196*61046927SAndroid Build Coastguard Worker (struct anv_address) {
197*61046927SAndroid Build Coastguard Worker .bo = measure->bo,
198*61046927SAndroid Build Coastguard Worker .offset = index * sizeof(uint64_t) },
199*61046927SAndroid Build Coastguard Worker capture_type,
200*61046927SAndroid Build Coastguard Worker NULL);
201*61046927SAndroid Build Coastguard Worker
202*61046927SAndroid Build Coastguard Worker struct intel_measure_snapshot *snapshot = &(measure->base.snapshots[index]);
203*61046927SAndroid Build Coastguard Worker memset(snapshot, 0, sizeof(*snapshot));
204*61046927SAndroid Build Coastguard Worker snapshot->type = INTEL_SNAPSHOT_END;
205*61046927SAndroid Build Coastguard Worker snapshot->event_count = event_count;
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker static bool
state_changed(struct anv_cmd_buffer * cmd_buffer,enum intel_measure_snapshot_type type)209*61046927SAndroid Build Coastguard Worker state_changed(struct anv_cmd_buffer *cmd_buffer,
210*61046927SAndroid Build Coastguard Worker enum intel_measure_snapshot_type type)
211*61046927SAndroid Build Coastguard Worker {
212*61046927SAndroid Build Coastguard Worker uint32_t vs=0, tcs=0, tes=0, gs=0, fs=0, cs=0, ms=0, ts=0;
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker if (cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)
215*61046927SAndroid Build Coastguard Worker /* can't record timestamps in this mode */
216*61046927SAndroid Build Coastguard Worker return false;
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker if (type == INTEL_SNAPSHOT_COMPUTE) {
219*61046927SAndroid Build Coastguard Worker const struct anv_compute_pipeline *cs_pipe =
220*61046927SAndroid Build Coastguard Worker anv_pipeline_to_compute(cmd_buffer->state.compute.base.pipeline);
221*61046927SAndroid Build Coastguard Worker assert(cs_pipe);
222*61046927SAndroid Build Coastguard Worker cs = cs_pipe->source_hash;
223*61046927SAndroid Build Coastguard Worker } else if (type == INTEL_SNAPSHOT_DRAW) {
224*61046927SAndroid Build Coastguard Worker const struct anv_graphics_pipeline *gfx =
225*61046927SAndroid Build Coastguard Worker anv_pipeline_to_graphics(cmd_buffer->state.gfx.base.pipeline);
226*61046927SAndroid Build Coastguard Worker assert(gfx);
227*61046927SAndroid Build Coastguard Worker vs = gfx->base.source_hashes[MESA_SHADER_VERTEX];
228*61046927SAndroid Build Coastguard Worker tcs = gfx->base.source_hashes[MESA_SHADER_TESS_CTRL];
229*61046927SAndroid Build Coastguard Worker tes = gfx->base.source_hashes[MESA_SHADER_TESS_EVAL];
230*61046927SAndroid Build Coastguard Worker gs = gfx->base.source_hashes[MESA_SHADER_GEOMETRY];
231*61046927SAndroid Build Coastguard Worker fs = gfx->base.source_hashes[MESA_SHADER_FRAGMENT];
232*61046927SAndroid Build Coastguard Worker ms = gfx->base.source_hashes[MESA_SHADER_MESH];
233*61046927SAndroid Build Coastguard Worker ts = gfx->base.source_hashes[MESA_SHADER_TASK];
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker /* else blorp, all programs NULL */
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker return intel_measure_state_changed(&cmd_buffer->measure->base,
238*61046927SAndroid Build Coastguard Worker vs, tcs, tes, gs, fs, cs, ms, ts);
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker
241*61046927SAndroid Build Coastguard Worker void
_anv_measure_snapshot(struct anv_cmd_buffer * cmd_buffer,enum intel_measure_snapshot_type type,const char * event_name,uint32_t count)242*61046927SAndroid Build Coastguard Worker _anv_measure_snapshot(struct anv_cmd_buffer *cmd_buffer,
243*61046927SAndroid Build Coastguard Worker enum intel_measure_snapshot_type type,
244*61046927SAndroid Build Coastguard Worker const char *event_name,
245*61046927SAndroid Build Coastguard Worker uint32_t count)
246*61046927SAndroid Build Coastguard Worker {
247*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
248*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker assert(config);
251*61046927SAndroid Build Coastguard Worker if (measure == NULL)
252*61046927SAndroid Build Coastguard Worker return;
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker assert(type != INTEL_SNAPSHOT_END);
255*61046927SAndroid Build Coastguard Worker if (!state_changed(cmd_buffer, type)) {
256*61046927SAndroid Build Coastguard Worker /* filter out this event */
257*61046927SAndroid Build Coastguard Worker return;
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker /* increment event count */
261*61046927SAndroid Build Coastguard Worker ++measure->base.event_count;
262*61046927SAndroid Build Coastguard Worker if (measure->base.event_count == 1 ||
263*61046927SAndroid Build Coastguard Worker measure->base.event_count == config->event_interval + 1) {
264*61046927SAndroid Build Coastguard Worker /* the first event of an interval */
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker if (measure->base.index % 2) {
267*61046927SAndroid Build Coastguard Worker /* end the previous event */
268*61046927SAndroid Build Coastguard Worker anv_measure_end_snapshot(cmd_buffer, measure->base.event_count - 1);
269*61046927SAndroid Build Coastguard Worker }
270*61046927SAndroid Build Coastguard Worker measure->base.event_count = 1;
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker if (measure->base.index == config->batch_size) {
273*61046927SAndroid Build Coastguard Worker /* Snapshot buffer is full. The batch must be flushed before
274*61046927SAndroid Build Coastguard Worker * additional snapshots can be taken.
275*61046927SAndroid Build Coastguard Worker */
276*61046927SAndroid Build Coastguard Worker static bool warned = false;
277*61046927SAndroid Build Coastguard Worker if (unlikely(!warned)) {
278*61046927SAndroid Build Coastguard Worker fprintf(config->file,
279*61046927SAndroid Build Coastguard Worker "WARNING: batch size exceeds INTEL_MEASURE limit: %d. "
280*61046927SAndroid Build Coastguard Worker "Data has been dropped. "
281*61046927SAndroid Build Coastguard Worker "Increase setting with INTEL_MEASURE=batch_size={count}\n",
282*61046927SAndroid Build Coastguard Worker config->batch_size);
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker warned = true;
286*61046927SAndroid Build Coastguard Worker return;
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker anv_measure_start_snapshot(cmd_buffer, type, event_name, count);
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker }
292*61046927SAndroid Build Coastguard Worker
293*61046927SAndroid Build Coastguard Worker /**
294*61046927SAndroid Build Coastguard Worker * Called when a command buffer is reset. Re-initializes existing anv_measure
295*61046927SAndroid Build Coastguard Worker * data structures.
296*61046927SAndroid Build Coastguard Worker */
297*61046927SAndroid Build Coastguard Worker void
anv_measure_reset(struct anv_cmd_buffer * cmd_buffer)298*61046927SAndroid Build Coastguard Worker anv_measure_reset(struct anv_cmd_buffer *cmd_buffer)
299*61046927SAndroid Build Coastguard Worker {
300*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
301*61046927SAndroid Build Coastguard Worker struct anv_device *device = cmd_buffer->device;
302*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker if (!config)
305*61046927SAndroid Build Coastguard Worker return;
306*61046927SAndroid Build Coastguard Worker
307*61046927SAndroid Build Coastguard Worker if (!config->enabled) {
308*61046927SAndroid Build Coastguard Worker cmd_buffer->measure = NULL;
309*61046927SAndroid Build Coastguard Worker return;
310*61046927SAndroid Build Coastguard Worker }
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker if (!measure) {
313*61046927SAndroid Build Coastguard Worker /* Capture has recently been enabled. Instead of resetting, a new data
314*61046927SAndroid Build Coastguard Worker * structure must be allocated and initialized.
315*61046927SAndroid Build Coastguard Worker */
316*61046927SAndroid Build Coastguard Worker return anv_measure_init(cmd_buffer);
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker /* it is possible that the command buffer contains snapshots that have not
320*61046927SAndroid Build Coastguard Worker * yet been processed
321*61046927SAndroid Build Coastguard Worker */
322*61046927SAndroid Build Coastguard Worker intel_measure_gather(&device->physical->measure_device,
323*61046927SAndroid Build Coastguard Worker device->info);
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker assert(cmd_buffer->device != NULL);
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker measure->base.index = 0;
328*61046927SAndroid Build Coastguard Worker measure->base.renderpass = 0;
329*61046927SAndroid Build Coastguard Worker measure->base.frame = 0;
330*61046927SAndroid Build Coastguard Worker measure->base.event_count = 0;
331*61046927SAndroid Build Coastguard Worker list_inithead(&measure->base.link);
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker void
anv_measure_destroy(struct anv_cmd_buffer * cmd_buffer)335*61046927SAndroid Build Coastguard Worker anv_measure_destroy(struct anv_cmd_buffer *cmd_buffer)
336*61046927SAndroid Build Coastguard Worker {
337*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
338*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
339*61046927SAndroid Build Coastguard Worker struct anv_device *device = cmd_buffer->device;
340*61046927SAndroid Build Coastguard Worker struct anv_physical_device *physical = device->physical;
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker if (!config)
343*61046927SAndroid Build Coastguard Worker return;
344*61046927SAndroid Build Coastguard Worker if (measure == NULL)
345*61046927SAndroid Build Coastguard Worker return;
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker /* it is possible that the command buffer contains snapshots that have not
348*61046927SAndroid Build Coastguard Worker * yet been processed
349*61046927SAndroid Build Coastguard Worker */
350*61046927SAndroid Build Coastguard Worker intel_measure_gather(&physical->measure_device, &physical->info);
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker if (measure->bo != NULL)
353*61046927SAndroid Build Coastguard Worker anv_device_release_bo(device, measure->bo);
354*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, measure);
355*61046927SAndroid Build Coastguard Worker cmd_buffer->measure = NULL;
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker static struct intel_measure_config*
config_from_device(struct anv_device * device)359*61046927SAndroid Build Coastguard Worker config_from_device(struct anv_device *device)
360*61046927SAndroid Build Coastguard Worker {
361*61046927SAndroid Build Coastguard Worker return device->physical->measure_device.config;
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker void
anv_measure_device_destroy(struct anv_physical_device * device)365*61046927SAndroid Build Coastguard Worker anv_measure_device_destroy(struct anv_physical_device *device)
366*61046927SAndroid Build Coastguard Worker {
367*61046927SAndroid Build Coastguard Worker struct intel_measure_device *measure_device = &device->measure_device;
368*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = measure_device->config;
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker if (!config)
371*61046927SAndroid Build Coastguard Worker return;
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker if (measure_device->ringbuffer != NULL) {
374*61046927SAndroid Build Coastguard Worker vk_free(&device->instance->vk.alloc, measure_device->ringbuffer);
375*61046927SAndroid Build Coastguard Worker measure_device->ringbuffer = NULL;
376*61046927SAndroid Build Coastguard Worker }
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker /**
380*61046927SAndroid Build Coastguard Worker * Hook for command buffer submission.
381*61046927SAndroid Build Coastguard Worker */
382*61046927SAndroid Build Coastguard Worker void
_anv_measure_submit(struct anv_cmd_buffer * cmd_buffer)383*61046927SAndroid Build Coastguard Worker _anv_measure_submit(struct anv_cmd_buffer *cmd_buffer)
384*61046927SAndroid Build Coastguard Worker {
385*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
386*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
387*61046927SAndroid Build Coastguard Worker struct intel_measure_device *measure_device = &cmd_buffer->device->physical->measure_device;
388*61046927SAndroid Build Coastguard Worker struct intel_measure_batch *base = &measure->base;
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker if (!config ||
391*61046927SAndroid Build Coastguard Worker measure == NULL ||
392*61046927SAndroid Build Coastguard Worker base->index == 0 /* no snapshots were started */ )
393*61046927SAndroid Build Coastguard Worker return;
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker if (measure->base.link.next->prev != measure->base.link.next->next) {
396*61046927SAndroid Build Coastguard Worker fprintf(stderr, "INTEL_MEASURE: not tracking events from reused"
397*61046927SAndroid Build Coastguard Worker "command buffer without reset. Not supported.\n");
398*61046927SAndroid Build Coastguard Worker return;
399*61046927SAndroid Build Coastguard Worker }
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker /* finalize snapshots and enqueue them */
402*61046927SAndroid Build Coastguard Worker static unsigned cmd_buffer_count = 0;
403*61046927SAndroid Build Coastguard Worker base->batch_count = p_atomic_inc_return(&cmd_buffer_count);
404*61046927SAndroid Build Coastguard Worker base->batch_size = cmd_buffer->total_batch_size;
405*61046927SAndroid Build Coastguard Worker base->frame = measure_device->frame;
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker if (base->index %2 == 1) {
408*61046927SAndroid Build Coastguard Worker anv_measure_end_snapshot(cmd_buffer, base->event_count);
409*61046927SAndroid Build Coastguard Worker base->event_count = 0;
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker if (config->cpu_measure)
413*61046927SAndroid Build Coastguard Worker return;
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker /* Mark the final timestamp as 'not completed'. This marker will be used
416*61046927SAndroid Build Coastguard Worker * to verify that rendering is complete.
417*61046927SAndroid Build Coastguard Worker */
418*61046927SAndroid Build Coastguard Worker base->timestamps[base->index - 1] = 0;
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker /* add to the list of submitted snapshots */
421*61046927SAndroid Build Coastguard Worker pthread_mutex_lock(&measure_device->mutex);
422*61046927SAndroid Build Coastguard Worker list_addtail(&measure->base.link, &measure_device->queued_snapshots);
423*61046927SAndroid Build Coastguard Worker pthread_mutex_unlock(&measure_device->mutex);
424*61046927SAndroid Build Coastguard Worker }
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker /**
427*61046927SAndroid Build Coastguard Worker * Hook for the start of a frame.
428*61046927SAndroid Build Coastguard Worker */
429*61046927SAndroid Build Coastguard Worker void
_anv_measure_acquire(struct anv_device * device)430*61046927SAndroid Build Coastguard Worker _anv_measure_acquire(struct anv_device *device)
431*61046927SAndroid Build Coastguard Worker {
432*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_device(device);
433*61046927SAndroid Build Coastguard Worker struct intel_measure_device *measure_device = &device->physical->measure_device;
434*61046927SAndroid Build Coastguard Worker
435*61046927SAndroid Build Coastguard Worker if (!config)
436*61046927SAndroid Build Coastguard Worker return;
437*61046927SAndroid Build Coastguard Worker if (measure_device == NULL)
438*61046927SAndroid Build Coastguard Worker return;
439*61046927SAndroid Build Coastguard Worker
440*61046927SAndroid Build Coastguard Worker intel_measure_frame_transition(p_atomic_inc_return(&measure_device->frame));
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker /* iterate the queued snapshots and publish those that finished */
443*61046927SAndroid Build Coastguard Worker intel_measure_gather(measure_device, &device->physical->info);
444*61046927SAndroid Build Coastguard Worker }
445*61046927SAndroid Build Coastguard Worker
446*61046927SAndroid Build Coastguard Worker void
_anv_measure_endcommandbuffer(struct anv_cmd_buffer * cmd_buffer)447*61046927SAndroid Build Coastguard Worker _anv_measure_endcommandbuffer(struct anv_cmd_buffer *cmd_buffer)
448*61046927SAndroid Build Coastguard Worker {
449*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
450*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
451*61046927SAndroid Build Coastguard Worker
452*61046927SAndroid Build Coastguard Worker if (!config)
453*61046927SAndroid Build Coastguard Worker return;
454*61046927SAndroid Build Coastguard Worker if (measure == NULL)
455*61046927SAndroid Build Coastguard Worker return;
456*61046927SAndroid Build Coastguard Worker if (measure->base.index % 2 == 0)
457*61046927SAndroid Build Coastguard Worker return;
458*61046927SAndroid Build Coastguard Worker
459*61046927SAndroid Build Coastguard Worker anv_measure_end_snapshot(cmd_buffer, measure->base.event_count);
460*61046927SAndroid Build Coastguard Worker measure->base.event_count = 0;
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker void
_anv_measure_beginrenderpass(struct anv_cmd_buffer * cmd_buffer)464*61046927SAndroid Build Coastguard Worker _anv_measure_beginrenderpass(struct anv_cmd_buffer *cmd_buffer)
465*61046927SAndroid Build Coastguard Worker {
466*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(cmd_buffer);
467*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = cmd_buffer->measure;
468*61046927SAndroid Build Coastguard Worker struct anv_physical_device *device = cmd_buffer->device->physical;
469*61046927SAndroid Build Coastguard Worker struct intel_measure_device *measure_device = &device->measure_device;
470*61046927SAndroid Build Coastguard Worker
471*61046927SAndroid Build Coastguard Worker if (!config || !measure)
472*61046927SAndroid Build Coastguard Worker return;
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker bool filtering = (config->flags & (INTEL_MEASURE_RENDERPASS |
475*61046927SAndroid Build Coastguard Worker INTEL_MEASURE_SHADER));
476*61046927SAndroid Build Coastguard Worker if (filtering && measure->base.index % 2 == 1) {
477*61046927SAndroid Build Coastguard Worker /* snapshot for previous renderpass was not ended */
478*61046927SAndroid Build Coastguard Worker anv_measure_end_snapshot(cmd_buffer,
479*61046927SAndroid Build Coastguard Worker measure->base.event_count);
480*61046927SAndroid Build Coastguard Worker measure->base.event_count = 0;
481*61046927SAndroid Build Coastguard Worker }
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker measure->base.renderpass =
484*61046927SAndroid Build Coastguard Worker (uintptr_t) p_atomic_inc_return(&measure_device->render_pass_count);
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker void
_anv_measure_add_secondary(struct anv_cmd_buffer * primary,struct anv_cmd_buffer * secondary)488*61046927SAndroid Build Coastguard Worker _anv_measure_add_secondary(struct anv_cmd_buffer *primary,
489*61046927SAndroid Build Coastguard Worker struct anv_cmd_buffer *secondary)
490*61046927SAndroid Build Coastguard Worker {
491*61046927SAndroid Build Coastguard Worker struct intel_measure_config *config = config_from_command_buffer(primary);
492*61046927SAndroid Build Coastguard Worker struct anv_measure_batch *measure = primary->measure;
493*61046927SAndroid Build Coastguard Worker if (!config)
494*61046927SAndroid Build Coastguard Worker return;
495*61046927SAndroid Build Coastguard Worker if (measure == NULL)
496*61046927SAndroid Build Coastguard Worker return;
497*61046927SAndroid Build Coastguard Worker if (config->flags & (INTEL_MEASURE_BATCH | INTEL_MEASURE_FRAME))
498*61046927SAndroid Build Coastguard Worker /* secondary timing will be contained within the primary */
499*61046927SAndroid Build Coastguard Worker return;
500*61046927SAndroid Build Coastguard Worker if (secondary->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) {
501*61046927SAndroid Build Coastguard Worker static bool warned = false;
502*61046927SAndroid Build Coastguard Worker if (unlikely(!warned)) {
503*61046927SAndroid Build Coastguard Worker fprintf(config->file,
504*61046927SAndroid Build Coastguard Worker "WARNING: INTEL_MEASURE cannot capture timings of commands "
505*61046927SAndroid Build Coastguard Worker "in secondary command buffers with "
506*61046927SAndroid Build Coastguard Worker "VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set.\n");
507*61046927SAndroid Build Coastguard Worker }
508*61046927SAndroid Build Coastguard Worker return;
509*61046927SAndroid Build Coastguard Worker }
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker if (measure->base.index % 2 == 1)
512*61046927SAndroid Build Coastguard Worker anv_measure_end_snapshot(primary, measure->base.event_count);
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker struct intel_measure_snapshot *snapshot = &(measure->base.snapshots[measure->base.index]);
515*61046927SAndroid Build Coastguard Worker _anv_measure_snapshot(primary, INTEL_SNAPSHOT_SECONDARY_BATCH, NULL, 0);
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker snapshot->secondary = &secondary->measure->base;
518*61046927SAndroid Build Coastguard Worker }
519