Commit 0f4143ec authored by Mark Janes's avatar Mark Janes
Browse files

intel: Print GPU timing data based on INTEL_MEASURE



This infrastructure collects GPU timestamps over common intervals, and
generates a CSV report to show how long rendering took.  The overhead
of collection is limited to the flushing that is required at the
interval boundaries for accurate timestamps.

By default, timing data is sent to stderr.  To direct output to a
file:
 INTEL_MEASURE=file=/tmp/measure.csv {workload}

To begin capturing timestamps at a particular frame:
 INTEL_MEASURE=file=/tmp/measure.csv,start=15 {workload}

To capture only 23 frames:
 INTEL_MEASURE=count=23 {workload}

To capture frames 15-37, stopping before frame 38:
 INTEL_MEASURE=start=15,count=23 {workload}

Designate an asynchronous control file with:
 INTEL_MEASURE=control=path/to/control.fifo {workload}

As the workload runs, enable capture for 5 frames with:

 $ echo 5 > path/to/control.fifo

Enable unbounded capture:

 $ echo -1 > path/to/control.fifo

and disable with:

 $ echo 0 > path/to/control.fifo

Select the boundaries of each snapshot with:
 INTEL_MEASURE=draw  : DEFAULT - Collects timings for every render
 INTEL_MEASURE=rt    : Collects timings when the render target changes
 INTEL_MEASURE=batch : Collects timings when batches are submitted
 INTEL_MEASURE=frame : Collects timings at frame boundaries

With INTEL_MEASURE=interval=5, the duration of 5 events will be
combined into a single record in the output.  When possible, a single
start and end event will be submitted to the GPU to minimize
stalling.  Combined events will not span batches, except in
the case of INTEL_MEASURE=frame.
Acked-by: Kenneth Graunke's avatarKenneth Graunke <kenneth@whitecape.org>
Part-of: <!7354>
parent f9960579
This diff is collapsed.
/*
* Copyright © 2020 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INTEL_MEASURE_H
#define INTEL_MEASURE_H
#include <pthread.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include "util/list.h"
enum intel_measure_snapshot_type {
INTEL_SNAPSHOT_UNDEFINED,
INTEL_SNAPSHOT_BLIT,
INTEL_SNAPSHOT_CCS_AMBIGUATE,
INTEL_SNAPSHOT_CCS_COLOR_CLEAR,
INTEL_SNAPSHOT_CCS_PARTIAL_RESOLVE,
INTEL_SNAPSHOT_CCS_RESOLVE,
INTEL_SNAPSHOT_COMPUTE,
INTEL_SNAPSHOT_COPY,
INTEL_SNAPSHOT_DRAW,
INTEL_SNAPSHOT_HIZ_AMBIGUATE,
INTEL_SNAPSHOT_HIZ_CLEAR,
INTEL_SNAPSHOT_HIZ_RESOLVE,
INTEL_SNAPSHOT_MCS_COLOR_CLEAR,
INTEL_SNAPSHOT_MCS_PARTIAL_RESOLVE,
INTEL_SNAPSHOT_SLOW_COLOR_CLEAR,
INTEL_SNAPSHOT_SLOW_DEPTH_CLEAR,
INTEL_SNAPSHOT_END,
};
enum intel_measure_events {
INTEL_MEASURE_DRAW = (1 << 0),
INTEL_MEASURE_RENDERPASS = (1 << 1),
INTEL_MEASURE_SHADER = (1 << 2),
INTEL_MEASURE_BATCH = (1 << 3),
INTEL_MEASURE_FRAME = (1 << 4),
};
struct intel_measure_config {
/* Stderr, or optionally set with INTEL_MEASURE=file={path{ */
FILE *file;
/* Events that will be measured. Set only one flag, with
* INTEL_MEASURE=[draw,rt,shader,batch,frame] */
enum intel_measure_events flags;
/* Optionally set with INTEL_MEASURE=start={num} */
unsigned start_frame;
/* Optionally calculated with INTEL_MEASURE=count={num} based on
* start_frame
*/
unsigned end_frame;
/* Number of events to combine per line of output. Optionally set with
* INTEL_MEASURE=interval={num}
*/
unsigned event_interval;
/* Max snapshots per batch. Set with
* INTEL_MEASURE=batch_size={num}. Additional snapshots will be dropped.
*/
unsigned batch_size;
/* Max number of batch measurements that can be buffered, for combining
* snapshots into frame or interval data.
*/
unsigned buffer_size;
/* Fifo which will be read to enable measurements at run-time. Set with
* INTEL_MEASURE=control={path}. `echo {num} > {path}` will collect num
* frames of measurements, beginning with the next frame boundary.
*/
int control_fh;
/* true when snapshots are currently being collected */
bool enabled;
};
struct intel_measure_snapshot {
enum intel_measure_snapshot_type type;
unsigned count, event_count;
const char* event_name;
uintptr_t framebuffer, vs, tcs, tes, gs, fs, cs;
};
struct intel_measure_buffered_result {
struct intel_measure_snapshot snapshot;
uint64_t start_ts, end_ts, idle_duration;
unsigned frame, batch_count, event_index;
};
struct intel_measure_ringbuffer {
unsigned head, tail;
struct intel_measure_buffered_result results[0];
};
struct intel_measure_device {
struct intel_measure_config *config;
unsigned frame;
/* Holds the list of (iris/anv)_measure_batch snapshots that have been
* submitted for rendering, but have not completed.
*/
pthread_mutex_t mutex;
struct list_head queued_snapshots;
/* Holds completed snapshots that may need to be combined before being
* written out
*/
struct intel_measure_ringbuffer *ringbuffer;
};
struct intel_measure_batch {
unsigned index;
unsigned frame, batch_count, event_count;
uintptr_t framebuffer;
bool submitted;
struct intel_measure_snapshot snapshots[0];
};
void intel_measure_init(struct intel_measure_device *device);
const char * intel_measure_snapshot_string(enum intel_measure_snapshot_type type);
bool intel_measure_state_changed(const struct intel_measure_batch *batch,
uintptr_t vs, uintptr_t tcs, uintptr_t tes,
uintptr_t gs, uintptr_t fs, uintptr_t cs);
void intel_measure_frame_transition(unsigned frame);
void intel_measure_push_result(struct intel_measure_device *device,
struct intel_measure_batch *batch,
uint64_t *timestamps);
struct gen_device_info;
void intel_measure_print(struct intel_measure_device *device,
struct gen_device_info *info);
#endif /* INTEL_MEASURE_H */
......@@ -40,6 +40,8 @@ files_libintel_common = files(
'gen_sample_positions.h',
'gen_uuid.c',
'gen_uuid.h',
'intel_measure.c',
'intel_measure.h',
)
libintel_common = static_library(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment