2 * Copyright © 2018 Intel Corporation
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:
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
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
21 * DEALINGS IN THE SOFTWARE.
28 #include "anv_private.h"
30 #include "perf/gen_perf.h"
31 #include "perf/gen_perf_mdapi.h"
33 struct gen_perf_config
*
34 anv_get_perf(const struct gen_device_info
*devinfo
, int fd
)
36 struct gen_perf_config
*perf
= gen_perf_new(NULL
);
38 gen_perf_init_metrics(perf
, devinfo
, fd
, false /* pipeline statistics */);
40 /* We need DRM_I915_PERF_PROP_HOLD_PREEMPTION support, only available in
43 if (perf
->i915_perf_version
< 3)
54 anv_device_perf_init(struct anv_device
*device
)
60 anv_device_perf_open(struct anv_device
*device
, uint64_t metric_id
)
62 uint64_t properties
[DRM_I915_PERF_PROP_MAX
* 2];
63 struct drm_i915_perf_open_param param
;
66 properties
[p
++] = DRM_I915_PERF_PROP_SAMPLE_OA
;
67 properties
[p
++] = true;
69 properties
[p
++] = DRM_I915_PERF_PROP_OA_METRICS_SET
;
70 properties
[p
++] = metric_id
;
72 properties
[p
++] = DRM_I915_PERF_PROP_OA_FORMAT
;
73 properties
[p
++] = device
->info
.gen
>= 8 ?
74 I915_OA_FORMAT_A32u40_A4u32_B8_C8
:
75 I915_OA_FORMAT_A45_B8_C8
;
77 properties
[p
++] = DRM_I915_PERF_PROP_OA_EXPONENT
;
78 properties
[p
++] = 31; /* slowest sampling period */
80 properties
[p
++] = DRM_I915_PERF_PROP_CTX_HANDLE
;
81 properties
[p
++] = device
->context_id
;
83 properties
[p
++] = DRM_I915_PERF_PROP_HOLD_PREEMPTION
;
84 properties
[p
++] = true;
86 /* If global SSEU is available, pin it to the default. This will ensure on
87 * Gen11 for instance we use the full EU array. Initially when perf was
88 * enabled we would use only half on Gen11 because of functional
91 if (device
->physical
->perf
->i915_perf_version
>= 4) {
92 properties
[p
++] = DRM_I915_PERF_PROP_GLOBAL_SSEU
;
93 properties
[p
++] = (uintptr_t) &device
->physical
->perf
->sseu
;
96 memset(¶m
, 0, sizeof(param
));
98 param
.flags
|= I915_PERF_FLAG_FD_CLOEXEC
| I915_PERF_FLAG_FD_NONBLOCK
;
99 param
.properties_ptr
= (uintptr_t)properties
;
100 param
.num_properties
= p
/ 2;
102 stream_fd
= gen_ioctl(device
->fd
, DRM_IOCTL_I915_PERF_OPEN
, ¶m
);
106 VkResult
anv_InitializePerformanceApiINTEL(
108 const VkInitializePerformanceApiInfoINTEL
* pInitializeInfo
)
110 ANV_FROM_HANDLE(anv_device
, device
, _device
);
112 if (!device
->physical
->perf
)
113 return VK_ERROR_EXTENSION_NOT_PRESENT
;
115 /* Not much to do here */
119 VkResult
anv_GetPerformanceParameterINTEL(
121 VkPerformanceParameterTypeINTEL parameter
,
122 VkPerformanceValueINTEL
* pValue
)
124 ANV_FROM_HANDLE(anv_device
, device
, _device
);
126 if (!device
->physical
->perf
)
127 return VK_ERROR_EXTENSION_NOT_PRESENT
;
129 VkResult result
= VK_SUCCESS
;
131 case VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL
:
132 pValue
->type
= VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL
;
133 pValue
->data
.valueBool
= VK_TRUE
;
136 case VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL
:
137 pValue
->type
= VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL
;
138 pValue
->data
.value32
= 25;
142 result
= VK_ERROR_FEATURE_NOT_PRESENT
;
149 VkResult
anv_CmdSetPerformanceMarkerINTEL(
150 VkCommandBuffer commandBuffer
,
151 const VkPerformanceMarkerInfoINTEL
* pMarkerInfo
)
153 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
155 cmd_buffer
->intel_perf_marker
= pMarkerInfo
->marker
;
160 VkResult
anv_AcquirePerformanceConfigurationINTEL(
162 const VkPerformanceConfigurationAcquireInfoINTEL
* pAcquireInfo
,
163 VkPerformanceConfigurationINTEL
* pConfiguration
)
165 ANV_FROM_HANDLE(anv_device
, device
, _device
);
167 struct gen_perf_registers
*perf_config
=
168 gen_perf_load_configuration(device
->physical
->perf
, device
->fd
,
169 GEN_PERF_QUERY_GUID_MDAPI
);
171 return VK_INCOMPLETE
;
173 int ret
= gen_perf_store_configuration(device
->physical
->perf
, device
->fd
,
174 perf_config
, NULL
/* guid */);
176 ralloc_free(perf_config
);
177 return VK_INCOMPLETE
;
180 *pConfiguration
= (VkPerformanceConfigurationINTEL
) (uint64_t) ret
;
185 VkResult
anv_ReleasePerformanceConfigurationINTEL(
187 VkPerformanceConfigurationINTEL _configuration
)
189 ANV_FROM_HANDLE(anv_device
, device
, _device
);
190 uint64_t config
= (uint64_t) _configuration
;
192 gen_ioctl(device
->fd
, DRM_IOCTL_I915_PERF_REMOVE_CONFIG
, &config
);
197 VkResult
anv_QueueSetPerformanceConfigurationINTEL(
199 VkPerformanceConfigurationINTEL _configuration
)
201 ANV_FROM_HANDLE(anv_queue
, queue
, _queue
);
202 struct anv_device
*device
= queue
->device
;
203 uint64_t configuration
= (uint64_t) _configuration
;
205 if (device
->perf_fd
< 0) {
206 device
->perf_fd
= anv_device_perf_open(device
, configuration
);
207 if (device
->perf_fd
< 0)
208 return VK_ERROR_INITIALIZATION_FAILED
;
210 int ret
= gen_ioctl(device
->perf_fd
, I915_PERF_IOCTL_CONFIG
,
211 (void *)(uintptr_t) _configuration
);
213 return anv_device_set_lost(device
, "i915-perf config failed: %m");
219 void anv_UninitializePerformanceApiINTEL(
222 ANV_FROM_HANDLE(anv_device
, device
, _device
);
224 if (device
->perf_fd
>= 0) {
225 close(device
->perf_fd
);
226 device
->perf_fd
= -1;