Henri Verbeet : wined3d: Disable vertex shader output clamping.

Alexandre Julliard julliard at winehq.org
Tue Jan 25 12:01:39 CST 2011


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Mon Jan 24 18:41:16 2011 +0100

wined3d: Disable vertex shader output clamping.

It looks like NV50+ hardware gets you infinities and NaN's in D3D as well for
most things, so we should only need special handling for pow and nrm.

---

 dlls/d3d9/tests/visual.c   |   42 +++++++++++++++++-------------------------
 dlls/wined3d/glsl_shader.c |   27 +++++++++++++--------------
 2 files changed, 30 insertions(+), 39 deletions(-)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index db67be3..d01252d 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -11233,8 +11233,9 @@ static void fp_special_test(IDirect3DDevice9 *device)
         const char *name;
         const DWORD *ops;
         DWORD size;
-        D3DCOLOR color1;
-        D3DCOLOR color2;
+        D3DCOLOR r600;
+        D3DCOLOR nv40;
+        D3DCOLOR nv50;
     }
     vs_body[] =
     {
@@ -11248,26 +11249,15 @@ static void fp_special_test(IDirect3DDevice9 *device)
          * component, but here 0.0 also results in 0x00. The actual value is
          * written to the blue component.
          *
-         * There are at least two different ways for D3D implementations to
-         * handle this. AMD seems to stick mostly to the D3D documentation,
-         * and doesn't generate floating point specials in the first place.
-         * Note that that doesn't just apply to functions like rcp and rsq,
-         * but also basic mul, add, etc. nVidia seems to generate infinities,
-         * but then clamp them before sending them to the interpolators. In
-         * OpenGL these aren't clamped, and interpolating them generates NANs
-         * in the fragment shader, unless flat shading is used (essentially
-         * replicating the values instead of interpolating them).
-         *
-         * I can't currently explain the nVidia results for pow and nrm.
-         * They're not specials in the vertex shader, but look like -INF in
-         * the pixel shader. */
-        {"log",     vs_log,     sizeof(vs_log),     0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
-        {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff /* +FLT_MAX */,  0x0000ff00 /* ???         */},
-        {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000 /*  0.0     */,  0x0000ff00 /* ???         */},
-        {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
-        {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
-        {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
-        {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
+         * There are considerable differences between graphics cards in how
+         * these are handled, but pow and nrm never generate INF or NAN. */
+        {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
+        {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
+        {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
+        {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
+        {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
+        {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
+        {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
     };
 
     static const DWORD ps_code[] =
@@ -11371,9 +11361,11 @@ static void fp_special_test(IDirect3DDevice9 *device)
         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
 
         color = getPixelColor(device, 320, 240);
-        ok(color_match(color, vs_body[i].color1, 1) || color_match(color, vs_body[i].color2, 1),
-                "Expected color 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
-                vs_body[i].color1, vs_body[i].color2, vs_body[i].name, color);
+        ok(color_match(color, vs_body[i].r600, 1)
+                || color_match(color, vs_body[i].nv40, 1)
+                || color_match(color, vs_body[i].nv50, 1),
+                "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
+                vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
 
         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index c4e4188..efd6d55 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2222,13 +2222,13 @@ static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
 
     if (dst_size > 1)
     {
-        shader_addline(buffer, "vec%u(pow(abs(%s), %s)));\n",
-                dst_size, src0_param.param_str, src1_param.param_str);
+        shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n",
+                dst_size, src1_param.param_str, 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);
+        shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n",
+                src1_param.param_str, src0_param.param_str, src1_param.param_str);
     }
 }
 
@@ -3799,7 +3799,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
             set[in_idx] = mask;
             shader_glsl_write_mask_to_str(mask, reg_mask);
 
-            shader_addline(buffer, "%s%s = clamp(OUT[%u]%s, -FLT_MAX, FLT_MAX);\n",
+            shader_addline(buffer, "%s%s = OUT[%u]%s;\n",
                     destination, reg_mask, j, reg_mask);
         }
     }
@@ -3847,7 +3847,6 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
     shader_buffer_clear(buffer);
 
     shader_addline(buffer, "#version 120\n");
-    shader_addline(buffer, "const float FLT_MAX = 1e38;\n");
 
     if (ps_major < 3)
     {
@@ -3867,15 +3866,15 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
             if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
             {
                 if (!semantic_idx)
-                    shader_addline(buffer, "gl_FrontColor%s = clamp(OUT[%u]%s, -FLT_MAX, FLT_MAX);\n",
+                    shader_addline(buffer, "gl_FrontColor%s = OUT[%u]%s;\n",
                             reg_mask, i, reg_mask);
                 else if (semantic_idx == 1)
-                    shader_addline(buffer, "gl_FrontSecondaryColor%s = clamp(OUT[%u]%s, -FLT_MAX, FLT_MAX);\n",
+                    shader_addline(buffer, "gl_FrontSecondaryColor%s = OUT[%u]%s;\n",
                             reg_mask, i, reg_mask);
             }
             else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
             {
-                shader_addline(buffer, "gl_Position%s = clamp(OUT[%u]%s, -FLT_MAX, FLT_MAX);\n",
+                shader_addline(buffer, "gl_Position%s = OUT[%u]%s;\n",
                         reg_mask, i, reg_mask);
             }
             else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
@@ -3885,7 +3884,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
                     if (!(gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) || ps_major > 0)
                         write_mask |= WINED3DSP_WRITEMASK_3;
 
-                    shader_addline(buffer, "gl_TexCoord[%u]%s = clamp(OUT[%u]%s, -FLT_MAX, FLT_MAX);\n",
+                    shader_addline(buffer, "gl_TexCoord[%u]%s = OUT[%u]%s;\n",
                             semantic_idx, reg_mask, i, reg_mask);
                     if (!(write_mask & WINED3DSP_WRITEMASK_3))
                         shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
@@ -3893,11 +3892,11 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
             }
             else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
             {
-                shader_addline(buffer, "gl_PointSize = clamp(OUT[%u].%c, -FLT_MAX, FLT_MAX);\n", i, reg_mask[1]);
+                shader_addline(buffer, "gl_PointSize = OUT[%u].%c;\n", i, reg_mask[1]);
             }
             else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
             {
-                shader_addline(buffer, "gl_FogFragCoord = clamp(OUT[%u].%c, -FLT_MAX, FLT_MAX);\n", i, reg_mask[1]);
+                shader_addline(buffer, "gl_FogFragCoord = OUT[%u].%c;\n", i, reg_mask[1]);
             }
         }
         shader_addline(buffer, "}\n");
@@ -3919,12 +3918,12 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
 
             if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
             {
-                shader_addline(buffer, "gl_Position%s = clamp(OUT[%u]%s, -FLT_MAX, FLT_MAX);\n",
+                shader_addline(buffer, "gl_Position%s = OUT[%u]%s;\n",
                         reg_mask, i, reg_mask);
             }
             else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
             {
-                shader_addline(buffer, "gl_PointSize = clamp(OUT[%u].%c, -FLT_MAX, FLT_MAX);\n", i, reg_mask[1]);
+                shader_addline(buffer, "gl_PointSize = OUT[%u].%c;\n", i, reg_mask[1]);
             }
         }
 




More information about the wine-cvs mailing list