Commit 4b11a991 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

d3dx9: Support skip_constants parameter for effect.

parent 6498a03a
...@@ -347,7 +347,8 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, ...@@ -347,7 +347,8 @@ struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code,
unsigned int byte_code_size, D3DXPARAMETER_TYPE type, unsigned int byte_code_size, D3DXPARAMETER_TYPE type,
struct d3dx_param_eval **peval, ULONG64 *version_counter) DECLSPEC_HIDDEN; struct d3dx_param_eval **peval, ULONG64 *version_counter,
const char **skip_constants, unsigned int skip_constants_count) DECLSPEC_HIDDEN;
void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN; void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval,
const struct d3dx_parameter *param, void *param_value) DECLSPEC_HIDDEN; const struct d3dx_parameter *param, void *param_value) DECLSPEC_HIDDEN;
...@@ -357,6 +358,7 @@ BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval, ULONG64 update_ver ...@@ -357,6 +358,7 @@ BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval, ULONG64 update_ver
struct ctab_constant { struct ctab_constant {
D3DXCONSTANT_DESC desc; D3DXCONSTANT_DESC desc;
WORD constantinfo_reserved;
struct ctab_constant *constants; struct ctab_constant *constants;
}; };
......
...@@ -588,7 +588,8 @@ static unsigned int *parse_pres_ins(unsigned int *ptr, unsigned int count, struc ...@@ -588,7 +588,8 @@ static unsigned int *parse_pres_ins(unsigned int *ptr, unsigned int count, struc
return ptr; return ptr;
} }
static HRESULT get_ctab_constant_desc(ID3DXConstantTable *ctab, D3DXHANDLE hc, D3DXCONSTANT_DESC *desc) static HRESULT get_ctab_constant_desc(ID3DXConstantTable *ctab, D3DXHANDLE hc, D3DXCONSTANT_DESC *desc,
WORD *constantinfo_reserved)
{ {
const struct ctab_constant *constant = d3dx_shader_get_ctab_constant(ctab, hc); const struct ctab_constant *constant = d3dx_shader_get_ctab_constant(ctab, hc);
...@@ -598,10 +599,13 @@ static HRESULT get_ctab_constant_desc(ID3DXConstantTable *ctab, D3DXHANDLE hc, D ...@@ -598,10 +599,13 @@ static HRESULT get_ctab_constant_desc(ID3DXConstantTable *ctab, D3DXHANDLE hc, D
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
*desc = constant->desc; *desc = constant->desc;
if (constantinfo_reserved)
*constantinfo_reserved = constant->constantinfo_reserved;
return D3D_OK; return D3D_OK;
} }
static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab *out, struct d3dx9_base_effect *base) static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab *out,
struct d3dx9_base_effect *base, const char **skip_constants, unsigned int skip_constants_count)
{ {
ID3DXConstantTable *ctab; ID3DXConstantTable *ctab;
D3DXCONSTANT_DESC *cdesc; D3DXCONSTANT_DESC *cdesc;
...@@ -609,7 +613,7 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab ...@@ -609,7 +613,7 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab
D3DXCONSTANTTABLE_DESC desc; D3DXCONSTANTTABLE_DESC desc;
HRESULT hr; HRESULT hr;
D3DXHANDLE hc; D3DXHANDLE hc;
unsigned int i; unsigned int i, j;
hr = D3DXGetShaderConstantTable(byte_code, &ctab); hr = D3DXGetShaderConstantTable(byte_code, &ctab);
if (FAILED(hr) || !ctab) if (FAILED(hr) || !ctab)
...@@ -621,7 +625,7 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab ...@@ -621,7 +625,7 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab
if (FAILED(hr = ID3DXConstantTable_GetDesc(ctab, &desc))) if (FAILED(hr = ID3DXConstantTable_GetDesc(ctab, &desc)))
{ {
FIXME("Could not get CTAB desc, hr %#x.\n", hr); FIXME("Could not get CTAB desc, hr %#x.\n", hr);
goto err_out; goto cleanup;
} }
out->inputs = cdesc = HeapAlloc(GetProcessHeap(), 0, sizeof(*cdesc) * desc.Constants); out->inputs = cdesc = HeapAlloc(GetProcessHeap(), 0, sizeof(*cdesc) * desc.Constants);
...@@ -629,47 +633,69 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab ...@@ -629,47 +633,69 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab
if (!cdesc || !inputs_param) if (!cdesc || !inputs_param)
{ {
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto err_out; goto cleanup;
} }
for (i = 0; i < desc.Constants; ++i) for (i = 0; i < desc.Constants; ++i)
{ {
unsigned int index = out->input_count;
WORD constantinfo_reserved;
hc = ID3DXConstantTable_GetConstant(ctab, NULL, i); hc = ID3DXConstantTable_GetConstant(ctab, NULL, i);
if (!hc) if (!hc)
{ {
FIXME("Null constant handle.\n"); FIXME("Null constant handle.\n");
goto err_out; goto cleanup;
} }
if (FAILED(hr = get_ctab_constant_desc(ctab, hc, &cdesc[i]))) if (FAILED(hr = get_ctab_constant_desc(ctab, hc, &cdesc[index], &constantinfo_reserved)))
goto err_out; goto cleanup;
inputs_param[i] = get_parameter_by_name(base, NULL, cdesc[i].Name); inputs_param[index] = get_parameter_by_name(base, NULL, cdesc[index].Name);
if (!inputs_param[i]) if (!inputs_param[index])
{ {
WARN("Could not find parameter %s in effect.\n", cdesc[i].Name); WARN("Could not find parameter %s in effect.\n", cdesc[index].Name);
continue; continue;
} }
if (cdesc[i].Class == D3DXPC_OBJECT) if (cdesc[index].Class == D3DXPC_OBJECT)
{ {
TRACE("Object %s, parameter %p.\n", cdesc[i].Name, inputs_param[i]); TRACE("Object %s, parameter %p.\n", cdesc[index].Name, inputs_param[index]);
if (cdesc[i].RegisterSet != D3DXRS_SAMPLER || inputs_param[i]->class != D3DXPC_OBJECT if (cdesc[index].RegisterSet != D3DXRS_SAMPLER || inputs_param[index]->class != D3DXPC_OBJECT
|| !is_param_type_sampler(inputs_param[i]->type)) || !is_param_type_sampler(inputs_param[index]->type))
{ {
WARN("Unexpected object type, constant %s.\n", debugstr_a(cdesc[i].Name)); WARN("Unexpected object type, constant %s.\n", debugstr_a(cdesc[index].Name));
hr = D3DERR_INVALIDCALL; hr = D3DERR_INVALIDCALL;
goto err_out; goto cleanup;
} }
if (max(inputs_param[i]->element_count, 1) < cdesc[i].RegisterCount) if (max(inputs_param[index]->element_count, 1) < cdesc[index].RegisterCount)
{ {
WARN("Register count exceeds parameter size, constant %s.\n", debugstr_a(cdesc[i].Name)); WARN("Register count exceeds parameter size, constant %s.\n", debugstr_a(cdesc[index].Name));
hr = D3DERR_INVALIDCALL; hr = D3DERR_INVALIDCALL;
goto err_out; goto cleanup;
} }
continue;
} }
if (FAILED(hr = init_set_constants_param(out, ctab, hc, inputs_param[i])))
goto err_out; for (j = 0; j < skip_constants_count; ++j)
{
if (!strcmp(cdesc[index].Name, skip_constants[j]))
{
if (!constantinfo_reserved)
{
WARN("skip_constants parameter %s is not register bound.\n",
cdesc[index].Name);
hr = D3DERR_INVALIDCALL;
goto cleanup;
}
TRACE("Skipping constant %s.\n", cdesc[index].Name);
break;
}
}
if (j < skip_constants_count)
continue;
++out->input_count;
if (inputs_param[index]->class == D3DXPC_OBJECT)
continue;
if (FAILED(hr = init_set_constants_param(out, ctab, hc, inputs_param[index])))
goto cleanup;
} }
out->input_count = desc.Constants;
if (out->const_set_count) if (out->const_set_count)
{ {
out->const_set = HeapReAlloc(GetProcessHeap(), 0, out->const_set, out->const_set = HeapReAlloc(GetProcessHeap(), 0, out->const_set,
...@@ -678,11 +704,11 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab ...@@ -678,11 +704,11 @@ static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab
{ {
ERR("Out of memory.\n"); ERR("Out of memory.\n");
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto err_out; goto cleanup;
} }
out->const_set_size = out->const_set_count; out->const_set_size = out->const_set_count;
} }
err_out: cleanup:
ID3DXConstantTable_Release(ctab); ID3DXConstantTable_Release(ctab);
return hr; return hr;
} }
...@@ -858,7 +884,7 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u ...@@ -858,7 +884,7 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u
saved_word = *ptr; saved_word = *ptr;
*ptr = 0xfffe0000; *ptr = 0xfffe0000;
hr = get_constants_desc(ptr, &pres->inputs, base); hr = get_constants_desc(ptr, &pres->inputs, base, NULL, 0);
*ptr = saved_word; *ptr = saved_word;
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
...@@ -912,7 +938,8 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u ...@@ -912,7 +938,8 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u
} }
HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, unsigned int byte_code_size, HRESULT 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, ULONG64 *version_counter) D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out, ULONG64 *version_counter,
const char **skip_constants, unsigned int skip_constants_count)
{ {
struct d3dx_param_eval *peval; struct d3dx_param_eval *peval;
unsigned int *ptr; unsigned int *ptr;
...@@ -963,9 +990,10 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte ...@@ -963,9 +990,10 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte
} }
TRACE("Shader version %#x.\n", *ptr & 0xffff); TRACE("Shader version %#x.\n", *ptr & 0xffff);
if (FAILED(ret = get_constants_desc(ptr, &peval->shader_inputs, base_effect))) if (FAILED(ret = get_constants_desc(ptr, &peval->shader_inputs, base_effect,
skip_constants, skip_constants_count)))
{ {
FIXME("Could not get shader constant table, ret %#x.\n", ret); WARN("Could not get shader constant table, ret %#x.\n", ret);
goto err_out; goto err_out;
} }
update_table_sizes_consts(peval->pres.regs.table_sizes, &peval->shader_inputs); update_table_sizes_consts(peval->pres.regs.table_sizes, &peval->shader_inputs);
...@@ -1006,7 +1034,7 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte ...@@ -1006,7 +1034,7 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte
return D3D_OK; return D3D_OK;
err_out: err_out:
FIXME("Error creating parameter evaluator.\n"); WARN("Error creating parameter evaluator.\n");
d3dx_free_param_eval(peval); d3dx_free_param_eval(peval);
*peval_out = NULL; *peval_out = NULL;
return ret; return ret;
...@@ -1352,7 +1380,7 @@ static HRESULT init_set_constants_param(struct d3dx_const_tab *const_tab, ID3DXC ...@@ -1352,7 +1380,7 @@ static HRESULT init_set_constants_param(struct d3dx_const_tab *const_tab, ID3DXC
enum pres_value_type table_type; enum pres_value_type table_type;
HRESULT hr; HRESULT hr;
if (FAILED(get_ctab_constant_desc(ctab, hc, &desc))) if (FAILED(get_ctab_constant_desc(ctab, hc, &desc, NULL)))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
if (param->element_count) if (param->element_count)
...@@ -1588,8 +1616,7 @@ static BOOL is_const_tab_input_dirty(struct d3dx_const_tab *ctab, ULONG64 update ...@@ -1588,8 +1616,7 @@ static BOOL is_const_tab_input_dirty(struct d3dx_const_tab *ctab, ULONG64 update
update_version = ctab->update_version; update_version = ctab->update_version;
for (i = 0; i < ctab->input_count; ++i) for (i = 0; i < ctab->input_count; ++i)
{ {
if (ctab->inputs_param[i] if (is_param_dirty(ctab->inputs_param[i], update_version))
&& is_param_dirty(ctab->inputs_param[i], update_version))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
......
...@@ -2054,6 +2054,7 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(const DWORD *byte_code, DWORD flags, ...@@ -2054,6 +2054,7 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(const DWORD *byte_code, DWORD flags,
{ {
object->constants[i].desc.RegisterCount = constant_info[i].RegisterCount; object->constants[i].desc.RegisterCount = constant_info[i].RegisterCount;
} }
object->constants[i].constantinfo_reserved = constant_info[i].Reserved;
} }
*constant_table = &object->ID3DXConstantTable_iface; *constant_table = &object->ID3DXConstantTable_iface;
......
...@@ -6920,25 +6920,17 @@ static void test_effect_skip_constants(IDirect3DDevice9 *device) ...@@ -6920,25 +6920,17 @@ static void test_effect_skip_constants(IDirect3DDevice9 *device)
hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob), hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
NULL, NULL, "v3", 0, NULL, &effect, NULL); NULL, NULL, "v3", 0, NULL, &effect, NULL);
todo_wine
ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
if (SUCCEEDED(hr))
effect->lpVtbl->Release(effect);
hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob), hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
NULL, NULL, "v4", 0, NULL, &effect, NULL); NULL, NULL, "v4", 0, NULL, &effect, NULL);
todo_wine
ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
if (SUCCEEDED(hr))
effect->lpVtbl->Release(effect);
hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob), hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
NULL, NULL, " v1#,.+-= &\t\nv2*/!\"'v5 v6[1]", 0, NULL, &effect, NULL); NULL, NULL, " v1#,.+-= &\t\nv2*/!\"'v5 v6[1]", 0, NULL, &effect, NULL);
ok(hr == D3D_OK, "Got result %#x.\n", hr); ok(hr == D3D_OK, "Got result %#x.\n", hr);
todo_wine
ok(!effect->lpVtbl->IsParameterUsed(effect, "v1", "tech0"), ok(!effect->lpVtbl->IsParameterUsed(effect, "v1", "tech0"),
"Unexpected IsParameterUsed result.\n"); "Unexpected IsParameterUsed result.\n");
todo_wine
ok(!effect->lpVtbl->IsParameterUsed(effect, "v2", "tech0"), ok(!effect->lpVtbl->IsParameterUsed(effect, "v2", "tech0"),
"Unexpected IsParameterUsed result.\n"); "Unexpected IsParameterUsed result.\n");
ok(effect->lpVtbl->IsParameterUsed(effect, "v3", "tech0"), ok(effect->lpVtbl->IsParameterUsed(effect, "v3", "tech0"),
...@@ -6970,11 +6962,11 @@ static void test_effect_skip_constants(IDirect3DDevice9 *device) ...@@ -6970,11 +6962,11 @@ static void test_effect_skip_constants(IDirect3DDevice9 *device)
fvect.x = 30.0f; fvect.x = 30.0f;
test_effect_shared_parameters_compare_vconst(device, 0, &fvect, FALSE); test_effect_shared_parameters_compare_vconst(device, 0, &fvect, FALSE);
for (i = 1; i < 4; ++i) for (i = 1; i < 4; ++i)
test_effect_shared_parameters_compare_vconst(device, i, &fvect_filler, i > 1); test_effect_shared_parameters_compare_vconst(device, i, &fvect_filler, FALSE);
fvect.x = 31.0f; fvect.x = 31.0f;
test_effect_shared_parameters_compare_vconst(device, 4, &fvect, FALSE); test_effect_shared_parameters_compare_vconst(device, 4, &fvect, FALSE);
for (i = 5; i < 256; ++i) for (i = 5; i < 256; ++i)
test_effect_shared_parameters_compare_vconst(device, i, &fvect_filler, i < 7); test_effect_shared_parameters_compare_vconst(device, i, &fvect_filler, FALSE);
hr = effect->lpVtbl->EndPass(effect); hr = effect->lpVtbl->EndPass(effect);
ok(hr == D3D_OK, "Got result %#x.\n", hr); ok(hr == D3D_OK, "Got result %#x.\n", hr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment