Stefan Dösinger : wined3d: POW and LOG operate on the absolute value.
Alexandre Julliard
julliard at winehq.org
Fri Jun 26 09:47:09 CDT 2009
Module: wine
Branch: master
Commit: f69fb5c011fcc55375c0f92616baf8ca832235c4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f69fb5c011fcc55375c0f92616baf8ca832235c4
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Thu Jun 25 22:08:36 2009 +0200
wined3d: POW and LOG operate on the absolute value.
---
dlls/wined3d/arb_program_shader.c | 81 ++++++++++++++++++++++++++++++++++---
1 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index c536b38..e0bd5e7 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1489,15 +1489,12 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
case WINED3DSIH_EXPP: instruction = "EXP"; break;
case WINED3DSIH_FRC: instruction = "FRC"; break;
case WINED3DSIH_LIT: instruction = "LIT"; break;
- case WINED3DSIH_LOG: instruction = "LG2"; break;
- case WINED3DSIH_LOGP: instruction = "LOG"; break;
case WINED3DSIH_LRP: instruction = "LRP"; break;
case WINED3DSIH_MAD: instruction = "MAD"; break;
case WINED3DSIH_MAX: instruction = "MAX"; break;
case WINED3DSIH_MIN: instruction = "MIN"; break;
case WINED3DSIH_MOV: instruction = "MOV"; break;
case WINED3DSIH_MUL: instruction = "MUL"; break;
- case WINED3DSIH_POW: instruction = "POW"; break;
case WINED3DSIH_SGE: instruction = "SGE"; break;
case WINED3DSIH_SLT: instruction = "SLT"; break;
case WINED3DSIH_SUB: instruction = "SUB"; break;
@@ -2411,6 +2408,78 @@ static void shader_hw_dsy(const struct wined3d_shader_instruction *ins)
shader_addline(buffer, "MUL%s %s, %s, ycorrection.y;\n", shader_arb_get_modifier(ins), dst, dst_name);
}
+static DWORD abs_modifier(DWORD mod, BOOL *need_abs)
+{
+ *need_abs = FALSE;
+
+ switch(mod)
+ {
+ case WINED3DSPSM_NONE: return WINED3DSPSM_ABS;
+ case WINED3DSPSM_NEG: return WINED3DSPSM_ABS;
+ case WINED3DSPSM_BIAS: *need_abs = TRUE; return WINED3DSPSM_BIAS;
+ case WINED3DSPSM_BIASNEG: *need_abs = TRUE; return WINED3DSPSM_BIASNEG;
+ case WINED3DSPSM_SIGN: *need_abs = TRUE; return WINED3DSPSM_SIGN;
+ case WINED3DSPSM_SIGNNEG: *need_abs = TRUE; return WINED3DSPSM_SIGNNEG;
+ case WINED3DSPSM_COMP: *need_abs = TRUE; return WINED3DSPSM_COMP;
+ case WINED3DSPSM_X2: *need_abs = TRUE; return WINED3DSPSM_X2;
+ case WINED3DSPSM_X2NEG: *need_abs = TRUE; return WINED3DSPSM_X2NEG;
+ case WINED3DSPSM_DZ: *need_abs = TRUE; return WINED3DSPSM_DZ;
+ case WINED3DSPSM_DW: *need_abs = TRUE; return WINED3DSPSM_DW;
+ case WINED3DSPSM_ABS: return WINED3DSPSM_ABS;
+ case WINED3DSPSM_ABSNEG: return WINED3DSPSM_ABS;
+ }
+ FIXME("Unknown modifier %u\n", mod);
+ return mod;
+}
+
+static void shader_hw_log_pow(const struct wined3d_shader_instruction *ins)
+{
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ char src0[50], src1[50], dst[50];
+ struct wined3d_shader_src_param src0_copy = ins->src[0];
+ BOOL need_abs = FALSE;
+ const char *instr;
+ BOOL arg2 = FALSE;
+
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_LOG: instr = "LG2"; break;
+ case WINED3DSIH_LOGP: instr = "LOG"; break;
+ case WINED3DSIH_POW: instr = "POW"; arg2 = TRUE; break;
+ default:
+ ERR("Unexpected instruction %d\n", ins->handler_idx);
+ return;
+ }
+
+ /* LOG, LOGP and POW operate on the absolute value of the input */
+ src0_copy.modifiers = abs_modifier(src0_copy.modifiers, &need_abs);
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst);
+ shader_arb_get_src_param(ins, &src0_copy, 0, src0);
+ if(arg2) shader_arb_get_src_param(ins, &ins->src[1], 1, src1);
+
+ if(need_abs)
+ {
+ shader_addline(buffer, "ABS TA, %s;\n", src0);
+ if(arg2)
+ {
+ shader_addline(buffer, "%s%s %s, TA, %s;\n", instr, shader_arb_get_modifier(ins), dst, src1);
+ }
+ else
+ {
+ shader_addline(buffer, "%s%s %s, TA;\n", instr, shader_arb_get_modifier(ins), dst);
+ }
+ }
+ else if(arg2)
+ {
+ shader_addline(buffer, "%s%s %s, %s, %s;\n", instr, shader_arb_get_modifier(ins), dst, src0, src1);
+ }
+ else
+ {
+ shader_addline(buffer, "%s%s %s, %s;\n", instr, shader_arb_get_modifier(ins), dst, src0);
+ }
+}
+
static void shader_hw_loop(const struct wined3d_shader_instruction *ins)
{
SHADER_BUFFER *buffer = ins->ctx->buffer;
@@ -4306,8 +4375,8 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_IFC */ shader_hw_ifc,
/* WINED3DSIH_LABEL */ NULL,
/* WINED3DSIH_LIT */ shader_hw_map2gl,
- /* WINED3DSIH_LOG */ shader_hw_map2gl,
- /* WINED3DSIH_LOGP */ shader_hw_map2gl,
+ /* WINED3DSIH_LOG */ shader_hw_log_pow,
+ /* WINED3DSIH_LOGP */ shader_hw_log_pow,
/* WINED3DSIH_LOOP */ shader_hw_loop,
/* WINED3DSIH_LRP */ shader_hw_lrp,
/* WINED3DSIH_M3x2 */ shader_hw_mnxn,
@@ -4324,7 +4393,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_NOP */ shader_hw_nop,
/* WINED3DSIH_NRM */ shader_hw_nrm,
/* WINED3DSIH_PHASE */ NULL,
- /* WINED3DSIH_POW */ shader_hw_map2gl,
+ /* WINED3DSIH_POW */ shader_hw_log_pow,
/* WINED3DSIH_RCP */ shader_hw_rsq_rcp,
/* WINED3DSIH_REP */ shader_hw_rep,
/* WINED3DSIH_RET */ NULL,
More information about the wine-cvs
mailing list