d3dx9: Return shader functions in d3dx9_base_effect_get_pass_desc().
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
911f8ffaae
commit
b7198efd42
|
@ -1019,24 +1019,139 @@ static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *ba
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
|
static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
|
||||||
D3DXHANDLE pass, D3DXPASS_DESC *desc)
|
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");
|
WARN("Invalid argument specified.\n");
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->Name = p->name;
|
desc->Name = pass->name;
|
||||||
desc->Annotations = p->annotation_count;
|
desc->Annotations = pass->annotation_count;
|
||||||
|
|
||||||
FIXME("Pixel shader and vertex shader are not supported, yet.\n");
|
|
||||||
desc->pVertexShaderFunction = NULL;
|
desc->pVertexShaderFunction = NULL;
|
||||||
desc->pPixelShaderFunction = 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;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2579,89 +2694,6 @@ static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base,
|
||||||
return E_NOTIMPL;
|
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 void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
|
||||||
{
|
{
|
||||||
static const struct
|
static const struct
|
||||||
|
|
|
@ -6227,7 +6227,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device)
|
||||||
|
|
||||||
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
||||||
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
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.x = fvect.y = fvect.w = 0.0f;
|
||||||
fvect.z = 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(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||||
ok(!desc.pPixelShaderFunction, "Unexpected non null desc.pPixelShaderFunction.\n");
|
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;
|
fvect.z = 3.0f;
|
||||||
hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
|
hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
|
||||||
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||||
|
|
||||||
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
||||||
todo_wine
|
|
||||||
ok(hr == E_FAIL, "Got result %#x.\n", hr);
|
ok(hr == E_FAIL, "Got result %#x.\n", hr);
|
||||||
ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
|
ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
|
||||||
|
|
||||||
/* Repeating call to confirm GetPassDesc() returns same error on the second call,
|
/* 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. */
|
* as it is not the case sometimes for BeginPass() with out of bound access. */
|
||||||
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
||||||
todo_wine
|
|
||||||
ok(hr == E_FAIL, "Got result %#x.\n", hr);
|
ok(hr == E_FAIL, "Got result %#x.\n", hr);
|
||||||
ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
|
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);
|
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||||
|
|
||||||
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
||||||
|
todo_wine
|
||||||
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||||
|
|
||||||
test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, TRUE);
|
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->SetVector(effect, "g_iVect", &fvect);
|
||||||
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
|
||||||
ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
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);
|
effect->lpVtbl->Release(effect);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue