d3dx9: Implement setting named shader constants in effect.
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
bf5508f9e0
commit
453d9f7bce
|
@ -195,5 +195,7 @@ void d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_co
|
|||
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) DECLSPEC_HIDDEN;
|
||||
HRESULT d3dx_param_eval_set_shader_constants(struct IDirect3DDevice9 *device,
|
||||
struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_D3DX9_PRIVATE_H */
|
||||
|
|
|
@ -2718,7 +2718,53 @@ static HRESULT d3dx_set_shader_const_state(IDirect3DDevice9 *device, enum SHADER
|
|||
}
|
||||
|
||||
static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
|
||||
struct d3dx_state *state, int parent_index)
|
||||
struct d3dx_state *state, unsigned int parent_index);
|
||||
|
||||
static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
|
||||
struct d3dx_parameter *param, BOOL vs)
|
||||
{
|
||||
IDirect3DDevice9 *device = effect->device;
|
||||
HRESULT hr, ret;
|
||||
struct d3dx_parameter **params;
|
||||
D3DXCONSTANT_DESC *cdesc;
|
||||
unsigned int parameters_count;
|
||||
unsigned int i, j;
|
||||
|
||||
if (!param->param_eval)
|
||||
{
|
||||
FIXME("param_eval structure is null.\n");
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
if (FAILED(hr = d3dx_param_eval_set_shader_constants(device, param->param_eval)))
|
||||
return hr;
|
||||
params = param->param_eval->shader_inputs.inputs_param;
|
||||
cdesc = param->param_eval->shader_inputs.inputs;
|
||||
parameters_count = param->param_eval->shader_inputs.input_count;
|
||||
ret = D3D_OK;
|
||||
for (i = 0; i < parameters_count; ++i)
|
||||
{
|
||||
if (params[i] && params[i]->class == D3DXPC_OBJECT && (params[i]->type == D3DXPT_SAMPLER
|
||||
|| params[i]->type == D3DXPT_SAMPLER1D || params[i]->type == D3DXPT_SAMPLER2D
|
||||
|| params[i]->type == D3DXPT_SAMPLER3D || params[i]->type == D3DXPT_SAMPLERCUBE))
|
||||
{
|
||||
struct d3dx_sampler *sampler;
|
||||
|
||||
sampler = (struct d3dx_sampler *)params[i]->data;
|
||||
TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
|
||||
cdesc[i].RegisterIndex, sampler->state_count);
|
||||
for (j = 0; j < sampler->state_count; ++j)
|
||||
{
|
||||
if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
|
||||
cdesc[i].RegisterIndex + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0))))
|
||||
ret = hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
|
||||
struct d3dx_state *state, unsigned int parent_index)
|
||||
{
|
||||
IDirect3DDevice9 *device = effect->device;
|
||||
struct d3dx_parameter *param;
|
||||
|
@ -2744,7 +2790,7 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
|
|||
{
|
||||
UINT unit;
|
||||
|
||||
unit = parent_index == -1 ? state->index : parent_index;
|
||||
unit = parent_index == ~0u ? state->index : parent_index;
|
||||
TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
|
||||
*(IDirect3DBaseTexture9 **)param_value);
|
||||
return IDirect3DDevice9_SetTexture(device, unit, *(IDirect3DBaseTexture9 **)param_value);
|
||||
|
@ -2774,7 +2820,7 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
|
|||
{
|
||||
UINT sampler;
|
||||
|
||||
sampler = parent_index == -1 ? state->index : parent_index;
|
||||
sampler = parent_index == ~0u ? state->index : parent_index;
|
||||
TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
|
||||
return IDirect3DDevice9_SetSamplerState(device, sampler, state_table[state->operation].op,
|
||||
*(DWORD *)param_value);
|
||||
|
@ -2783,13 +2829,15 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
|
|||
TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
|
||||
if (FAILED(hr = IDirect3DDevice9_SetVertexShader(device, *(IDirect3DVertexShader9 **)param_value)))
|
||||
ERR("Could not set vertex shader, hr %#x.\n", hr);
|
||||
FIXME("Not executing preshader and not setting constants.\n");
|
||||
else if (*(IDirect3DVertexShader9 **)param_value)
|
||||
hr = d3dx_set_shader_constants(effect, pass, param, TRUE);
|
||||
return hr;
|
||||
case SC_PIXELSHADER:
|
||||
TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
|
||||
if (FAILED(hr = IDirect3DDevice9_SetPixelShader(device, *(IDirect3DPixelShader9 **)param_value)))
|
||||
ERR("Could not set pixel shader, hr %#x.\n", hr);
|
||||
FIXME("Not executing preshader and not setting constants.\n");
|
||||
else if (*(IDirect3DPixelShader9 **)param_value)
|
||||
hr = d3dx_set_shader_constants(effect, pass, param, FALSE);
|
||||
return hr;
|
||||
case SC_TRANSFORM:
|
||||
TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
|
||||
|
@ -2853,7 +2901,7 @@ static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3
|
|||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], -1)))
|
||||
if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u)))
|
||||
{
|
||||
WARN("Error applying state, hr %#x.\n", hr);
|
||||
ret = hr;
|
||||
|
|
|
@ -297,6 +297,18 @@ 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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
static void dump_bytecode(void *data, unsigned int size)
|
||||
{
|
||||
unsigned int *bytecode = (unsigned int *)data;
|
||||
|
@ -1059,3 +1071,104 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx
|
|||
set_number((unsigned int *)param_value + i, param->type, oc + i, D3DXPT_FLOAT);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT set_shader_constants_device(struct IDirect3DDevice9 *device, struct d3dx_regstore *rs,
|
||||
D3DXPARAMETER_TYPE type, enum pres_reg_tables table)
|
||||
{
|
||||
unsigned int start, count;
|
||||
void *ptr;
|
||||
HRESULT hr, result;
|
||||
|
||||
result = D3D_OK;
|
||||
start = 0;
|
||||
while (start < rs->table_sizes[table])
|
||||
{
|
||||
count = 0;
|
||||
while (start < rs->table_sizes[table] && !regstore_is_val_set_reg(rs, table, start))
|
||||
++start;
|
||||
while (start + count < rs->table_sizes[table] && regstore_is_val_set_reg(rs, table, start + count))
|
||||
++count;
|
||||
if (!count)
|
||||
break;
|
||||
TRACE("Setting %u constants at %u.\n", count, start);
|
||||
ptr = (BYTE *)rs->tables[table] + start * table_info[table].reg_component_count
|
||||
* table_info[table].component_size;
|
||||
if (type == D3DXPT_VERTEXSHADER)
|
||||
{
|
||||
switch(table)
|
||||
{
|
||||
case PRES_REGTAB_OCONST:
|
||||
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, start, (const float *)ptr, count);
|
||||
break;
|
||||
case PRES_REGTAB_OICONST:
|
||||
hr = IDirect3DDevice9_SetVertexShaderConstantI(device, start, (const int *)ptr, count);
|
||||
break;
|
||||
case PRES_REGTAB_OBCONST:
|
||||
hr = IDirect3DDevice9_SetVertexShaderConstantB(device, start, (const BOOL *)ptr, count);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unexpected register table %u.\n", table);
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
}
|
||||
else if (type == D3DXPT_PIXELSHADER)
|
||||
{
|
||||
switch(table)
|
||||
{
|
||||
case PRES_REGTAB_OCONST:
|
||||
hr = IDirect3DDevice9_SetPixelShaderConstantF(device, start, (const float *)ptr, count);
|
||||
break;
|
||||
case PRES_REGTAB_OICONST:
|
||||
hr = IDirect3DDevice9_SetPixelShaderConstantI(device, start, (const int *)ptr, count);
|
||||
break;
|
||||
case PRES_REGTAB_OBCONST:
|
||||
hr = IDirect3DDevice9_SetPixelShaderConstantB(device, start, (const BOOL *)ptr, count);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unexpected register table %u.\n", table);
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unexpected parameter type %u.\n", type);
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Setting constants failed, type %u, table %u, hr %#x.\n", type, table, hr);
|
||||
result = hr;
|
||||
}
|
||||
start += count;
|
||||
}
|
||||
regstore_reset_table(rs, table);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT d3dx_param_eval_set_shader_constants(struct IDirect3DDevice9 *device, struct d3dx_param_eval *peval)
|
||||
{
|
||||
static const enum pres_reg_tables set_tables[] =
|
||||
{PRES_REGTAB_OCONST, PRES_REGTAB_OICONST, PRES_REGTAB_OBCONST};
|
||||
HRESULT hr, result;
|
||||
struct d3dx_preshader *pres = &peval->pres;
|
||||
struct d3dx_regstore *rs = &pres->regs;
|
||||
unsigned int i;
|
||||
|
||||
TRACE("device %p, peval %p, param_type %u.\n", device, peval, peval->param_type);
|
||||
|
||||
if (FAILED(hr = set_constants(rs, &pres->inputs)))
|
||||
return hr;
|
||||
if (FAILED(hr = execute_preshader(pres)))
|
||||
return hr;
|
||||
if (FAILED(hr = set_constants(rs, &peval->shader_inputs)))
|
||||
return hr;
|
||||
|
||||
result = D3D_OK;
|
||||
for (i = 0; i < ARRAY_SIZE(set_tables); ++i)
|
||||
{
|
||||
if (FAILED(hr = set_shader_constants_device(device, rs, peval->param_type, set_tables[i])))
|
||||
result = hr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -3790,7 +3790,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
|
|||
|
||||
hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, &fdata[0].x, TEST_EFFECT_PRES_NFLOATV);
|
||||
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||
todo_wine ok(!memcmp(fdata, test_effect_preshader_fconstsv, sizeof(test_effect_preshader_fconstsv)),
|
||||
ok(!memcmp(fdata, test_effect_preshader_fconstsv, sizeof(test_effect_preshader_fconstsv)),
|
||||
"Vertex shader float constants do not match.\n");
|
||||
for (i = TEST_EFFECT_PRES_NFLOATV; i < 256; ++i)
|
||||
{
|
||||
|
@ -3801,7 +3801,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
|
|||
}
|
||||
hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, &fdata[0].x, TEST_EFFECT_PRES_NFLOATP);
|
||||
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||
todo_wine ok(!memcmp(fdata, test_effect_preshader_fconstsp, sizeof(test_effect_preshader_fconstsp)),
|
||||
ok(!memcmp(fdata, test_effect_preshader_fconstsp, sizeof(test_effect_preshader_fconstsp)),
|
||||
"Pixel shader float constants do not match.\n");
|
||||
for (i = TEST_EFFECT_PRES_NFLOATP; i < 224; ++i)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue