diff options
author | Timothy Arceri <[email protected]> | 2016-04-03 12:44:33 +1000 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2016-04-06 09:56:24 +1000 |
commit | f1293b2f9bc3a45c71941931edb5148d7b5f5a27 (patch) | |
tree | ba998230fc2b04bf8d130b6d7704650dbba09e83 /src/compiler/glsl | |
parent | 506b561ba7e3df2a7759dded684fae84bf459f65 (diff) |
glsl: fully split apart buffer block arrays
With this change we create the UBO and SSBO arrays separately from the
beginning rather than putting them into a combined array and splitting
it apart later.
A bug is with UBO and SSBO stage reference querying is also fixed as
we now use the block index to lookup the references in the separate arrays
not the combined buffer block array.
Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]>
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r-- | src/compiler/glsl/link_uniform_blocks.cpp | 204 | ||||
-rw-r--r-- | src/compiler/glsl/link_uniform_initializers.cpp | 17 | ||||
-rw-r--r-- | src/compiler/glsl/link_uniforms.cpp | 32 | ||||
-rw-r--r-- | src/compiler/glsl/linker.cpp | 225 | ||||
-rw-r--r-- | src/compiler/glsl/linker.h | 7 | ||||
-rw-r--r-- | src/compiler/glsl/standalone_scaffolding.cpp | 4 |
6 files changed, 251 insertions, 238 deletions
diff --git a/src/compiler/glsl/link_uniform_blocks.cpp b/src/compiler/glsl/link_uniform_blocks.cpp index c8fa181a15d..586363d4f12 100644 --- a/src/compiler/glsl/link_uniform_blocks.cpp +++ b/src/compiler/glsl/link_uniform_blocks.cpp @@ -291,13 +291,105 @@ resize_block_array(const glsl_type *type, } } -unsigned +static void +create_buffer_blocks(void *mem_ctx, struct gl_context *ctx, + struct gl_shader_program *prog, + struct gl_uniform_block **out_blks, unsigned num_blocks, + struct hash_table *block_hash, unsigned num_variables, + bool create_ubo_blocks) +{ + if (num_blocks == 0) { + assert(num_variables == 0); + return; + } + + assert(num_variables != 0); + + /* Allocate storage to hold all of the information related to uniform + * blocks that can be queried through the API. + */ + struct gl_uniform_block *blocks = ralloc_array(mem_ctx, gl_uniform_block, num_blocks); + gl_uniform_buffer_variable *variables = + ralloc_array(blocks, gl_uniform_buffer_variable, num_variables); + + /* Add each variable from each uniform block to the API tracking + * structures. + */ + ubo_visitor parcel(blocks, variables, num_variables); + + STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140) + == unsigned(ubo_packing_std140)); + STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED) + == unsigned(ubo_packing_shared)); + STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED) + == unsigned(ubo_packing_packed)); + STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD430) + == unsigned(ubo_packing_std430)); + + unsigned i = 0; + struct hash_entry *entry; + hash_table_foreach (block_hash, entry) { + const struct link_uniform_block_active *const b = + (const struct link_uniform_block_active *) entry->data; + const glsl_type *block_type = b->type; + + if ((create_ubo_blocks && !b->is_shader_storage) || + (!create_ubo_blocks && b->is_shader_storage)) { + + if (b->array != NULL) { + unsigned binding_offset = 0; + char *name = ralloc_strdup(NULL, + block_type->without_array()->name); + size_t name_length = strlen(name); + + assert(b->has_instance_name); + process_block_array(b->array, &name, name_length, blocks, &parcel, + variables, b, &i, &binding_offset, ctx, prog); + ralloc_free(name); + } else { + blocks[i].Name = ralloc_strdup(blocks, block_type->name); + blocks[i].Uniforms = &variables[parcel.index]; + blocks[i].Binding = (b->has_binding) ? b->binding : 0; + blocks[i].UniformBufferSize = 0; + blocks[i]._Packing = + gl_uniform_block_packing(block_type->interface_packing); + + parcel.process(block_type, + b->has_instance_name ? block_type->name : ""); + + blocks[i].UniformBufferSize = parcel.buffer_size; + + /* Check SSBO size is lower than maximum supported size for SSBO + */ + if (b->is_shader_storage && + parcel.buffer_size > ctx->Const.MaxShaderStorageBlockSize) { + linker_error(prog, "shader storage block `%s' has size %d, " + "which is larger than than the maximum allowed (%d)", + block_type->name, parcel.buffer_size, + ctx->Const.MaxShaderStorageBlockSize); + } + blocks[i].NumUniforms = (unsigned)(ptrdiff_t) + (&variables[parcel.index] - blocks[i].Uniforms); + i++; + } + } + } + + *out_blks = blocks; + + assert(parcel.index == num_variables); +} + +void link_uniform_blocks(void *mem_ctx, struct gl_context *ctx, struct gl_shader_program *prog, struct gl_shader **shader_list, unsigned num_shaders, - struct gl_uniform_block **blocks_ret) + struct gl_uniform_block **ubo_blocks, + unsigned *num_ubo_blocks, + struct gl_uniform_block **ssbo_blocks, + unsigned *num_ssbo_blocks) { /* This hash table will track all of the uniform blocks that have been * encountered. Since blocks with the same block-name must be the same, @@ -310,7 +402,7 @@ link_uniform_blocks(void *mem_ctx, if (block_hash == NULL) { _mesa_error_no_memory(__func__); linker_error(prog, "out of memory\n"); - return 0; + return; } /* Determine which uniform blocks are active. @@ -323,8 +415,8 @@ link_uniform_blocks(void *mem_ctx, /* Count the number of active uniform blocks. Count the total number of * active slots in those uniform blocks. */ - unsigned num_blocks = 0; - unsigned num_variables = 0; + unsigned num_ubo_variables = 0; + unsigned num_ssbo_variables = 0; count_block_size block_size; struct hash_entry *entry; @@ -346,97 +438,31 @@ link_uniform_blocks(void *mem_ctx, if (b->array != NULL) { unsigned aoa_size = b->type->arrays_of_arrays_size(); - num_blocks += aoa_size; - num_variables += aoa_size * block_size.num_active_uniforms; - } else { - num_blocks++; - num_variables += block_size.num_active_uniforms; - } - - } - - if (num_blocks == 0) { - assert(num_variables == 0); - _mesa_hash_table_destroy(block_hash, NULL); - return 0; - } - - assert(num_variables != 0); - - /* Allocate storage to hold all of the informatation related to uniform - * blocks that can be queried through the API. - */ - gl_uniform_block *blocks = - ralloc_array(mem_ctx, gl_uniform_block, num_blocks); - gl_uniform_buffer_variable *variables = - ralloc_array(blocks, gl_uniform_buffer_variable, num_variables); - - /* Add each variable from each uniform block to the API tracking - * structures. - */ - unsigned i = 0; - ubo_visitor parcel(blocks, variables, num_variables); - - STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140) - == unsigned(ubo_packing_std140)); - STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED) - == unsigned(ubo_packing_shared)); - STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED) - == unsigned(ubo_packing_packed)); - STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD430) - == unsigned(ubo_packing_std430)); - - hash_table_foreach (block_hash, entry) { - const struct link_uniform_block_active *const b = - (const struct link_uniform_block_active *) entry->data; - const glsl_type *block_type = b->type; - - if (b->array != NULL) { - unsigned binding_offset = 0; - char *name = ralloc_strdup(NULL, block_type->without_array()->name); - size_t name_length = strlen(name); - - assert(b->has_instance_name); - process_block_array(b->array, &name, name_length, blocks, &parcel, - variables, b, &i, &binding_offset, ctx, prog); - ralloc_free(name); + if (b->is_shader_storage) { + *num_ssbo_blocks += aoa_size; + num_ssbo_variables += aoa_size * block_size.num_active_uniforms; + } else { + *num_ubo_blocks += aoa_size; + num_ubo_variables += aoa_size * block_size.num_active_uniforms; + } } else { - blocks[i].Name = ralloc_strdup(blocks, block_type->name); - blocks[i].Uniforms = &variables[parcel.index]; - blocks[i].Binding = (b->has_binding) ? b->binding : 0; - blocks[i].UniformBufferSize = 0; - blocks[i]._Packing = - gl_uniform_block_packing(block_type->interface_packing); - - parcel.process(block_type, - b->has_instance_name ? block_type->name : ""); - - blocks[i].UniformBufferSize = parcel.buffer_size; - - /* Check SSBO size is lower than maximum supported size for SSBO */ - if (b->is_shader_storage && - parcel.buffer_size > ctx->Const.MaxShaderStorageBlockSize) { - linker_error(prog, "shader storage block `%s' has size %d, " - "which is larger than than the maximum allowed (%d)", - block_type->name, - parcel.buffer_size, - ctx->Const.MaxShaderStorageBlockSize); + if (b->is_shader_storage) { + (*num_ssbo_blocks)++; + num_ssbo_variables += block_size.num_active_uniforms; + } else { + (*num_ubo_blocks)++; + num_ubo_variables += block_size.num_active_uniforms; } - blocks[i].NumUniforms = - (unsigned)(ptrdiff_t)(&variables[parcel.index] - blocks[i].Uniforms); - - blocks[i].IsShaderStorage = b->is_shader_storage; - - i++; } + } - assert(parcel.index == num_variables); + create_buffer_blocks(mem_ctx, ctx, prog, ubo_blocks, *num_ubo_blocks, + block_hash, num_ubo_variables, true); + create_buffer_blocks(mem_ctx, ctx, prog, ssbo_blocks, *num_ssbo_blocks, + block_hash, num_ssbo_variables, false); _mesa_hash_table_destroy(block_hash, NULL); - - *blocks_ret = blocks; - return num_blocks; } bool diff --git a/src/compiler/glsl/link_uniform_initializers.cpp b/src/compiler/glsl/link_uniform_initializers.cpp index e5edf2e72e4..c6346d573ab 100644 --- a/src/compiler/glsl/link_uniform_initializers.cpp +++ b/src/compiler/glsl/link_uniform_initializers.cpp @@ -154,11 +154,17 @@ set_opaque_binding(void *mem_ctx, gl_shader_program *prog, } void -set_block_binding(gl_shader_program *prog, const char *block_name, int binding) +set_block_binding(gl_shader_program *prog, const char *block_name, + unsigned mode, int binding) { - for (unsigned i = 0; i < prog->NumBufferInterfaceBlocks; i++) { - if (!strcmp(prog->BufferInterfaceBlocks[i].Name, block_name)) { - prog->BufferInterfaceBlocks[i].Binding = binding; + unsigned num_blocks = mode == ir_var_uniform ? prog->NumUniformBlocks : + prog->NumShaderStorageBlocks; + struct gl_uniform_block *blks = mode == ir_var_uniform ? + prog->UniformBlocks : prog->ShaderStorageBlocks; + + for (unsigned i = 0; i < num_blocks; i++) { + if (!strcmp(blks[i].Name, block_name)) { + blks[i].Binding = binding; return; } } @@ -308,11 +314,12 @@ link_set_uniform_initializers(struct gl_shader_program *prog, * each subsequent element takes the next consecutive * uniform block binding point." */ - linker::set_block_binding(prog, name, + linker::set_block_binding(prog, name, var->data.mode, var->data.binding + i); } } else { linker::set_block_binding(prog, iface_type->name, + var->data.mode, var->data.binding); } } else if (type->contains_atomic()) { diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp index 7d8a4b4fb79..8db60a36f16 100644 --- a/src/compiler/glsl/link_uniforms.cpp +++ b/src/compiler/glsl/link_uniforms.cpp @@ -462,7 +462,7 @@ public: buffer_block_index = -1; if (var->is_in_buffer_block()) { - struct gl_uniform_block **blks = var->is_in_shader_storage_block() ? + struct gl_uniform_block *blks = var->is_in_shader_storage_block() ? prog->ShaderStorageBlocks : prog->UniformBlocks; unsigned num_blks = var->is_in_shader_storage_block() ? prog->NumShaderStorageBlocks : prog->NumUniformBlocks; @@ -471,15 +471,15 @@ public: unsigned l = strlen(var->get_interface_type()->name); for (unsigned i = 0; i < num_blks; i++) { - if (strncmp(var->get_interface_type()->name, blks[i]->Name, l) - == 0 && blks[i]->Name[l] == '[') { + if (strncmp(var->get_interface_type()->name, blks[i].Name, l) + == 0 && blks[i].Name[l] == '[') { buffer_block_index = i; break; } } } else { for (unsigned i = 0; i < num_blks; i++) { - if (strcmp(var->get_interface_type()->name, blks[i]->Name) == + if (strcmp(var->get_interface_type()->name, blks[i].Name) == 0) { buffer_block_index = i; break; @@ -500,7 +500,7 @@ public: var->get_interface_type()->name); } else { const struct gl_uniform_block *const block = - blks[buffer_block_index]; + &blks[buffer_block_index]; assert(var->data.location != -1); @@ -960,11 +960,16 @@ link_update_uniform_buffer_variables(struct gl_shader *shader) sentinel = '['; } + unsigned num_blocks = var->data.mode == ir_var_uniform ? + shader->NumUniformBlocks : shader->NumShaderStorageBlocks; + struct gl_uniform_block **blks = var->data.mode == ir_var_uniform ? + shader->UniformBlocks : shader->ShaderStorageBlocks; + const unsigned l = strlen(var->name); - for (unsigned i = 0; i < shader->NumBufferInterfaceBlocks; i++) { - for (unsigned j = 0; j < shader->BufferInterfaceBlocks[i]->NumUniforms; j++) { + for (unsigned i = 0; i < num_blocks; i++) { + for (unsigned j = 0; j < blks[i]->NumUniforms; j++) { if (sentinel) { - const char *begin = shader->BufferInterfaceBlocks[i]->Uniforms[j].Name; + const char *begin = blks[i]->Uniforms[j].Name; const char *end = strchr(begin, sentinel); if (end == NULL) @@ -978,8 +983,7 @@ link_update_uniform_buffer_variables(struct gl_shader *shader) var->data.location = j; break; } - } else if (!strcmp(var->name, - shader->BufferInterfaceBlocks[i]->Uniforms[j].Name)) { + } else if (!strcmp(var->name, blks[i]->Uniforms[j].Name)) { found = true; var->data.location = j; break; @@ -1104,11 +1108,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog, sh->num_uniform_components = uniform_size.num_shader_uniform_components; sh->num_combined_uniform_components = sh->num_uniform_components; - for (unsigned i = 0; i < sh->NumBufferInterfaceBlocks; i++) { - if (!sh->BufferInterfaceBlocks[i]->IsShaderStorage) { - sh->num_combined_uniform_components += - sh->BufferInterfaceBlocks[i]->UniformBufferSize / 4; - } + for (unsigned i = 0; i < sh->NumUniformBlocks; i++) { + sh->num_combined_uniform_components += + sh->UniformBlocks[i]->UniformBufferSize / 4; } } diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index d9a681ccca1..957efe5b55d 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -1165,39 +1165,58 @@ cross_validate_uniforms(struct gl_shader_program *prog) } /** - * Accumulates the array of prog->BufferInterfaceBlocks and checks that all - * definitons of blocks agree on their contents. + * Accumulates the array of buffer blocks and checks that all definitions of + * blocks agree on their contents. */ static bool -interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog) +interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog, + bool validate_ssbo) { int *InterfaceBlockStageIndex[MESA_SHADER_STAGES]; + struct gl_uniform_block *blks = NULL; + unsigned *num_blks = validate_ssbo ? &prog->NumShaderStorageBlocks : + &prog->NumUniformBlocks; - unsigned max_num_uniform_blocks = 0; + unsigned max_num_buffer_blocks = 0; for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - if (prog->_LinkedShaders[i]) - max_num_uniform_blocks += prog->_LinkedShaders[i]->NumBufferInterfaceBlocks; + if (prog->_LinkedShaders[i]) { + if (validate_ssbo) { + max_num_buffer_blocks += + prog->_LinkedShaders[i]->NumShaderStorageBlocks; + } else { + max_num_buffer_blocks += + prog->_LinkedShaders[i]->NumUniformBlocks; + } + } } for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; - InterfaceBlockStageIndex[i] = new int[max_num_uniform_blocks]; - for (unsigned int j = 0; j < max_num_uniform_blocks; j++) + InterfaceBlockStageIndex[i] = new int[max_num_buffer_blocks]; + for (unsigned int j = 0; j < max_num_buffer_blocks; j++) InterfaceBlockStageIndex[i][j] = -1; if (sh == NULL) continue; - for (unsigned int j = 0; j < sh->NumBufferInterfaceBlocks; j++) { - int index = link_cross_validate_uniform_block(prog, - &prog->BufferInterfaceBlocks, - &prog->NumBufferInterfaceBlocks, - sh->BufferInterfaceBlocks[j]); + unsigned sh_num_blocks; + struct gl_uniform_block **sh_blks; + if (validate_ssbo) { + sh_num_blocks = prog->_LinkedShaders[i]->NumShaderStorageBlocks; + sh_blks = sh->ShaderStorageBlocks; + } else { + sh_num_blocks = prog->_LinkedShaders[i]->NumUniformBlocks; + sh_blks = sh->UniformBlocks; + } + + for (unsigned int j = 0; j < sh_num_blocks; j++) { + int index = link_cross_validate_uniform_block(prog, &blks, num_blks, + sh_blks[j]); if (index == -1) { - linker_error(prog, "uniform block `%s' has mismatching definitions\n", - sh->BufferInterfaceBlocks[j]->Name); + linker_error(prog, "buffer block `%s' has mismatching " + "definitions\n", sh_blks[j]->Name); for (unsigned k = 0; k <= i; k++) { delete[] InterfaceBlockStageIndex[k]; @@ -1213,16 +1232,18 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog) * FIXME: We should be able to free the per stage blocks here. */ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - for (unsigned j = 0; j < prog->NumBufferInterfaceBlocks; j++) { + for (unsigned j = 0; j < *num_blks; j++) { int stage_index = InterfaceBlockStageIndex[i][j]; if (stage_index != -1) { struct gl_shader *sh = prog->_LinkedShaders[i]; - prog->BufferInterfaceBlocks[j].stageref |= (1 << i); + blks[j].stageref |= (1 << i); + + struct gl_uniform_block **sh_blks = validate_ssbo ? + sh->ShaderStorageBlocks : sh->UniformBlocks; - sh->BufferInterfaceBlocks[stage_index] = - &prog->BufferInterfaceBlocks[j]; + sh_blks[stage_index] = &blks[j]; } } } @@ -1231,6 +1252,11 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog) delete[] InterfaceBlockStageIndex[i]; } + if (validate_ssbo) + prog->ShaderStorageBlocks = blks; + else + prog->UniformBlocks = blks; + return true; } @@ -2074,7 +2100,10 @@ link_intrastage_shaders(void *mem_ctx, struct gl_shader **shader_list, unsigned num_shaders) { - struct gl_uniform_block *uniform_blocks = NULL; + struct gl_uniform_block *ubo_blocks = NULL; + struct gl_uniform_block *ssbo_blocks = NULL; + unsigned num_ubo_blocks = 0; + unsigned num_ssbo_blocks = 0; /* Check that global variables defined in multiple shaders are consistent. */ @@ -2090,9 +2119,10 @@ link_intrastage_shaders(void *mem_ctx, return NULL; /* Link up uniform blocks defined within this stage. */ - const unsigned num_uniform_blocks = - link_uniform_blocks(mem_ctx, ctx, prog, shader_list, num_shaders, - &uniform_blocks); + link_uniform_blocks(mem_ctx, ctx, prog, shader_list, num_shaders, + &ubo_blocks, &num_ubo_blocks, &ssbo_blocks, + &num_ssbo_blocks); + if (!prog->LinkStatus) return NULL; @@ -2159,15 +2189,23 @@ link_intrastage_shaders(void *mem_ctx, linked->ir = new(linked) exec_list; clone_ir_list(mem_ctx, linked->ir, main->ir); - linked->BufferInterfaceBlocks = - ralloc_array(linked, gl_uniform_block *, num_uniform_blocks); - - ralloc_steal(linked, uniform_blocks); - for (unsigned i = 0; i < num_uniform_blocks; i++) { - linked->BufferInterfaceBlocks[i] = &uniform_blocks[i]; + /* Copy ubo blocks to linked shader list */ + linked->UniformBlocks = + ralloc_array(linked, gl_uniform_block *, num_ubo_blocks); + ralloc_steal(linked, ubo_blocks); + for (unsigned i = 0; i < num_ubo_blocks; i++) { + linked->UniformBlocks[i] = &ubo_blocks[i]; } + linked->NumUniformBlocks = num_ubo_blocks; - linked->NumBufferInterfaceBlocks = num_uniform_blocks; + /* Copy ssbo blocks to linked shader list */ + linked->ShaderStorageBlocks = + ralloc_array(linked, gl_uniform_block *, num_ssbo_blocks); + ralloc_steal(linked, ssbo_blocks); + for (unsigned i = 0; i < num_ssbo_blocks; i++) { + linked->ShaderStorageBlocks[i] = &ssbo_blocks[i]; + } + linked->NumShaderStorageBlocks = num_ssbo_blocks; link_fs_input_layout_qualifiers(prog, linked, shader_list, num_shaders); link_tcs_out_layout_qualifiers(prog, linked, shader_list, num_shaders); @@ -2973,21 +3011,22 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) ctx->Const.MaxCombinedShaderStorageBlocks); } - for (unsigned i = 0; i < prog->NumBufferInterfaceBlocks; i++) { - /* Don't check SSBOs for Uniform Block Size */ - if (!prog->BufferInterfaceBlocks[i].IsShaderStorage && - prog->BufferInterfaceBlocks[i].UniformBufferSize > ctx->Const.MaxUniformBlockSize) { + for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { + if (prog->UniformBlocks[i].UniformBufferSize > + ctx->Const.MaxUniformBlockSize) { linker_error(prog, "Uniform block %s too big (%d/%d)\n", - prog->BufferInterfaceBlocks[i].Name, - prog->BufferInterfaceBlocks[i].UniformBufferSize, + prog->UniformBlocks[i].Name, + prog->UniformBlocks[i].UniformBufferSize, ctx->Const.MaxUniformBlockSize); } + } - if (prog->BufferInterfaceBlocks[i].IsShaderStorage && - prog->BufferInterfaceBlocks[i].UniformBufferSize > ctx->Const.MaxShaderStorageBlockSize) { + for (unsigned i = 0; i < prog->NumShaderStorageBlocks; i++) { + if (prog->ShaderStorageBlocks[i].UniformBufferSize > + ctx->Const.MaxShaderStorageBlockSize) { linker_error(prog, "Shader storage block %s too big (%d/%d)\n", - prog->BufferInterfaceBlocks[i].Name, - prog->BufferInterfaceBlocks[i].UniformBufferSize, + prog->ShaderStorageBlocks[i].Name, + prog->ShaderStorageBlocks[i].UniformBufferSize, ctx->Const.MaxShaderStorageBlockSize); } } @@ -3295,8 +3334,8 @@ should_add_buffer_variable(struct gl_shader_program *shProg, if (type != GL_BUFFER_VARIABLE) return true; - for (unsigned i = 0; i < shProg->NumBufferInterfaceBlocks; i++) { - const char *block_name = shProg->BufferInterfaceBlocks[i].Name; + for (unsigned i = 0; i < shProg->NumShaderStorageBlocks; i++) { + const char *block_name = shProg->ShaderStorageBlocks[i].Name; block_name_len = strlen(block_name); const char *block_square_bracket = strchr(block_name, '['); @@ -3805,8 +3844,8 @@ calculate_array_size_and_stride(struct gl_shader_program *shProg, char *var_name = get_top_level_name(uni->name); char *interface_name = get_top_level_name(uni->is_shader_storage ? - shProg->ShaderStorageBlocks[block_index]->Name : - shProg->UniformBlocks[block_index]->Name); + shProg->ShaderStorageBlocks[block_index].Name : + shProg->UniformBlocks[block_index].Name); if (strcmp(var_name, interface_name) == 0) { /* Deal with instanced array of SSBOs */ @@ -3947,8 +3986,8 @@ build_program_resource_list(struct gl_context *ctx, int block_index = shProg->UniformStorage[i].block_index; if (block_index != -1) { stageref |= is_shader_storage ? - shProg->ShaderStorageBlocks[block_index]->stageref : - shProg->UniformBlocks[block_index]->stageref; + shProg->ShaderStorageBlocks[block_index].stageref : + shProg->UniformBlocks[block_index].stageref; } GLenum type = is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM; @@ -3965,12 +4004,17 @@ build_program_resource_list(struct gl_context *ctx, return; } - /* Add program uniform blocks and shader storage blocks. */ - for (unsigned i = 0; i < shProg->NumBufferInterfaceBlocks; i++) { - bool is_shader_storage = shProg->BufferInterfaceBlocks[i].IsShaderStorage; - GLenum type = is_shader_storage ? GL_SHADER_STORAGE_BLOCK : GL_UNIFORM_BLOCK; - if (!add_program_resource(shProg, type, - &shProg->BufferInterfaceBlocks[i], 0)) + /* Add program uniform blocks. */ + for (unsigned i = 0; i < shProg->NumUniformBlocks; i++) { + if (!add_program_resource(shProg, GL_UNIFORM_BLOCK, + &shProg->UniformBlocks[i], 0)) + return; + } + + /* Add program shader storage blocks. */ + for (unsigned i = 0; i < shProg->NumShaderStorageBlocks; i++) { + if (!add_program_resource(shProg, GL_SHADER_STORAGE_BLOCK, + &shProg->ShaderStorageBlocks[i], 0)) return; } @@ -4116,49 +4160,6 @@ link_assign_subroutine_types(struct gl_shader_program *prog) } static void -split_ubos_and_ssbos(void *mem_ctx, - struct gl_uniform_block **s_blks, - struct gl_uniform_block *p_blks, - unsigned num_blocks, - struct gl_uniform_block ***ubos, - unsigned *num_ubos, - struct gl_uniform_block ***ssbos, - unsigned *num_ssbos) -{ - unsigned num_ubo_blocks = 0; - unsigned num_ssbo_blocks = 0; - - /* Are we spliting the list of blocks for the shader or the program */ - bool is_shader = p_blks == NULL; - - for (unsigned i = 0; i < num_blocks; i++) { - if (is_shader ? s_blks[i]->IsShaderStorage : p_blks[i].IsShaderStorage) - num_ssbo_blocks++; - else - num_ubo_blocks++; - } - - *ubos = ralloc_array(mem_ctx, gl_uniform_block *, num_ubo_blocks); - *num_ubos = 0; - - *ssbos = ralloc_array(mem_ctx, gl_uniform_block *, num_ssbo_blocks); - *num_ssbos = 0; - - for (unsigned i = 0; i < num_blocks; i++) { - struct gl_uniform_block *blk = is_shader ? s_blks[i] : &p_blks[i]; - if (blk->IsShaderStorage) { - (*ssbos)[*num_ssbos] = blk; - (*num_ssbos)++; - } else { - (*ubos)[*num_ubos] = blk; - (*num_ubos)++; - } - } - - assert(*num_ubos + *num_ssbos == num_blocks); -} - -static void set_always_active_io(exec_list *ir, ir_variable_mode io_mode) { assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out); @@ -4498,7 +4499,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (prog->SeparateShader) disable_varying_optimizations_for_sso(prog); - if (!interstage_cross_validate_uniform_blocks(prog)) + /* Process UBOs */ + if (!interstage_cross_validate_uniform_blocks(prog, false)) + goto done; + + /* Process SSBOs */ + if (!interstage_cross_validate_uniform_blocks(prog, true)) goto done; /* Do common optimization before assigning storage for attributes, @@ -4695,33 +4701,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) has_xfb_qualifiers)) goto done; - /* Split BufferInterfaceBlocks into UniformBlocks and ShaderStorageBlocks - * for gl_shader_program and gl_shader, so that drivers that need separate - * index spaces for each set can have that. - */ - for (unsigned i = MESA_SHADER_VERTEX; i < MESA_SHADER_STAGES; i++) { - if (prog->_LinkedShaders[i] != NULL) { - gl_shader *sh = prog->_LinkedShaders[i]; - split_ubos_and_ssbos(sh, - sh->BufferInterfaceBlocks, - NULL, - sh->NumBufferInterfaceBlocks, - &sh->UniformBlocks, - &sh->NumUniformBlocks, - &sh->ShaderStorageBlocks, - &sh->NumShaderStorageBlocks); - } - } - - split_ubos_and_ssbos(prog, - NULL, - prog->BufferInterfaceBlocks, - prog->NumBufferInterfaceBlocks, - &prog->UniformBlocks, - &prog->NumUniformBlocks, - &prog->ShaderStorageBlocks, - &prog->NumShaderStorageBlocks); - update_array_sizes(prog); link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue, num_explicit_uniform_locs, diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h index 97144df8ff7..3a0ec8b35d3 100644 --- a/src/compiler/glsl/linker.h +++ b/src/compiler/glsl/linker.h @@ -53,13 +53,16 @@ extern bool link_uniform_blocks_are_compatible(const gl_uniform_block *a, const gl_uniform_block *b); -extern unsigned +extern void link_uniform_blocks(void *mem_ctx, struct gl_context *ctx, struct gl_shader_program *prog, struct gl_shader **shader_list, unsigned num_shaders, - struct gl_uniform_block **blocks_ret); + struct gl_uniform_block **ubo_blocks, + unsigned *num_ubo_blocks, + struct gl_uniform_block **ssbo_blocks, + unsigned *num_ssbo_blocks); bool validate_intrastage_arrays(struct gl_shader_program *prog, diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp index 49b4a26dc12..09d7d6e8c26 100644 --- a/src/compiler/glsl/standalone_scaffolding.cpp +++ b/src/compiler/glsl/standalone_scaffolding.cpp @@ -105,10 +105,6 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg) ralloc_free(shProg->InfoLog); shProg->InfoLog = ralloc_strdup(shProg, ""); - ralloc_free(shProg->BufferInterfaceBlocks); - shProg->BufferInterfaceBlocks = NULL; - shProg->NumBufferInterfaceBlocks = 0; - ralloc_free(shProg->UniformBlocks); shProg->UniformBlocks = NULL; shProg->NumUniformBlocks = 0; |