[PATCH] d3dx9: Return shader functions in d3dx9_base_effect_get_pass_desc().
Matteo Bruni
mbruni at codeweavers.com
Thu May 4 17:03:50 CDT 2017
From: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
dlls/d3dx9_36/effect.c | 210 +++++++++++++++++++++++++------------------
dlls/d3dx9_36/tests/effect.c | 9 +-
2 files changed, 125 insertions(+), 94 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 1a14edb..864c390 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_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 HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
- D3DXHANDLE pass, D3DXPASS_DESC *desc)
+ D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
{
- struct d3dx_pass *p = get_valid_pass(base, pass);
+ struct d3dx_pass *pass = get_valid_pass(base, pass_handle);
+ unsigned int i;
- if (!desc || !p)
+ 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 8b2fb5d..f3bc9e3 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);
--
2.10.2
More information about the wine-patches
mailing list