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




More information about the wine-patches mailing list