+static int param_rb_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const char *name = key;
+ struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
+
+ return strcmp(name, param->full_name);
+}
+
+static void add_param_to_tree(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
+ struct d3dx_parameter *parent, char separator, unsigned int element)
+{
+ const char *parent_name = parent ? parent->full_name : NULL;
+ unsigned int i;
+
+ TRACE("Adding parameter %p (%s - parent %p, element %u) to the rbtree.\n",
+ param, debugstr_a(param->name), parent, element);
+
+ if (parent_name)
+ {
+ unsigned int parent_name_len = strlen(parent_name);
+ unsigned int name_len = strlen(param->name);
+ unsigned int part_str_len;
+ unsigned int len;
+ char part_str[16];
+
+ if (separator == '[')
+ {
+ sprintf(part_str, "[%u]", element);
+ part_str_len = strlen(part_str);
+ name_len = 0;
+ }
+ else
+ {
+ part_str[0] = separator;
+ part_str[1] = 0;
+ part_str_len = 1;
+ }
+ len = parent_name_len + part_str_len + name_len + 1;
+
+ if (!(param->full_name = heap_alloc(len)))
+ {
+ ERR("Out of memory.\n");
+ return;
+ }
+
+ memcpy(param->full_name, parent_name, parent_name_len);
+ memcpy(param->full_name + parent_name_len, part_str, part_str_len);
+ memcpy(param->full_name + parent_name_len + part_str_len, param->name, name_len);
+ param->full_name[len - 1] = 0;
+ }
+ else
+ {
+ unsigned int len = strlen(param->name) + 1;
+
+ if (!(param->full_name = heap_alloc(len)))
+ {
+ ERR("Out of memory.\n");
+ return;
+ }
+
+ memcpy(param->full_name, param->name, len);
+ }
+ TRACE("Full name is %s.\n", param->full_name);
+ wine_rb_put(&base->param_tree, param->full_name, ¶m->rb_entry);
+
+ if (is_top_level_parameter(param))
+ for (i = 0; i < param->top_level_param->annotation_count; ++i)
+ add_param_to_tree(base, ¶m->top_level_param->annotations[i], param, '@', 0);
+
+ if (param->element_count)
+ for (i = 0; i < param->element_count; ++i)
+ add_param_to_tree(base, ¶m->members[i], param, '[', i);
+ else
+ for (i = 0; i < param->member_count; ++i)
+ add_param_to_tree(base, ¶m->members[i], param, '.', 0);
+}
+