Module: wine Branch: master Commit: 5e87656ec3b054fec0d3ae19db4af7c8ac2e67f2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5e87656ec3b054fec0d3ae19db...
Author: Paul Gofman gofmanp@gmail.com Date: Thu May 18 19:23:19 2017 +0200
d3dx9: Avoid redundant constant tables updates.
Signed-off-by: Paul Gofman gofmanp@gmail.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 6eddf6e..49eeb22 100644 --- a/dlls/d3dx9_36/preshader.c +++ b/dlls/d3dx9_36/preshader.c @@ -352,13 +352,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)); @@ -950,7 +945,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;
@@ -965,7 +960,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) @@ -1305,6 +1300,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; @@ -1337,7 +1349,7 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx
if (is_const_tab_input_dirty(&peval->pres.inputs, ULONG64_MAX)) { - 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))) @@ -1424,7 +1436,7 @@ static HRESULT set_shader_constants_device(ID3DXEffectStateManager *manager, str } start += count; } - regstore_reset_table(rs, table); + regstore_reset_modified(rs, table); return result; }
@@ -1438,22 +1450,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, ULONG64_MAX)) + if (is_const_tab_input_dirty(&pres->inputs, ULONG64_MAX)) { - 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, ULONG64_MAX)) + { + 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; }