On Monday, February 26, 2018 2:17:05 PM PDT Dongwon Kim wrote: > extraction of linked binary program to a file using glGetProgramBinary. > This file is intended to be loaded by glProgramBinary in the graphic > application running on the target system. > > To enable this feature, a new option '--bin' has to be passed to the > program execution. > > v2: 1. define MAX_LOG_LEN and use it as the size of gl log > 2. define MAX_PROG_SIZE and use it as the max size of extracted > shader_program > 3. out_file is now pointer allocated by strdup for the file name > > v3: 1. automatically using original shader test file's name + ".bin" > as a filename for program binary - better way to cover the case > with batch compilation of many shader test files in the same > directory > 2. remove --out=<file name> since it is now unnecessary (due to v3-1.) > to provide custom file name. Instead, option, "--bin", which is > basically a flag that enables getting program binary as a file. > 3. Now it tries to get the length of binary by reading program's > GL_PROGRAM_BINARY_LENGTH_OES parameter > > Signed-off-by: Dongwon Kim <[email protected]> > --- > run.c | 68 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 64 insertions(+), 4 deletions(-) > > diff --git a/run.c b/run.c > index d066567..bbab5d9 100644 > --- a/run.c > +++ b/run.c > @@ -52,6 +52,9 @@ > > #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) > > +#define MAX_LOG_LEN 4096 > +#define MAX_PROG_SIZE (10*1024*1024) /* maximum 10MB for shader program */ > + > struct context_info { > char *extension_string; > int extension_string_len; > @@ -358,18 +361,20 @@ const struct platform platforms[] = { > enum > { > PCI_ID_OVERRIDE_OPTION = CHAR_MAX + 1, > + LOADABLE_PROGRAM_BINARY_OPTION, > }; > > const struct option const long_options[] = > { > {"pciid", required_argument, NULL, PCI_ID_OVERRIDE_OPTION}, > + {"bin", no_argument, NULL, LOADABLE_PROGRAM_BINARY_OPTION},
This sounds like we're loading binaries. Can we call it
GENERATE_PROGRAM_BINARY_OPTION instead?
> {NULL, 0, NULL, 0}
> };
>
> void print_usage(const char *prog_name)
> {
> fprintf(stderr,
> - "Usage: %s [-d <device>] [-j <max_threads>] [-o <driver>] [-p
> <platform>] [--pciid=<chip id of targetted gen arch>] <directories and
> *.shader_test files>\n",
> + "Usage: %s [-d <device>] [-j <max_threads>] [-o <driver>] [-p
> <platform>] [--pciid=<pci id of targetted gen arch>] <directories and
> *.shader_test files>\n",
> prog_name);
> }
>
> @@ -450,6 +455,7 @@ main(int argc, char **argv)
> int opt;
> bool platf_overridden = 0;
> bool pci_id_overridden = 0;
> + bool enable_prog_bin = 0;
Maybe generate_prog_bin here as well.
>
> max_threads = omp_get_max_threads();
>
> @@ -518,6 +524,9 @@ main(int argc, char **argv)
> setenv("INTEL_DEVID_OVERRIDE", optarg, 1);
> pci_id_overridden = 1;
> break;
> + case LOADABLE_PROGRAM_BINARY_OPTION:
> + enable_prog_bin = 1;
> + break;
> default:
> fprintf(stderr, "Unknown option: %x\n", opt);
> print_usage(argv[0]);
> @@ -858,18 +867,18 @@ main(int argc, char **argv)
> }
> } else if (type == TYPE_CORE || type == TYPE_COMPAT || type ==
> TYPE_ES) {
> GLuint prog = glCreateProgram();
> + GLint param;
So...putting this here means that you're not going to support generating
program binaries for SSO-based programs. That seems a bit unfortunate...
>
> for (unsigned i = 0; i < num_shaders; i++) {
> GLuint s = glCreateShader(shader[i].type);
> glShaderSource(s, 1, &shader[i].text, &shader[i].length);
> glCompileShader(s);
>
> - GLint param;
> glGetShaderiv(s, GL_COMPILE_STATUS, ¶m);
> if (unlikely(!param)) {
> - GLchar log[4096];
> + GLchar log[MAX_LOG_LEN];
> GLsizei length;
> - glGetShaderInfoLog(s, 4096, &length, log);
> + glGetShaderInfoLog(s, sizeof(log), &length, log);
It would be nice to make a helper function for getting the info log and
printing an error, since you've now got it twice. Should probably be a
separate patch (and include the MAX_LOG_LEN change).
>
> fprintf(stderr, "ERROR: %s failed to compile:\n%s\n",
> current_shader_name, log);
> @@ -879,6 +888,57 @@ main(int argc, char **argv)
> }
>
> glLinkProgram(prog);
> +
> + glGetProgramiv(prog, GL_LINK_STATUS, ¶m);
> + if (unlikely(!param)) {
> + GLchar log[MAX_LOG_LEN];
> + GLsizei length;
> + glGetProgramInfoLog(prog, sizeof(log), &length, log);
> +
> + fprintf(stderr, "ERROR: failed to link progam:\n%s\n",
> + log);
> + } else if (enable_prog_bin) { /* generate program binary if
> enable_prog_bin == true */
> + char *prog_buf;
> + GLenum format;
> + GLsizei length = 0;
> + FILE *fp;
> +
> + glGetProgramiv(prog,
> + (type == TYPE_ES) ?
> GL_PROGRAM_BINARY_LENGTH_OES :
> + GL_PROGRAM_BINARY_LENGTH, &length);
GL_PROGRAM_BINARY_LENGTH_OES and GL_PROGRAM_BINARY_LENGTH are identical
hex values (intentionally). Just use GL_PROGRAM_BINARY_LENGTH and skip
the type == TYPE_ES check.
> +
> + if (glGetError() != GL_NO_ERROR)
> + length = MAX_PROG_SIZE;
Surely you don't want to truncate the program if you exceed
MAX_PROG_SIZE? It doesn't look like this is necessary now that you're
malloc'ing an appropriately sized buffer, so we can probably just drop
it altogether.
> +
> + prog_buf = (char *)malloc(length);
> + glGetProgramBinary(prog, length, &length, &format,
> prog_buf);
> +
> + if (glGetError() != GL_NO_ERROR) {
Maybe add || !prog_buf to guard against malloc failure?
> + fprintf(stderr, "ERROR: failed to get Program
> Binary\n");
> + } else {
> + char *out_filename;
> +
> + out_filename = malloc(strlen(current_shader_name) + 4);
> +
> + printf("%s\n", current_shader_name);
> + strncpy(out_filename, current_shader_name,
> strlen(current_shader_name) + 1);
> + out_filename = strcat(out_filename, ".bin");
> +
> + fp = fopen(out_filename, "wb");
> + fprintf(stdout, "\n");
> + fprintf(stdout, "Binary program has been successfully
> generated.\n\n");
> + fprintf(stdout, "Writing to file.....\n");
> + fprintf(stdout,
> "===============================================\n");
> + fprintf(stdout, "File Name : \"%s\"\n", out_filename);
> + fprintf(stdout, "Format : %d\n", format);
> + fprintf(stdout, "Size : %d Byte\n", length);
> + fprintf(stdout,
> "===============================================\n");
I suspect this output is going to be completely jumbled if you run with
concurrency. If you're only supporting this with -1, that's probably
OK...but maybe it would be better to just use a snigle fprintf?
> + fwrite(prog_buf, sizeof(char), length, fp);
> + fclose(fp);
> + free(out_filename);
> + }
> + free(prog_buf);
> + }
> glDeleteProgram(prog);
> } else {
> for (unsigned i = 0; i < num_shaders; i++) {
>
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
