H. Verbeet : wined3d: WINED3DSIO_POW should use the absolute value of the first source register.

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 11 07:28:02 CDT 2007


Module: wine
Branch: master
Commit: c3c57247899fbc31b19293f63625b89f46e2be7b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c3c57247899fbc31b19293f63625b89f46e2be7b

Author: H. Verbeet <hverbeet at gmail.com>
Date:   Fri May 11 12:12:40 2007 +0200

wined3d: WINED3DSIO_POW should use the absolute value of the first source register.

---

 dlls/wined3d/glsl_shader.c     |   24 +++++++++++++++++++++++-
 dlls/wined3d/pixelshader.c     |    2 +-
 dlls/wined3d/vertexshader.c    |    2 +-
 dlls/wined3d/wined3d_private.h |    1 +
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 9ff5378..6636892 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -987,6 +987,29 @@ void shader_glsl_cross(SHADER_OPCODE_ARG *arg) {
     shader_addline(arg->buffer, "cross(%s, %s).%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
 }
 
+/* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
+ * Src0 and src1 are scalars. Note that D3D uses the absolute of src0, while
+ * GLSL uses the value as-is. */
+void shader_glsl_pow(SHADER_OPCODE_ARG *arg) {
+    SHADER_BUFFER *buffer = arg->buffer;
+    glsl_src_param_t src0_param;
+    glsl_src_param_t src1_param;
+    DWORD dst_write_mask;
+    size_t dst_size;
+
+    dst_write_mask = shader_glsl_append_dst(buffer, arg);
+    dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
+
+    shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+
+    if (dst_size > 1) {
+        shader_addline(buffer, "vec%d(pow(abs(%s), %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
+    } else {
+        shader_addline(buffer, "pow(abs(%s), %s));\n", src0_param.param_str, src1_param.param_str);
+    }
+}
+
 /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
 void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
@@ -1005,7 +1028,6 @@ void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
         case WINED3DSIO_RSQ: instruction = "inversesqrt"; break;
         case WINED3DSIO_ABS: instruction = "abs"; break;
         case WINED3DSIO_FRC: instruction = "fract"; break;
-        case WINED3DSIO_POW: instruction = "pow"; break;
         case WINED3DSIO_NRM: instruction = "normalize"; break;
         case WINED3DSIO_LOGP:
         case WINED3DSIO_LOG: instruction = "log2"; break;
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 6627c06..1cab706 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -183,7 +183,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
     {WINED3DSIO_FRC,  "frc",  "FRC", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
     {WINED3DSIO_CND,  "cnd",  NULL, 1, 4, pshader_hw_cnd, shader_glsl_cnd, WINED3DPS_VERSION(1,1), WINED3DPS_VERSION(1,4)},
     {WINED3DSIO_CMP,  "cmp",  NULL, 1, 4, pshader_hw_cmp, shader_glsl_cmp, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
-    {WINED3DSIO_POW,  "pow",  "POW", 1, 3, NULL, shader_glsl_map2gl, 0, 0},
+    {WINED3DSIO_POW,  "pow",  "POW", 1, 3, NULL, shader_glsl_pow, 0, 0},
     {WINED3DSIO_CRS,  "crs",  "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0},
     /* TODO: xyz normalise can be performed as VS_ARB using one temporary register,
         DP3 tmp , vec, vec;
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 56a4354..0b9d4cf 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -108,7 +108,7 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
     {WINED3DSIO_DST,    "dst",  "DST", 1, 3, vshader_hw_map2gl,   shader_glsl_dst, 0, 0},
     {WINED3DSIO_LRP,    "lrp",  "LRP", 1, 4, NULL,                shader_glsl_lrp, 0, 0},
     {WINED3DSIO_FRC,    "frc",  "FRC", 1, 2, vshader_hw_map2gl,   shader_glsl_map2gl, 0, 0},
-    {WINED3DSIO_POW,    "pow",  "POW", 1, 3, NULL,                shader_glsl_map2gl, 0, 0},
+    {WINED3DSIO_POW,    "pow",  "POW", 1, 3, NULL,                shader_glsl_pow, 0, 0},
     {WINED3DSIO_CRS,    "crs",  "XPS", 1, 3, NULL,                shader_glsl_cross, 0, 0},
     /* TODO: sng can possibly be performed a  s
         RCP tmp, vec
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3c03cac..b7e3453 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1725,6 +1725,7 @@ extern void shader_glsl_rep(SHADER_OPCODE_ARG* arg);
 extern void shader_glsl_call(SHADER_OPCODE_ARG* arg);
 extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg);
 extern void shader_glsl_label(SHADER_OPCODE_ARG* arg);
+extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg);
 
 /** GLSL Pixel Shader Prototypes */
 extern void pshader_glsl_tex(SHADER_OPCODE_ARG* arg);




More information about the wine-cvs mailing list