From 6901f74fbf112fa129197b7b0101578ba992d24a Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Fri, 28 Mar 2025 19:27:17 -0700 Subject: [PATCH] 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 Part-of: --- src/intel/executor/executor_main.c | 278 ++++++++++++++++++----------- 1 file changed, 172 insertions(+), 106 deletions(-) diff --git a/src/intel/executor/executor_main.c b/src/intel/executor/executor_main.c index b1bdbf0fc03..29354c98e90 100644 --- a/src/intel/executor/executor_main.c +++ b/src/intel/executor/executor_main.c @@ -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;