[v2 4/5] d3dx9: Avoid redundant constant tables updates.

Paul Gofman gofmanp at gmail.com
Tue May 16 11:49:20 CDT 2017


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
v2:
    - avoid redundant updates on temporary table in set_preshader_modified().
---
 dlls/d3dx9_36/preshader.c | 72 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 56 insertions(+), 16 deletions(-)

diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
index 208e631..e29ede0 100644
--- a/dlls/d3dx9_36/preshader.c
+++ b/dlls/d3dx9_36/preshader.c
@@ -348,13 +348,8 @@ static void regstore_set_double(struct d3dx_regstore *rs, unsigned int table, un
             1u << (reg_idx % PRES_BITMASK_BLOCK_SIZE);
 }
 
-static void regstore_reset_table(struct d3dx_regstore *rs, unsigned int table)
+static void regstore_reset_modified(struct d3dx_regstore *rs, unsigned int table)
 {
-    unsigned int size;
-
-    size = rs->table_sizes[table] * table_info[table].reg_component_count * table_info[table].component_size;
-
-    memset(rs->tables[table], 0, size);
     memset(rs->table_value_set[table], 0,
             sizeof(*rs->table_value_set[table]) *
             ((rs->table_sizes[table] + PRES_BITMASK_BLOCK_SIZE - 1) / PRES_BITMASK_BLOCK_SIZE));
@@ -946,7 +941,7 @@ void d3dx_free_param_eval(struct d3dx_param_eval *peval)
 }
 
 static void set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const_tab,
-        BOOL update_all, ULONG64 new_update_version)
+        ULONG64 new_update_version)
 {
     unsigned int const_idx;
 
@@ -961,7 +956,7 @@ static void set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const
         BOOL transpose;
         unsigned int count;
 
-        if (!(update_all || is_param_dirty(param, const_tab->update_version)))
+        if (!is_param_dirty(param, const_tab->update_version))
             continue;
 
         transpose = (const_set->constant_class == D3DXPC_MATRIX_COLUMNS && param->class == D3DXPC_MATRIX_ROWS)
@@ -1301,6 +1296,23 @@ static HRESULT execute_preshader(struct d3dx_preshader *pres)
     return D3D_OK;
 }
 
+static void set_preshader_modified(struct d3dx_preshader *pres)
+{
+    unsigned int i;
+
+    for (i = 0; i < pres->ins_count; ++i)
+    {
+        const struct d3dx_pres_ins *ins = &pres->ins[i];
+        const struct d3dx_pres_reg *reg = &ins->output.reg;
+
+        if (reg->table == PRES_REGTAB_TEMP)
+            continue;
+
+        regstore_set_modified(&pres->regs, reg->table, reg->offset,
+                pres_op_info[ins->op].func_all_comps ? 1 : ins->component_count);
+    }
+}
+
 static BOOL is_const_tab_input_dirty(struct d3dx_const_tab *ctab, ULONG64 update_version)
 {
     unsigned int i;
@@ -1333,7 +1345,7 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx
 
     if (is_const_tab_input_dirty(&peval->pres.inputs, ~0))
     {
-        set_constants(&peval->pres.regs, &peval->pres.inputs, FALSE,
+        set_constants(&peval->pres.regs, &peval->pres.inputs,
                 next_update_version(peval->version_counter));
 
         if (FAILED(hr = execute_preshader(&peval->pres)))
@@ -1420,7 +1432,7 @@ static HRESULT set_shader_constants_device(ID3DXEffectStateManager *manager, str
         }
         start += count;
     }
-    regstore_reset_table(rs, table);
+    regstore_reset_modified(rs, table);
     return result;
 }
 
@@ -1434,22 +1446,50 @@ HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, s
     struct d3dx_regstore *rs = &pres->regs;
     unsigned int i;
     ULONG64 new_update_version = next_update_version(peval->version_counter);
+    BOOL update_device = update_all;
 
     TRACE("device %p, peval %p, param_type %u.\n", device, peval, peval->param_type);
 
-    if (update_all || is_const_tab_input_dirty(&pres->inputs, ~0))
+    if (is_const_tab_input_dirty(&pres->inputs, ~0))
     {
-        set_constants(rs, &pres->inputs, update_all, new_update_version);
+        set_constants(rs, &pres->inputs, new_update_version);
         if (FAILED(hr = execute_preshader(pres)))
             return hr;
+        update_device = TRUE;
     }
 
-    set_constants(rs, &peval->shader_inputs, update_all, new_update_version);
+    if (is_const_tab_input_dirty(&peval->shader_inputs, ~0))
+    {
+        set_constants(rs, &peval->shader_inputs, new_update_version);
+        update_device = TRUE;
+    }
     result = D3D_OK;
-    for (i = 0; i < ARRAY_SIZE(set_tables); ++i)
+
+    if (update_device)
     {
-        if (FAILED(hr = set_shader_constants_device(manager, device, rs, peval->param_type, set_tables[i])))
-            result = hr;
+        if (update_all)
+        {
+            for (i = 0; i < peval->shader_inputs.input_count; ++i)
+            {
+                unsigned int table;
+
+                if (!peval->shader_inputs.inputs[i].RegisterCount)
+                    continue;
+                table = peval->shader_inputs.regset2table[peval->shader_inputs.inputs[i].RegisterSet];
+                if (table < PRES_REGTAB_COUNT)
+                    regstore_set_modified_reg(rs, table,
+                            peval->shader_inputs.inputs[i].RegisterIndex,
+                            peval->shader_inputs.inputs[i].RegisterIndex
+                            + peval->shader_inputs.inputs[i].RegisterCount - 1);
+            }
+            set_preshader_modified(pres);
+        }
+
+        for (i = 0; i < ARRAY_SIZE(set_tables); ++i)
+        {
+            if (FAILED(hr = set_shader_constants_device(manager, device, rs, peval->param_type, set_tables[i])))
+                result = hr;
+        }
     }
     return result;
 }
-- 
2.9.3




More information about the wine-patches mailing list