d3dx9: Use versioned parameter updates instead of 'dirty' flags.

Signed-off-by: Paul Gofman <gofmanp@gmail.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Paul Gofman 2017-05-16 19:49:17 +03:00 committed by Alexandre Julliard
parent a100d6a7a5
commit a179584844
3 changed files with 87 additions and 53 deletions

View File

@ -163,6 +163,7 @@ struct d3dx_const_tab
unsigned int const_set_size;
struct d3dx_const_param_eval_output *const_set;
const enum pres_reg_tables *regset2table;
ULONG64 update_version;
};
struct d3dx_regstore
@ -190,9 +191,9 @@ struct d3dx_param_eval
struct d3dx_preshader pres;
struct d3dx_const_tab shader_inputs;
};
#define PARAMETER_FLAG_DIRTY 0x1u
ULONG64 *version_counter;
};
struct d3dx_shared_data;
@ -211,8 +212,9 @@ struct d3dx_parameter
UINT member_count;
DWORD flags;
UINT bytes;
DWORD runtime_flags;
DWORD object_id;
ULONG64 update_version;
ULONG64 *version_counter;
struct d3dx_parameter *annotations;
struct d3dx_parameter *members;
@ -227,13 +229,31 @@ struct d3dx_parameter
} u;
};
static inline BOOL is_param_dirty(struct d3dx_parameter *param)
struct d3dx_shared_data
{
return param->top_level_param->runtime_flags & PARAMETER_FLAG_DIRTY;
}
void *data;
struct d3dx_parameter **parameters;
unsigned int size, count;
ULONG64 update_version;
};
struct d3dx9_base_effect;
static inline ULONG64 next_update_version(ULONG64 *version_counter)
{
return ++*version_counter;
}
static inline BOOL is_param_dirty(struct d3dx_parameter *param, ULONG64 update_version)
{
struct d3dx_shared_data *shared_data;
if ((shared_data = param->top_level_param->u.shared_data))
return update_version < shared_data->update_version;
else
return update_version < param->top_level_param->update_version;
}
struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
@ -242,10 +262,11 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
#define SET_D3D_STATE(base_effect, args...) SET_D3D_STATE_(base_effect->manager, base_effect->device, args)
void d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code,
unsigned int byte_code_size, D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval) DECLSPEC_HIDDEN;
unsigned int byte_code_size, D3DXPARAMETER_TYPE type,
struct d3dx_param_eval **peval, ULONG64 *version_counter) DECLSPEC_HIDDEN;
void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval,
const struct d3dx_parameter *param, void *param_value, BOOL update_all) DECLSPEC_HIDDEN;
const struct d3dx_parameter *param, void *param_value) DECLSPEC_HIDDEN;
HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
struct d3dx_param_eval *peval, BOOL update_all) DECLSPEC_HIDDEN;
BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;

View File

@ -127,6 +127,8 @@ struct d3dx_pass
struct d3dx_state *states;
struct d3dx_parameter *annotations;
ULONG64 update_version;
};
struct d3dx_technique
@ -155,6 +157,8 @@ struct d3dx9_base_effect
struct d3dx_effect_pool *pool;
DWORD flags;
ULONG64 version_counter;
};
struct ID3DXEffectImpl
@ -180,13 +184,6 @@ struct ID3DXEffectImpl
#define INITIAL_SHARED_DATA_SIZE 4
struct d3dx_shared_data
{
void *data;
struct d3dx_parameter **parameters;
unsigned int size, count;
};
struct d3dx_effect_pool
{
ID3DXEffectPool ID3DXEffectPool_iface;
@ -194,6 +191,8 @@ struct d3dx_effect_pool
struct d3dx_shared_data *shared_data;
unsigned int size;
ULONG64 version_counter;
};
struct ID3DXEffectCompilerImpl
@ -1033,7 +1032,7 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta
{
case ST_PARAMETER:
param = param->u.referenced_param;
*param_dirty = is_param_dirty(param);
*param_dirty = is_param_dirty(param, pass->update_version);
/* fallthrough */
case ST_CONSTANT:
*out_param = param;
@ -1054,8 +1053,7 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta
}
if (update_all || is_param_eval_input_dirty(param->param_eval))
{
if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param,
&array_idx, update_all)))
if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
return hr;
}
else
@ -1073,7 +1071,7 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta
return E_FAIL;
}
selected_param = &ref_param->members[array_idx];
*param_dirty = state->index != array_idx || is_param_dirty(selected_param);
*param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
state->index = array_idx;
*param_value = selected_param->data;
@ -1088,7 +1086,7 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta
if (update_all || is_param_eval_input_dirty(param->param_eval))
{
*param_dirty = TRUE;
return d3dx_evaluate_parameter(param->param_eval, param, *param_value, update_all);
return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
}
else
return D3D_OK;
@ -1473,28 +1471,26 @@ static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep
return FALSE;
}
static ULONG64 *get_version_counter_ptr(struct d3dx9_base_effect *base)
{
return base->pool ? &base->pool->version_counter : &base->version_counter;
}
static ULONG64 next_effect_update_version(struct d3dx9_base_effect *base)
{
return next_update_version(get_version_counter_ptr(base));
}
static void set_dirty(struct d3dx_parameter *param)
{
struct d3dx_shared_data *shared_data;
unsigned int i;
struct d3dx_parameter *top_param = param->top_level_param;
ULONG64 new_update_version = next_update_version(top_param->version_counter);
if ((shared_data = param->top_level_param->u.shared_data))
{
for (i = 0; i < shared_data->count; ++i)
shared_data->parameters[i]->runtime_flags |= PARAMETER_FLAG_DIRTY;
}
if ((shared_data = top_param->u.shared_data))
shared_data->update_version = new_update_version;
else
{
param->top_level_param->runtime_flags |= PARAMETER_FLAG_DIRTY;
}
}
static void clear_dirty_params(struct d3dx9_base_effect *base)
{
unsigned int i;
for (i = 0; i < base->parameter_count; ++i)
base->parameters[i].runtime_flags &= ~PARAMETER_FLAG_DIRTY;
top_param->update_version = new_update_version;
}
static HRESULT set_string(char **param_data, const char *string)
@ -3078,6 +3074,7 @@ static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3
unsigned int i;
HRESULT ret;
HRESULT hr;
ULONG64 new_update_version = next_effect_update_version(&effect->base_effect);
TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
@ -3109,7 +3106,7 @@ static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3
}
effect->material_updated = FALSE;
clear_dirty_params(&effect->base_effect);
pass->update_version = new_update_version;
return ret;
}
@ -5944,7 +5941,7 @@ static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct
if (string_size % sizeof(DWORD))
FIXME("Unaligned string_size %u.\n", string_size);
d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1, object->size - (string_size + sizeof(DWORD)),
D3DXPT_INT, &param->param_eval);
D3DXPT_INT, &param->param_eval, get_version_counter_ptr(base));
ret = D3D_OK;
param = param->u.referenced_param;
if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
@ -5962,7 +5959,8 @@ static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct
{
TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
object = &base->objects[param->members[i].object_id];
d3dx_create_param_eval(base, object->data, object->size, param->type, &param->members[i].param_eval);
d3dx_create_param_eval(base, object->data, object->size, param->type,
&param->members[i].param_eval, get_version_counter_ptr(base));
}
}
}
@ -6075,7 +6073,8 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
{
if (FAILED(hr = d3dx9_create_object(base, object)))
return hr;
d3dx_create_param_eval(base, object->data, object->size, param->type, &param->param_eval);
d3dx_create_param_eval(base, object->data, object->size, param->type,
&param->param_eval, get_version_counter_ptr(base));
}
break;
@ -6086,7 +6085,8 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
state->type = ST_FXLC;
if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
return hr;
d3dx_create_param_eval(base, object->data, object->size, param->type, &param->param_eval);
d3dx_create_param_eval(base, object->data, object->size, param->type,
&param->param_eval, get_version_counter_ptr(base));
break;
default:
@ -6113,7 +6113,7 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
if (!refpar->param_eval)
d3dx_create_param_eval(base, refobj->data, refobj->size,
refpar->type, &refpar->param_eval);
refpar->type, &refpar->param_eval, get_version_counter_ptr(base));
}
}
else
@ -6257,6 +6257,10 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da
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]);
}
return D3D_OK;

View File

@ -813,7 +813,7 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u
}
void d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, unsigned int byte_code_size,
D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out)
D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out, ULONG64 *version_counter)
{
struct d3dx_param_eval *peval;
unsigned int *ptr;
@ -836,6 +836,8 @@ void d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_co
if (!peval)
goto err_out;
peval->version_counter = version_counter;
peval->param_type = type;
switch (type)
{
@ -934,7 +936,8 @@ void d3dx_free_param_eval(struct d3dx_param_eval *peval)
HeapFree(GetProcessHeap(), 0, peval);
}
static void set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const_tab, BOOL update_all)
static void set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const_tab,
BOOL update_all, ULONG64 new_update_version)
{
unsigned int const_idx;
@ -949,7 +952,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)))
if (!(update_all || is_param_dirty(param, const_tab->update_version)))
continue;
transpose = (const_set->constant_class == D3DXPC_MATRIX_COLUMNS && param->class == D3DXPC_MATRIX_ROWS)
@ -1020,6 +1023,7 @@ static void set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const
}
}
}
const_tab->update_version = new_update_version;
}
#define INITIAL_CONST_SET_SIZE 16
@ -1294,7 +1298,7 @@ static BOOL is_const_tab_input_dirty(struct d3dx_const_tab *ctab)
for (i = 0; i < ctab->const_set_count; ++i)
{
if (is_param_dirty(ctab->const_set[i].param))
if (is_param_dirty(ctab->const_set[i].param, ctab->update_version))
return TRUE;
}
return FALSE;
@ -1307,7 +1311,7 @@ BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval)
}
HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx_parameter *param,
void *param_value, BOOL update_all)
void *param_value)
{
HRESULT hr;
unsigned int i;
@ -1316,10 +1320,14 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx
TRACE("peval %p, param %p, param_value %p.\n", peval, param, param_value);
set_constants(&peval->pres.regs, &peval->pres.inputs, update_all);
if (is_const_tab_input_dirty(&peval->pres.inputs))
{
set_constants(&peval->pres.regs, &peval->pres.inputs, FALSE,
next_update_version(peval->version_counter));
if (FAILED(hr = execute_preshader(&peval->pres)))
return hr;
if (FAILED(hr = execute_preshader(&peval->pres)))
return hr;
}
elements_table = table_info[PRES_REGTAB_OCONST].reg_component_count
* peval->pres.regs.table_sizes[PRES_REGTAB_OCONST];
@ -1414,17 +1422,18 @@ HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, s
struct d3dx_preshader *pres = &peval->pres;
struct d3dx_regstore *rs = &pres->regs;
unsigned int i;
ULONG64 new_update_version = next_update_version(peval->version_counter);
TRACE("device %p, peval %p, param_type %u.\n", device, peval, peval->param_type);
if (update_all || is_const_tab_input_dirty(&pres->inputs))
{
set_constants(rs, &pres->inputs, update_all);
set_constants(rs, &pres->inputs, update_all, new_update_version);
if (FAILED(hr = execute_preshader(pres)))
return hr;
}
set_constants(rs, &peval->shader_inputs, update_all);
set_constants(rs, &peval->shader_inputs, update_all, new_update_version);
result = D3D_OK;
for (i = 0; i < ARRAY_SIZE(set_tables); ++i)
{