[PATCH 8/8] d3dx9: Use local dirty flags for shared parameters.

Paul Gofman gofmanp at gmail.com
Thu Apr 20 06:26:50 CDT 2017


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
 dlls/d3dx9_36/d3dx9_private.h |  5 ++---
 dlls/d3dx9_36/effect.c        | 47 +++++++++++++++++++++++++++++++++++--------
 dlls/d3dx9_36/tests/effect.c  |  4 ++--
 3 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index d6d4280..f9cbf7c 100644
--- a/dlls/d3dx9_36/d3dx9_private.h
+++ b/dlls/d3dx9_36/d3dx9_private.h
@@ -222,15 +222,14 @@ struct d3dx_parameter
     {
         struct d3dx_parameter *referenced_param;
         struct d3dx_parameter *shared_param;
+        struct d3dx_parameter **shared_param_list;
     };
     LONG shared_refcount;
 };
 
 static inline BOOL is_param_dirty(struct d3dx_parameter *param)
 {
-    return param->top_level_param->shared_param
-            ? param->top_level_param->shared_param->runtime_flags & PARAMETER_FLAG_DIRTY
-            : param->top_level_param->runtime_flags & PARAMETER_FLAG_DIRTY;
+    return param->top_level_param->runtime_flags & PARAMETER_FLAG_DIRTY;
 }
 
 struct d3dx9_base_effect;
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 74a3e4d..16e01ed 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -1404,9 +1404,17 @@ static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep
 static void set_dirty(struct d3dx_parameter *param)
 {
     if (param->top_level_param->shared_param)
-        param->top_level_param->shared_param->runtime_flags |= PARAMETER_FLAG_DIRTY;
+    {
+        struct d3dx_parameter *shared_param = param->top_level_param->shared_param;
+        unsigned int i;
+
+        for (i = 0; i < shared_param->shared_refcount; ++i)
+            shared_param->shared_param_list[i]->runtime_flags |= PARAMETER_FLAG_DIRTY;
+    }
     else
+    {
         param->top_level_param->runtime_flags |= PARAMETER_FLAG_DIRTY;
+    }
 }
 
 static void clear_dirty_params(struct d3dx9_base_effect *base)
@@ -1414,12 +1422,7 @@ static void clear_dirty_params(struct d3dx9_base_effect *base)
     unsigned int i;
 
     for (i = 0; i < base->parameter_count; ++i)
-    {
-        if (base->parameters[i].shared_param)
-            base->parameters[i].shared_param->runtime_flags &= ~PARAMETER_FLAG_DIRTY;
-        else
-            base->parameters[i].runtime_flags &= ~PARAMETER_FLAG_DIRTY;
-    }
+        base->parameters[i].runtime_flags &= ~PARAMETER_FLAG_DIRTY;
 }
 
 static HRESULT d3dx9_base_effect_set_value(struct d3dx9_base_effect *base,
@@ -3193,7 +3196,16 @@ static void d3dx_pool_sync_shared_parameter(struct ID3DXEffectPoolImpl *pool, st
         param_set_data_pointer(param, (unsigned char *)pool->parameters[i]->data, FALSE, TRUE);
     }
     new_refcount = InterlockedIncrement(&pool->parameters[i]->shared_refcount);
+    if (new_refcount == 1)
+        pool->parameters[i]->shared_param_list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                sizeof(*pool->parameters[i]->shared_param_list));
+    else
+        pool->parameters[i]->shared_param_list = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                pool->parameters[i]->shared_param_list,
+                sizeof(*pool->parameters[i]->shared_param_list) * new_refcount);
+
     param->shared_param = pool->parameters[i];
+    pool->parameters[i]->shared_param_list[new_refcount - 1] = param;
 
     TRACE("name %s, parameter idx %u, new refcount %u.\n", param->name, i,
             new_refcount);
@@ -3219,8 +3231,27 @@ static void d3dx_pool_release_shared_parameter(struct d3dx_parameter *param)
 
     walk_parameter_tree(param, param_zero_data_func, NULL);
 
-    if (!new_refcount)
+    if (new_refcount)
+    {
+        unsigned int i;
+
+        for (i = 0; i < new_refcount; ++i)
+        {
+            if (param->shared_param->shared_param_list[i] == param)
+            {
+                memmove(&param->shared_param->shared_param_list[i],
+                        &param->shared_param->shared_param_list[i + 1],
+                        sizeof(param->shared_param->shared_param_list[i]) * (new_refcount - i));
+                break;
+            }
+        }
+    }
+    else
+    {
+        HeapFree(GetProcessHeap(), 0, param->shared_param->shared_param_list);
+        param->shared_param->shared_param_list = NULL;
         free_parameter(param->shared_param, FALSE, FALSE);
+    }
 }
 
 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 968a447..4246fe2 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -6093,9 +6093,9 @@ static void test_effect_shared_parameters(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     fvect.x = 28.0f;
-    test_effect_shared_parameters_compare_vconst(device, 29, &fvect, TRUE);
+    test_effect_shared_parameters_compare_vconst(device, 29, &fvect, FALSE);
     fvect.x = -1.0f;
-    test_effect_shared_parameters_compare_vconst(device, 30, &fvect, TRUE);
+    test_effect_shared_parameters_compare_vconst(device, 30, &fvect, FALSE);
 
     fval[0] = -2.0f;
     hr = effect2->lpVtbl->SetFloat(effect2, "arr2[0]", fval[0]);
-- 
2.9.3




More information about the wine-patches mailing list