1 /*
2 * Copyright © 2023 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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23 #include "xe/intel_gem.h"
24
25 #include "drm-uapi/xe_drm.h"
26
27 #include "common/intel_gem.h"
28 #include "common/xe/intel_engine.h"
29
30 bool
xe_gem_read_render_timestamp(int fd,uint64_t * value)31 xe_gem_read_render_timestamp(int fd, uint64_t *value)
32 {
33 UNUSED uint64_t cpu;
34
35 return xe_gem_read_correlate_cpu_gpu_timestamp(fd, INTEL_ENGINE_CLASS_RENDER,
36 0, CLOCK_MONOTONIC, &cpu,
37 value, NULL);
38 }
39
40 bool
xe_gem_can_render_on_fd(int fd)41 xe_gem_can_render_on_fd(int fd)
42 {
43 struct drm_xe_device_query query = {
44 .query = DRM_XE_DEVICE_QUERY_ENGINES,
45 };
46 return intel_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) == 0;
47 }
48
49 bool
xe_gem_read_correlate_cpu_gpu_timestamp(int fd,enum intel_engine_class engine_class,uint16_t engine_instance,clockid_t cpu_clock_id,uint64_t * cpu_timestamp,uint64_t * gpu_timestamp,uint64_t * cpu_delta)50 xe_gem_read_correlate_cpu_gpu_timestamp(int fd,
51 enum intel_engine_class engine_class,
52 uint16_t engine_instance,
53 clockid_t cpu_clock_id,
54 uint64_t *cpu_timestamp,
55 uint64_t *gpu_timestamp,
56 uint64_t *cpu_delta)
57 {
58 struct drm_xe_query_engine_cycles engine_cycles = {};
59 struct drm_xe_device_query query = {
60 .query = DRM_XE_DEVICE_QUERY_ENGINE_CYCLES,
61 .size = sizeof(engine_cycles),
62 .data = (uintptr_t)&engine_cycles,
63 };
64
65 switch (cpu_clock_id) {
66 case CLOCK_MONOTONIC:
67 #ifdef CLOCK_MONOTONIC_RAW
68 case CLOCK_MONOTONIC_RAW:
69 #endif
70 case CLOCK_REALTIME:
71 #ifdef CLOCK_BOOTTIME
72 case CLOCK_BOOTTIME:
73 #endif
74 #ifdef CLOCK_TAI
75 case CLOCK_TAI:
76 #endif
77 break;
78 default:
79 return false;
80 }
81
82 engine_cycles.eci.engine_class = intel_engine_class_to_xe(engine_class);
83 engine_cycles.eci.engine_instance = engine_instance;
84 engine_cycles.eci.gt_id = 0;
85 engine_cycles.clockid = cpu_clock_id;
86
87 if (intel_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query))
88 return false;
89
90 *cpu_timestamp = engine_cycles.cpu_timestamp;
91 *gpu_timestamp = engine_cycles.engine_cycles;
92 if (cpu_delta)
93 *cpu_delta = engine_cycles.cpu_delta;
94
95 return true;
96 }
97