[Mesa-dev] [PATCH 04/23] main, glsl: Add UniformDataDefaults which stores uniform defaults

Timothy Arceri tarceri at itsqueeze.com
Wed Nov 29 01:24:40 UTC 2017


From: Jordan Justen <jordan.l.justen at intel.com>

The ARB_get_program_binary extension requires that uniform values in a
program be restored to their initial value just after linking.

This patch saves off the initial values just after linking. When the
program is restored by glProgramBinary, we can use this to copy the
initial value of uniforms into UniformDataSlots.

V2 (Timothy Arceri):
 - Store UniformDataDefaults only when serializing GLSL as this
   is what we want for both disk cache and ARB_get_program_binary.
   This saves us having to come back later and reset the Uniforms
   on program binary restores.

Signed-off-by: Timothy Arceri <tarceri at itsqueeze.com>
Signed-off-by: Jordan Justen <jordan.l.justen at intel.com> (v1)
---
 src/compiler/glsl/link_uniform_initializers.cpp |  2 ++
 src/compiler/glsl/link_uniforms.cpp             |  3 +++
 src/compiler/glsl/serialize.cpp                 | 16 ++++++++++++++--
 src/mesa/main/mtypes.h                          | 11 +++++++++++
 4 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/compiler/glsl/link_uniform_initializers.cpp b/src/compiler/glsl/link_uniform_initializers.cpp
index f70d9100e12..2395f5cf695 100644
--- a/src/compiler/glsl/link_uniform_initializers.cpp
+++ b/src/compiler/glsl/link_uniform_initializers.cpp
@@ -347,12 +347,14 @@ link_set_uniform_initializers(struct gl_shader_program *prog,
                assert(!"Explicit binding not on a sampler, UBO or atomic.");
             }
          } else if (var->constant_initializer) {
             linker::set_uniform_initializer(mem_ctx, prog, var->name,
                                             var->type, var->constant_initializer,
                                             boolean_true);
          }
       }
    }
 
+   memcpy(prog->data->UniformDataDefaults, prog->data->UniformDataSlots,
+          sizeof(union gl_constant_value) * prog->data->NumUniformDataSlots);
    ralloc_free(mem_ctx);
 }
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index 46c746bc701..15813cb0aed 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -1358,20 +1358,23 @@ link_assign_uniform_storage(struct gl_context *ctx,
 
    unsigned int boolean_true = ctx->Const.UniformBooleanTrue;
 
    union gl_constant_value *data;
    if (prog->data->UniformStorage == NULL) {
       prog->data->UniformStorage = rzalloc_array(prog->data,
                                                  struct gl_uniform_storage,
                                                  prog->data->NumUniformStorage);
       data = rzalloc_array(prog->data->UniformStorage,
                            union gl_constant_value, num_data_slots);
+      prog->data->UniformDataDefaults =
+         rzalloc_array(prog->data->UniformStorage,
+                       union gl_constant_value, num_data_slots);
    } else {
       data = prog->data->UniformDataSlots;
    }
 
 #ifndef NDEBUG
    union gl_constant_value *data_end = &data[num_data_slots];
 #endif
 
    parcel_out_uniform_storage parcel(prog, prog->UniformHash,
                                      prog->data->UniformStorage, data,
diff --git a/src/compiler/glsl/serialize.cpp b/src/compiler/glsl/serialize.cpp
index 81781f32dfd..529b74e2002 100644
--- a/src/compiler/glsl/serialize.cpp
+++ b/src/compiler/glsl/serialize.cpp
@@ -442,21 +442,24 @@ write_uniforms(struct blob *metadata, struct gl_shader_program *prog)
     * uniforms with initialisers and also hidden uniforms that may be lowered
     * constant arrays. We could possibly just store the values we need but for
     * now we just store everything.
     */
    blob_write_uint32(metadata, prog->data->NumHiddenUniforms);
    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
       if (has_uniform_storage(prog, i)) {
          unsigned vec_size =
             prog->data->UniformStorage[i].type->component_slots() *
             MAX2(prog->data->UniformStorage[i].array_elements, 1);
-         blob_write_bytes(metadata, prog->data->UniformStorage[i].storage,
+         unsigned slot =
+            prog->data->UniformStorage[i].storage -
+            prog->data->UniformDataSlots;
+         blob_write_bytes(metadata, &prog->data->UniformDataDefaults[slot],
                           sizeof(union gl_constant_value) * vec_size);
       }
    }
 }
 
 static void
 read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog)
 {
    struct gl_uniform_storage *uniforms;
    union gl_constant_value *data;
@@ -465,20 +468,23 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog)
    prog->data->NumUniformStorage = blob_read_uint32(metadata);
    prog->data->NumUniformDataSlots = blob_read_uint32(metadata);
 
    uniforms = rzalloc_array(prog->data, struct gl_uniform_storage,
                             prog->data->NumUniformStorage);
    prog->data->UniformStorage = uniforms;
 
    data = rzalloc_array(uniforms, union gl_constant_value,
                         prog->data->NumUniformDataSlots);
    prog->data->UniformDataSlots = data;
+   prog->data->UniformDataDefaults =
+      rzalloc_array(uniforms, union gl_constant_value,
+                    prog->data->NumUniformDataSlots);
 
    prog->UniformHash = new string_to_uint_map;
 
    for (unsigned i = 0; i < prog->data->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].builtin = blob_read_uint32(metadata);
       uniforms[i].remap_location = blob_read_uint32(metadata);
       uniforms[i].block_index = blob_read_uint32(metadata);
@@ -505,28 +511,34 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog)
              sizeof(uniforms[i].opaque));
    }
 
    /* Restore uniform values. */
    prog->data->NumHiddenUniforms = blob_read_uint32(metadata);
    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
       if (has_uniform_storage(prog, i)) {
          unsigned vec_size =
             prog->data->UniformStorage[i].type->component_slots() *
             MAX2(prog->data->UniformStorage[i].array_elements, 1);
+         unsigned slot =
+            prog->data->UniformStorage[i].storage -
+            prog->data->UniformDataSlots;
          blob_copy_bytes(metadata,
-                         (uint8_t *) prog->data->UniformStorage[i].storage,
+                         (uint8_t *) &prog->data->UniformDataSlots[slot],
                          sizeof(union gl_constant_value) * vec_size);
 
         assert(vec_size + prog->data->UniformStorage[i].storage <=
                data +  prog->data->NumUniformDataSlots);
       }
    }
+
+   memcpy(prog->data->UniformDataDefaults, prog->data->UniformDataSlots,
+          sizeof(union gl_constant_value) * prog->data->NumUniformDataSlots);
 }
 
 enum uniform_remap_type
 {
    remap_type_inactive_explicit_location,
    remap_type_null_ptr,
    remap_type_uniform_offset
 };
 
 static void
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 96775824ea6..548cf944aa8 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2880,20 +2880,31 @@ struct gl_shader_program_data
    struct gl_uniform_block *UniformBlocks;
    struct gl_uniform_block *ShaderStorageBlocks;
 
    struct gl_active_atomic_buffer *AtomicBuffers;
    unsigned NumAtomicBuffers;
 
    /* Shader cache variables used during restore */
    unsigned NumUniformDataSlots;
    union gl_constant_value *UniformDataSlots;
 
+   /* Used to hold initial uniform values for program binary restores.
+    *
+    * From the ARB_get_program_binary spec:
+    *
+    *    "A successful call to ProgramBinary will reset all uniform
+    *    variables to their initial values. The initial value is either
+    *    the value of the variable's initializer as specified in the
+    *    original shader source, or 0 if no initializer was present.
+    */
+   union gl_constant_value *UniformDataDefaults;
+
    GLboolean Validated;
 
    /** List of all active resources after linking. */
    struct gl_program_resource *ProgramResourceList;
    unsigned NumProgramResourceList;
 
    enum gl_link_status LinkStatus;   /**< GL_LINK_STATUS */
    GLchar *InfoLog;
 
    unsigned Version;       /**< GLSL version used for linking */
-- 
2.14.3



More information about the mesa-dev mailing list