[PATCH 4/5] d3dx9: Use distinct structure for top level parameters.
Matteo Bruni
mbruni at codeweavers.com
Thu Aug 3 12:42:08 CDT 2017
From: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
v2: Use CONTAINING_RECORD(), small simplification in
get_parameter_by_name().
dlls/d3dx9_36/d3dx9_private.h | 33 +++++---
dlls/d3dx9_36/effect.c | 172 ++++++++++++++++++++++--------------------
2 files changed, 115 insertions(+), 90 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index 1136d48927..55b7431379 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;
- ULONG64 update_version;
- ULONG64 *version_counter;
- struct d3dx_parameter *annotations;
struct d3dx_parameter *members;
+ char *semantic;
+};
- struct d3dx_param_eval *param_eval;
-
- struct d3dx_parameter *top_level_param;
+struct d3dx_top_level_parameter
+{
+ struct d3dx_parameter param;
+ UINT annotation_count;
+ struct d3dx_parameter *annotations;
+ ULONG64 update_version;
+ ULONG64 *version_counter;
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 d52301cff9..8095a0ee33 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);
--
2.13.0
More information about the wine-patches
mailing list