d3dx9: Use distinct structure for top level parameters.

Signed-off-by: Paul Gofman <gofmanp@gmail.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2017-08-03 19:42:08 +02:00 committed by Alexandre Julliard
parent 3a10679b7a
commit 847f772fe1
2 changed files with 116 additions and 91 deletions

View File

@ -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 &param->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;

View File

@ -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(&param->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(&param->annotations[i], FALSE, FALSE);
HeapFree(GetProcessHeap(), 0, param->annotations);
}
d3dx_pool_release_shared_parameter(param);
free_parameter(&param->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 = &parameters[i];
temp_parameter = !parameter ? &base->parameters[i].param
: &parameter->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(&param->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(&param->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(&param->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 = &param->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, &param->flags);
TRACE("Flags: %#x\n", param->flags);
read_dword(ptr, &param->param.flags);
TRACE("Flags: %#x.\n", param->param.flags);
read_dword(ptr, &param->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, &param->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, &param->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, &param->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 = &parameter->members[element_index];
if (parameter->element_count)
parameter = &parameter->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);