d3dx9: Introduce a handle table for parameters to make lookup faster.

This commit is contained in:
Matteo Bruni 2014-03-05 18:35:17 +01:00 committed by Alexandre Julliard
parent db8e1df742
commit 7788161c91
1 changed files with 122 additions and 106 deletions

View File

@ -32,6 +32,8 @@
#define INT_FLOAT_MULTI 255.0f
#define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
#define INITIAL_PARAM_TABLE_SIZE 16
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
enum STATE_CLASS
@ -112,6 +114,8 @@ struct d3dx_parameter
UINT bytes;
DWORD object_id;
D3DXHANDLE handle;
struct d3dx_parameter *annotations;
struct d3dx_parameter *members;
};
@ -157,6 +161,12 @@ struct d3dx_technique
struct d3dx_pass *passes;
};
struct param_table
{
struct d3dx_parameter **table;
unsigned int count, size;
};
struct d3dx9_base_effect
{
struct ID3DXEffectImpl *effect;
@ -168,6 +178,8 @@ struct d3dx9_base_effect
struct d3dx_parameter *parameters;
struct d3dx_technique *techniques;
struct d3dx_object *objects;
struct param_table param_table;
};
struct ID3DXEffectImpl
@ -198,8 +210,8 @@ static struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *ba
struct d3dx_parameter *parameter, const char *name);
static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *parameters,
const char *name);
static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr,
struct d3dx_object *objects);
static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
const char *data, const char **ptr, struct d3dx_object *objects);
static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
static const struct
@ -426,7 +438,7 @@ static void skip_dword_unknown(const char **ptr, unsigned int count)
static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
{
return (D3DXHANDLE) parameter;
return parameter ? parameter->handle : NULL;
}
static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
@ -485,74 +497,12 @@ static struct d3dx_pass *get_valid_pass(struct d3dx9_base_effect *base, D3DXHAND
return NULL;
}
static struct d3dx_parameter *get_valid_sub_parameter(struct d3dx_parameter *param, D3DXHANDLE parameter)
{
unsigned int i, count;
struct d3dx_parameter *p;
for (i = 0; i < param->annotation_count; ++i)
{
if (get_parameter_handle(&param->annotations[i]) == parameter)
return &param->annotations[i];
p = get_valid_sub_parameter(&param->annotations[i], parameter);
if (p) return p;
}
count = param->element_count ? param->element_count : param->member_count;
for (i = 0; i < count; ++i)
{
if (get_parameter_handle(&param->members[i]) == parameter)
return &param->members[i];
p = get_valid_sub_parameter(&param->members[i], parameter);
if (p) return p;
}
return NULL;
}
static struct d3dx_parameter *get_valid_parameter(struct d3dx9_base_effect *base, D3DXHANDLE parameter)
{
unsigned int i, k, m;
struct d3dx_parameter *p;
struct d3dx_parameter **handle_param = (struct d3dx_parameter **)parameter;
for (i = 0; i < base->parameter_count; ++i)
{
if (get_parameter_handle(&base->parameters[i]) == parameter)
return &base->parameters[i];
p = get_valid_sub_parameter(&base->parameters[i], parameter);
if (p) return p;
}
for (i = 0; i < base->technique_count; ++i)
{
struct d3dx_technique *technique = &base->techniques[i];
for (k = 0; k < technique->pass_count; ++k)
{
struct d3dx_pass *pass = &technique->passes[k];
for (m = 0; m < pass->annotation_count; ++m)
{
if (get_parameter_handle(&pass->annotations[m]) == parameter)
return &pass->annotations[m];
p = get_valid_sub_parameter(&pass->annotations[m], parameter);
if (p) return p;
}
}
for (k = 0; k < technique->annotation_count; ++k)
{
if (get_parameter_handle(&technique->annotations[k]) == parameter)
return &technique->annotations[k];
p = get_valid_sub_parameter(&technique->annotations[k], parameter);
if (p) return p;
}
}
if (handle_param >= base->param_table.table && handle_param < base->param_table.table + base->param_table.count)
return *handle_param;
return get_parameter_by_name(base, NULL, parameter);
}
@ -714,6 +664,8 @@ static void d3dx9_base_effect_cleanup(struct d3dx9_base_effect *base)
TRACE("base %p.\n", base);
HeapFree(GetProcessHeap(), 0, base->param_table.table);
if (base->parameters)
{
for (i = 0; i < base->parameter_count; ++i)
@ -4147,8 +4099,8 @@ static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
ID3DXEffectCompilerImpl_CompileShader,
};
static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *data, const char **ptr,
struct d3dx_object *objects)
static HRESULT d3dx9_parse_sampler(struct d3dx9_base_effect *base, struct d3dx_sampler *sampler,
const char *data, const char **ptr, struct d3dx_object *objects)
{
HRESULT hr;
UINT i;
@ -4165,7 +4117,7 @@ static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *dat
for (i = 0; i < sampler->state_count; ++i)
{
hr = d3dx9_parse_state(&sampler->states[i], data, ptr, objects);
hr = d3dx9_parse_state(base, &sampler->states[i], data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse state %u\n", i);
@ -4187,8 +4139,8 @@ err_out:
return hr;
}
static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char *data,
const char **ptr, struct d3dx_object *objects)
static HRESULT d3dx9_parse_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
void *value, const char *data, const char **ptr, struct d3dx_object *objects)
{
unsigned int i;
HRESULT hr;
@ -4202,7 +4154,7 @@ static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, cons
{
struct d3dx_parameter *member = &param->members[i];
hr = d3dx9_parse_value(member, value ? (char *)value + old_size : NULL, data, ptr, objects);
hr = d3dx9_parse_value(base, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse value %u\n", i);
@ -4231,7 +4183,7 @@ static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, cons
{
struct d3dx_parameter *member = &param->members[i];
hr = d3dx9_parse_value(member, (char *)value + old_size, data, ptr, objects);
hr = d3dx9_parse_value(base, member, (char *)value + old_size, data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse value %u\n", i);
@ -4271,7 +4223,7 @@ static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, cons
if (!sampler)
return E_OUTOFMEMORY;
hr = d3dx9_parse_sampler(sampler, data, ptr, objects);
hr = d3dx9_parse_sampler(base, sampler, data, ptr, objects);
if (hr != D3D_OK)
{
HeapFree(GetProcessHeap(), 0, sampler);
@ -4297,8 +4249,8 @@ static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, cons
return D3D_OK;
}
static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *data, const char *ptr,
struct d3dx_object *objects)
static HRESULT d3dx9_parse_init_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
const char *data, const char *ptr, struct d3dx_object *objects)
{
UINT size = param->bytes;
HRESULT hr;
@ -4335,7 +4287,7 @@ static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *
}
}
hr = d3dx9_parse_value(param, value, data, &ptr, objects);
hr = d3dx9_parse_value(base, param, value, data, &ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse value\n");
@ -4394,8 +4346,63 @@ static HRESULT d3dx9_copy_data(struct d3dx_object *object, const char **ptr)
return D3D_OK;
}
static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
struct d3dx_parameter *parent, UINT flags)
static void add_param_to_table(struct d3dx9_base_effect *base, struct d3dx_parameter *param)
{
struct param_table *table = &base->param_table;
if (table->count >= table->size)
{
unsigned int new_size;
struct d3dx_parameter **new_alloc;
if (!table->size)
{
new_size = INITIAL_PARAM_TABLE_SIZE;
new_alloc = HeapAlloc(GetProcessHeap(), 0, sizeof(*table->table) * new_size);
if (!new_alloc)
{
ERR("Out of memory.\n");
return;
}
}
else
{
new_size = table->size * 2;
new_alloc = HeapReAlloc(GetProcessHeap(), 0, table->table, sizeof(*table->table) * new_size);
if (!new_alloc)
{
ERR("Out of memory.\n");
return;
}
}
table->table = new_alloc;
table->size = new_size;
}
table->table[table->count++] = param;
}
static void sync_param_handles(struct d3dx9_base_effect *base)
{
struct param_table *table = &base->param_table;
struct d3dx_parameter **new_alloc;
unsigned int i;
if (table->count)
{
new_alloc = HeapReAlloc(GetProcessHeap(), 0, table->table, sizeof(*table->table) * table->count);
if (new_alloc)
table->table = new_alloc;
else
ERR("Out of memory.\n");
}
for (i = 0; i < table->count; ++i)
table->table[i]->handle = (D3DXHANDLE)&table->table[i];
}
static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
{
DWORD offset;
HRESULT hr;
@ -4528,7 +4535,8 @@ static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const ch
{
*ptr = save_ptr;
hr = d3dx9_parse_effect_typedef(&param->members[i], data, ptr, param, flags);
add_param_to_table(base, &param->members[i]);
hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, param, flags);
if (hr != D3D_OK)
{
WARN("Failed to parse member %u\n", i);
@ -4552,7 +4560,8 @@ static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const ch
for (i = 0; i < param->member_count; ++i)
{
hr = d3dx9_parse_effect_typedef(&param->members[i], data, ptr, NULL, flags);
add_param_to_table(base, &param->members[i]);
hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, NULL, flags);
if (hr != D3D_OK)
{
WARN("Failed to parse member %u\n", i);
@ -4587,8 +4596,8 @@ err_out:
return hr;
}
static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data,
const char **ptr, struct d3dx_object *objects)
static HRESULT d3dx9_parse_effect_annotation(struct d3dx9_base_effect *base, struct d3dx_parameter *anno,
const char *data, const char **ptr, struct d3dx_object *objects)
{
DWORD offset;
const char *ptr2;
@ -4599,7 +4608,7 @@ static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const
read_dword(ptr, &offset);
TRACE("Typedef offset: %#x\n", offset);
ptr2 = data + offset;
hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
hr = d3dx9_parse_effect_typedef(base, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
if (hr != D3D_OK)
{
WARN("Failed to parse type definition\n");
@ -4608,7 +4617,7 @@ static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const
read_dword(ptr, &offset);
TRACE("Value offset: %#x\n", offset);
hr = d3dx9_parse_init_value(anno, data, data + offset, objects);
hr = d3dx9_parse_init_value(base, anno, data, data + offset, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse value\n");
@ -4618,8 +4627,8 @@ static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const
return D3D_OK;
}
static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr,
struct d3dx_object *objects)
static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
const char *data, const char **ptr, struct d3dx_object *objects)
{
DWORD offset;
const char *ptr2;
@ -4636,7 +4645,7 @@ static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, con
read_dword(ptr, &offset);
TRACE("Typedef offset: %#x\n", offset);
ptr2 = data + offset;
hr = d3dx9_parse_effect_typedef(&state->parameter, data, &ptr2, NULL, 0);
hr = d3dx9_parse_effect_typedef(base, &state->parameter, data, &ptr2, NULL, 0);
if (hr != D3D_OK)
{
WARN("Failed to parse type definition\n");
@ -4645,7 +4654,7 @@ static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, con
read_dword(ptr, &offset);
TRACE("Value offset: %#x\n", offset);
hr = d3dx9_parse_init_value(&state->parameter, data, data + offset, objects);
hr = d3dx9_parse_init_value(base, &state->parameter, data, data + offset, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse value\n");
@ -4661,8 +4670,8 @@ err_out:
return hr;
}
static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data,
const char **ptr, struct d3dx_object *objects)
static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
const char *data, const char **ptr, struct d3dx_object *objects)
{
DWORD offset;
HRESULT hr;
@ -4682,14 +4691,14 @@ static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const
read_dword(ptr, &param->annotation_count);
TRACE("Annotation count: %u\n", param->annotation_count);
hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
hr = d3dx9_parse_effect_typedef(base, param, data, &ptr2, NULL, param->flags);
if (hr != D3D_OK)
{
WARN("Failed to parse type definition\n");
return hr;
}
hr = d3dx9_parse_init_value(param, data, data + offset, objects);
hr = d3dx9_parse_init_value(base, param, data, data + offset, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse value\n");
@ -4709,7 +4718,8 @@ static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const
for (i = 0; i < param->annotation_count; ++i)
{
hr = d3dx9_parse_effect_annotation(&param->annotations[i], data, ptr, objects);
add_param_to_table(base, &param->annotations[i]);
hr = d3dx9_parse_effect_annotation(base, &param->annotations[i], data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse annotation\n");
@ -4733,8 +4743,8 @@ err_out:
return hr;
}
static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr,
struct d3dx_object *objects)
static HRESULT d3dx9_parse_effect_pass(struct d3dx9_base_effect *base, struct d3dx_pass *pass,
const char *data, const char **ptr, struct d3dx_object *objects)
{
DWORD offset;
HRESULT hr;
@ -4770,7 +4780,8 @@ static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data,
for (i = 0; i < pass->annotation_count; ++i)
{
hr = d3dx9_parse_effect_annotation(&pass->annotations[i], data, ptr, objects);
add_param_to_table(base, &pass->annotations[i]);
hr = d3dx9_parse_effect_annotation(base, &pass->annotations[i], data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse annotation %u\n", i);
@ -4791,7 +4802,7 @@ static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data,
for (i = 0; i < pass->state_count; ++i)
{
hr = d3dx9_parse_state(&states[i], data, ptr, objects);
hr = d3dx9_parse_state(base, &states[i], data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse annotation %u\n", i);
@ -4829,8 +4840,8 @@ err_out:
return hr;
}
static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data,
const char **ptr, struct d3dx_object *objects)
static HRESULT d3dx9_parse_effect_technique(struct d3dx9_base_effect *base, struct d3dx_technique *technique,
const char *data, const char **ptr, struct d3dx_object *objects)
{
DWORD offset;
HRESULT hr;
@ -4865,7 +4876,8 @@ static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, co
for (i = 0; i < technique->annotation_count; ++i)
{
hr = d3dx9_parse_effect_annotation(&technique->annotations[i], data, ptr, objects);
add_param_to_table(base, &technique->annotations[i]);
hr = d3dx9_parse_effect_annotation(base, &technique->annotations[i], data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse annotation %u\n", i);
@ -4887,7 +4899,7 @@ static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, co
for (i = 0; i < technique->pass_count; ++i)
{
hr = d3dx9_parse_effect_pass(&technique->passes[i], data, ptr, objects);
hr = d3dx9_parse_effect_pass(base, &technique->passes[i], data, ptr, objects);
if (hr != D3D_OK)
{
WARN("Failed to parse pass %u\n", i);
@ -5089,7 +5101,8 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da
for (i = 0; i < base->parameter_count; ++i)
{
hr = d3dx9_parse_effect_parameter(&base->parameters[i], data, &ptr, base->objects);
add_param_to_table(base, &base->parameters[i]);
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);
@ -5111,7 +5124,8 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da
for (i = 0; i < base->technique_count; ++i)
{
hr = d3dx9_parse_effect_technique(&base->techniques[i], data, &ptr, base->objects);
TRACE("Parsing technique %u.\n", i);
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);
@ -5120,6 +5134,8 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da
}
}
sync_param_handles(base);
read_dword(&ptr, &stringcount);
TRACE("String count: %u\n", stringcount);