[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(&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);
 
-- 
1.8.3.2




More information about the wine-patches mailing list