[PATCH 1/5] wined3d: Handle zero-length vectors for WINED3DSIH_NRM.

Henri Verbeet hverbeet at codeweavers.com
Mon Feb 1 06:52:55 CST 2010


Unfortunately there's no reliable way to generate infinity in GLSL, but a
sufficiently large value will probably do. The important part of the patch is
that we don't generate NaN, because that will keep propagating through the
entire shader.
---
 dlls/wined3d/glsl_shader.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index dc1dc28..e548aca 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1172,6 +1172,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
         }
     }
 
+    shader_addline(buffer, "const float FLT_MAX = 1e38;\n");
+
     /* Start the main program */
     shader_addline(buffer, "void main() {\n");
     if(pshader && reg_maps->vpos) {
@@ -2127,7 +2129,6 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
         case WINED3DSIH_MAX: instruction = "max"; break;
         case WINED3DSIH_ABS: instruction = "abs"; break;
         case WINED3DSIH_FRC: instruction = "fract"; break;
-        case WINED3DSIH_NRM: instruction = "normalize"; break;
         case WINED3DSIH_EXP: instruction = "exp2"; break;
         case WINED3DSIH_DSX: instruction = "dFdx"; break;
         case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break;
@@ -2154,6 +2155,22 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
     shader_addline(buffer, "));\n");
 }
 
+static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    glsl_src_param_t src_param;
+    DWORD write_mask;
+    char dst_mask[6];
+
+    write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask);
+    shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
+
+    shader_addline(buffer, "tmp0.x = length(%s);\n", src_param.param_str);
+    shader_glsl_append_dst(buffer, ins);
+    shader_addline(buffer, "tmp0.x == 0.0 ? (%s * FLT_MAX) : (%s / tmp0.x));",
+            src_param.param_str, src_param.param_str);
+}
+
 /** Process the WINED3DSIO_EXPP instruction in GLSL:
  * For shader model 1.x, do the following (and honor the writemask, so use a temporary variable):
  *   dst.x = 2^(floor(src))
@@ -4941,7 +4958,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_MOVA          */ shader_glsl_mov,
     /* WINED3DSIH_MUL           */ shader_glsl_arith,
     /* WINED3DSIH_NOP           */ NULL,
-    /* WINED3DSIH_NRM           */ shader_glsl_map2gl,
+    /* WINED3DSIH_NRM           */ shader_glsl_nrm,
     /* WINED3DSIH_PHASE         */ NULL,
     /* WINED3DSIH_POW           */ shader_glsl_pow,
     /* WINED3DSIH_RCP           */ shader_glsl_rcp,
-- 
1.6.4.4




More information about the wine-patches mailing list