From bef792f5ff2cd87db98b58acb182123ef76be6e6 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 1 Feb 2010 13:52:55 +0100 Subject: [PATCH] wined3d: Handle zero-length vectors for WINED3DSIH_NRM. 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 file changed, 19 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index dc1dc2813bd..e548aca5465 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,