diff --git a/src/compiler/glsl/link_uniform_initializers.cpp b/src/compiler/glsl/link_uniform_initializers.cpp index be3715cc1a3..97796e721bf 100644 --- a/src/compiler/glsl/link_uniform_initializers.cpp +++ b/src/compiler/glsl/link_uniform_initializers.cpp @@ -357,5 +357,7 @@ link_set_uniform_initializers(struct gl_shader_program *prog, } } + 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 @@ -1365,6 +1365,9 @@ link_assign_uniform_storage(struct gl_context *ctx, 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; } diff --git a/src/compiler/glsl/serialize.cpp b/src/compiler/glsl/serialize.cpp index b5f68f907f5..57c91d90bb2 100644 --- a/src/compiler/glsl/serialize.cpp +++ b/src/compiler/glsl/serialize.cpp @@ -449,7 +449,10 @@ write_uniforms(struct blob *metadata, struct gl_shader_program *prog) 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); } } @@ -472,6 +475,9 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog) 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; @@ -512,14 +518,20 @@ read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog) 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 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 397b113dfbc..40f70b067e8 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2886,6 +2886,17 @@ struct gl_shader_program_data 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. */