[Mesa-dev] [PATCH 32/68] glsl: add support for caching subroutines

Timothy Arceri timothy.arceri at collabora.com
Wed Jun 1 06:23:13 UTC 2016


---
 src/compiler/glsl/shader_cache.cpp | 120 +++++++++++++++++++++++++++++++++----
 1 file changed, 110 insertions(+), 10 deletions(-)

diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index d8f8709..35cd99c 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -133,6 +133,62 @@ 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_shader *sh = prog->_LinkedShaders[i];
+      if (!sh)
+         continue;
+
+      blob_write_uint32(metadata, sh->MaxSubroutineFunctionIndex);
+      blob_write_uint32(metadata, sh->NumSubroutineFunctions);
+      for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) {
+         int num_types = sh->SubroutineFunctions[j].num_compat_types;
+
+         blob_write_string(metadata, sh->SubroutineFunctions[j].name);
+         blob_write_uint32(metadata, sh->SubroutineFunctions[j].index);
+         blob_write_uint32(metadata, num_types);
+
+         for (int k = 0; k < num_types; k++) {
+            encode_type_to_blob(metadata,
+                                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_shader *sh = prog->_LinkedShaders[i];
+      if (!sh)
+         continue;
+
+      sh->MaxSubroutineFunctionIndex = blob_read_uint32(metadata);
+      sh->NumSubroutineFunctions = blob_read_uint32(metadata);
+
+      subs = rzalloc_array(prog, struct gl_subroutine_function,
+                           sh->NumSubroutineFunctions);
+      sh->SubroutineFunctions = subs;
+
+      for (unsigned j = 0; j < 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_uniforms(struct blob *metadata, struct gl_shader_program *prog)
 {
    uint32_t i;
@@ -145,6 +201,8 @@ write_uniforms(struct blob *metadata, struct gl_shader_program *prog)
       printf("uniform %s %s\n",
              prog->UniformStorage[i].type->name,
              prog->UniformStorage[i].name);
+      encode_type_to_blob(metadata, prog->UniformStorage[i].type);
+
       blob_write_uint32(metadata, prog->UniformStorage[i].array_elements);
       blob_write_string(metadata, prog->UniformStorage[i].name);
       blob_write_uint32(metadata, prog->UniformStorage[i].storage -
@@ -164,8 +222,6 @@ write_uniforms(struct blob *metadata, struct gl_shader_program *prog)
       blob_write_uint32(metadata,
                         prog->UniformStorage[i].top_level_array_stride);
 
-      encode_type_to_blob(metadata, prog->UniformStorage[i].type);
-
       blob_write_bytes(metadata, prog->UniformStorage[i].opaque,
                        sizeof(prog->UniformStorage[i].opaque));
    }
@@ -193,6 +249,7 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog)
    prog->UniformHash = new string_to_uint_map;
 
    for (i = 0; i < prog->NumUniformStorage; i++) {
+      uniforms[i].type = decode_type_from_blob(metadata);
       uniforms[i].array_elements = blob_read_uint32(metadata);
       uniforms[i].name = ralloc_strdup(prog, blob_read_string (metadata));
       uniforms[i].storage = data + blob_read_uint32(metadata);
@@ -206,7 +263,6 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog)
       uniforms[i].num_compatible_subroutines = blob_read_uint32(metadata);
       uniforms[i].top_level_array_size = blob_read_uint32(metadata);
       uniforms[i].top_level_array_stride = blob_read_uint32(metadata);
-      uniforms[i].type = decode_type_from_blob(metadata);
 
       prog->UniformHash->put(i, uniforms[i].name);
 
@@ -326,10 +382,27 @@ read_hash_tables(struct blob_reader *metadata, struct gl_shader_program *prog)
 }
 
 static void
+write_shader_subroutine_index(struct blob *metadata, struct gl_shader *sh,
+                              struct gl_program_resource *res)
+{
+   assert(sh);
+
+   for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) {
+      if (strcmp(((gl_subroutine_function *)res->Data)->name,
+                 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_shader *sh;
+
    switch(res->Type) {
    case GL_PROGRAM_INPUT:
    case GL_PROGRAM_OUTPUT: {
@@ -353,9 +426,6 @@ write_program_resource_data(struct blob *metadata,
    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
    case GL_UNIFORM:
       for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
-         if (prog->UniformStorage[i].hidden)
-            break; /* No more user defined uniforms */
-
          if (strcmp(((gl_uniform_storage *)res->Data)->name,
                     prog->UniformStorage[i].name) == 0) {
             blob_write_uint32(metadata, i);
@@ -370,6 +440,18 @@ write_program_resource_data(struct blob *metadata,
        * TODO: We may want to this for shaders that use the xfb_* qualifiers.
        */
       break;
+   case GL_VERTEX_SUBROUTINE:
+      sh = prog->_LinkedShaders[MESA_SHADER_VERTEX];
+      write_shader_subroutine_index(metadata, sh, res);
+      break;
+   case GL_FRAGMENT_SUBROUTINE:
+      sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+      write_shader_subroutine_index(metadata, sh, res);
+      break;
+   case GL_GEOMETRY_SUBROUTINE:
+   case GL_COMPUTE_SUBROUTINE:
+   case GL_TESS_CONTROL_SUBROUTINE:
+   case GL_TESS_EVALUATION_SUBROUTINE:
    default:
       assert(!"Support for writting resource not yet implemneted.");
    }
@@ -380,6 +462,8 @@ read_program_resource_data(struct blob_reader *metadata,
                            struct gl_shader_program *prog,
                            struct gl_program_resource *res)
 {
+   struct gl_shader *sh;
+
    switch(res->Type) {
    case GL_PROGRAM_INPUT:
    case GL_PROGRAM_OUTPUT: {
@@ -406,6 +490,18 @@ read_program_resource_data(struct blob_reader *metadata,
    case GL_UNIFORM:
       res->Data = &prog->UniformStorage[blob_read_uint32(metadata)];
       break;
+   case GL_VERTEX_SUBROUTINE:
+      sh = prog->_LinkedShaders[MESA_SHADER_VERTEX];
+      res->Data = &sh->SubroutineFunctions[blob_read_uint32(metadata)];
+      break;
+   case GL_FRAGMENT_SUBROUTINE:
+      sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+      res->Data = &sh->SubroutineFunctions[blob_read_uint32(metadata)];
+      break;
+   case GL_GEOMETRY_SUBROUTINE:
+   case GL_COMPUTE_SUBROUTINE:
+   case GL_TESS_CONTROL_SUBROUTINE:
+   case GL_TESS_EVALUATION_SUBROUTINE:
    default:
       assert(!"Support for reading resource not yet implemneted.");
    }
@@ -595,11 +691,13 @@ shader_cache_write_program_metadata(struct gl_context *ctx,
 
    write_uniform_remap_table(metadata, prog);
 
-   write_program_resource_list(metadata, prog);
-
    write_shader_metadata(metadata, prog->_LinkedShaders[MESA_SHADER_VERTEX]);
    write_shader_metadata(metadata, prog->_LinkedShaders[MESA_SHADER_FRAGMENT]);
 
+   write_subroutines(metadata, prog);
+
+   write_program_resource_list(metadata, prog);
+
    for (unsigned i = 0; i < prog->NumShaders; i++) {
       cache_put_key(cache, prog->Shaders[i]->sha1);
       printf("marking shader: %s\n",
@@ -692,8 +790,6 @@ shader_cache_read_program_metadata(struct gl_context *ctx,
 
    read_uniform_remap_table(&metadata, prog);
 
-   read_program_resource_list(&metadata, prog);
-
    _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
    unsigned name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
    linked = ctx->Driver.NewShader(ctx, name, GL_VERTEX_SHADER);
@@ -718,6 +814,10 @@ shader_cache_read_program_metadata(struct gl_context *ctx,
    _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
                           linked);
 
+   read_subroutines(&metadata, prog);
+
+   read_program_resource_list(&metadata, prog);
+
    if (metadata.current != metadata.end || metadata.overrun) {
       printf ("Error reading shader metadata. FIXME At this point, we should "
               "discard the item from the cache and rebuild from source.\n");
-- 
2.5.5



More information about the mesa-dev mailing list