[v2 5/5] d3dx9: Match native out of bounds array selector index handling.

Paul Gofman gofmanp at gmail.com
Thu May 4 05:18:56 CDT 2017


Sorry, please ignore this last patch in the series. I found it is not 
correct for some cases and I will come up with more tests and corrected 
version separately.

On 05/04/2017 01:33 AM, Paul Gofman wrote:
> Signed-off-by: Paul Gofman <gofmanp at gmail.com>
> ---
>   dlls/d3dx9_36/effect.c       | 25 ++++++++++++++++---------
>   dlls/d3dx9_36/tests/effect.c | 17 ++++++-----------
>   2 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
> index 1ecd32e..a3511c8 100644
> --- a/dlls/d3dx9_36/effect.c
> +++ b/dlls/d3dx9_36/effect.c
> @@ -1056,7 +1056,7 @@ static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
>               BOOL param_dirty;
>   
>               if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
> -                    TRUE, &param_dirty)))
> +                    FALSE, &param_dirty)))
>                   return hr;
>   
>               if (!param->object_id)
> @@ -2647,7 +2647,9 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta
>                   FIXME("Preshader structure is null.\n");
>                   return D3DERR_INVALIDCALL;
>               }
> -            if (update_all || is_param_eval_input_dirty(param->param_eval))
> +            /* According to the tests, native d3dx handles the case of array index evaluated to -1
> +             * in a specific way. */
> +            if (is_param_eval_input_dirty(param->param_eval) || state->index == 0xffffffffu)
>               {
>                   if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param,
>                           &array_idx, update_all)))
> @@ -2660,6 +2662,11 @@ static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_sta
>               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 == 0xffffffffu)
> +            {
> +                WARN("Array index is -1, setting to 0.\n");
> +                array_idx = 0;
> +            }
>   
>               if (array_idx >= ref_param->element_count)
>               {
> @@ -2920,13 +2927,11 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
>       if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
>               update_all, &param_dirty)))
>       {
> -        if (hr == E_FAIL)
> +        if (!update_all && hr == E_FAIL)
>           {
> -            /* Native d3dx9 returns D3D_OK from BeginPass or Commit involving
> +            /* Native d3dx9 returns D3D_OK from Commit involving
>                * out of bounds array access and does not touch the affected
> -             * state, except for BeginPass when the out of bounds array index
> -             * depends on dirty parameters. The latter case is supposed to
> -             * return E_FAIL but is currently TODO. */
> +             * state. */
>               WARN("Returning D3D_OK on out of bounds array access.\n");
>               return D3D_OK;
>           }
> @@ -6101,6 +6106,7 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
>               if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
>                   return hr;
>               hr = d3dx9_parse_array_selector(base, param);
> +            state->index = 0xffffffffu;
>               break;
>   
>           default:
> @@ -6226,10 +6232,11 @@ static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *da
>   
>       for (i = 0; i < base->parameter_count; ++i)
>       {
> -        if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i])))
> -            goto err_out;
>           walk_parameter_tree(&base->parameters[i], param_set_top_level_param,
>                   &base->parameters[i]);
> +        set_dirty(&base->parameters[i]);
> +        if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i])))
> +            goto err_out;
>       }
>       return D3D_OK;
>   
> diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
> index 7f7487e..c6713af 100644
> --- a/dlls/d3dx9_36/tests/effect.c
> +++ b/dlls/d3dx9_36/tests/effect.c
> @@ -4658,14 +4658,12 @@ static void test_effect_out_of_bounds_selector(IDirect3DDevice9 *device)
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
>   
>       hr = effect->lpVtbl->BeginPass(effect, 1);
> -    todo_wine ok(hr == E_FAIL, "Got result %#x.\n", hr);
> -    if (SUCCEEDED(hr))
> -        effect->lpVtbl->EndPass(effect);
> +    ok(hr == E_FAIL, "Got result %#x.\n", hr);
>   
>       hr = effect->lpVtbl->BeginPass(effect, 1);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
>   
> -    test_effect_preshader_compare_shader(device, 2, TRUE);
> +    test_effect_preshader_compare_shader(device, 2, FALSE);
>   
>       hr = effect->lpVtbl->EndPass(effect);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
> @@ -4678,9 +4676,7 @@ static void test_effect_out_of_bounds_selector(IDirect3DDevice9 *device)
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
>   
>       hr = effect->lpVtbl->BeginPass(effect, 1);
> -    todo_wine ok(hr == E_FAIL, "Got result %#x.\n", hr);
> -    if (SUCCEEDED(hr))
> -        hr = effect->lpVtbl->EndPass(effect);
> +    ok(hr == E_FAIL, "Got result %#x.\n", hr);
>   
>       hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
> @@ -4689,7 +4685,7 @@ static void test_effect_out_of_bounds_selector(IDirect3DDevice9 *device)
>       hr = effect->lpVtbl->BeginPass(effect, 1);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
>   
> -    test_effect_preshader_compare_shader(device, 2, TRUE);
> +    test_effect_preshader_compare_shader(device, 2, FALSE);
>   
>       hr = effect->lpVtbl->EndPass(effect);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
> @@ -4701,7 +4697,7 @@ static void test_effect_out_of_bounds_selector(IDirect3DDevice9 *device)
>       hr = effect->lpVtbl->BeginPass(effect, 1);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
>   
> -    test_effect_preshader_compare_shader(device, 0, TRUE);
> +    test_effect_preshader_compare_shader(device, 0, FALSE);
>   
>       hr = IDirect3DDevice9_SetVertexShader(device, NULL);
>       ok(hr == D3D_OK, "Got result %#x.\n", hr);
> @@ -6266,10 +6262,9 @@ 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);
> +    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, FALSE);
>   
>       fvect.z = 2.0f;
>       hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);





More information about the wine-devel mailing list