}
void
-uniform_field_visitor::process(const glsl_type *type, const char *name)
+program_resource_visitor::process(const glsl_type *type, const char *name)
{
assert(type->is_record()
|| (type->is_array() && type->fields.array->is_record())
}
void
-uniform_field_visitor::process(ir_variable *var)
+program_resource_visitor::process(ir_variable *var)
{
const glsl_type *t = var->type;
}
void
-uniform_field_visitor::recursion(const glsl_type *t, char **name,
- size_t name_length, bool row_major)
+program_resource_visitor::recursion(const glsl_type *t, char **name,
+ size_t name_length, bool row_major)
{
/* Records need to have each field processed individually.
*
if (t->fields.structure[i].type->is_record())
this->visit_field(&t->fields.structure[i]);
- /* Append '.field' to the current uniform name. */
+ /* Append '.field' to the current variable name. */
if (name_length == 0) {
ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field);
} else {
for (unsigned i = 0; i < t->length; i++) {
size_t new_length = name_length;
- /* Append the subscript to the current uniform name */
+ /* Append the subscript to the current variable name */
ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
recursion(t->fields.array, name, new_length,
}
void
-uniform_field_visitor::visit_field(const glsl_struct_field *field)
+program_resource_visitor::visit_field(const glsl_struct_field *field)
{
(void) field;
/* empty */
* If the same uniform is added multiple times (i.e., once for each shader
* target), it will only be accounted once.
*/
-class count_uniform_size : public uniform_field_visitor {
+class count_uniform_size : public program_resource_visitor {
public:
count_uniform_size(struct string_to_uint_map *map)
: num_active_uniforms(0), num_values(0), num_shader_samplers(0),
void process(ir_variable *var)
{
if (var->is_interface_instance())
- uniform_field_visitor::process(var->interface_type,
- var->interface_type->name);
+ program_resource_visitor::process(var->interface_type,
+ var->interface_type->name);
else
- uniform_field_visitor::process(var);
+ program_resource_visitor::process(var);
}
/**
* the \c gl_uniform_storage and \c gl_constant_value arrays are "big
* enough."
*/
-class parcel_out_uniform_storage : public uniform_field_visitor {
+class parcel_out_uniform_storage : public program_resource_visitor {
public:
parcel_out_uniform_storage(struct string_to_uint_map *map,
struct gl_uniform_storage *uniforms,
assert(var->mode == ir_var_uniform);
+ if (var->is_interface_instance()) {
+ var->location = 0;
+ continue;
+ }
+
bool found = false;
+ char sentinel = '\0';
+
+ if (var->type->is_record()) {
+ sentinel = '.';
+ } else if (var->type->is_array()
+ && var->type->fields.array->is_record()) {
+ sentinel = '[';
+ }
+
+ const unsigned l = strlen(var->name);
for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
for (unsigned j = 0; j < shader->UniformBlocks[i].NumUniforms; j++) {
- if (!strcmp(var->name, shader->UniformBlocks[i].Uniforms[j].Name)) {
+ if (sentinel) {
+ const char *begin = shader->UniformBlocks[i].Uniforms[j].Name;
+ const char *end = strchr(begin, sentinel);
+
+ if (end == NULL)
+ continue;
+
+ if (l != (end - begin))
+ continue;
+
+ if (strncmp(var->name, begin, l) == 0) {
+ found = true;
+ var->location = j;
+ break;
+ }
+ } else if (!strcmp(var->name,
+ shader->UniformBlocks[i].Uniforms[j].Name)) {
found = true;
- var->uniform_block = i;
var->location = j;
break;
}
*/
memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
- for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
- if (prog->_LinkedShaders[i] == NULL)
- continue;
-
- link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
- }
-
/* First pass: Count the uniform resources used by the user-defined
* uniforms. While this happens, each active uniform will have an index
* assigned to it.
if (prog->_LinkedShaders[i] == NULL)
continue;
+ link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
+
/* Reset various per-shader target counts.
*/
uniform_size.start_shader();