[4/5] wined3d: Fix pow handling with special values in ARB backend.

Matteo Bruni matteo.mystral at gmail.com
Wed Apr 27 17:34:33 CDT 2011


-------------- next part --------------
From 29aa31d654de541cb09e6a689289150b4a98e6cc Mon Sep 17 00:00:00 2001
From: Matteo Bruni <mbruni at codeweavers.com>
Date: Sat, 23 Apr 2011 00:38:49 +0200
Subject: wined3d: Fix pow handling with special values in ARB backend.

---
 dlls/wined3d/arb_program_shader.c |   22 ++++++++++++++++++++--
 dlls/wined3d/shader.c             |    1 +
 dlls/wined3d/wined3d_private.h    |    3 ++-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index fd97c96..397310e 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -340,6 +340,7 @@ static BOOL need_helper_const(const struct arb_vshader_private *shader_data,
     if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) return TRUE; /* Have to init texcoords. */
     if (!use_nv_clip(gl_info)) return TRUE; /* Init the clip texcoord */
     if (reg_maps->usesnrm) return TRUE; /* 0.0 */
+    if (reg_maps->usespow) return TRUE; /* EPS, 0.0 and 1.0 */
     return FALSE;
 }
 
@@ -2773,6 +2774,8 @@ static void shader_hw_pow(const struct wined3d_shader_instruction *ins)
     char src0[50], src1[50], dst[50];
     struct wined3d_shader_src_param src0_copy = ins->src[0];
     BOOL need_abs = FALSE;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
 
     /* POW operates on the absolute value of the input */
     src0_copy.modifiers = abs_modifier(src0_copy.modifiers, &need_abs);
@@ -2784,11 +2787,26 @@ static void shader_hw_pow(const struct wined3d_shader_instruction *ins)
     if (need_abs)
     {
         shader_addline(buffer, "ABS TA.x, %s;\n", src0);
-        shader_addline(buffer, "POW%s %s, TA.x, %s;\n", shader_arb_get_modifier(ins), dst, src1);
+        strcpy(src0, "TA.x");
+    }
+
+    if (priv->target_version >= NV2)
+    {
+        shader_addline(buffer, "MOVC TA.y, %s;\n", src1);
+        shader_addline(buffer, "POW%s %s, %s, TA.y;\n", shader_arb_get_modifier(ins), dst, src0);
+        shader_addline(buffer, "MOV %s (EQ.y), %s;\n", dst, one);
     }
     else
     {
-        shader_addline(buffer, "POW%s %s, %s, %s;\n", shader_arb_get_modifier(ins), dst, src0, src1);
+        const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+        const char *flt_eps = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_EPS);
+        shader_addline(buffer, "ABS TA.y, %s;\n", src1);
+        shader_addline(buffer, "SGE TA.y, -TA.y, %s;\n", zero);
+        /* Possibly add flt_eps to avoid getting float special values */
+        shader_addline(buffer, "MAD TA.x, TA.y, %s, %s;\n", flt_eps, src1);
+        shader_addline(buffer, "POW%s TA.x, %s, TA.x;\n", shader_arb_get_modifier(ins), src0);
+        shader_addline(buffer, "MAD TA.x, -TA.x, TA.y, TA.x;\n");
+        shader_addline(buffer, "MAD %s, TA.y, %s, TA.x;\n", dst, one);
     }
 }
 
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 464fa9a..738a9c0 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -788,6 +788,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1;
             else if (ins.handler_idx == WINED3DSIH_IFC) reg_maps->usesifc = 1;
             else if (ins.handler_idx == WINED3DSIH_CALL) reg_maps->usescall = 1;
+            else if (ins.handler_idx == WINED3DSIH_POW) reg_maps->usespow = 1;
 
             limit = ins.src_count + (ins.predicate ? 1 : 0);
             for (i = 0; i < limit; ++i)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 69e6a1f..b4674ac 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -559,7 +559,8 @@ struct wined3d_shader_reg_maps
     WORD usestexldl     : 1;
     WORD usesifc        : 1;
     WORD usescall       : 1;
-    WORD padding        : 4;
+    WORD usespow        : 1;
+    WORD padding        : 3;
 
     /* Whether or not loops are used in this shader, and nesting depth */
     unsigned loop_depth;
-- 
1.7.3.4


More information about the wine-patches mailing list