From 847f772fe1d3d18b0095c6a965c7254554ef4932 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Thu, 3 Aug 2017 19:42:08 +0200 Subject: [PATCH] d3dx9: Use distinct structure for top level parameters. Signed-off-by: Paul Gofman Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3dx9_36/d3dx9_private.h | 35 +++++-- dlls/d3dx9_36/effect.c | 172 ++++++++++++++++++---------------- 2 files changed, 116 insertions(+), 91 deletions(-) diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 1136d48927b..55b74313799 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -280,45 +280,60 @@ struct d3dx_param_eval }; struct d3dx_shared_data; +struct d3dx_top_level_parameter; struct d3dx_parameter { char magic_string[4]; + struct d3dx_top_level_parameter *top_level_param; + struct d3dx_param_eval *param_eval; char *name; - char *semantic; void *data; D3DXPARAMETER_CLASS class; D3DXPARAMETER_TYPE type; UINT rows; UINT columns; UINT element_count; - UINT annotation_count; UINT member_count; DWORD flags; UINT bytes; DWORD object_id; + + struct d3dx_parameter *members; + char *semantic; +}; + +struct d3dx_top_level_parameter +{ + struct d3dx_parameter param; + UINT annotation_count; + struct d3dx_parameter *annotations; ULONG64 update_version; ULONG64 *version_counter; - - struct d3dx_parameter *annotations; - struct d3dx_parameter *members; - - struct d3dx_param_eval *param_eval; - - struct d3dx_parameter *top_level_param; struct d3dx_shared_data *shared_data; }; struct d3dx_shared_data { void *data; - struct d3dx_parameter **parameters; + struct d3dx_top_level_parameter **parameters; unsigned int size, count; ULONG64 update_version; }; struct d3dx9_base_effect; +static inline BOOL is_top_level_parameter(struct d3dx_parameter *param) +{ + return ¶m->top_level_param->param == param; +} + +static inline struct d3dx_top_level_parameter + *top_level_parameter_from_parameter(struct d3dx_parameter *param) +{ + return CONTAINING_RECORD(param, struct d3dx_top_level_parameter, param); +} + static inline ULONG64 next_update_version(ULONG64 *version_counter) { return ++*version_counter; diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index d52301cff95..8095a0ee33d 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -152,7 +152,7 @@ struct d3dx9_base_effect UINT technique_count; UINT object_count; - struct d3dx_parameter *parameters; + struct d3dx_top_level_parameter *parameters; struct d3dx_technique *techniques; struct d3dx_object *objects; @@ -527,7 +527,7 @@ static void free_sampler(struct d3dx_sampler *sampler) HeapFree(GetProcessHeap(), 0, sampler->states); } -static void d3dx_pool_release_shared_parameter(struct d3dx_parameter *param); +static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param); static void free_parameter_data(struct d3dx_parameter *param, BOOL child) { @@ -578,15 +578,6 @@ static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL chil if (param->param_eval) d3dx_free_param_eval(param->param_eval); - if (param->annotations) - { - for (i = 0; i < param->annotation_count; ++i) - free_parameter(¶m->annotations[i], FALSE, FALSE); - HeapFree(GetProcessHeap(), 0, param->annotations); - } - - d3dx_pool_release_shared_parameter(param); - if (param->members) { unsigned int count = param->element_count ? param->element_count : param->member_count; @@ -606,6 +597,20 @@ static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL chil } } +static void free_top_level_parameter(struct d3dx_top_level_parameter *param) +{ + if (param->annotations) + { + unsigned int i; + + for (i = 0; i < param->annotation_count; ++i) + free_parameter(¶m->annotations[i], FALSE, FALSE); + HeapFree(GetProcessHeap(), 0, param->annotations); + } + d3dx_pool_release_shared_parameter(param); + free_parameter(¶m->param, FALSE, FALSE); +} + static void free_pass(struct d3dx_pass *pass) { unsigned int i; @@ -679,7 +684,7 @@ static void d3dx9_base_effect_cleanup(struct d3dx9_base_effect *base) if (base->parameters) { for (i = 0; i < base->parameter_count; ++i) - free_parameter(&base->parameters[i], FALSE, FALSE); + free_top_level_parameter(&base->parameters[i]); HeapFree(GetProcessHeap(), 0, base->parameters); base->parameters = NULL; } @@ -894,30 +899,20 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, { UINT i, count, length; struct d3dx_parameter *temp_parameter; - struct d3dx_parameter *parameters; const char *part; TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name)); if (!name || !*name) return NULL; - if (!parameter) - { - count = base->parameter_count; - parameters = base->parameters; - } - else - { - count = parameter->member_count; - parameters = parameter->members; - } - + count = parameter ? parameter->member_count : base->parameter_count; length = strcspn( name, "[.@" ); part = name + length; for (i = 0; i < count; i++) { - temp_parameter = ¶meters[i]; + temp_parameter = !parameter ? &base->parameters[i].param + : ¶meter->members[i]; if (!strcmp(temp_parameter->name, name)) { @@ -932,10 +927,13 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, return get_parameter_by_name(NULL, temp_parameter, part); case '@': - return parameter ? NULL - : get_annotation_by_name(temp_parameter->annotation_count, - temp_parameter->annotations, part); + { + struct d3dx_top_level_parameter *top_param + = top_level_parameter_from_parameter(temp_parameter); + return parameter ? NULL : get_annotation_by_name(top_param->annotation_count, + top_param->annotations, part); + } case '[': return get_parameter_element_by_name(temp_parameter, part); @@ -992,7 +990,8 @@ static HRESULT d3dx9_base_effect_get_parameter_desc(struct d3dx9_base_effect *ba desc->Rows = param->rows; desc->Columns = param->columns; desc->Elements = param->element_count; - desc->Annotations = param->annotation_count; + desc->Annotations = is_top_level_parameter(param) + ? top_level_parameter_from_parameter(param)->annotation_count : 0; desc->StructMembers = param->member_count; desc->Flags = param->flags; desc->Bytes = param->bytes; @@ -1042,7 +1041,7 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta { unsigned int array_idx; static const struct d3dx_parameter array_idx_param = - {"", NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, sizeof(array_idx)}; + {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)}; HRESULT hr; struct d3dx_parameter *ref_param, *selected_param; @@ -1183,7 +1182,7 @@ static D3DXHANDLE d3dx9_base_effect_get_parameter(struct d3dx9_base_effect *base if (index < base->parameter_count) { TRACE("Returning parameter %p.\n", &base->parameters[index]); - return get_parameter_handle(&base->parameters[index]); + return get_parameter_handle(&base->parameters[index].param); } } else @@ -1230,7 +1229,7 @@ static D3DXHANDLE d3dx9_base_effect_get_parameter_by_semantic(struct d3dx9_base_ { for (i = 0; i < base->parameter_count; ++i) { - temp_param = &base->parameters[i]; + temp_param = &base->parameters[i].param; if (!temp_param->semantic) { @@ -1288,7 +1287,7 @@ static D3DXHANDLE d3dx9_base_effect_get_parameter_element(struct d3dx9_base_effe if (index < base->parameter_count) { TRACE("Returning parameter %p.\n", &base->parameters[index]); - return get_parameter_handle(&base->parameters[index]); + return get_parameter_handle(&base->parameters[index].param); } } else @@ -1409,8 +1408,19 @@ static UINT get_annotation_from_object(struct d3dx9_base_effect *base, } else if (param) { - *annotations = param->annotations; - return param->annotation_count; + if (is_top_level_parameter(param)) + { + struct d3dx_top_level_parameter *top_param + = top_level_parameter_from_parameter(param); + + *annotations = top_param->annotations; + return top_param->annotation_count; + } + else + { + *annotations = NULL; + return 0; + } } else { @@ -1496,7 +1506,7 @@ static ULONG64 next_effect_update_version(struct d3dx9_base_effect *base) static void set_dirty(struct d3dx_parameter *param) { struct d3dx_shared_data *shared_data; - struct d3dx_parameter *top_param = param->top_level_param; + struct d3dx_top_level_parameter *top_param = param->top_level_param; ULONG64 new_update_version = next_update_version(top_param->version_counter); if ((shared_data = top_param->shared_data)) @@ -3166,12 +3176,12 @@ static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2) return TRUE; } -static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_parameter *param) +static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param) { unsigned int i, free_entry_index; unsigned int new_size, new_count; - if (!(param->flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->type)) + if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type)) return D3D_OK; free_entry_index = pool->size; @@ -3179,7 +3189,7 @@ static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, st { if (!pool->shared_data[i].count) free_entry_index = i; - else if (is_same_parameter(param, pool->shared_data[i].parameters[0])) + else if (is_same_parameter(¶m->param, &pool->shared_data[i].parameters[0]->param)) break; } if (i == pool->size) @@ -3222,11 +3232,11 @@ static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, st pool->shared_data = new_alloc; pool->size = new_size; } - pool->shared_data[i].data = param->data; + pool->shared_data[i].data = param->param.data; } else { - param_set_data_pointer(param, pool->shared_data[i].data, FALSE, TRUE); + param_set_data_pointer(¶m->param, pool->shared_data[i].data, FALSE, TRUE); } new_count = ++pool->shared_data[i].count; if (new_count >= pool->shared_data[i].size) @@ -3250,7 +3260,7 @@ static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, st param->shared_data = &pool->shared_data[i]; pool->shared_data[i].parameters[new_count - 1] = param; - TRACE("name %s, parameter idx %u, new refcount %u.\n", param->name, i, + TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i, new_count); return D3D_OK; @@ -3262,11 +3272,11 @@ static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param) return FALSE; } -static void d3dx_pool_release_shared_parameter(struct d3dx_parameter *param) +static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param) { unsigned int new_count; - if (!(param->flags & PARAMETER_FLAG_SHARED) || !param->shared_data) + if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data) return; new_count = --param->shared_data->count; @@ -3286,7 +3296,7 @@ static void d3dx_pool_release_shared_parameter(struct d3dx_parameter *param) break; } } - walk_parameter_tree(param, param_zero_data_func, NULL); + walk_parameter_tree(¶m->param, param_zero_data_func, NULL); } else { @@ -3995,7 +4005,7 @@ static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_ unsigned int i; unsigned int member_count; - param = param->top_level_param; + param = ¶m->top_level_param->param; if (param_func(data, param)) return TRUE; @@ -5476,7 +5486,6 @@ static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct param->name = parent->name; param->semantic = parent->semantic; param->element_count = 0; - param->annotation_count = 0; param->member_count = parent->member_count; param->bytes = parent->bytes; param->rows = parent->rows; @@ -5635,7 +5644,7 @@ err_out: return hr; } -static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_parameter *param, +static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_top_level_parameter *param, const char *data, const char **ptr, struct d3dx_object *objects) { DWORD offset; @@ -5644,29 +5653,29 @@ static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, stru const char *ptr2; read_dword(ptr, &offset); - TRACE("Typedef offset: %#x\n", offset); + TRACE("Typedef offset: %#x.\n", offset); ptr2 = data + offset; read_dword(ptr, &offset); - TRACE("Value offset: %#x\n", offset); + TRACE("Value offset: %#x.\n", offset); - read_dword(ptr, ¶m->flags); - TRACE("Flags: %#x\n", param->flags); + read_dword(ptr, ¶m->param.flags); + TRACE("Flags: %#x.\n", param->param.flags); read_dword(ptr, ¶m->annotation_count); - TRACE("Annotation count: %u\n", param->annotation_count); + TRACE("Annotation count: %u.\n", param->annotation_count); - hr = d3dx9_parse_effect_typedef(base, param, data, &ptr2, NULL, param->flags); + hr = d3dx9_parse_effect_typedef(base, ¶m->param, data, &ptr2, NULL, param->param.flags); if (hr != D3D_OK) { - WARN("Failed to parse type definition\n"); + WARN("Failed to parse type definition.\n"); return hr; } - hr = d3dx9_parse_init_value(base, param, data, data + offset, objects); + hr = d3dx9_parse_init_value(base, ¶m->param, data, data + offset, objects); if (hr != D3D_OK) { - WARN("Failed to parse value\n"); + WARN("Failed to parse value.\n"); return hr; } @@ -5676,7 +5685,7 @@ static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, stru sizeof(*param->annotations) * param->annotation_count); if (!param->annotations) { - ERR("Out of memory\n"); + ERR("Out of memory.\n"); hr = E_OUTOFMEMORY; goto err_out; } @@ -5687,7 +5696,7 @@ static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, stru hr = d3dx9_parse_effect_annotation(base, ¶m->annotations[i], data, ptr, objects); if (hr != D3D_OK) { - WARN("Failed to parse annotation\n"); + WARN("Failed to parse annotation.\n"); goto err_out; } } @@ -6035,7 +6044,7 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char * return E_FAIL; } - parameter = &base->parameters[index]; + parameter = &base->parameters[index].param; if (element_index != 0xffffffff) { if (element_index >= parameter->element_count && parameter->element_count != 0) @@ -6044,7 +6053,8 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char * return E_FAIL; } - if (parameter->element_count != 0) parameter = ¶meter->members[element_index]; + if (parameter->element_count) + parameter = ¶meter->members[element_index]; } sampler = parameter->data; @@ -6193,20 +6203,20 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da UINT i; read_dword(&ptr, &base->parameter_count); - TRACE("Parameter count: %u\n", base->parameter_count); + TRACE("Parameter count: %u.\n", base->parameter_count); read_dword(&ptr, &base->technique_count); - TRACE("Technique count: %u\n", base->technique_count); + TRACE("Technique count: %u.\n", base->technique_count); skip_dword_unknown(&ptr, 1); read_dword(&ptr, &base->object_count); - TRACE("Object count: %u\n", base->object_count); + TRACE("Object count: %u.\n", base->object_count); base->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base->objects) * base->object_count); if (!base->objects) { - ERR("Out of memory\n"); + ERR("Out of memory.\n"); hr = E_OUTOFMEMORY; goto err_out; } @@ -6217,20 +6227,22 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da sizeof(*base->parameters) * base->parameter_count); if (!base->parameters) { - ERR("Out of memory\n"); + ERR("Out of memory.\n"); hr = E_OUTOFMEMORY; goto err_out; } for (i = 0; i < base->parameter_count; ++i) { - param_set_magic_number(&base->parameters[i]); + param_set_magic_number(&base->parameters[i].param); hr = d3dx9_parse_effect_parameter(base, &base->parameters[i], data, &ptr, base->objects); if (hr != D3D_OK) { - WARN("Failed to parse parameter %u\n", i); + WARN("Failed to parse parameter %u.\n", i); goto err_out; } + walk_parameter_tree(&base->parameters[i].param, param_set_top_level_param, + &base->parameters[i]); } } @@ -6240,7 +6252,7 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da sizeof(*base->techniques) * base->technique_count); if (!base->techniques) { - ERR("Out of memory\n"); + ERR("Out of memory.\n"); hr = E_OUTOFMEMORY; goto err_out; } @@ -6251,24 +6263,24 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da hr = d3dx9_parse_effect_technique(base, &base->techniques[i], data, &ptr, base->objects); if (hr != D3D_OK) { - WARN("Failed to parse technique %u\n", i); + WARN("Failed to parse technique %u.\n", i); goto err_out; } } } read_dword(&ptr, &stringcount); - TRACE("String count: %u\n", stringcount); + TRACE("String count: %u.\n", stringcount); read_dword(&ptr, &resourcecount); - TRACE("Resource count: %u\n", resourcecount); + TRACE("Resource count: %u.\n", resourcecount); for (i = 0; i < stringcount; ++i) { DWORD id; read_dword(&ptr, &id); - TRACE("Id: %u\n", id); + TRACE("id: %u.\n", id); if (FAILED(hr = d3dx9_copy_data(base, id, &ptr))) goto err_out; @@ -6282,12 +6294,12 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da for (i = 0; i < resourcecount; ++i) { - TRACE("parse resource %u\n", i); + TRACE("parse resource %u.\n", i); hr = d3dx9_parse_resource(base, data, &ptr, skip_constants, skip_constants_count); if (hr != D3D_OK) { - WARN("Failed to parse resource %u\n", i); + WARN("Failed to parse resource %u.\n", i); goto err_out; } } @@ -6296,12 +6308,10 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da { if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i]))) goto err_out; - walk_parameter_tree(&base->parameters[i], param_set_top_level_param, - &base->parameters[i]); base->parameters[i].version_counter = base->pool ? &base->pool->version_counter : &base->version_counter; - set_dirty(&base->parameters[i]); + set_dirty(&base->parameters[i].param); } return D3D_OK; @@ -6319,7 +6329,7 @@ err_out: { for (i = 0; i < base->parameter_count; ++i) { - free_parameter(&base->parameters[i], FALSE, FALSE); + free_top_level_parameter(&base->parameters[i]); } HeapFree(GetProcessHeap(), 0, base->parameters); base->parameters = NULL; @@ -6723,12 +6733,12 @@ static void free_effect_pool(struct d3dx_effect_pool *pool) WARN("Releasing pool with referenced parameters.\n"); - param_set_data_pointer(pool->shared_data[i].parameters[0], NULL, FALSE, TRUE); + param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE); pool->shared_data[i].parameters[0]->shared_data = NULL; for (j = 1; j < pool->shared_data[i].count; ++j) { - walk_parameter_tree(pool->shared_data[i].parameters[j], param_zero_data_func, NULL); + walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL); pool->shared_data[i].parameters[j]->shared_data = NULL; } HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);