[Mesa-dev] [PATCH shaderdb 3/3] run: shader program file created via GetProgramBinary (v3)

Dongwon Kim dongwon.kim at intel.com
Mon Feb 26 22:17:05 UTC 2018


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 <dongwon.kim at intel.com>
---
 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},
     {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;
 
     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;
 
                 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, &param);
                     if (unlikely(!param)) {
-                        GLchar log[4096];
+                        GLchar log[MAX_LOG_LEN];
                         GLsizei length;
-                        glGetShaderInfoLog(s, 4096, &length, log);
+                        glGetShaderInfoLog(s, sizeof(log), &length, log);
 
                         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, &param);
+                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);
+
+                   if (glGetError() != GL_NO_ERROR)
+                       length = MAX_PROG_SIZE;
+
+                   prog_buf = (char *)malloc(length);
+                   glGetProgramBinary(prog, length, &length, &format, prog_buf);
+
+                   if (glGetError() != GL_NO_ERROR) {
+                      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");
+                      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++) {
-- 
2.16.2



More information about the mesa-dev mailing list