intel/executor: Reorganize -h and --help

Using -h will show a summarized view of the options, functions and
macros.  Using --help will open `man` with the longer contets,
which is more convenient to search and gives a little bit of
formatting.

This scheme is similar to what is done for git subcommands, e.g.
`git commit -h` and `git commit --help`.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34268>
This commit is contained in:
Caio Oliveira
2025-03-28 19:27:17 -07:00
committed by Marge Bot
parent d383d78e8c
commit 6901f74fbf
+172 -106
View File
@@ -41,121 +41,184 @@ enum {
const char usage_line[] = "usage: executor [-d DEVICE] FILENAME";
static void
open_manual()
{
FILE *f = NULL;
/* This fd will be set as stdin for executing man. */
int fd = memfd_create("executor.1", 0);
if (fd != -1)
f = fdopen(fd, "w");
if (!f) {
/* Fallback to just printing the content out. */
f = stderr;
}
static const char *contents[] = {
".TH executor 1 2025-03-28",
"",
".SH NAME",
"",
"executor - executes assembly for Intel GPUs",
"",
".SH SYNOPSIS",
"",
"executor [-d DEVICE] FILENAME",
"",
"executor -d list",
"",
".SH DESCRIPTION",
"",
"Runs a Lua script that can perform data manipulation",
"and dispatch execution of compute shaders, written in the same",
"assembly format used by the brw_asm assembler or when dumping",
"shaders in debug mode.",
"",
"The goal is to have a tool to experiment directly with certain",
"assembly instructions and the shared units without having to",
"instrument the drivers.",
"",
"The program will pick the first available device unless -d is",
"passed with either the index or a substring of the device to use.",
"Use \"-d list\" to list available devices.",
"",
".SH SCRIPTING ENVIRONMENT",
"",
"In addition to the regular Lua standard library the following variables and",
"functions are available",
"",
"- execute({src=STR, data=ARRAY}) -> ARRAY",
" Takes a table as argument. The 'src' in the table contains the shader to be",
" executed. The 'data' argument will be used to fill the data buffer with 32-bit",
" values. The function returns an ARRAY with the contents of the data buffer",
" after the shader completes.",
"",
"- dump(ARRAY, COUNT)",
" Pretty print the COUNT first elements of an array of 32-bit values.",
"",
"- check_ver(V, ...), check_verx10(V, ...)",
" Exit if the Gfx version being executed isn't in the arguments list.",
"",
"- ver, verx10",
" Variables containing the Gfx version being executed.",
"",
".SH ASSEMBLY MACROS",
"",
"In addition to regular instructions, the follow macros will generate",
"assembly code based on the Gfx version being executed. Unlike in regular",
"instructions, REGs don't use regions and can't be immediates.",
"",
"- @eot",
" Send an EOT message.",
"",
"- @mov REG IMM",
" Like a regular MOV but accepts numbers in both decimal and",
" floating-point.",
"",
"- @id REG",
" Write a local invocation index into REG.",
"",
"- @read DST_REG OFFSET_REG",
" Read 32-bit values from the memory buffer at OFFSET_REG into DST_REG.",
"",
"- @write OFFSET_REG SRC_REG",
" Write 32-bit values from SRC_REG to the memory buffer at OFFSET_REG.",
"",
"- @syncnop",
" Produce a coarse grained sync.nop (when applicable) to ensure data from",
" macros above are read/written.",
"",
".SH GPU EXECUTION",
"",
"Compute shaders are dispatched with SIMD8 for Gfx9-125 and SIMD16",
"for Xe2+. Only a single thread is dispatched. A data buffer is used to",
"pipe data into the shader and out of it, it is bound to the graphics",
"address 0x30000000.",
"",
"The Gfx versions have differences in their assembly and shared units, so",
"other than very simple examples, scripts for this program will be either",
"specific to a version or provide shader variants for multiple versions.",
"",
".SH ENVIRONMENT VARIABLES",
"",
"The following INTEL_DEBUG values (comma separated) are used:",
"",
" - bat Dumps the batch buffer.",
" - color Uses colors for the batch buffer dump.",
" - cs Dumps the source after macro processing",
" the final assembly.",
"",
".SH EXAMPLE",
"",
"The script",
"",
" local r = execute {",
" data={ [42] = 0x100 },",
" src=[[",
" @mov g1 42",
" @read g2 g1",
"",
" @id g3",
"",
" add(8) g4<1>UD g2<8,8,1>UD g3<8,8,1>UD { align1 @1 1Q };",
"",
" @write g3 g4",
" @eot",
" ]]",
" }",
"",
" dump(r, 4)",
"",
"Will produce the output",
"",
" [0x00000000] 0x00000100 0x00000101 0x00000102 0x00000103",
"",
"More examples can be found in the examples/ directory in the source code.",
"",
};
for (int i = 0; i < ARRAY_SIZE(contents); i++) {
fputs(contents[i], f);
putc('\n', f);
}
fflush(f);
if (f != stderr) {
/* Inject the temporary as stdin for man. */
lseek(fd, 0, SEEK_SET);
dup2(fd, STDIN_FILENO);
fclose(f);
execlp("man", "man", "-l", "-", (char *)NULL);
} else {
exit(0);
}
}
static void
print_help()
{
printf(
"Executes shaders written for Intel GPUs\n"
"%s\n"
"\n"
"The input is a Lua script that can perform data manipulation\n"
"and dispatch execution of compute shaders, written in assembly,\n"
"the same format used by the brw_asm assembler or when dumping\n"
"shaders in debug mode.\n"
"\n"
"The goal is to have a tool to experiment directly with certain\n"
"assembly instructions and the shared units without having to\n"
"instrument the drivers.\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"
"\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"
"pipe data into the shader and out of it, it is bound to the graphics\n"
"address 0x%08x.\n"
"\n"
"The Gfx versions have differences in their assembly and shared units, so\n"
"other than very simple examples, scripts for this program will be either\n"
"specific to a version or provide shader variants for multiple versions.\n"
"\n"
"ASSEMBLY MACROS\n"
"\n"
"In addition to regular instructions, the follow macros will generate\n"
"assembly code based on the Gfx version being executed. Unlike in regular\n"
"instructions, REGs don't use regions and can't be immediates.\n"
"\n"
"- @eot\n"
" Send an EOT message.\n"
"\n"
"- @mov REG IMM\n"
" Like a regular MOV but accepts numbers in both decimal and\n"
" floating-point.\n"
"\n"
"- @id REG\n"
" Write a local invocation index into REG.\n"
"\n"
"- @read DST_REG OFFSET_REG\n"
" Read 32-bit values from the memory buffer at OFFSET_REG into DST_REG.\n"
"\n"
"- @write OFFSET_REG SRC_REG\n"
" Write 32-bit values from SRC_REG to the memory buffer at OFFSET_REG.\n"
"\n"
"- @syncnop\n"
" Produce a coarse grained sync.nop (when applicable) to ensure data from\n"
" macros above are read/written.\n"
"\n"
"LUA ENVIRONMENT\n"
"\n"
"In addition to the regular Lua standard library the following variables and.\n"
"functions are available.\n"
"\n"
"SCRIPTING ENVIRONMENT:\n"
"- execute({src=STR, data=ARRAY}) -> ARRAY\n"
" Takes a table as argument. The 'src' in the table contains the shader to be\n"
" executed. The 'data' argument will be used to fill the data buffer with 32-bit\n"
" values. The function returns an ARRAY with the contents of the data buffer\n"
" after the shader completes.\n"
"\n"
"- dump(ARRAY, COUNT)\n"
" Pretty print the COUNT first elements of an array of 32-bit values.\n"
"- check_ver(V, ...), check_verx10(V, ...), ver, verx10\n"
"\n"
"- check_ver(V, ...), check_verx10(V, ...)\n"
" Exit if the Gfx version being executed isn't in the arguments list.\n"
"ASSEMBLY MACROS:\n"
"- @eot, @syncnop\n"
"- @mov REG IMM\n"
"- @id REG\n"
"- @read DST_REG OFFSET_REG\n"
"- @write OFFSET_REG SRC_REG\n"
"\n"
"- ver, verx10\n"
" Variables containing the Gfx version being executed.\n"
"\n"
"This program was compiled with %s.\n"
"\n"
"ENVIRONMENT VARIABLES\n"
"\n"
"The following INTEL_DEBUG values (comma separated) are used:\n"
"\n"
" - bat Dumps the batch buffer.\n"
" - color Uses colors for the batch buffer dump.\n"
" - cs Dumps the source after macro processing\n"
" the final assembly.\n"
"\n"
"EXAMPLE\n"
"\n"
"The following script\n"
"\n"
" local r = execute {\n"
" data={ [42] = 0x100 },\n"
" src=[[\n"
" @mov g1 42\n"
" @read g2 g1\n"
"\n"
" @id g3\n"
"\n"
" add(8) g4<1>UD g2<8,8,1>UD g3<8,8,1>UD { align1 @1 1Q };\n"
"\n"
" @write g3 g4\n"
" @eot\n"
" ]]\n"
" }\n"
"\n"
" dump(r, 4)\n"
"\n"
"Will produce the following output\n"
"\n"
" [0x00000000] 0x00000100 0x00000101 0x00000102 0x00000103\n"
"\n"
"More examples can be found in the examples/ directory in the source code.\n"
"\n", usage_line, EXECUTOR_BO_DATA_ADDR, LUA_RELEASE);
"Use \'executor -d list\' to list available devices.\n"
"For more details, use \'executor --help\' to open manual.\n",
usage_line);
}
static struct {
@@ -853,7 +916,7 @@ main(int argc, char *argv[])
const char *device_pattern = NULL;
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"help", no_argument, 0, 'H'},
{"device", required_argument, 0, 'd'},
{},
};
@@ -870,6 +933,9 @@ main(int argc, char *argv[])
case 'h':
print_help();
return 0;
case 'H':
open_manual();
return 0;
default:
fprintf(stderr, "%s\n", usage_line);
return 1;