From 787535fb11b08f41ac4f19683e112a04a84afe53 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 22 Mar 2016 21:54:27 +1100 Subject: [PATCH] glsl: add support for caching subroutines MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Nicolai Hähnle --- src/compiler/glsl/shader_cache.cpp | 107 +++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp index cec104f4aee..a9bb7715ef9 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -207,6 +207,68 @@ decode_type_from_blob(struct blob_reader *blob) } } +static void +write_subroutines(struct blob *metadata, struct gl_shader_program *prog) +{ + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + struct gl_linked_shader *sh = prog->_LinkedShaders[i]; + if (!sh) + continue; + + struct gl_program *glprog = sh->Program; + + blob_write_uint32(metadata, glprog->sh.NumSubroutineUniforms); + blob_write_uint32(metadata, glprog->sh.MaxSubroutineFunctionIndex); + blob_write_uint32(metadata, glprog->sh.NumSubroutineFunctions); + for (unsigned j = 0; j < glprog->sh.NumSubroutineFunctions; j++) { + int num_types = glprog->sh.SubroutineFunctions[j].num_compat_types; + + blob_write_string(metadata, glprog->sh.SubroutineFunctions[j].name); + blob_write_uint32(metadata, glprog->sh.SubroutineFunctions[j].index); + blob_write_uint32(metadata, num_types); + + for (int k = 0; k < num_types; k++) { + encode_type_to_blob(metadata, + glprog->sh.SubroutineFunctions[j].types[k]); + } + } + } +} + +static void +read_subroutines(struct blob_reader *metadata, struct gl_shader_program *prog) +{ + struct gl_subroutine_function *subs; + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + struct gl_linked_shader *sh = prog->_LinkedShaders[i]; + if (!sh) + continue; + + struct gl_program *glprog = sh->Program; + + glprog->sh.NumSubroutineUniforms = blob_read_uint32(metadata); + glprog->sh.MaxSubroutineFunctionIndex = blob_read_uint32(metadata); + glprog->sh.NumSubroutineFunctions = blob_read_uint32(metadata); + + subs = rzalloc_array(prog, struct gl_subroutine_function, + glprog->sh.NumSubroutineFunctions); + glprog->sh.SubroutineFunctions = subs; + + for (unsigned j = 0; j < glprog->sh.NumSubroutineFunctions; j++) { + subs[j].name = ralloc_strdup(prog, blob_read_string (metadata)); + subs[j].index = (int) blob_read_uint32(metadata); + subs[j].num_compat_types = (int) blob_read_uint32(metadata); + + subs[j].types = rzalloc_array(prog, const struct glsl_type *, + subs[j].num_compat_types); + for (int k = 0; k < subs[j].num_compat_types; k++) { + subs[j].types[k] = decode_type_from_blob(metadata); + } + } + } +} + static void write_xfb(struct blob *metadata, struct gl_shader_program *shProg) { @@ -499,11 +561,29 @@ read_hash_tables(struct blob_reader *metadata, struct gl_shader_program *prog) read_hash_table(metadata, prog->FragDataIndexBindings); } +static void +write_shader_subroutine_index(struct blob *metadata, + struct gl_linked_shader *sh, + struct gl_program_resource *res) +{ + assert(sh); + + for (unsigned j = 0; j < sh->Program->sh.NumSubroutineFunctions; j++) { + if (strcmp(((gl_subroutine_function *)res->Data)->name, + sh->Program->sh.SubroutineFunctions[j].name) == 0) { + blob_write_uint32(metadata, j); + break; + } + } +} + static void write_program_resource_data(struct blob *metadata, struct gl_shader_program *prog, struct gl_program_resource *res) { + struct gl_linked_shader *sh; + switch(res->Type) { case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: { @@ -554,6 +634,16 @@ write_program_resource_data(struct blob *metadata, } } break; + case GL_VERTEX_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + sh = + prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; + write_shader_subroutine_index(metadata, sh, res); + break; default: assert(!"Support for writing resource not yet implemented."); } @@ -564,6 +654,8 @@ read_program_resource_data(struct blob_reader *metadata, struct gl_shader_program *prog, struct gl_program_resource *res) { + struct gl_linked_shader *sh; + switch(res->Type) { case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: { @@ -601,6 +693,17 @@ read_program_resource_data(struct blob_reader *metadata, res->Data = &prog->last_vert_prog-> sh.LinkedTransformFeedback->Varyings[blob_read_uint32(metadata)]; break; + case GL_VERTEX_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + sh = + prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; + res->Data = + &sh->Program->sh.SubroutineFunctions[blob_read_uint32(metadata)]; + break; default: assert(!"Support for reading resource not yet implemented."); } @@ -817,6 +920,8 @@ shader_cache_write_program_metadata(struct gl_context *ctx, write_uniform_remap_table(metadata, prog); + write_subroutines(metadata, prog); + write_program_resource_list(metadata, prog); char sha1_buf[41]; @@ -924,6 +1029,8 @@ shader_cache_read_program_metadata(struct gl_context *ctx, read_uniform_remap_table(&metadata, prog); + read_subroutines(&metadata, prog); + read_program_resource_list(&metadata, prog); if (metadata.current != metadata.end || metadata.overrun) { -- 2.30.2