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>
This commit is contained in:
parent
43208b6348
commit
58d80d90a5
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue