[Mesa-dev] [PATCH shaderdb] run: shader program file created via GetProgramBinary (v5)
Dongwon Kim
dongwon.kim at intel.com
Sat Mar 24 00:56:30 UTC 2018
With optin '-b', shader-db now generates a shader program binary file
using GetProgramBinary(). This shader program binary can be loaded via
ProgramBinary() to be executed by an application later.
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
v4: 1. '--bin' -> '-b'
2. stop generating binary program when failing to retrieve the binary
size
3. error checking after malloc for binary program
4. changed some of variable names
5. several consecutive fprintfs are consolidated
6. removed MAX_LOG_LEN and MAX_PROG_SIZE
v5: bug fix: +1 to the length of the output file to cover '/0'
Signed-off-by: Dongwon Kim <dongwon.kim at intel.com>
---
run.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 78 insertions(+), 3 deletions(-)
diff --git a/run.c b/run.c
index 69e64c7..4712e27 100644
--- a/run.c
+++ b/run.c
@@ -356,7 +356,8 @@ const struct platform platforms[] = {
void print_usage(const char *prog_name)
{
fprintf(stderr,
- "Usage: %s [-d <device>] [-j <max_threads>] [-o <driver>] [-p <platform>] <directories and *.shader_test files>\n",
+ "Usage: %s [-d <device>] [-j <max_threads>] [-o <driver>] "
+ "[-p <platform>] [-b] <directories and *.shader_test files>\n",
prog_name);
}
@@ -435,10 +436,11 @@ main(int argc, char **argv)
char device_path[64];
int device_id = 0;
int opt;
+ bool generate_prog_bin = 0;
max_threads = omp_get_max_threads();
- while ((opt = getopt(argc, argv, "d:j:o:p:")) != -1) {
+ while ((opt = getopt(argc, argv, "d:j:o:p:b")) != -1) {
switch(opt) {
case 'd': {
char *endptr;
@@ -478,6 +480,9 @@ main(int argc, char **argv)
case 'j':
max_threads = atoi(optarg);
break;
+ case 'b':
+ generate_prog_bin = 1;
+ break;
default:
fprintf(stderr, "Unknown option: %x\n", opt);
print_usage(argv[0]);
@@ -813,18 +818,24 @@ main(int argc, char **argv)
const_text = text;
GLuint prog = glCreateShaderProgramv(shader[i].type, 1,
&const_text);
+
+ if (generate_prog_bin)
+ fprintf(stderr,
+ "Currently, program binary generation "
+ "doesn't support SSO.\n");
+
glDeleteProgram(prog);
free(text);
}
} 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, ¶m);
if (unlikely(!param)) {
GLchar log[4096];
@@ -839,6 +850,70 @@ main(int argc, char **argv)
}
glLinkProgram(prog);
+
+ glGetProgramiv(prog, GL_LINK_STATUS, ¶m);
+ if (unlikely(!param)) {
+ GLchar log[4096];
+ GLsizei length;
+ glGetProgramInfoLog(prog, sizeof(log), &length, log);
+
+ fprintf(stderr, "ERROR: failed to link progam:\n%s\n",
+ log);
+ } else if (generate_prog_bin) {
+ /* generating shader program binary */
+ char *prog_buf;
+ GLenum format;
+ GLsizei length = 0;
+ FILE *fp;
+
+ glGetProgramiv(prog, GL_PROGRAM_BINARY_LENGTH, &length);
+
+ if (glGetError() != GL_NO_ERROR) {
+ fprintf(stderr,
+ "ERROR: failed to generate a program binary "
+ "(invalid program size).\n");
+ continue;
+ }
+
+ prog_buf = (char *)malloc(length);
+
+ if (!prog_buf) {
+ fprintf(stderr,
+ "ERROR: failed to generate a program binary "
+ "(malloc failed)\n");
+ continue;
+ }
+
+ glGetProgramBinary(prog, length, &length, &format, prog_buf);
+ if (glGetError() != GL_NO_ERROR) {
+ fprintf(stderr,
+ "ERROR: failed to generate a program binary "
+ "(GetProgramBinary failed)\n");
+ free(prog_buf);
+ continue;
+ }
+
+ char *out_filename = malloc(strlen(current_shader_name) + 5);
+
+ strncpy(out_filename, current_shader_name,
+ strlen(current_shader_name) + 1);
+ out_filename = strcat(out_filename, ".bin");
+
+ fp = fopen(out_filename, "wb");
+ fprintf(stdout,
+ "\nBinary program has been successfully generated for %s.\n"
+ "\nWriting it to the file.....\n"
+ "===============================================\n"
+ "File Name : %s\nFormat : %d\nSize : %d Byte\n"
+ "===============================================\n\n",
+ current_shader_name, out_filename, format, length);
+
+ 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