}
}
+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_buffer_block(struct blob *metadata, struct gl_uniform_block *b)
+{
+ blob_write_string(metadata, b->Name);
+ blob_write_uint32(metadata, b->NumUniforms);
+ blob_write_uint32(metadata, b->Binding);
+ blob_write_uint32(metadata, b->UniformBufferSize);
+ blob_write_uint32(metadata, b->stageref);
+
+ for (unsigned j = 0; j < b->NumUniforms; j++) {
+ blob_write_string(metadata, b->Uniforms[j].Name);
+ blob_write_string(metadata, b->Uniforms[j].IndexName);
+ encode_type_to_blob(metadata, b->Uniforms[j].Type);
+ blob_write_uint32(metadata, b->Uniforms[j].Offset);
+ }
+}
+
+static void
+write_buffer_blocks(struct blob *metadata, struct gl_shader_program *prog)
+{
+ blob_write_uint32(metadata, prog->data->NumUniformBlocks);
+ blob_write_uint32(metadata, prog->data->NumShaderStorageBlocks);
+
+ for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
+ write_buffer_block(metadata, &prog->data->UniformBlocks[i]);
+ }
+
+ for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
+ write_buffer_block(metadata, &prog->data->ShaderStorageBlocks[i]);
+ }
+
+ 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->info.num_ubos);
+ blob_write_uint32(metadata, glprog->info.num_ssbos);
+
+ for (unsigned j = 0; j < glprog->info.num_ubos; j++) {
+ uint32_t offset =
+ glprog->sh.UniformBlocks[j] - prog->data->UniformBlocks;
+ blob_write_uint32(metadata, offset);
+ }
+
+ for (unsigned j = 0; j < glprog->info.num_ssbos; j++) {
+ uint32_t offset = glprog->sh.ShaderStorageBlocks[j] -
+ prog->data->ShaderStorageBlocks;
+ blob_write_uint32(metadata, offset);
+ }
+ }
+}
+
+static void
+read_buffer_block(struct blob_reader *metadata, struct gl_uniform_block *b,
+ struct gl_shader_program *prog)
+{
+ b->Name = ralloc_strdup(prog->data, blob_read_string (metadata));
+ b->NumUniforms = blob_read_uint32(metadata);
+ b->Binding = blob_read_uint32(metadata);
+ b->UniformBufferSize = blob_read_uint32(metadata);
+ b->stageref = blob_read_uint32(metadata);
+
+ b->Uniforms =
+ rzalloc_array(prog->data, struct gl_uniform_buffer_variable,
+ b->NumUniforms);
+ for (unsigned j = 0; j < b->NumUniforms; j++) {
+ b->Uniforms[j].Name = ralloc_strdup(prog->data,
+ blob_read_string (metadata));
+
+ char *index_name = blob_read_string(metadata);
+ if (strcmp(b->Uniforms[j].Name, index_name) == 0) {
+ b->Uniforms[j].IndexName = b->Uniforms[j].Name;
+ } else {
+ b->Uniforms[j].IndexName = ralloc_strdup(prog->data, index_name);
+ }
+
+ b->Uniforms[j].Type = decode_type_from_blob(metadata);
+ b->Uniforms[j].Offset = blob_read_uint32(metadata);
+ }
+}
+
+static void
+read_buffer_blocks(struct blob_reader *metadata,
+ struct gl_shader_program *prog)
+{
+ prog->data->NumUniformBlocks = blob_read_uint32(metadata);
+ prog->data->NumShaderStorageBlocks = blob_read_uint32(metadata);
+
+ prog->data->UniformBlocks =
+ rzalloc_array(prog->data, struct gl_uniform_block,
+ prog->data->NumUniformBlocks);
+
+ prog->data->ShaderStorageBlocks =
+ rzalloc_array(prog->data, struct gl_uniform_block,
+ prog->data->NumShaderStorageBlocks);
+
+ for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
+ read_buffer_block(metadata, &prog->data->UniformBlocks[i], prog);
+ }
+
+ for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
+ read_buffer_block(metadata, &prog->data->ShaderStorageBlocks[i], 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;
+
+ glprog->info.num_ubos = blob_read_uint32(metadata);
+ glprog->info.num_ssbos = blob_read_uint32(metadata);
+
+ glprog->sh.UniformBlocks =
+ rzalloc_array(glprog, gl_uniform_block *, glprog->info.num_ubos);
+ glprog->sh.ShaderStorageBlocks =
+ rzalloc_array(glprog, gl_uniform_block *, glprog->info.num_ssbos);
+
+ for (unsigned j = 0; j < glprog->info.num_ubos; j++) {
+ uint32_t offset = blob_read_uint32(metadata);
+ glprog->sh.UniformBlocks[j] = prog->data->UniformBlocks + offset;
+ }
+
+ for (unsigned j = 0; j < glprog->info.num_ssbos; j++) {
+ uint32_t offset = blob_read_uint32(metadata);
+ glprog->sh.ShaderStorageBlocks[j] =
+ prog->data->ShaderStorageBlocks + offset;
+ }
+ }
+}
+
+static void
+write_atomic_buffers(struct blob *metadata, struct gl_shader_program *prog)
+{
+ blob_write_uint32(metadata, prog->data->NumAtomicBuffers);
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (prog->_LinkedShaders[i]) {
+ struct gl_program *glprog = prog->_LinkedShaders[i]->Program;
+ blob_write_uint32(metadata, glprog->info.num_abos);
+ }
+ }
+
+ for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {
+ blob_write_uint32(metadata, prog->data->AtomicBuffers[i].Binding);
+ blob_write_uint32(metadata, prog->data->AtomicBuffers[i].MinimumSize);
+ blob_write_uint32(metadata, prog->data->AtomicBuffers[i].NumUniforms);
+
+ blob_write_bytes(metadata, prog->data->AtomicBuffers[i].StageReferences,
+ sizeof(prog->data->AtomicBuffers[i].StageReferences));
+
+ for (unsigned j = 0; j < prog->data->AtomicBuffers[i].NumUniforms; j++) {
+ blob_write_uint32(metadata, prog->data->AtomicBuffers[i].Uniforms[j]);
+ }
+ }
+}
+
+static void
+read_atomic_buffers(struct blob_reader *metadata,
+ struct gl_shader_program *prog)
+{
+ prog->data->NumAtomicBuffers = blob_read_uint32(metadata);
+ prog->data->AtomicBuffers =
+ rzalloc_array(prog, gl_active_atomic_buffer,
+ prog->data->NumAtomicBuffers);
+
+ struct gl_active_atomic_buffer **stage_buff_list[MESA_SHADER_STAGES];
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (prog->_LinkedShaders[i]) {
+ struct gl_program *glprog = prog->_LinkedShaders[i]->Program;
+
+ glprog->info.num_abos = blob_read_uint32(metadata);
+ glprog->sh.AtomicBuffers =
+ rzalloc_array(glprog, gl_active_atomic_buffer *,
+ glprog->info.num_abos);
+ stage_buff_list[i] = glprog->sh.AtomicBuffers;
+ }
+ }
+
+ for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {
+ prog->data->AtomicBuffers[i].Binding = blob_read_uint32(metadata);
+ prog->data->AtomicBuffers[i].MinimumSize = blob_read_uint32(metadata);
+ prog->data->AtomicBuffers[i].NumUniforms = blob_read_uint32(metadata);
+
+ blob_copy_bytes(metadata,
+ (uint8_t *) &prog->data->AtomicBuffers[i].StageReferences,
+ sizeof(prog->data->AtomicBuffers[i].StageReferences));
+
+ prog->data->AtomicBuffers[i].Uniforms = rzalloc_array(prog, unsigned,
+ prog->data->AtomicBuffers[i].NumUniforms);
+
+ for (unsigned j = 0; j < prog->data->AtomicBuffers[i].NumUniforms; j++) {
+ prog->data->AtomicBuffers[i].Uniforms[j] = blob_read_uint32(metadata);
+ }
+
+ for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
+ if (prog->data->AtomicBuffers[i].StageReferences[j]) {
+ *stage_buff_list[j] = &prog->data->AtomicBuffers[i];
+ stage_buff_list[j]++;
+ }
+ }
+ }
+}
+
+static void
+write_xfb(struct blob *metadata, struct gl_shader_program *shProg)
+{
+ struct gl_program *prog = shProg->last_vert_prog;
+
+ if (!prog) {
+ blob_write_uint32(metadata, ~0u);
+ return;
+ }
+
+ struct gl_transform_feedback_info *ltf = prog->sh.LinkedTransformFeedback;
+
+ blob_write_uint32(metadata, prog->info.stage);
+
+ blob_write_uint32(metadata, ltf->NumOutputs);
+ blob_write_uint32(metadata, ltf->ActiveBuffers);
+ blob_write_uint32(metadata, ltf->NumVarying);
+
+ blob_write_bytes(metadata, ltf->Outputs,
+ sizeof(struct gl_transform_feedback_output) *
+ ltf->NumOutputs);
+
+ for (int i = 0; i < ltf->NumVarying; i++) {
+ blob_write_string(metadata, ltf->Varyings[i].Name);
+ blob_write_uint32(metadata, ltf->Varyings[i].Type);
+ blob_write_uint32(metadata, ltf->Varyings[i].BufferIndex);
+ blob_write_uint32(metadata, ltf->Varyings[i].Size);
+ blob_write_uint32(metadata, ltf->Varyings[i].Offset);
+ }
+
+ blob_write_bytes(metadata, ltf->Buffers,
+ sizeof(struct gl_transform_feedback_buffer) *
+ MAX_FEEDBACK_BUFFERS);
+}
+
+static void
+read_xfb(struct blob_reader *metadata, struct gl_shader_program *shProg)
+{
+ unsigned xfb_stage = blob_read_uint32(metadata);
+
+ if (xfb_stage == ~0u)
+ return;
+
+ struct gl_program *prog = shProg->_LinkedShaders[xfb_stage]->Program;
+ struct gl_transform_feedback_info *ltf =
+ rzalloc(prog, struct gl_transform_feedback_info);
+
+ prog->sh.LinkedTransformFeedback = ltf;
+ shProg->last_vert_prog = prog;
+
+ ltf->NumOutputs = blob_read_uint32(metadata);
+ ltf->ActiveBuffers = blob_read_uint32(metadata);
+ ltf->NumVarying = blob_read_uint32(metadata);
+
+ ltf->Outputs = rzalloc_array(prog, struct gl_transform_feedback_output,
+ ltf->NumOutputs);
+
+ blob_copy_bytes(metadata, (uint8_t *) ltf->Outputs,
+ sizeof(struct gl_transform_feedback_output) *
+ ltf->NumOutputs);
+
+ ltf->Varyings = rzalloc_array(prog,
+ struct gl_transform_feedback_varying_info,
+ ltf->NumVarying);
+
+ for (int i = 0; i < ltf->NumVarying; i++) {
+ ltf->Varyings[i].Name = ralloc_strdup(prog, blob_read_string(metadata));
+ ltf->Varyings[i].Type = blob_read_uint32(metadata);
+ ltf->Varyings[i].BufferIndex = blob_read_uint32(metadata);
+ ltf->Varyings[i].Size = blob_read_uint32(metadata);
+ ltf->Varyings[i].Offset = blob_read_uint32(metadata);
+ }
+
+ blob_copy_bytes(metadata, (uint8_t *) ltf->Buffers,
+ sizeof(struct gl_transform_feedback_buffer) *
+ MAX_FEEDBACK_BUFFERS);
+}
+
static void
write_uniforms(struct blob *metadata, struct gl_shader_program *prog)
{
blob_write_string(metadata, prog->data->UniformStorage[i].name);
blob_write_uint32(metadata, prog->data->UniformStorage[i].storage -
prog->data->UniformDataSlots);
+ blob_write_uint32(metadata, prog->data->UniformStorage[i].builtin);
blob_write_uint32(metadata, prog->data->UniformStorage[i].remap_location);
blob_write_uint32(metadata, prog->data->UniformStorage[i].block_index);
blob_write_uint32(metadata, prog->data->UniformStorage[i].atomic_buffer_index);
blob_write_uint32(metadata, prog->data->UniformStorage[i].offset);
blob_write_uint32(metadata, prog->data->UniformStorage[i].array_stride);
+ blob_write_uint32(metadata, prog->data->UniformStorage[i].hidden);
+ blob_write_uint32(metadata, prog->data->UniformStorage[i].is_shader_storage);
blob_write_uint32(metadata, prog->data->UniformStorage[i].matrix_stride);
blob_write_uint32(metadata, prog->data->UniformStorage[i].row_major);
blob_write_uint32(metadata,
blob_write_bytes(metadata, prog->data->UniformStorage[i].opaque,
sizeof(prog->data->UniformStorage[i].opaque));
}
+
+ /* Here we cache all uniform values. We do this to retain values for
+ * 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 (!prog->data->UniformStorage[i].builtin &&
+ !prog->data->UniformStorage[i].is_shader_storage &&
+ prog->data->UniformStorage[i].block_index == -1) {
+ unsigned vec_size =
+ values_for_type(prog->data->UniformStorage[i].type) *
+ MAX2(prog->data->UniformStorage[i].array_elements, 1);
+ blob_write_bytes(metadata, prog->data->UniformStorage[i].storage,
+ sizeof(union gl_constant_value) * vec_size);
+ }
+ }
}
static void
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);
+ uniforms[i].builtin = blob_read_uint32(metadata);
uniforms[i].remap_location = blob_read_uint32(metadata);
uniforms[i].block_index = blob_read_uint32(metadata);
uniforms[i].atomic_buffer_index = blob_read_uint32(metadata);
uniforms[i].offset = blob_read_uint32(metadata);
uniforms[i].array_stride = blob_read_uint32(metadata);
+ uniforms[i].hidden = blob_read_uint32(metadata);
+ uniforms[i].is_shader_storage = blob_read_uint32(metadata);
uniforms[i].matrix_stride = blob_read_uint32(metadata);
uniforms[i].row_major = blob_read_uint32(metadata);
uniforms[i].num_compatible_subroutines = blob_read_uint32(metadata);
blob_read_bytes(metadata, sizeof(uniforms[i].opaque)),
sizeof(uniforms[i].opaque));
}
+
+ /* Restore uniform values. */
+ prog->data->NumHiddenUniforms = blob_read_uint32(metadata);
+ for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
+ if (!prog->data->UniformStorage[i].builtin &&
+ !prog->data->UniformStorage[i].is_shader_storage &&
+ prog->data->UniformStorage[i].block_index == -1) {
+ unsigned vec_size =
+ values_for_type(prog->data->UniformStorage[i].type) *
+ MAX2(prog->data->UniformStorage[i].array_elements, 1);
+ blob_copy_bytes(metadata,
+ (uint8_t *) prog->data->UniformStorage[i].storage,
+ sizeof(union gl_constant_value) * vec_size);
+
+ assert(vec_size + prog->data->UniformStorage[i].storage <=
+ data + prog->data->NumUniformDataSlots);
+ }
+ }
}
enum uniform_remap_type
}
static void
-write_uniform_remap_table(struct blob *metadata,
- struct gl_shader_program *prog)
+write_uniform_remap_tables(struct blob *metadata,
+ struct gl_shader_program *prog)
{
blob_write_uint32(metadata, prog->NumUniformRemapTable);
write_uniform_remap_table_entry(metadata, prog->data->UniformStorage,
prog->UniformRemapTable[i]);
}
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+ if (sh) {
+ struct gl_program *glprog = sh->Program;
+ blob_write_uint32(metadata, glprog->sh.NumSubroutineUniformRemapTable);
+
+ for (unsigned j = 0; j < glprog->sh.NumSubroutineUniformRemapTable; j++) {
+ write_uniform_remap_table_entry(metadata,
+ prog->data->UniformStorage,
+ glprog->sh.SubroutineUniformRemapTable[j]);
+ }
+ }
+ }
}
static void
}
static void
-read_uniform_remap_table(struct blob_reader *metadata,
- struct gl_shader_program *prog)
+read_uniform_remap_tables(struct blob_reader *metadata,
+ struct gl_shader_program *prog)
{
prog->NumUniformRemapTable = blob_read_uint32(metadata);
read_uniform_remap_table_entry(metadata, prog->data->UniformStorage,
&prog->UniformRemapTable[i], type);
}
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+ if (sh) {
+ struct gl_program *glprog = sh->Program;
+ glprog->sh.NumSubroutineUniformRemapTable = blob_read_uint32(metadata);
+
+ glprog->sh.SubroutineUniformRemapTable =
+ rzalloc_array(glprog, struct gl_uniform_storage *,
+ glprog->sh.NumSubroutineUniformRemapTable);
+
+ for (unsigned j = 0; j < glprog->sh.NumSubroutineUniformRemapTable; j++) {
+ enum uniform_remap_type type =
+ (enum uniform_remap_type) blob_read_uint32(metadata);
+
+ read_uniform_remap_table_entry(metadata,
+ prog->data->UniformStorage,
+ &glprog->sh.SubroutineUniformRemapTable[j],
+ type);
+ }
+ }
+ }
}
struct whte_closure
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: {
blob_write_string(metadata, var->name);
break;
}
+ case GL_UNIFORM_BLOCK:
+ for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
+ if (strcmp(((gl_uniform_block *)res->Data)->Name,
+ prog->data->UniformBlocks[i].Name) == 0) {
+ blob_write_uint32(metadata, i);
+ break;
+ }
+ }
+ break;
+ case GL_SHADER_STORAGE_BLOCK:
+ for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
+ if (strcmp(((gl_uniform_block *)res->Data)->Name,
+ prog->data->ShaderStorageBlocks[i].Name) == 0) {
+ blob_write_uint32(metadata, i);
+ break;
+ }
+ }
+ break;
case GL_BUFFER_VARIABLE:
case GL_VERTEX_SUBROUTINE_UNIFORM:
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
}
}
break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {
+ if (((gl_active_atomic_buffer *)res->Data)->Binding ==
+ prog->data->AtomicBuffers[i].Binding) {
+ blob_write_uint32(metadata, i);
+ break;
+ }
+ }
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
+ if (((gl_transform_feedback_buffer *)res->Data)->Binding ==
+ prog->last_vert_prog->sh.LinkedTransformFeedback->Buffers[i].Binding) {
+ blob_write_uint32(metadata, i);
+ break;
+ }
+ }
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ for (int i = 0; i < prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying; i++) {
+ if (strcmp(((gl_transform_feedback_varying_info *)res->Data)->Name,
+ prog->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].Name) == 0) {
+ blob_write_uint32(metadata, i);
+ break;
+ }
+ }
+ 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.");
}
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: {
res->Data = var;
break;
}
+ case GL_UNIFORM_BLOCK:
+ res->Data = &prog->data->UniformBlocks[blob_read_uint32(metadata)];
+ break;
+ case GL_SHADER_STORAGE_BLOCK:
+ res->Data = &prog->data->ShaderStorageBlocks[blob_read_uint32(metadata)];
+ break;
case GL_BUFFER_VARIABLE:
case GL_VERTEX_SUBROUTINE_UNIFORM:
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
case GL_UNIFORM:
res->Data = &prog->data->UniformStorage[blob_read_uint32(metadata)];
break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ res->Data = &prog->data->AtomicBuffers[blob_read_uint32(metadata)];
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ res->Data = &prog->last_vert_prog->
+ sh.LinkedTransformFeedback->Buffers[blob_read_uint32(metadata)];
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ 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.");
}
uint32_t i = 0;
uint32_t num_parameters = blob_read_uint32(metadata);
+ _mesa_reserve_parameter_storage(params, num_parameters);
while (i < num_parameters) {
gl_register_file type = (gl_register_file) blob_read_uint32(metadata);
const char *name = blob_read_string(metadata);
sizeof(glprog->sh.SamplerTargets));
blob_write_uint32(metadata, glprog->ShadowSamplers);
+ blob_write_bytes(metadata, glprog->sh.ImageAccess,
+ sizeof(glprog->sh.ImageAccess));
+ blob_write_bytes(metadata, glprog->sh.ImageUnits,
+ sizeof(glprog->sh.ImageUnits));
+
write_shader_parameters(metadata, glprog->Parameters);
}
sizeof(glprog->sh.SamplerTargets));
glprog->ShadowSamplers = blob_read_uint32(metadata);
+ blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageAccess,
+ sizeof(glprog->sh.ImageAccess));
+ blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageUnits,
+ sizeof(glprog->sh.ImageUnits));
+
glprog->Parameters = _mesa_new_parameter_list();
read_shader_parameters(metadata, glprog->Parameters);
}
if (*prog->data->sha1 == 0)
return;
- struct blob *metadata = blob_create(NULL);
+ struct blob *metadata = blob_create();
write_uniforms(metadata, prog);
}
}
- write_uniform_remap_table(metadata, prog);
+ write_xfb(metadata, prog);
+
+ write_uniform_remap_tables(metadata, prog);
+
+ write_atomic_buffers(metadata, prog);
+
+ write_buffer_blocks(metadata, prog);
+
+ write_subroutines(metadata, prog);
write_program_resource_list(metadata, prog);
for (unsigned i = 0; i < prog->NumShaders; i++) {
disk_cache_put_key(cache, prog->Shaders[i]->sha1);
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
- fprintf(stderr, "marking shader: %s\n",
- _mesa_sha1_format(sha1_buf, prog->Shaders[i]->sha1));
+ _mesa_sha1_format(sha1_buf, prog->Shaders[i]->sha1);
+ fprintf(stderr, "marking shader: %s\n", sha1_buf);
}
}
disk_cache_put(cache, prog->data->sha1, metadata->data, metadata->size);
- ralloc_free(metadata);
+ free(metadata);
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
- fprintf(stderr, "putting program metadata in cache: %s\n",
- _mesa_sha1_format(sha1_buf, prog->data->sha1));
+ _mesa_sha1_format(sha1_buf, prog->data->sha1);
+ fprintf(stderr, "putting program metadata in cache: %s\n", sha1_buf);
}
}
return false;
struct disk_cache *cache = ctx->Cache;
- if (!cache)
+ if (!cache || prog->data->cache_fallback)
return false;
/* Include bindings when creating sha1. These bindings change the resulting
ralloc_asprintf_append(&buf, "sso: %s\n",
prog->SeparateShader ? "T" : "F");
+ /* A shader might end up producing different output depending on the glsl
+ * version supported by the compiler. For example a different path might be
+ * taken by the preprocessor, so add the version to the hash input.
+ */
+ ralloc_asprintf_append(&buf, "api: %d glsl: %d fglsl: %d\n",
+ ctx->API, ctx->Const.GLSLVersion,
+ ctx->Const.ForceGLSLVersion);
+
+ /* DRI config options may also change the output from the compiler so
+ * include them as an input to sha1 creation.
+ */
char sha1buf[41];
+ _mesa_sha1_format(sha1buf, ctx->Const.dri_config_options_sha1);
+ ralloc_strcat(&buf, sha1buf);
+
for (unsigned i = 0; i < prog->NumShaders; i++) {
struct gl_shader *sh = prog->Shaders[i];
+ _mesa_sha1_format(sha1buf, sh->sha1);
ralloc_asprintf_append(&buf, "%s: %s\n",
- _mesa_shader_stage_to_abbrev(sh->Stage),
- _mesa_sha1_format(sha1buf, sh->sha1));
+ _mesa_shader_stage_to_abbrev(sh->Stage), sha1buf);
}
- _mesa_sha1_compute(buf, strlen(buf), prog->data->sha1);
+ disk_cache_compute_key(cache, buf, strlen(buf), prog->data->sha1);
ralloc_free(buf);
size_t size;
}
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
+ _mesa_sha1_format(sha1buf, prog->data->sha1);
fprintf(stderr, "loading shader program meta data from cache: %s\n",
- _mesa_sha1_format(sha1buf, prog->data->sha1));
+ sha1buf);
}
struct blob_reader metadata;
&metadata);
}
- read_uniform_remap_table(&metadata, prog);
+ read_xfb(&metadata, prog);
+
+ read_uniform_remap_tables(&metadata, prog);
+
+ read_atomic_buffers(&metadata, prog);
+
+ read_buffer_blocks(&metadata, prog);
+
+ read_subroutines(&metadata, prog);
read_program_resource_list(&metadata, prog);