From b7198efd42ad56ce587c8d608ea32068ea43fb72 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Fri, 5 May 2017 00:03:50 +0200 Subject: [PATCH] d3dx9: Return shader functions in d3dx9_base_effect_get_pass_desc(). Signed-off-by: Paul Gofman Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3dx9_36/effect.c | 212 ++++++++++++++++++++--------------- dlls/d3dx9_36/tests/effect.c | 9 +- 2 files changed, 126 insertions(+), 95 deletions(-) diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 1a14edb4a58..864c3902fde 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -1019,24 +1019,139 @@ static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *ba return D3D_OK; } -static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base, - D3DXHANDLE pass, D3DXPASS_DESC *desc) +static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state, + void **param_value, struct d3dx_parameter **out_param, + BOOL update_all, BOOL *param_dirty) { - struct d3dx_pass *p = get_valid_pass(base, pass); + struct d3dx_parameter *param = &state->parameter; - if (!desc || !p) + *param_value = NULL; + *out_param = NULL; + *param_dirty = FALSE; + + switch (state->type) + { + case ST_PARAMETER: + param = param->referenced_param; + *param_dirty = is_param_dirty(param); + /* fallthrough */ + case ST_CONSTANT: + *out_param = param; + *param_value = param->data; + return D3D_OK; + case ST_ARRAY_SELECTOR: + { + unsigned int array_idx; + static const struct d3dx_parameter array_idx_param = + {"", NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, sizeof(array_idx)}; + HRESULT hr; + struct d3dx_parameter *ref_param, *selected_param; + + if (!param->param_eval) + { + FIXME("Preshader structure is null.\n"); + return D3DERR_INVALIDCALL; + } + 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))) + return hr; + } + else + { + array_idx = state->index; + } + ref_param = param->referenced_param; + TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index, + ref_param->element_count); + + if (array_idx >= ref_param->element_count) + { + WARN("Computed array index %u is larger than array size %u.\n", + array_idx, ref_param->element_count); + return E_FAIL; + } + selected_param = &ref_param->members[array_idx]; + *param_dirty = state->index != array_idx || is_param_dirty(selected_param); + state->index = array_idx; + + *param_value = selected_param->data; + *out_param = selected_param; + return D3D_OK; + } + case ST_FXLC: + if (param->param_eval) + { + *out_param = param; + *param_value = param->data; + 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); + } + else + return D3D_OK; + } + else + { + FIXME("No preshader for FXLC parameter.\n"); + return D3DERR_INVALIDCALL; + } + } + return E_NOTIMPL; +} + +static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base, + D3DXHANDLE pass_handle, D3DXPASS_DESC *desc) +{ + struct d3dx_pass *pass = get_valid_pass(base, pass_handle); + unsigned int i; + + if (!desc || !pass) { WARN("Invalid argument specified.\n"); return D3DERR_INVALIDCALL; } - desc->Name = p->name; - desc->Annotations = p->annotation_count; + desc->Name = pass->name; + desc->Annotations = pass->annotation_count; - FIXME("Pixel shader and vertex shader are not supported, yet.\n"); desc->pVertexShaderFunction = NULL; desc->pPixelShaderFunction = NULL; + if (base->flags & D3DXFX_NOT_CLONEABLE) + return D3D_OK; + + for (i = 0; i < pass->state_count; ++i) + { + struct d3dx_state *state = &pass->states[i]; + + if (state_table[state->operation].class == SC_VERTEXSHADER + || state_table[state->operation].class == SC_PIXELSHADER) + { + struct d3dx_parameter *param; + void *param_value; + BOOL param_dirty; + HRESULT hr; + + if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], ¶m_value, ¶m, + TRUE, ¶m_dirty))) + return hr; + + if (!param->object_id) + { + FIXME("Zero object ID in shader parameter.\n"); + return E_FAIL; + } + + if (state_table[state->operation].class == SC_VERTEXSHADER) + desc->pVertexShaderFunction = base->objects[param->object_id].data; + else + desc->pPixelShaderFunction = base->objects[param->object_id].data; + } + } + return D3D_OK; } @@ -2579,89 +2694,6 @@ static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base, return E_NOTIMPL; } -static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state, - void **param_value, struct d3dx_parameter **out_param, - BOOL update_all, BOOL *param_dirty) -{ - struct d3dx_parameter *param = &state->parameter; - - *param_value = NULL; - *out_param = NULL; - *param_dirty = FALSE; - - switch (state->type) - { - case ST_PARAMETER: - param = param->referenced_param; - *param_dirty = is_param_dirty(param); - /* fallthrough */ - case ST_CONSTANT: - *out_param = param; - *param_value = param->data; - return D3D_OK; - case ST_ARRAY_SELECTOR: - { - unsigned int array_idx; - static const struct d3dx_parameter array_idx_param = - {"", NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, sizeof(array_idx)}; - HRESULT hr; - struct d3dx_parameter *ref_param, *selected_param; - - if (!param->param_eval) - { - FIXME("Preshader structure is null.\n"); - return D3DERR_INVALIDCALL; - } - 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))) - return hr; - } - else - { - array_idx = state->index; - } - ref_param = param->referenced_param; - TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index, - ref_param->element_count); - - if (array_idx >= ref_param->element_count) - { - WARN("Computed array index %u is larger than array size %u.\n", - array_idx, ref_param->element_count); - return E_FAIL; - } - selected_param = &ref_param->members[array_idx]; - *param_dirty = state->index != array_idx || is_param_dirty(selected_param); - state->index = array_idx; - - *param_value = selected_param->data; - *out_param = selected_param; - return D3D_OK; - } - case ST_FXLC: - if (param->param_eval) - { - *out_param = param; - *param_value = param->data; - 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); - } - else - return D3D_OK; - } - else - { - FIXME("No preshader for FXLC parameter.\n"); - return D3DERR_INVALIDCALL; - } - } - return E_NOTIMPL; -} - static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value) { static const struct diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 8b2fb5d201a..f3bc9e3c36a 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -6227,7 +6227,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device) hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc); ok(hr == D3D_OK, "Got result %#x.\n", hr); - test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, TRUE); + test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, FALSE); fvect.x = fvect.y = fvect.w = 0.0f; fvect.z = 0.0f; @@ -6238,21 +6238,19 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Got result %#x.\n", hr); ok(!desc.pPixelShaderFunction, "Unexpected non null desc.pPixelShaderFunction.\n"); - test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, TRUE); + test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, FALSE); fvect.z = 3.0f; hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect); ok(hr == D3D_OK, "Got result %#x.\n", hr); hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc); - todo_wine ok(hr == E_FAIL, "Got result %#x.\n", hr); ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n"); /* Repeating call to confirm GetPassDesc() returns same error on the second call, * as it is not the case sometimes for BeginPass() with out of bound access. */ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc); - todo_wine ok(hr == E_FAIL, "Got result %#x.\n", hr); ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n"); @@ -6263,6 +6261,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Got result %#x.\n", hr); hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc); + todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr); test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, TRUE); @@ -6271,7 +6270,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device) hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect); hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc); ok(hr == D3D_OK, "Got result %#x.\n", hr); - test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, TRUE); + test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, FALSE); effect->lpVtbl->Release(effect);