[v4 6/6] d3dx9: imlement setting named shader constants in effect.
Paul Gofman
gofmanp at gmail.com
Thu Mar 17 06:59:43 CDT 2016
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
CHANGES
- Changed 'unsigned' to 'unsigned int'
- Got rid of using helper functions to access shader inputs
- Changed 'hr = ...; if (FAILED(hr...' to 'if (FAILED(hr=...'
- Added '{ }' to for loop for clarity
dlls/d3dx9_36/d3dx9_private.h | 2 ++
dlls/d3dx9_36/effect.c | 58 +++++++++++++++++++++++++++++++++++----
dlls/d3dx9_36/preshader.c | 64 +++++++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/tests/effect.c | 4 +--
4 files changed, 120 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index 27b6978..a1e52e7 100644
--- a/dlls/d3dx9_36/d3dx9_private.h
+++ b/dlls/d3dx9_36/d3dx9_private.h
@@ -199,5 +199,7 @@ HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte
void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval,
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 */
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index e8c7057..a130c59 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -2726,7 +2726,51 @@ HRESULT d3dx_set_shader_const_state(IDirect3DDevice9 *device, enum SHADER_CONSTA
}
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);
+
+HRESULT d3dx_set_shader_const_fxlc(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
+ struct d3dx_parameter *param, unsigned int 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("Preshader 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)
+ {
+ struct d3dx_sampler *sampler;
+
+ sampler = (struct d3dx_sampler *)params[i]->data;
+ TRACE("sampler %s, register index %u, state count %u.\n", 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;
@@ -2752,7 +2796,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);
@@ -2782,7 +2826,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);
@@ -2791,13 +2835,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_const_fxlc(effect, pass, param, 1);
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_const_fxlc(effect, pass, param, 0);
return hr;
case SC_TRANSFORM:
TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
@@ -2861,7 +2907,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;
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
index 6d8f577..db4f054 100644
--- a/dlls/d3dx9_36/preshader.c
+++ b/dlls/d3dx9_36/preshader.c
@@ -971,3 +971,67 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, struct d3dx_param
set_number((unsigned int *)(*param_value) + i, param->type, oc + i, D3DXPT_FLOAT);
return D3D_OK;
}
+
+HRESULT d3dx_param_eval_set_shader_constants(struct IDirect3DDevice9 *device, struct d3dx_param_eval *peval)
+{
+ HRESULT hr, res;
+ struct d3dx_preshader *pres = &peval->pres;
+ struct d3dx_regstore *rs = &pres->regs;
+
+ 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;
+
+ #define SET_TABLE(table, func_suff, type) \
+ { \
+ unsigned int is, n; \
+ \
+ is = 0; \
+ while (is < rs->table_sizes[table]) \
+ {\
+ n = 0; \
+ while (is < rs->table_sizes[table] && !regstore_is_val_set_reg(rs, table, is)) \
+ is++; \
+ while (is + n < rs->table_sizes[table] && regstore_is_val_set_reg(rs, table, is + n)) \
+ n++; \
+ if (!n) \
+ continue; \
+ TRACE("setting %u consts at %u.\n", n, is); \
+ hr = IDirect3DDevice9_##func_suff(device, is, \
+ (const type *)rs->tables[table] + is * table_info[table].reg_component_count, n); \
+ if (FAILED(hr)) \
+ { \
+ ERR(#func_suff " failed, hr %#x.\n", hr); \
+ res = hr; \
+ } \
+ is += n; \
+ } \
+ regstore_reset_table(rs, table); \
+ }
+ res = D3D_OK;
+ if (peval->param_type == D3DXPT_VERTEXSHADER)
+ {
+ SET_TABLE(PRES_REGTAB_OCONST, SetVertexShaderConstantF, float);
+ SET_TABLE(PRES_REGTAB_OICONST, SetVertexShaderConstantI, int);
+ SET_TABLE(PRES_REGTAB_OBCONST, SetVertexShaderConstantB, BOOL);
+ }
+ else if (peval->param_type == D3DXPT_PIXELSHADER)
+ {
+ SET_TABLE(PRES_REGTAB_OCONST, SetPixelShaderConstantF, float);
+ SET_TABLE(PRES_REGTAB_OICONST, SetPixelShaderConstantI, int);
+ SET_TABLE(PRES_REGTAB_OBCONST, SetPixelShaderConstantB, BOOL);
+ }
+ else
+ {
+ FIXME("Unexpected parameter type %u.\n", peval->param_type);
+ return D3DERR_INVALIDCALL;
+ }
+ #undef SET_TABLE
+
+ return res;
+}
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index b0b401c..659539d 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -3719,7 +3719,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)
{
@@ -3730,7 +3730,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)
{
--
2.5.0
More information about the wine-patches
mailing list