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>
This commit is contained in:
parent
a100d6a7a5
commit
a179584844
|
@ -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;
|
||||
|
|
|
@ -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, ¶m->param_eval);
|
||||
D3DXPT_INT, ¶m->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, ¶m->members[i].param_eval);
|
||||
d3dx_create_param_eval(base, object->data, object->size, param->type,
|
||||
¶m->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, ¶m->param_eval);
|
||||
d3dx_create_param_eval(base, object->data, object->size, param->type,
|
||||
¶m->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, ¶m->param_eval);
|
||||
d3dx_create_param_eval(base, object->data, object->size, param->type,
|
||||
¶m->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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue