diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index b4f1dda415d..7240ab11611 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -10351,7 +10351,7 @@ static void sgn_test(IDirect3DDevice9 *device) { 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */ 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */ 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */ - 0x02000022, 0x800f0000, 0xa0e40000, /* sgn r0, c0 */ + 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */ 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */ 0x0000ffff /* end */ }; diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 3fefec9f23b..f1218adc509 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1578,7 +1578,6 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) case WINED3DSIH_SLT: instruction = "SLT"; break; case WINED3DSIH_SUB: instruction = "SUB"; break; case WINED3DSIH_MOVA:instruction = "ARR"; break; - case WINED3DSIH_SGN: instruction = "SSG"; break; case WINED3DSIH_DSX: instruction = "DDX"; break; default: instruction = ""; FIXME("Unhandled opcode %#x\n", ins->handler_idx); @@ -2455,14 +2454,15 @@ static void shader_hw_sgn(const struct wined3d_shader_instruction *ins) char src_name[50]; struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data; - /* SGN is only valid in vertex shaders */ - if(ctx->target_version == NV2) { - shader_hw_map2gl(ins); - return; - } shader_arb_get_dst_param(ins, &ins->dst[0], dst_name); shader_arb_get_src_param(ins, &ins->src[0], 0, src_name); + /* SGN is only valid in vertex shaders */ + if(ctx->target_version >= NV2) { + shader_addline(buffer, "SSG%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name); + return; + } + /* If SRC > 0.0, -SRC < SRC = TRUE, otherwise false. * if SRC < 0.0, SRC < -SRC = TRUE. If neither is true, src = 0.0 */ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index cf61117d4f7..a8922d89f35 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1956,7 +1956,6 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins) case WINED3DSIH_FRC: instruction = "fract"; break; case WINED3DSIH_NRM: instruction = "normalize"; break; case WINED3DSIH_EXP: instruction = "exp2"; break; - case WINED3DSIH_SGN: instruction = "sign"; break; case WINED3DSIH_DSX: instruction = "dFdx"; break; case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break; default: instruction = ""; @@ -2449,6 +2448,21 @@ static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins) } } +/* sgn in vs_2_0 has 2 extra parameters(registers for temporary storage) which we don't use + * here. But those extra parameters require a dedicated function for sgn, since map2gl would + * generate invalid code + */ +static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins) +{ + glsl_src_param_t src0_param; + DWORD write_mask; + + write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins); + shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); + + shader_addline(ins->ctx->buffer, "sign(%s));\n", src0_param.param_str); +} + /** Process the WINED3DSIO_LOOP instruction in GLSL: * Start a for() loop where src1.y is the initial value of aL, * increment aL by src1.z for a total of src1.x iterations. @@ -4719,7 +4733,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_RSQ */ shader_glsl_rsq, /* WINED3DSIH_SETP */ NULL, /* WINED3DSIH_SGE */ shader_glsl_compare, - /* WINED3DSIH_SGN */ shader_glsl_map2gl, + /* WINED3DSIH_SGN */ shader_glsl_sgn, /* WINED3DSIH_SINCOS */ shader_glsl_sincos, /* WINED3DSIH_SLT */ shader_glsl_compare, /* WINED3DSIH_SUB */ shader_glsl_arith, diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c index ead2769e34c..e84132e37af 100644 --- a/dlls/wined3d/shader_sm1.c +++ b/dlls/wined3d/shader_sm1.c @@ -145,7 +145,8 @@ static const struct wined3d_sm1_opcode_info vs_opcode_table[] = {WINED3DSIO_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 }, {WINED3DSIO_POW, 1, 3, WINED3DSIH_POW, 0, 0 }, {WINED3DSIO_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 }, - {WINED3DSIO_SGN, 1, 2, WINED3DSIH_SGN, 0, 0 }, + {WINED3DSIO_SGN, 1, 4, WINED3DSIH_SGN, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)}, + {WINED3DSIO_SGN, 1, 2, WINED3DSIH_SGN, WINED3D_SHADER_VERSION(3,0), -1 }, {WINED3DSIO_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 }, {WINED3DSIO_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)}, {WINED3DSIO_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 },