intel/executor: Allow selecting a device to use
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Add a command line option `-d DEVICE` to select
a device either by index or by substring of the
name.

Use `-d list` to print available devices.

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34267>
This commit is contained in:
Caio Oliveira 2025-03-28 13:55:23 -07:00 committed by Marge Bot
parent 9b2b3255e1
commit 71ae31dbd8

View file

@ -3,6 +3,7 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <getopt.h> #include <getopt.h>
#include <stdio.h> #include <stdio.h>
@ -38,7 +39,7 @@ enum {
EXECUTOR_BO_SIZE = 10 * 1024 * 1024, EXECUTOR_BO_SIZE = 10 * 1024 * 1024,
}; };
const char usage_line[] = "usage: executor FILENAME"; const char usage_line[] = "usage: executor [-d DEVICE] FILENAME";
static void static void
print_help() print_help()
@ -48,7 +49,7 @@ print_help()
"%s\n" "%s\n"
"\n" "\n"
"The input is a Lua script that can perform data manipulation\n" "The input is a Lua script that can perform data manipulation\n"
"and dispatch execution of compute shaders, written in Xe assembly,\n" "and dispatch execution of compute shaders, written in assembly,\n"
"the same format used by the brw_asm assembler or when dumping\n" "the same format used by the brw_asm assembler or when dumping\n"
"shaders in debug mode.\n" "shaders in debug mode.\n"
"\n" "\n"
@ -56,10 +57,14 @@ print_help()
"assembly instructions and the shared units without having to\n" "assembly instructions and the shared units without having to\n"
"instrument the drivers.\n" "instrument the drivers.\n"
"\n" "\n"
"The program will pick the first available device unless -d is\n"
"passed with either the index or a substring of the device to use.\n"
"Use \"-d list\" to list available devices.\n"
"\n"
"EXECUTION CONTEXT\n" "EXECUTION CONTEXT\n"
"\n" "\n"
"By default compute shaders are used with SIMD8 for Gfx9-125 and SIMD16\n" "By default compute shaders are used with SIMD8 for Gfx9-125 and SIMD16\n"
"for Xe2. Only a single thread is dispatched. A data buffer is used to\n" "for Xe2+. Only a single thread is dispatched. A data buffer is used to\n"
"pipe data into the shader and out of it, it is bound to the graphics\n" "pipe data into the shader and out of it, it is bound to the graphics\n"
"address 0x%08x.\n" "address 0x%08x.\n"
"\n" "\n"
@ -289,34 +294,91 @@ executor_address_of_ptr(executor_bo *bo, void *ptr)
return (executor_address){ptr - bo->map + bo->addr}; return (executor_address){ptr - bo->map + bo->addr};
} }
static int static bool
get_drm_device(struct intel_device_info *devinfo) open_intel_render_device(drmDevicePtr dev,
struct intel_device_info *devinfo,
int *fd)
{
if (!(dev->available_nodes & 1 << DRM_NODE_RENDER) ||
dev->bustype != DRM_BUS_PCI ||
dev->deviceinfo.pci->vendor_id != 0x8086)
return false;
*fd = open(dev->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
if (fd < 0)
return false;
if (!intel_get_device_info_from_fd(*fd, devinfo, -1, -1) ||
devinfo->ver < 8) {
close(*fd);
*fd = -1;
return false;
}
return true;
}
static void
print_drm_devices()
{ {
drmDevicePtr devices[8]; drmDevicePtr devices[8];
int max_devices = drmGetDevices2(0, devices, 8); int num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
int i, fd = -1; if (num_devices < 1) {
for (i = 0; i < max_devices; i++) { printf("No devices found.\n");
if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER && return;
devices[i]->bustype == DRM_BUS_PCI && }
devices[i]->deviceinfo.pci->vendor_id == 0x8086) {
fd = open(devices[i]->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
if (fd < 0)
continue;
if (!intel_get_device_info_from_fd(fd, devinfo, -1, -1) || for (int i = 0; i < num_devices; i++) {
devinfo->ver < 8) { struct intel_device_info devinfo = {};
close(fd); int fd = -1;
fd = -1;
continue;
}
/* Found a device! */ if (open_intel_render_device(devices[i], &devinfo, &fd)) {
break; printf("%d: %s\n", i, devinfo.name);
close(fd);
} }
} }
drmFreeDevices(devices, max_devices);
drmFreeDevices(devices, num_devices);
}
static int
get_drm_device(struct intel_device_info *devinfo, const char *device_pattern)
{
drmDevicePtr devices[8];
int num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
int fd = -1;
int index = -1;
if (!device_pattern)
device_pattern = "";
/* Interpret numbers as picking an index. */
if (isdigit(device_pattern[0])) {
index = atoi(device_pattern);
}
if (index != -1) {
if (index >= num_devices)
failf("No device with index %d", index);
if (!open_intel_render_device(devices[index], devinfo, &fd))
failf("Couldn't open device with index %d", index);
} else {
for (int i = 0; i < num_devices; i++) {
if (open_intel_render_device(devices[i], devinfo, &fd)) {
if (strcasestr(devinfo->name, device_pattern)) {
/* Found a device! */
break;
}
close(fd);
fd = -1;
}
}
}
drmFreeDevices(devices, num_devices);
return fd; return fd;
} }
@ -788,14 +850,23 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int opt; int opt;
const char *device_pattern = NULL;
static const struct option long_options[] = { static const struct option long_options[] = {
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"device", required_argument, 0, 'd'},
{}, {},
}; };
while ((opt = getopt_long(argc, argv, "h", long_options, NULL)) != -1) { while ((opt = getopt_long(argc, argv, "d:h", long_options, NULL)) != -1) {
switch (opt) { switch (opt) {
case 'd':
if (!strcmp(optarg, "list")) {
print_drm_devices();
return 0;
}
device_pattern = optarg;
break;
case 'h': case 'h':
print_help(); print_help();
return 0; return 0;
@ -815,7 +886,12 @@ main(int argc, char *argv[])
process_intel_debug_variable(); process_intel_debug_variable();
E.fd = get_drm_device(&E.devinfo); E.fd = get_drm_device(&E.devinfo, device_pattern);
if (E.fd < 0)
failf("Failed to open DRM device");
fprintf(stderr, "Using device: %s\n", E.devinfo.name);
isl_device_init(&E.isl_dev, &E.devinfo); isl_device_init(&E.isl_dev, &E.devinfo);
brw_init_isa_info(&E.isa, &E.devinfo); brw_init_isa_info(&E.isa, &E.devinfo);
assert(E.devinfo.kmd_type == INTEL_KMD_TYPE_I915 || assert(E.devinfo.kmd_type == INTEL_KMD_TYPE_I915 ||