void program_resource_visitor::recursion(const glsl_type *t, char **name, size_t name_length, bool row_major, const glsl_type *record_type) { /* Records need to have each field processed individually. * * Arrays of records need to have each array element processed * individually, then each field of the resulting array elements processed * individually. */ if (t->is_record() || t->is_interface()) { if (record_type == NULL && t->is_record()) record_type = t; for (unsigned i = 0; i < t->length; i++) { const char *field = t->fields.structure[i].name; size_t new_length = name_length; if (t->fields.structure[i].type->is_record()) this->visit_field(&t->fields.structure[i]); /* Append '.field' to the current variable name. */ if (name_length == 0) { ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field); } else { ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field); } recursion(t->fields.structure[i].type, name, new_length, t->fields.structure[i].row_major, record_type); /* Only the first leaf-field of the record gets called with the * record type pointer. */ record_type = NULL; } } else if (t->is_array() && (t->fields.array->is_record() || t->fields.array->is_interface())) { if (record_type == NULL && t->fields.array->is_record()) record_type = t->fields.array; for (unsigned i = 0; i < t->length; i++) { size_t new_length = name_length; /* Append the subscript to the current variable name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); recursion(t->fields.array, name, new_length, row_major, record_type); /* Only the first leaf-field of the record gets called with the * record type pointer. */ record_type = NULL; } } else { this->visit_field(t, *name, row_major, record_type); } }
void uniform_field_visitor::recursion(const glsl_type *t, char **name, size_t name_length) { /* Records need to have each field processed individually. * * Arrays of records need to have each array element processed * individually, then each field of the resulting array elements processed * individually. */ if (t->is_record()) { for (unsigned i = 0; i < t->length; i++) { const char *field = t->fields.structure[i].name; size_t new_length = name_length; /* Append '.field' to the current uniform name. */ ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field); recursion(t->fields.structure[i].type, name, new_length); } } else if (t->is_array() && t->fields.array->is_record()) { for (unsigned i = 0; i < t->length; i++) { size_t new_length = name_length; /* Append the subscript to the current uniform name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); recursion(t->fields.array, name, new_length); } } else { this->visit_field(t, *name); } }
/** * * \param first_index Value of \c block_index for the first element of the * array. */ static void process_block_array(struct uniform_block_array_elements *ub_array, char **name, size_t name_length, gl_uniform_block *blocks, ubo_visitor *parcel, gl_uniform_buffer_variable *variables, const struct link_uniform_block_active *const b, unsigned *block_index, unsigned *binding_offset, struct gl_context *ctx, struct gl_shader_program *prog, unsigned first_index) { for (unsigned j = 0; j < ub_array->num_array_elements; j++) { size_t new_length = name_length; /* Append the subscript to the current variable name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", ub_array->array_elements[j]); if (ub_array->array) { process_block_array(ub_array->array, name, new_length, blocks, parcel, variables, b, block_index, binding_offset, ctx, prog, first_index); } else { process_block_array_leaf(*name, blocks, parcel, variables, b, block_index, binding_offset, *block_index - first_index, ctx, prog); } } }
static void process_block_array(struct uniform_block_array_elements *ub_array, char **name, size_t name_length, gl_uniform_block *blocks, ubo_visitor *parcel, gl_uniform_buffer_variable *variables, const struct link_uniform_block_active *const b, unsigned *block_index, unsigned *binding_offset, struct gl_context *ctx, struct gl_shader_program *prog) { if (ub_array) { for (unsigned j = 0; j < ub_array->num_array_elements; j++) { size_t new_length = name_length; /* Append the subscript to the current variable name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", ub_array->array_elements[j]); process_block_array(ub_array->array, name, new_length, blocks, parcel, variables, b, block_index, binding_offset, ctx, prog); } } else { unsigned i = *block_index; const glsl_type *type = b->type->without_array(); blocks[i].Name = ralloc_strdup(blocks, *name); blocks[i].Uniforms = &variables[(*parcel).index]; /* The GL_ARB_shading_language_420pack spec says: * * "If the binding identifier is used with a uniform block * instanced as an array then the first element of the array * takes the specified block binding and each subsequent * element takes the next consecutive uniform block binding * point." */ blocks[i].Binding = (b->has_binding) ? b->binding + *binding_offset : 0; blocks[i].UniformBufferSize = 0; blocks[i]._Packing = gl_uniform_block_packing(type->interface_packing); parcel->process(type, blocks[i].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)", b->type->name, parcel->buffer_size, ctx->Const.MaxShaderStorageBlockSize); } blocks[i].NumUniforms = (unsigned)(ptrdiff_t)(&variables[parcel->index] - blocks[i].Uniforms); *block_index = *block_index + 1; *binding_offset = *binding_offset + 1; } }
void glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...) { va_list ap; ralloc_asprintf_rewrite_tail(&parser->info_log, &parser->info_log_length, "%u:%u(%u): " "preprocessor warning: ", locp->source, locp->first_line, locp->first_column); va_start(ap, fmt); ralloc_vasprintf_rewrite_tail(&parser->info_log, &parser->info_log_length, fmt, ap); va_end(ap); ralloc_asprintf_rewrite_tail(&parser->info_log, &parser->info_log_length, "\n"); }
void program_resource_visitor::process(ir_variable *var) { const glsl_type *t = var->type; const bool row_major = var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR; /* false is always passed for the row_major parameter to the other * processing functions because no information is available to do * otherwise. See the warning in linker.h. */ /* Only strdup the name if we actually will need to modify it. */ if (var->data.from_named_ifc_block_array) { /* lower_named_interface_blocks created this variable by lowering an * interface block array to an array variable. For example if the * original source code was: * * out Blk { vec4 bar } foo[3]; * * Then the variable is now: * * out vec4 bar[3]; * * We need to visit each array element using the names constructed like * so: * * Blk[0].bar * Blk[1].bar * Blk[2].bar */ assert(t->is_array()); const glsl_type *ifc_type = var->get_interface_type(); char *name = ralloc_strdup(NULL, ifc_type->name); size_t name_length = strlen(name); for (unsigned i = 0; i < t->length; i++) { size_t new_length = name_length; ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i, var->name); /* Note: row_major is only meaningful for uniform blocks, and * lowering is only applied to non-uniform interface blocks, so we * can safely pass false for row_major. */ recursion(var->type, &name, new_length, row_major, NULL, false); } ralloc_free(name); } else if (var->data.from_named_ifc_block_nonarray) { /* lower_named_interface_blocks created this variable by lowering a * named interface block (non-array) to an ordinary variable. For * example if the original source code was: * * out Blk { vec4 bar } foo; * * Then the variable is now: * * out vec4 bar; * * We need to visit this variable using the name: * * Blk.bar */ const glsl_type *ifc_type = var->get_interface_type(); char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name); /* Note: row_major is only meaningful for uniform blocks, and lowering * is only applied to non-uniform interface blocks, so we can safely * pass false for row_major. */ recursion(var->type, &name, strlen(name), row_major, NULL, false); ralloc_free(name); } else if (t->without_array()->is_record()) { char *name = ralloc_strdup(NULL, var->name); recursion(var->type, &name, strlen(name), row_major, NULL, false); ralloc_free(name); } else if (t->is_interface()) { char *name = ralloc_strdup(NULL, var->type->name); recursion(var->type, &name, strlen(name), row_major, NULL, false); ralloc_free(name); } else if (t->is_array() && t->fields.array->is_interface()) { char *name = ralloc_strdup(NULL, var->type->fields.array->name); recursion(var->type, &name, strlen(name), row_major, NULL, false); ralloc_free(name); } else { this->visit_field(t, var->name, row_major, NULL, false); } }
void program_resource_visitor::recursion(const glsl_type *t, char **name, size_t name_length, bool row_major, const glsl_type *record_type, bool last_field) { /* Records need to have each field processed individually. * * Arrays of records need to have each array element processed * individually, then each field of the resulting array elements processed * individually. */ if (t->is_record() || t->is_interface()) { if (record_type == NULL && t->is_record()) record_type = t; for (unsigned i = 0; i < t->length; i++) { const char *field = t->fields.structure[i].name; size_t new_length = name_length; if (t->fields.structure[i].type->is_record()) this->visit_field(&t->fields.structure[i]); /* Append '.field' to the current variable name. */ if (name_length == 0) { ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field); } else { ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field); } /* The layout of structures at the top level of the block is set * during parsing. For matrices contained in multiple levels of * structures in the block, the inner structures have no layout. * These cases must potentially inherit the layout from the outer * levels. */ bool field_row_major = row_major; const enum glsl_matrix_layout matrix_layout = glsl_matrix_layout(t->fields.structure[i].matrix_layout); if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) { field_row_major = true; } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) { field_row_major = false; } recursion(t->fields.structure[i].type, name, new_length, field_row_major, record_type, (i + 1) == t->length); /* Only the first leaf-field of the record gets called with the * record type pointer. */ record_type = NULL; } } else if (t->is_array() && (t->fields.array->is_record() || t->fields.array->is_interface())) { if (record_type == NULL && t->fields.array->is_record()) record_type = t->fields.array; for (unsigned i = 0; i < t->length; i++) { size_t new_length = name_length; /* Append the subscript to the current variable name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); recursion(t->fields.array, name, new_length, row_major, record_type, (i + 1) == t->length); /* Only the first leaf-field of the record gets called with the * record type pointer. */ record_type = NULL; } } else { this->visit_field(t, *name, row_major, record_type, last_field); } }
void program_resource_visitor::recursion(const glsl_type *t, char **name, size_t name_length, bool row_major, const glsl_type *record_type, const unsigned packing, bool last_field, unsigned record_array_count, const glsl_struct_field *named_ifc_member) { /* Records need to have each field processed individually. * * Arrays of records need to have each array element processed * individually, then each field of the resulting array elements processed * individually. */ if (t->is_interface() && named_ifc_member) { ralloc_asprintf_rewrite_tail(name, &name_length, ".%s", named_ifc_member->name); recursion(named_ifc_member->type, name, name_length, row_major, NULL, packing, false, record_array_count, NULL); } else if (t->is_record() || t->is_interface()) { if (record_type == NULL && t->is_record()) record_type = t; if (t->is_record()) this->enter_record(t, *name, row_major, packing); for (unsigned i = 0; i < t->length; i++) { const char *field = t->fields.structure[i].name; size_t new_length = name_length; if (t->fields.structure[i].type->is_record()) this->visit_field(&t->fields.structure[i]); if (t->is_interface() && t->fields.structure[i].offset != -1) this->set_buffer_offset(t->fields.structure[i].offset); /* Append '.field' to the current variable name. */ if (name_length == 0) { ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field); } else { ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field); } /* The layout of structures at the top level of the block is set * during parsing. For matrices contained in multiple levels of * structures in the block, the inner structures have no layout. * These cases must potentially inherit the layout from the outer * levels. */ bool field_row_major = row_major; const enum glsl_matrix_layout matrix_layout = glsl_matrix_layout(t->fields.structure[i].matrix_layout); if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) { field_row_major = true; } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) { field_row_major = false; } recursion(t->fields.structure[i].type, name, new_length, field_row_major, record_type, packing, (i + 1) == t->length, record_array_count, NULL); /* Only the first leaf-field of the record gets called with the * record type pointer. */ record_type = NULL; } if (t->is_record()) { (*name)[name_length] = '\0'; this->leave_record(t, *name, row_major, packing); } } else if (t->without_array()->is_record() || t->without_array()->is_interface() || (t->is_array() && t->fields.array->is_array())) { if (record_type == NULL && t->fields.array->is_record()) record_type = t->fields.array; unsigned length = t->length; /* Shader storage block unsized arrays: add subscript [0] to variable * names */ if (t->is_unsized_array()) length = 1; record_array_count *= length; for (unsigned i = 0; i < length; i++) { size_t new_length = name_length; /* Append the subscript to the current variable name */ ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); recursion(t->fields.array, name, new_length, row_major, record_type, packing, (i + 1) == t->length, record_array_count, named_ifc_member); /* Only the first leaf-field of the record gets called with the * record type pointer. */ record_type = NULL; } } else { this->set_record_array_count(record_array_count); this->visit_field(t, *name, row_major, record_type, packing, last_field); } }