diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/glsl/link_uniform_blocks.cpp | 215 | ||||
-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/lower_ubo_reference.cpp | 3 | ||||
-rw-r--r-- | src/compiler/glsl/lower_variable_index_to_cond_assign.cpp | 20 | ||||
-rw-r--r-- | src/compiler/glsl/standalone_scaffolding.cpp | 4 | ||||
-rw-r--r-- | src/compiler/nir/nir_search.c | 5 |
9 files changed, 280 insertions, 248 deletions
diff --git a/src/compiler/glsl/link_uniform_blocks.cpp b/src/compiler/glsl/link_uniform_blocks.cpp index c8fa181a15d..58f22fd61c5 100644 --- a/src/compiler/glsl/link_uniform_blocks.cpp +++ b/src/compiler/glsl/link_uniform_blocks.cpp @@ -216,7 +216,7 @@ process_block_array(struct uniform_block_array_elements *ub_array, char **name, { if (ub_array) { for (unsigned j = 0; j < ub_array->num_array_elements; j++) { - size_t new_length = name_length; + size_t new_length = name_length; /* Append the subscript to the current variable name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", @@ -261,7 +261,6 @@ process_block_array(struct uniform_block_array_elements *ub_array, char **name, } blocks[i].NumUniforms = (unsigned)(ptrdiff_t)(&variables[parcel->index] - blocks[i].Uniforms); - blocks[i].IsShaderStorage = b->is_shader_storage; *block_index = *block_index + 1; *binding_offset = *binding_offset + 1; @@ -291,13 +290,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 +401,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 +414,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,102 +437,36 @@ 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 link_uniform_blocks_are_compatible(const gl_uniform_block *a, - const gl_uniform_block *b) + const gl_uniform_block *b) { assert(strcmp(a->Name, b->Name) == 0); @@ -464,13 +489,13 @@ link_uniform_blocks_are_compatible(const gl_uniform_block *a, for (unsigned i = 0; i < a->NumUniforms; i++) { if (strcmp(a->Uniforms[i].Name, b->Uniforms[i].Name) != 0) - return false; + return false; if (a->Uniforms[i].Type != b->Uniforms[i].Type) - return false; + return false; if (a->Uniforms[i].RowMajor != b->Uniforms[i].RowMajor) - return false; + return false; } return true; 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/lower_ubo_reference.cpp b/src/compiler/glsl/lower_ubo_reference.cpp index 3155ab6225e..1a0140fad15 100644 --- a/src/compiler/glsl/lower_ubo_reference.cpp +++ b/src/compiler/glsl/lower_ubo_reference.cpp @@ -372,8 +372,7 @@ lower_ubo_reference_visitor::ubo_load(void *mem_ctx, static bool shader_storage_buffer_object(const _mesa_glsl_parse_state *state) { - return state->ARB_shader_storage_buffer_object_enable || - state->is_version(430, 310); + return state->has_shader_storage_buffer_objects(); } uint32_t diff --git a/src/compiler/glsl/lower_variable_index_to_cond_assign.cpp b/src/compiler/glsl/lower_variable_index_to_cond_assign.cpp index 278d5450bfb..fcb12d1b77d 100644 --- a/src/compiler/glsl/lower_variable_index_to_cond_assign.cpp +++ b/src/compiler/glsl/lower_variable_index_to_cond_assign.cpp @@ -385,6 +385,26 @@ public: case ir_var_const_in: return this->lower_temps; + case ir_var_system_value: + /* There are only a few system values that have array types: + * + * gl_TessLevelInner[] + * gl_TessLevelOuter[] + * gl_SampleMaskIn[] + * + * The tessellation factor arrays are lowered to vec4/vec2s + * by lower_tess_level() before this pass occurs, so we'll + * never see them here. + * + * The only remaining case is gl_SampleMaskIn[], which has + * a length of ceil(ctx->Const.MaxSamples / 32). Most hardware + * supports no more than 32 samples, in which case our lowering + * produces a single read of gl_SampleMaskIn[0]. Even with 64x + * MSAA, the array length is only 2, so the lowering is fairly + * efficient. Therefore, lower unconditionally. + */ + return true; + case ir_var_shader_in: /* The input array size is unknown at compiler time for non-patch * inputs in TCS and TES. The arrays are sized to 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; diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c index b915101ce32..3a65ab18928 100644 --- a/src/compiler/nir/nir_search.c +++ b/src/compiler/nir/nir_search.c @@ -25,6 +25,7 @@ * */ +#include <inttypes.h> #include "nir_search.h" struct match_state { @@ -494,7 +495,7 @@ construct_value(const nir_search_value *value, break; case nir_type_int: - load->def.name = ralloc_asprintf(load, "%ld", c->data.i); + load->def.name = ralloc_asprintf(load, "%" PRIi64, c->data.i); switch (bitsize->dest_size) { case 32: load->value.i32[0] = c->data.i; @@ -508,7 +509,7 @@ construct_value(const nir_search_value *value, break; case nir_type_uint: - load->def.name = ralloc_asprintf(load, "%lu", c->data.u); + load->def.name = ralloc_asprintf(load, "%" PRIu64, c->data.u); switch (bitsize->dest_size) { case 32: load->value.u32[0] = c->data.u; |