[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