[v2 1/2] d3dx9: Add 'exp' preshader opcode.

Paul Gofman gofmanp at gmail.com
Mon Apr 25 03:52:17 CDT 2016


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
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




More information about the wine-patches mailing list