Module: wine Branch: master Commit: 91ac0c37b1f36978d8bf974daf24ad9c77d49d6f URL: http://source.winehq.org/git/wine.git/?a=commit;h=91ac0c37b1f36978d8bf974daf...
Author: Henri Verbeet hverbeet@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]); } }