Module: wine Branch: master Commit: 58d80d90a54a9d3be853e549ae828edc411f2649 URL: http://source.winehq.org/git/wine.git/?a=commit;h=58d80d90a54a9d3be853e549ae...
Author: Paul Gofman gofmanp@gmail.com Date: Sun Apr 17 18:59:45 2016 +0200
d3dx9: Add basic opcodes to preshader.
Signed-off-by: Paul Gofman gofmanp@gmail.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d3dx9_36/preshader.c | 64 ++++++++++++++++++++++++++++++++++++++++++-- dlls/d3dx9_36/tests/effect.c | 56 +++++++++++++++++++------------------- 2 files changed, 90 insertions(+), 30 deletions(-)
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c index fba9973..b831be1 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..99f0d46 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 ulps; } 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); @@ -3828,17 +3825,20 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
for (i = 0; i < TEST_EFFECT_PRES_NOPTESTS; ++i) { - unsigned int *v; + float *v;
hr = IDirect3DDevice9_GetLight(device, i % 8, &light); - v = i < 8 ? (unsigned int *)&light.Diffuse : (unsigned int *)&light.Ambient; + v = i < 8 ? &light.Diffuse.r : &light.Ambient.r; ok(hr == D3D_OK, "Got result %#x.\n", hr); for (j = 0; j < 4; ++j) + { todo_wine_if(test_effect_preshader_op_results[i].todo[j]) - ok(v[j] == test_effect_preshader_op_results[i].result[j], + ok(compare_float(v[j], ((float *)test_effect_preshader_op_results[i].result)[j], + test_effect_preshader_op_results[i].ulps), "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]); + test_effect_preshader_op_results[i].result[j], ((unsigned int *)v)[j], v[j]); + } }
hr = effect->lpVtbl->EndPass(effect);