From: Paul Gofman Subject: [v2 1/2] d3dx9: Add 'exp' preshader opcode. Message-Id: <1461574338-21604-1-git-send-email-gofmanp@gmail.com> Date: Mon, 25 Apr 2016 11:52:17 +0300 Signed-off-by: Paul Gofman --- Changes - renamed npasses to passes_count; - made test_effect_blob allocation dynamic; - changed i++ to ++i in for loop; - changed op_pos, result_index to be parameters for test_preshader_op; - compute op_step instead of defining it; - renamed _POS defines; - made test table based dlls/d3dx9_36/preshader.c | 3 ++ dlls/d3dx9_36/tests/effect.c | 107 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c index 2287f15..a16c065 100644 --- a/dlls/d3dx9_36/preshader.c +++ b/dlls/d3dx9_36/preshader.c @@ -43,6 +43,7 @@ enum pres_ops PRESHADER_OP_SIN, PRESHADER_OP_COS, PRESHADER_OP_RSQ, + PRESHADER_OP_EXP, }; typedef double (*pres_op_func)(double *args, int n); @@ -80,6 +81,7 @@ static double pres_rsq(double *args, int n) else return 1.0 / sqrt(v); } +static double pres_exp(double *args, int n) {return pow(2.0, args[0]);} #define PRES_OPCODE_MASK 0x7ff00000 #define PRES_OPCODE_SHIFT 20 @@ -119,6 +121,7 @@ static const struct op_info pres_op_info[] = {0x108, "sin", 1, 0, pres_sin}, /* PRESHADER_OP_SIN */ {0x109, "cos", 1, 0, pres_cos}, /* PRESHADER_OP_COS */ {0x107, "rsq", 1, 0, pres_rsq}, /* PRESHADER_OP_RSQ */ + {0x105, "exp", 1, 0, pres_exp}, /* PRESHADER_OP_EXP */ }; enum pres_value_type diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 9d58a80..fff317f 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -3634,6 +3634,9 @@ static const DWORD test_effect_preshader_effect_blob[] = #define TEST_EFFECT_PRESHADER_VSHADER_POS 1035 #define TEST_EFFECT_PRESHADER_VSHADER_LEN 13 +#define TEST_EFFECT_PRESHADER_OP1ARG_POS 2468 +#define TEST_EFFECT_PRESHADER_OP2ARG_POS 2319 + static void test_effect_preshader(IDirect3DDevice9 *device) { static const D3DXVECTOR4 test_effect_preshader_fconstsv[] = @@ -3886,6 +3889,109 @@ static void test_effect_preshader(IDirect3DDevice9 *device) effect->lpVtbl->Release(effect); } +static void test_preshader_op(IDirect3DDevice9 *device, const DWORD *sample_effect_blob, + unsigned int sample_effect_blob_size, unsigned int op_pos, unsigned int result_index, + const char *op_mnem, unsigned int opcode, unsigned int args_count, + const unsigned int *expected_result, const D3DXVECTOR4 *fvect1, const D3DXVECTOR4 *fvect2, + unsigned int ulps, const BOOL *todo) +{ + DWORD *test_effect_blob; + HRESULT hr; + ID3DXEffect *effect; + D3DLIGHT9 light; + unsigned int i, passes_count; + float *v; + unsigned int op_step; + D3DXHANDLE param; + + op_step = 2 + (args_count + 1) * 3; + + test_effect_blob = HeapAlloc(GetProcessHeap(), 0, sample_effect_blob_size); + memcpy(test_effect_blob, sample_effect_blob, sample_effect_blob_size); + for (i = 0; i < 4; ++i) + test_effect_blob[op_pos + i * op_step] = opcode; + + hr = D3DXCreateEffect(device, test_effect_blob, sample_effect_blob_size, + NULL, NULL, 0, NULL, &effect, NULL); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + hr = effect->lpVtbl->Begin(effect, &passes_count, 0); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + + if (fvect1) + { + param = effect->lpVtbl->GetParameterByName(effect, NULL, "opvect1"); + ok(!!param, "GetParameterByName failed.\n"); + hr = effect->lpVtbl->SetVector(effect, param, fvect1); + ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr); + } + if (fvect2) + { + param = effect->lpVtbl->GetParameterByName(effect, NULL, "opvect2"); + ok(!!param, "GetParameterByName failed.\n"); + hr = effect->lpVtbl->SetVector(effect, param, fvect2); + ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr); + } + + hr = effect->lpVtbl->BeginPass(effect, 0); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + + hr = IDirect3DDevice9_GetLight(device, result_index, &light); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + v = &light.Diffuse.r; + for (i = 0; i < 4; ++i) + todo_wine_if(todo && todo[i]) + ok(compare_float(v[i], ((float *)expected_result)[i], ulps), + "Operation %s, component %u, expected %#x (%g), got %#x (%g).\n", op_mnem, + i, expected_result[i], ((float *)expected_result)[i], ((unsigned int *)v)[i], v[i]); + + hr = effect->lpVtbl->EndPass(effect); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + hr = effect->lpVtbl->End(effect); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + effect->lpVtbl->Release(effect); + HeapFree(GetProcessHeap(), 0, test_effect_blob); +} + +static void test_effect_preshader_ops(IDirect3DDevice9 *device) +{ + static const struct + { + const char *mnem; + unsigned int opcode; + unsigned int args_count; + unsigned int expected_result[4]; + D3DXVECTOR4 fvect1, fvect2; + unsigned int ulps; + BOOL todo[4]; + } + op_tests[] = + { + {"exp", 0x10500001, 1, {0x3f800000, 0x3f800000, 0x3e5edc66, 0x7f800000}, + {0.0f, -0.0f, -2.2f, 3.402823466e+38f}, {1.0f, 2.0f, -3.0f, 4.0f}}, + }; + + static const struct + { + unsigned int pos; + unsigned int result_index; + } + blob_position[] = + { + {0, 0}, + {TEST_EFFECT_PRESHADER_OP1ARG_POS, 0}, + {TEST_EFFECT_PRESHADER_OP2ARG_POS, 2} + }; + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(op_tests); ++i) + test_preshader_op(device, test_effect_preshader_effect_blob, sizeof test_effect_preshader_effect_blob, + blob_position[op_tests[i].args_count].pos, blob_position[op_tests[i].args_count].result_index, + op_tests[i].mnem, op_tests[i].opcode, op_tests[i].args_count, + op_tests[i].expected_result, &op_tests[i].fvect1, &op_tests[i].fvect2, + op_tests[i].ulps, op_tests[i].todo); +} + START_TEST(effect) { HWND wnd; @@ -3927,6 +4033,7 @@ START_TEST(effect) test_effect_compilation_errors(device); test_effect_states(device); test_effect_preshader(device); + test_effect_preshader_ops(device); count = IDirect3DDevice9_Release(device); ok(count == 0, "The device was not properly freed: refcount %u\n", count); -- 2.5.5