[PATCH 2/5] d3dx9: Introduce a handle table for parameters to make lookup faster.
Matteo Bruni
mbruni at codeweavers.com
Wed Mar 5 11:35:17 CST 2014
---
dlls/d3dx9_36/effect.c | 228 ++++++++++++++++++++++++++-----------------------
1 file changed, 122 insertions(+), 106 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index b7abe24..9a8f727 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -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(¶m->annotations[i]) == parameter)
- return ¶m->annotations[i];
-
- p = get_valid_sub_parameter(¶m->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(¶m->members[i]) == parameter)
- return ¶m->members[i];
-
- p = get_valid_sub_parameter(¶m->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 = ¶m->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 = ¶m->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(¶m->members[i], data, ptr, param, flags);
+ add_param_to_table(base, ¶m->members[i]);
+ hr = d3dx9_parse_effect_typedef(base, ¶m->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(¶m->members[i], data, ptr, NULL, flags);
+ add_param_to_table(base, ¶m->members[i]);
+ hr = d3dx9_parse_effect_typedef(base, ¶m->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, ¶m->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(¶m->annotations[i], data, ptr, objects);
+ add_param_to_table(base, ¶m->annotations[i]);
+ hr = d3dx9_parse_effect_annotation(base, ¶m->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);
--
1.8.3.2
More information about the wine-patches
mailing list