[v10 2/4] d3dx9: Add basic opcodes to preshader.

Paul Gofman gofmanp at gmail.com
Thu Apr 7 10:41:33 CDT 2016


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
Changes
- Renamed 'ncomp' to 'n' for all opcode functions
- Fixed indentation in pres_rsq()
- Added tolerance to rsq opcode test
 dlls/d3dx9_36/preshader.c    | 64 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/d3dx9_36/tests/effect.c | 52 ++++++++++++++++++-----------------
 2 files changed, 89 insertions(+), 27 deletions(-)

diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
index a21cdb2..f21c3d1 100644
--- a/dlls/d3dx9_36/preshader.c
+++ b/dlls/d3dx9_36/preshader.c
@@ -29,11 +29,57 @@ enum pres_ops
 {
     PRESHADER_OP_NOP,
     PRESHADER_OP_MOV,
+    PRESHADER_OP_ADD,
+    PRESHADER_OP_MUL,
+    PRESHADER_OP_DOT,
+    PRESHADER_OP_NEG,
+    PRESHADER_OP_RCP,
+    PRESHADER_OP_LT,
+    PRESHADER_OP_FRC,
+    PRESHADER_OP_MIN,
+    PRESHADER_OP_MAX,
+    PRESHADER_OP_GE,
+    PRESHADER_OP_CMP,
+    PRESHADER_OP_SIN,
+    PRESHADER_OP_COS,
+    PRESHADER_OP_RSQ,
 };
 
-typedef double (*pres_op_func)(double *args, int ncomp);
+typedef double (*pres_op_func)(double *args, int n);
 
-static double pres_mov(double *args, int ncomp) {return args[0];}
+static double pres_mov(double *args, int n) {return args[0];}
+static double pres_add(double *args, int n) {return args[0] + args[1];}
+static double pres_mul(double *args, int n) {return args[0] * args[1];}
+static double pres_dot(double *args, int n)
+{
+    int i;
+    double sum;
+
+    sum = 0.0;
+    for (i = 0; i < n; ++i)
+        sum += args[i] * args[i + n];
+    return sum;
+}
+static double pres_neg(double *args, int n) {return -args[0];}
+static double pres_rcp(double *args, int n) {return 1.0 / args[0];}
+static double pres_lt(double *args, int n)  {return args[0] < args[1] ? 1.0 : 0.0;}
+static double pres_ge(double *args, int n)  {return args[0] >= args[1] ? 1.0 : 0.0;}
+static double pres_frc(double *args, int n) {return args[0] - floor(args[0]);}
+static double pres_min(double *args, int n) {return fmin(args[0], args[1]);}
+static double pres_max(double *args, int n) {return fmax(args[0], args[1]);}
+static double pres_cmp(double *args, int n) {return args[0] < 0.0 ? args[2] : args[1];}
+static double pres_sin(double *args, int n) {return sin(args[0]);}
+static double pres_cos(double *args, int n) {return cos(args[0]);}
+static double pres_rsq(double *args, int n)
+{
+    double v;
+
+    v = fabs(args[0]);
+    if (v == 0.0)
+        return INFINITY;
+    else
+        return 1.0 / sqrt(v);
+}
 
 #define PRES_OPCODE_MASK 0x7ff00000
 #define PRES_OPCODE_SHIFT 20
@@ -59,6 +105,20 @@ static const struct op_info pres_op_info[] =
 {
     {0x000, "nop", 0, 0, NULL    }, /* PRESHADER_OP_NOP */
     {0x100, "mov", 1, 0, pres_mov}, /* PRESHADER_OP_MOV */
+    {0x204, "add", 2, 0, pres_add}, /* PRESHADER_OP_ADD */
+    {0x205, "mul", 2, 0, pres_mul}, /* PRESHADER_OP_MUL */
+    {0x500, "dot", 2, 1, pres_dot}, /* PRESHADER_OP_DOT */
+    {0x101, "neg", 1, 0, pres_neg}, /* PRESHADER_OP_NEG */
+    {0x103, "rcp", 1, 0, pres_rcp}, /* PRESHADER_OP_RCP */
+    {0x202, "lt",  2, 0, pres_lt }, /* PRESHADER_OP_LT  */
+    {0x104, "frc", 1, 0, pres_frc}, /* PRESHADER_OP_FRC */
+    {0x200, "min", 2, 0, pres_min}, /* PRESHADER_OP_MIN */
+    {0x201, "max", 2, 0, pres_max}, /* PRESHADER_OP_MAX */
+    {0x203, "ge",  2, 0, pres_ge }, /* PRESHADER_OP_GE  */
+    {0x300, "cmp", 3, 0, pres_cmp}, /* PRESHADER_OP_CMP */
+    {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 */
 };
 
 enum pres_value_type
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 4f017bd..459fbb0 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -3692,37 +3692,34 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
         const char *comment;
         BOOL todo[4];
         unsigned int result[4];
+        unsigned int tolerance_bit_count;
     }
     test_effect_preshader_op_results[] =
     {
-        {"1 / op", { TRUE,  TRUE,  TRUE,  TRUE}, {0x7f800000, 0xff800000, 0xbee8ba2e, 0x00200000}},
+        {"1 / op", {FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0xff800000, 0xbee8ba2e, 0x00200000}},
+        {"rsq",    {FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0x7f800000, 0x3f2c985c, 0x1f800001}, 1},
+        {"mul",    {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x80000000, 0x40d33334, 0x7f800000}},
+        {"add",    {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x40000000, 0xc0a66666, 0x7f7fffff}},
+        {"lt",     {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x3f800000, 0x00000000, 0x00000000}},
+        {"ge",     {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+        {"neg",    {FALSE, FALSE, FALSE, FALSE}, {0x80000000, 0x00000000, 0x400ccccd, 0xff7fffff}},
+        {"rcp",    {FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0xff800000, 0xbee8ba2e, 0x00200000}},
+        {"frac",   {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x00000000, 0x3f4ccccc, 0x00000000}},
+        {"min",    {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x80000000, 0xc0400000, 0x40800000}},
+        {"max",    {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x40000000, 0xc00ccccd, 0x7f7fffff}},
 #if __x86_64__
-        {"rsq",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x7f800000, 0x7f800000, 0x3f2c985d, 0x1f800000}},
+        {"sin",    {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x80000000, 0xbf4ef99e, 0xbf0599b3}},
+        {"cos",    {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x3f800000, 0xbf16a803, 0x3f5a5f96}},
 #else
-        {"rsq",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x7f800000, 0x7f800000, 0x3f2c985c, 0x1f800001}},
+        {"sin",    {FALSE, FALSE, FALSE,  TRUE}, {0x00000000, 0x80000000, 0xbf4ef99e, 0x3f792dc4}},
+        {"cos",    {FALSE, FALSE, FALSE,  TRUE}, {0x3f800000, 0x3f800000, 0xbf16a803, 0xbe6acefc}},
 #endif
-        {"mul",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x00000000, 0x80000000, 0x40d33334, 0x7f800000}},
-        {"add",    {FALSE,  TRUE,  TRUE,  TRUE}, {0x3f800000, 0x40000000, 0xc0a66666, 0x7f7fffff}},
-        {"lt",     {FALSE, FALSE,  TRUE, FALSE}, {0x3f800000, 0x3f800000, 0x00000000, 0x00000000}},
-        {"ge",     { TRUE,  TRUE, FALSE,  TRUE}, {0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
-        {"neg",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x80000000, 0x00000000, 0x400ccccd, 0xff7fffff}},
-        {"rcp",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x7f800000, 0xff800000, 0xbee8ba2e, 0x00200000}},
-        {"frac",   {FALSE, FALSE,  TRUE, FALSE}, {0x00000000, 0x00000000, 0x3f4ccccc, 0x00000000}},
-        {"min",    {FALSE,  TRUE,  TRUE,  TRUE}, {0x00000000, 0x80000000, 0xc0400000, 0x40800000}},
-        {"max",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x3f800000, 0x40000000, 0xc00ccccd, 0x7f7fffff}},
+        {"den mul",{FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0xff800000, 0xbb94f209, 0x000051ec}},
+        {"dot",    {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x7f800000, 0x41f00000, 0x00000000}},
 #if __x86_64__
-        {"sin",    {FALSE,  TRUE,  TRUE,  TRUE}, {0x00000000, 0x80000000, 0xbf4ef99e, 0xbf0599b3}},
-        {"cos",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x3f800000, 0x3f800000, 0xbf16a803, 0x3f5a5f96}},
+        {"prec",   {FALSE, FALSE,  TRUE, FALSE}, {0x2b8cbccc, 0x2c0cbccc, 0xac531800, 0x00000000}}
 #else
-        {"sin",    {FALSE,  TRUE,  TRUE,  TRUE}, {0x00000000, 0x80000000, 0xbf4ef99e, 0x3f792dc4}},
-        {"cos",    { TRUE,  TRUE,  TRUE,  TRUE}, {0x3f800000, 0x3f800000, 0xbf16a803, 0xbe6acefc}},
-#endif
-        {"den mul",{ TRUE,  TRUE,  TRUE,  TRUE}, {0x7f800000, 0xff800000, 0xbb94f209, 0x000051ec}},
-        {"dot",    {FALSE,  TRUE,  TRUE, FALSE}, {0x00000000, 0x7f800000, 0x41f00000, 0x00000000}},
-#if __x86_64__
-        {"prec",   { TRUE,  TRUE,  TRUE, FALSE}, {0x2b8cbccc, 0x2c0cbccc, 0xac531800, 0x00000000}}
-#else
-        {"prec",   { TRUE,  TRUE, FALSE, FALSE}, {0x2b8cbccc, 0x2c0cbccc, 0x00000000, 0x00000000}}
+        {"prec",   {FALSE, FALSE, FALSE, FALSE}, {0x2b8cbccc, 0x2c0cbccc, 0x00000000, 0x00000000}}
 #endif
     };
 #define TEST_EFFECT_PRES_NFLOATV ARRAY_SIZE(test_effect_preshader_fconstsv)
@@ -3789,7 +3786,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
 
     hr = effect->lpVtbl->BeginPass(effect, 0);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, &fdata[0].x, TEST_EFFECT_PRES_NFLOATV);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
@@ -3834,11 +3831,16 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
         v = i < 8 ? (unsigned int *)&light.Diffuse : (unsigned int *)&light.Ambient;
         ok(hr == D3D_OK, "Got result %#x.\n", hr);
         for (j = 0; j < 4; ++j)
+        {
+            unsigned int mask;
+
+            mask = ~0u << test_effect_preshader_op_results[i].tolerance_bit_count;
             todo_wine_if(test_effect_preshader_op_results[i].todo[j])
-            ok(v[j] == test_effect_preshader_op_results[i].result[j],
+            ok((v[j] & mask) == (test_effect_preshader_op_results[i].result[j] & mask),
                     "Operation %s, component %u, expected %#x, got %#x (%g).\n",
                     test_effect_preshader_op_results[i].comment, j,
                     test_effect_preshader_op_results[i].result[j], v[j], ((float *)v)[j]);
+        }
     }
 
     hr = effect->lpVtbl->EndPass(effect);
-- 
2.5.5




More information about the wine-patches mailing list