2018-06-07 18:02:03 +01:00
|
|
|
/*
|
|
|
|
* Copyright © 2018 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
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "anv_private.h"
|
2018-10-06 19:12:34 +01:00
|
|
|
#include "vk_util.h"
|
2018-06-07 18:02:03 +01:00
|
|
|
|
|
|
|
#include "perf/gen_perf.h"
|
|
|
|
#include "perf/gen_perf_mdapi.h"
|
|
|
|
|
2018-10-06 19:12:34 +01:00
|
|
|
#include "util/mesa-sha1.h"
|
|
|
|
|
2018-06-07 18:02:03 +01:00
|
|
|
struct gen_perf_config *
|
|
|
|
anv_get_perf(const struct gen_device_info *devinfo, int fd)
|
|
|
|
{
|
2018-10-06 19:12:34 +01:00
|
|
|
/* We need self modifying batches. The i915 parser prevents it on
|
|
|
|
* Gen7.5 :( maybe one day.
|
|
|
|
*/
|
|
|
|
if (devinfo->gen < 8)
|
|
|
|
return NULL;
|
|
|
|
|
2018-06-07 18:02:03 +01:00
|
|
|
struct gen_perf_config *perf = gen_perf_new(NULL);
|
|
|
|
|
2019-09-04 17:05:47 +03:00
|
|
|
gen_perf_init_metrics(perf, devinfo, fd, false /* pipeline statistics */);
|
2018-06-07 18:02:03 +01:00
|
|
|
|
2018-10-06 19:12:34 +01:00
|
|
|
if (!perf->n_queries) {
|
|
|
|
if (perf->platform_supported)
|
mesa: Promote Intel's simple logging façade for Android to util/
I'm bringing up freedreno Vulkan on an Android phone, and my pains are
exactly what Chad said when working on Intel's vulkan for Android in
aa716db0f64d ("intel: Add simple logging façade for Android (v2)"):
On Android, stdio goes to /dev/null. On Android, remote gdb is even
more painful than the usual remote gdb. On Android, nothing works like
you expect and debugging is hell. I need logging.
This patch introduces a small, simple logging API that can easily wrap
Android's API. On non-Android platforms, this logger does nothing
fancy. It follows the time-honored Unix tradition of spewing
everything to stderr with minimal fuss.
My goal here is not perfection. My goal is to make a minimal, clean API,
that people hate merely a little instead of a lot, and that's good
enough to let me bring up Android Vulkan. And it needs to be fast,
which means it must be small. No one wants to their game to miss frames
while aiming a flaming bow into the jaws of an angry robot t-rex, and
thus become t-rex breakfast, because some fool had too much fun desiging
a bloated, ideal logging API.
Compared to trusty fprintf, _mesa_log[ewi]() is actually usable on
Android. Compared to os_log_message(), this has different error levels
and supports format arguments.
The only code change in the move is wrapping flockfile/funlockfile in
!DETECT_OS_WINDOWS, since mingw32 doesn't have it. Windows likely wants
different logging code, anyway.
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6806>
2020-09-21 12:53:14 -07:00
|
|
|
mesa_logw("Performance support disabled, "
|
|
|
|
"consider sysctl dev.i915.perf_stream_paranoid=0\n");
|
2018-10-06 19:12:34 +01:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2018-06-07 18:02:03 +01:00
|
|
|
/* We need DRM_I915_PERF_PROP_HOLD_PREEMPTION support, only available in
|
|
|
|
* perf revision 2.
|
|
|
|
*/
|
2020-08-27 15:29:07 +03:00
|
|
|
if (!(INTEL_DEBUG & DEBUG_NO_OACONFIG)) {
|
2020-09-01 13:09:04 +03:00
|
|
|
if (!gen_perf_has_hold_preemption(perf))
|
2020-08-27 15:29:07 +03:00
|
|
|
goto err;
|
|
|
|
}
|
2018-06-07 18:02:03 +01:00
|
|
|
|
|
|
|
return perf;
|
|
|
|
|
|
|
|
err:
|
|
|
|
ralloc_free(perf);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
anv_device_perf_init(struct anv_device *device)
|
|
|
|
{
|
|
|
|
device->perf_fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
anv_device_perf_open(struct anv_device *device, uint64_t metric_id)
|
|
|
|
{
|
|
|
|
uint64_t properties[DRM_I915_PERF_PROP_MAX * 2];
|
|
|
|
struct drm_i915_perf_open_param param;
|
|
|
|
int p = 0, stream_fd;
|
|
|
|
|
|
|
|
properties[p++] = DRM_I915_PERF_PROP_SAMPLE_OA;
|
|
|
|
properties[p++] = true;
|
|
|
|
|
|
|
|
properties[p++] = DRM_I915_PERF_PROP_OA_METRICS_SET;
|
|
|
|
properties[p++] = metric_id;
|
|
|
|
|
|
|
|
properties[p++] = DRM_I915_PERF_PROP_OA_FORMAT;
|
|
|
|
properties[p++] = device->info.gen >= 8 ?
|
|
|
|
I915_OA_FORMAT_A32u40_A4u32_B8_C8 :
|
|
|
|
I915_OA_FORMAT_A45_B8_C8;
|
|
|
|
|
|
|
|
properties[p++] = DRM_I915_PERF_PROP_OA_EXPONENT;
|
|
|
|
properties[p++] = 31; /* slowest sampling period */
|
|
|
|
|
|
|
|
properties[p++] = DRM_I915_PERF_PROP_CTX_HANDLE;
|
|
|
|
properties[p++] = device->context_id;
|
|
|
|
|
|
|
|
properties[p++] = DRM_I915_PERF_PROP_HOLD_PREEMPTION;
|
|
|
|
properties[p++] = true;
|
|
|
|
|
2020-03-02 14:44:55 +02:00
|
|
|
/* If global SSEU is available, pin it to the default. This will ensure on
|
|
|
|
* Gen11 for instance we use the full EU array. Initially when perf was
|
|
|
|
* enabled we would use only half on Gen11 because of functional
|
|
|
|
* requirements.
|
|
|
|
*/
|
2020-09-01 13:09:04 +03:00
|
|
|
if (gen_perf_has_global_sseu(device->physical->perf)) {
|
2020-03-02 14:44:55 +02:00
|
|
|
properties[p++] = DRM_I915_PERF_PROP_GLOBAL_SSEU;
|
|
|
|
properties[p++] = (uintptr_t) &device->physical->perf->sseu;
|
|
|
|
}
|
|
|
|
|
2018-06-07 18:02:03 +01:00
|
|
|
memset(¶m, 0, sizeof(param));
|
|
|
|
param.flags = 0;
|
|
|
|
param.flags |= I915_PERF_FLAG_FD_CLOEXEC | I915_PERF_FLAG_FD_NONBLOCK;
|
|
|
|
param.properties_ptr = (uintptr_t)properties;
|
|
|
|
param.num_properties = p / 2;
|
|
|
|
|
|
|
|
stream_fd = gen_ioctl(device->fd, DRM_IOCTL_I915_PERF_OPEN, ¶m);
|
|
|
|
return stream_fd;
|
|
|
|
}
|
|
|
|
|
2018-10-06 19:12:34 +01:00
|
|
|
/* VK_INTEL_performance_query */
|
2018-06-07 18:02:03 +01:00
|
|
|
VkResult anv_InitializePerformanceApiINTEL(
|
|
|
|
VkDevice _device,
|
|
|
|
const VkInitializePerformanceApiInfoINTEL* pInitializeInfo)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
2020-01-17 22:23:30 -06:00
|
|
|
if (!device->physical->perf)
|
2018-06-07 18:02:03 +01:00
|
|
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
|
|
|
|
|
|
/* Not much to do here */
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult anv_GetPerformanceParameterINTEL(
|
|
|
|
VkDevice _device,
|
|
|
|
VkPerformanceParameterTypeINTEL parameter,
|
|
|
|
VkPerformanceValueINTEL* pValue)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
2020-01-17 22:23:30 -06:00
|
|
|
if (!device->physical->perf)
|
2018-06-07 18:02:03 +01:00
|
|
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
|
|
|
|
|
|
VkResult result = VK_SUCCESS;
|
|
|
|
switch (parameter) {
|
|
|
|
case VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL:
|
|
|
|
pValue->type = VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL;
|
|
|
|
pValue->data.valueBool = VK_TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL:
|
|
|
|
pValue->type = VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL;
|
|
|
|
pValue->data.value32 = 25;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
result = VK_ERROR_FEATURE_NOT_PRESENT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult anv_CmdSetPerformanceMarkerINTEL(
|
|
|
|
VkCommandBuffer commandBuffer,
|
|
|
|
const VkPerformanceMarkerInfoINTEL* pMarkerInfo)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
|
|
|
|
|
|
|
cmd_buffer->intel_perf_marker = pMarkerInfo->marker;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult anv_AcquirePerformanceConfigurationINTEL(
|
|
|
|
VkDevice _device,
|
|
|
|
const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo,
|
|
|
|
VkPerformanceConfigurationINTEL* pConfiguration)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2020-08-10 10:27:57 +03:00
|
|
|
struct anv_performance_configuration_intel *config;
|
|
|
|
|
|
|
|
config = vk_alloc(&device->vk.alloc, sizeof(*config), 8,
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
|
|
|
if (!config)
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
2020-04-06 10:42:22 +03:00
|
|
|
|
2020-09-14 18:53:13 +02:00
|
|
|
if (!(INTEL_DEBUG & DEBUG_NO_OACONFIG)) {
|
2020-08-10 10:27:57 +03:00
|
|
|
config->register_config =
|
2020-04-06 10:42:22 +03:00
|
|
|
gen_perf_load_configuration(device->physical->perf, device->fd,
|
|
|
|
GEN_PERF_QUERY_GUID_MDAPI);
|
2020-08-10 10:27:57 +03:00
|
|
|
if (!config->register_config) {
|
|
|
|
vk_free(&device->vk.alloc, config);
|
2020-04-06 10:42:22 +03:00
|
|
|
return VK_INCOMPLETE;
|
2020-08-10 10:27:57 +03:00
|
|
|
}
|
2020-04-06 10:42:22 +03:00
|
|
|
|
2020-08-10 10:27:57 +03:00
|
|
|
int ret =
|
|
|
|
gen_perf_store_configuration(device->physical->perf, device->fd,
|
|
|
|
config->register_config, NULL /* guid */);
|
2020-04-06 10:42:22 +03:00
|
|
|
if (ret < 0) {
|
2020-08-10 10:27:57 +03:00
|
|
|
ralloc_free(config->register_config);
|
|
|
|
vk_free(&device->vk.alloc, config);
|
2020-04-06 10:42:22 +03:00
|
|
|
return VK_INCOMPLETE;
|
|
|
|
}
|
2020-08-10 10:27:57 +03:00
|
|
|
|
|
|
|
config->config_id = ret;
|
2018-06-07 18:02:03 +01:00
|
|
|
}
|
|
|
|
|
2020-08-10 10:27:57 +03:00
|
|
|
vk_object_base_init(&device->vk, &config->base,
|
|
|
|
VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL);
|
|
|
|
|
|
|
|
*pConfiguration = anv_performance_configuration_intel_to_handle(config);
|
2018-06-07 18:02:03 +01:00
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult anv_ReleasePerformanceConfigurationINTEL(
|
|
|
|
VkDevice _device,
|
|
|
|
VkPerformanceConfigurationINTEL _configuration)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2020-08-10 10:27:57 +03:00
|
|
|
ANV_FROM_HANDLE(anv_performance_configuration_intel, config, _configuration);
|
2018-06-07 18:02:03 +01:00
|
|
|
|
2020-09-14 18:53:13 +02:00
|
|
|
if (!(INTEL_DEBUG & DEBUG_NO_OACONFIG))
|
2020-08-10 10:27:57 +03:00
|
|
|
gen_ioctl(device->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config->config_id);
|
|
|
|
|
|
|
|
ralloc_free(config->register_config);
|
|
|
|
vk_object_base_finish(&config->base);
|
|
|
|
vk_free(&device->vk.alloc, config);
|
2018-06-07 18:02:03 +01:00
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult anv_QueueSetPerformanceConfigurationINTEL(
|
|
|
|
VkQueue _queue,
|
|
|
|
VkPerformanceConfigurationINTEL _configuration)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_queue, queue, _queue);
|
2020-08-10 10:27:57 +03:00
|
|
|
ANV_FROM_HANDLE(anv_performance_configuration_intel, config, _configuration);
|
2018-06-07 18:02:03 +01:00
|
|
|
struct anv_device *device = queue->device;
|
|
|
|
|
2020-09-14 18:53:13 +02:00
|
|
|
if (!(INTEL_DEBUG & DEBUG_NO_OACONFIG)) {
|
2020-04-06 10:42:22 +03:00
|
|
|
if (device->perf_fd < 0) {
|
2020-08-10 10:27:57 +03:00
|
|
|
device->perf_fd = anv_device_perf_open(device, config->config_id);
|
2020-04-06 10:42:22 +03:00
|
|
|
if (device->perf_fd < 0)
|
|
|
|
return VK_ERROR_INITIALIZATION_FAILED;
|
|
|
|
} else {
|
|
|
|
int ret = gen_ioctl(device->perf_fd, I915_PERF_IOCTL_CONFIG,
|
2020-08-10 10:27:57 +03:00
|
|
|
(void *)(uintptr_t) config->config_id);
|
2020-04-06 10:42:22 +03:00
|
|
|
if (ret < 0)
|
|
|
|
return anv_device_set_lost(device, "i915-perf config failed: %m");
|
|
|
|
}
|
2018-06-07 18:02:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void anv_UninitializePerformanceApiINTEL(
|
|
|
|
VkDevice _device)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
|
|
if (device->perf_fd >= 0) {
|
|
|
|
close(device->perf_fd);
|
|
|
|
device->perf_fd = -1;
|
|
|
|
}
|
|
|
|
}
|
2018-10-06 19:12:34 +01:00
|
|
|
|
|
|
|
/* VK_KHR_performance_query */
|
|
|
|
static const VkPerformanceCounterUnitKHR
|
|
|
|
gen_perf_counter_unit_to_vk_unit[] = {
|
|
|
|
[GEN_PERF_COUNTER_UNITS_BYTES] = VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_HZ] = VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_NS] = VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_US] = VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR, /* todo */
|
|
|
|
[GEN_PERF_COUNTER_UNITS_PIXELS] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_TEXELS] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_THREADS] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_PERCENT] = VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_MESSAGES] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_NUMBER] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_CYCLES] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_EVENTS] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_UTILIZATION] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_EU_SENDS_TO_L3_CACHE_LINES] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_EU_ATOMIC_REQUESTS_TO_L3_CACHE_LINES] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_EU_REQUESTS_TO_L3_CACHE_LINES] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
[GEN_PERF_COUNTER_UNITS_EU_BYTES_PER_L3_CACHE_LINE] = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const VkPerformanceCounterStorageKHR
|
|
|
|
gen_perf_counter_data_type_to_vk_storage[] = {
|
|
|
|
[GEN_PERF_COUNTER_DATA_TYPE_BOOL32] = VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR,
|
|
|
|
[GEN_PERF_COUNTER_DATA_TYPE_UINT32] = VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR,
|
|
|
|
[GEN_PERF_COUNTER_DATA_TYPE_UINT64] = VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR,
|
|
|
|
[GEN_PERF_COUNTER_DATA_TYPE_FLOAT] = VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR,
|
|
|
|
[GEN_PERF_COUNTER_DATA_TYPE_DOUBLE] = VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkResult anv_EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
uint32_t queueFamilyIndex,
|
|
|
|
uint32_t* pCounterCount,
|
|
|
|
VkPerformanceCounterKHR* pCounters,
|
|
|
|
VkPerformanceCounterDescriptionKHR* pCounterDescriptions)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
|
|
|
struct gen_perf_config *perf = pdevice->perf;
|
|
|
|
|
|
|
|
uint32_t desc_count = *pCounterCount;
|
|
|
|
|
|
|
|
VK_OUTARRAY_MAKE(out, pCounters, pCounterCount);
|
|
|
|
VK_OUTARRAY_MAKE(out_desc, pCounterDescriptions, &desc_count);
|
|
|
|
|
|
|
|
for (int c = 0; c < (perf ? perf->n_counters : 0); c++) {
|
2020-06-16 14:40:21 +02:00
|
|
|
const struct gen_perf_query_counter *gen_counter = perf->counter_infos[c].counter;
|
2018-10-06 19:12:34 +01:00
|
|
|
|
|
|
|
vk_outarray_append(&out, counter) {
|
|
|
|
counter->unit = gen_perf_counter_unit_to_vk_unit[gen_counter->units];
|
|
|
|
counter->scope = VK_QUERY_SCOPE_COMMAND_KHR;
|
|
|
|
counter->storage = gen_perf_counter_data_type_to_vk_storage[gen_counter->data_type];
|
|
|
|
|
|
|
|
unsigned char sha1_result[20];
|
|
|
|
_mesa_sha1_compute(gen_counter->symbol_name,
|
|
|
|
strlen(gen_counter->symbol_name),
|
|
|
|
sha1_result);
|
|
|
|
memcpy(counter->uuid, sha1_result, sizeof(counter->uuid));
|
|
|
|
}
|
|
|
|
|
|
|
|
vk_outarray_append(&out_desc, desc) {
|
|
|
|
desc->flags = 0; /* None so far. */
|
|
|
|
snprintf(desc->name, sizeof(desc->name), "%s", gen_counter->name);
|
|
|
|
snprintf(desc->category, sizeof(desc->category), "%s", gen_counter->category);
|
|
|
|
snprintf(desc->description, sizeof(desc->description), "%s", gen_counter->desc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
}
|
|
|
|
|
|
|
|
void anv_GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo,
|
|
|
|
uint32_t* pNumPasses)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
|
|
|
struct gen_perf_config *perf = pdevice->perf;
|
|
|
|
|
|
|
|
if (!perf) {
|
|
|
|
*pNumPasses = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pNumPasses = gen_perf_get_n_passes(perf,
|
|
|
|
pPerformanceQueryCreateInfo->pCounterIndices,
|
|
|
|
pPerformanceQueryCreateInfo->counterIndexCount,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult anv_AcquireProfilingLockKHR(
|
|
|
|
VkDevice _device,
|
|
|
|
const VkAcquireProfilingLockInfoKHR* pInfo)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
struct gen_perf_config *perf = device->physical->perf;
|
|
|
|
struct gen_perf_query_info *first_metric_set = &perf->queries[0];
|
2020-04-06 10:42:22 +03:00
|
|
|
int fd = -1;
|
2018-10-06 19:12:34 +01:00
|
|
|
|
|
|
|
assert(device->perf_fd == -1);
|
|
|
|
|
2020-09-14 18:53:13 +02:00
|
|
|
if (!(INTEL_DEBUG & DEBUG_NO_OACONFIG)) {
|
2020-04-06 10:42:22 +03:00
|
|
|
fd = anv_device_perf_open(device, first_metric_set->oa_metrics_set_id);
|
|
|
|
if (fd < 0)
|
|
|
|
return VK_TIMEOUT;
|
|
|
|
}
|
2018-10-06 19:12:34 +01:00
|
|
|
|
|
|
|
device->perf_fd = fd;
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void anv_ReleaseProfilingLockKHR(
|
|
|
|
VkDevice _device)
|
|
|
|
{
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
2020-09-14 18:53:13 +02:00
|
|
|
if (!(INTEL_DEBUG & DEBUG_NO_OACONFIG)) {
|
2020-04-06 10:42:22 +03:00
|
|
|
assert(device->perf_fd >= 0);
|
|
|
|
close(device->perf_fd);
|
|
|
|
}
|
2018-10-06 19:12:34 +01:00
|
|
|
device->perf_fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
anv_perf_write_pass_results(struct gen_perf_config *perf,
|
|
|
|
struct anv_query_pool *pool, uint32_t pass,
|
|
|
|
const struct gen_perf_query_result *accumulated_results,
|
|
|
|
union VkPerformanceCounterResultKHR *results)
|
|
|
|
{
|
|
|
|
for (uint32_t c = 0; c < pool->n_counters; c++) {
|
|
|
|
const struct gen_perf_counter_pass *counter_pass = &pool->counter_pass[c];
|
|
|
|
|
|
|
|
if (counter_pass->pass != pass)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch (pool->pass_query[pass]->kind) {
|
|
|
|
case GEN_PERF_QUERY_TYPE_PIPELINE: {
|
|
|
|
assert(counter_pass->counter->data_type == GEN_PERF_COUNTER_DATA_TYPE_UINT64);
|
|
|
|
uint32_t accu_offset = counter_pass->counter->offset / sizeof(uint64_t);
|
|
|
|
results[c].uint64 = accumulated_results->accumulator[accu_offset];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GEN_PERF_QUERY_TYPE_OA:
|
|
|
|
case GEN_PERF_QUERY_TYPE_RAW:
|
|
|
|
switch (counter_pass->counter->data_type) {
|
|
|
|
case GEN_PERF_COUNTER_DATA_TYPE_UINT64:
|
|
|
|
results[c].uint64 =
|
|
|
|
counter_pass->counter->oa_counter_read_uint64(perf,
|
|
|
|
counter_pass->query,
|
|
|
|
accumulated_results->accumulator);
|
|
|
|
break;
|
|
|
|
case GEN_PERF_COUNTER_DATA_TYPE_FLOAT:
|
|
|
|
results[c].float32 =
|
|
|
|
counter_pass->counter->oa_counter_read_float(perf,
|
|
|
|
counter_pass->query,
|
|
|
|
accumulated_results->accumulator);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* So far we aren't using uint32, double or bool32... */
|
|
|
|
unreachable("unexpected counter data type");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
unreachable("invalid query type");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The Vulkan extension only has nanoseconds as a unit */
|
|
|
|
if (counter_pass->counter->units == GEN_PERF_COUNTER_UNITS_US) {
|
|
|
|
assert(counter_pass->counter->data_type == GEN_PERF_COUNTER_DATA_TYPE_UINT64);
|
|
|
|
results[c].uint64 *= 1000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|