diff --git a/patches/wined3d-zero-inf-shaders/0001-wined3d-Add-a-setting-to-workaround-0-inf-problem-in.patch b/patches/wined3d-zero-inf-shaders/0001-wined3d-Add-a-setting-to-workaround-0-inf-problem-in.patch index 9860acd2..abfea75c 100644 --- a/patches/wined3d-zero-inf-shaders/0001-wined3d-Add-a-setting-to-workaround-0-inf-problem-in.patch +++ b/patches/wined3d-zero-inf-shaders/0001-wined3d-Add-a-setting-to-workaround-0-inf-problem-in.patch @@ -1,4 +1,4 @@ -From 2c66de2b511d09d4998c5df1ca48487ff8e80142 Mon Sep 17 00:00:00 2001 +From 7b97835b41aa751196b87d1c2739e48312d4b899 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Mon, 9 Sep 2019 18:48:43 +0300 Subject: [PATCH] wined3d: Add a setting to workaround 0 * inf problem in @@ -9,20 +9,20 @@ https://bugs.winehq.org/show_bug.cgi?id=34266. Signed-off-by: Paul Gofman --- - dlls/wined3d/glsl_shader.c | 75 +++++++++++++++++++++++++++++----- - dlls/wined3d/wined3d_main.c | 3 ++ - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 68 insertions(+), 11 deletions(-) + dlls/wined3d/glsl_shader.c | 123 +++++++++++++++++++++++++++------ + dlls/wined3d/wined3d_main.c | 3 + + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 107 insertions(+), 20 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c -index 99ffbf2634..aff92b6935 100644 +index c0713527ba..1632fd6005 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c -@@ -2307,6 +2307,19 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c +@@ -2298,6 +2298,19 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c if (wined3d_settings.strict_shader_math) shader_addline(buffer, "#pragma optionNV(fastmath off)\n"); -+ if (wined3d_settings.multiply_special) ++ if (wined3d_settings.multiply_special == 2 && version->major < 4) + { + shader_addline(buffer, "float dot1(float v1, float v2) {return abs(v1) == 0.0 || abs(v2) == 0.0 ? 0.0 : v1 * v2;}\n"); + shader_addline(buffer, "float dot2(vec2 v1, vec2 v2) {return dot1(v1.x, v2.x) + dot1(v1.y, v2.y);}\n"); @@ -38,12 +38,13 @@ index 99ffbf2634..aff92b6935 100644 prefix = shader_glsl_get_prefix(version->type); /* Prototype the subroutines */ -@@ -3837,7 +3850,11 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins) +@@ -3829,7 +3842,12 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins) write_mask = shader_glsl_append_dst(buffer, ins); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); - shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str); -+ if (wined3d_settings.multiply_special && ins->handler_idx == WINED3DSIH_MUL) ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4 ++ && ins->handler_idx == WINED3DSIH_MUL) + shader_addline(buffer, "mul%d(%s, %s));\n", shader_glsl_get_write_mask_size(write_mask), + src0_param.param_str, src1_param.param_str); + else @@ -51,7 +52,7 @@ index 99ffbf2634..aff92b6935 100644 } static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) -@@ -4049,26 +4066,45 @@ static void shader_glsl_dot(const struct wined3d_shader_instruction *ins) +@@ -4041,26 +4059,45 @@ static void shader_glsl_dot(const struct wined3d_shader_instruction *ins) struct glsl_src_param src0_param; struct glsl_src_param src1_param; DWORD dst_write_mask, src_write_mask; @@ -87,7 +88,7 @@ index 99ffbf2634..aff92b6935 100644 - shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str); + if (dst_size > 1) + { -+ if (wined3d_settings.multiply_special) ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) + shader_addline(buffer, "vec%d(dot%d(%s, %s)));\n", dst_size, src_size, + src0_param.param_str, src1_param.param_str); + else @@ -96,43 +97,126 @@ index 99ffbf2634..aff92b6935 100644 + } + else + { -+ if (wined3d_settings.multiply_special) ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) + shader_addline(buffer, "dot%d(%s, %s));\n", src_size, src0_param.param_str, src1_param.param_str); + else + shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str); } } -@@ -4290,8 +4326,20 @@ static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) - src_param.param_str, src_param.param_str); - shader_glsl_append_dst(buffer, ins); +@@ -4290,11 +4327,15 @@ static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) + { + DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, + ins->ctx->reg_maps->shader_version.minor); ++ static const float max_float = FLT_MAX, min_float = -FLT_MAX; ++ struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; ++ struct wined3d_string_buffer *suffix; + struct glsl_src_param src0_param; +- const char *prefix, *suffix; + unsigned int dst_size; + DWORD dst_write_mask; ++ const char *prefix; ++ BOOL guard_inf; -- shader_addline(buffer, "tmp0.x == 0.0 ? %s : (%s * inversesqrt(tmp0.x)));\n", -- src_param.param_str, src_param.param_str); -+ if (wined3d_settings.multiply_special && mask_size == 4) -+ { -+ static const float max_float = FLT_MAX; + dst_write_mask = shader_glsl_append_dst(buffer, ins); + dst_size = shader_glsl_get_write_mask_size(dst_write_mask); +@@ -4304,41 +4345,78 @@ static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) + + shader_glsl_add_src_param(ins, &ins->src[0], dst_write_mask, &src0_param); + ++ guard_inf = wined3d_settings.multiply_special == 1 && shader_version < WINED3D_SHADER_VERSION(4, 0); ++ suffix = string_buffer_get(priv->string_buffers); + -+ shader_addline(buffer, "tmp0.x == 0.0 ? vec4(vec3(0.0), sign(%s[3]) * ", -+ src_param.param_str); -+ shader_glsl_append_imm_vec(buffer, &max_float, 1, ins->ctx->gl_info); -+ shader_addline(buffer, ") : (%s * inversesqrt(tmp0.x)));\n", src_param.param_str); -+ } -+ else -+ { -+ shader_addline(buffer, "tmp0.x == 0.0 ? %s : (%s * inversesqrt(tmp0.x)));\n", -+ src_param.param_str, src_param.param_str); -+ } + switch (ins->handler_idx) + { + case WINED3DSIH_EXP: + case WINED3DSIH_EXPP: + prefix = "exp2("; +- suffix = ")"; ++ string_buffer_sprintf(suffix, ")"); + break; + + case WINED3DSIH_LOG: + case WINED3DSIH_LOGP: +- prefix = "log2(abs("; +- suffix = "))"; ++ if (guard_inf) ++ { ++ prefix = "max(log2(abs("; ++ string_buffer_sprintf(suffix, ")), "); ++ shader_glsl_append_imm_vec(suffix, &min_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ")"); ++ } ++ else ++ { ++ prefix = "log2(abs("; ++ string_buffer_sprintf(suffix, "))"); ++ } + break; + + case WINED3DSIH_RCP: +- prefix = "1.0 / "; +- suffix = ""; ++ if (guard_inf) ++ { ++ prefix = "clamp(1.0 / "; ++ string_buffer_sprintf(suffix, ", "); ++ shader_glsl_append_imm_vec(suffix, &min_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ", "); ++ shader_glsl_append_imm_vec(suffix, &max_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ")"); ++ } ++ else ++ { ++ prefix = "1.0 / "; ++ string_buffer_clear(suffix); ++ } + break; + + case WINED3DSIH_RSQ: +- prefix = "inversesqrt(abs("; +- suffix = "))"; ++ if (guard_inf) ++ { ++ prefix = "min(inversesqrt(abs("; ++ string_buffer_sprintf(suffix, ")), "); ++ shader_glsl_append_imm_vec(suffix, &max_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ")"); ++ } ++ else ++ { ++ prefix = "inversesqrt(abs("; ++ string_buffer_sprintf(suffix, "))"); ++ } + break; + + default: + prefix = ""; +- suffix = ""; ++ string_buffer_clear(suffix); + FIXME("Unhandled instruction %#x.\n", ins->handler_idx); + break; + } + + if (dst_size > 1 && shader_version < WINED3D_SHADER_VERSION(4, 0)) +- shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix); ++ shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix->buffer); + else +- shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix); ++ shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix->buffer); ++ ++ string_buffer_release(priv->string_buffers, suffix); } - static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) -@@ -4663,8 +4711,13 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins) + /** Process the WINED3DSIO_EXPP instruction in GLSL: +@@ -4655,8 +4733,13 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param); - shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n", - src0_param.param_str, src1_param.param_str, src2_param.param_str); -+ if (wined3d_settings.multiply_special) ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) + shader_addline(ins->ctx->buffer, "mul%d(%s, %s) + %s);\n", + shader_glsl_get_write_mask_size(write_mask), src0_param.param_str, + src1_param.param_str, src2_param.param_str); @@ -143,7 +227,7 @@ index 99ffbf2634..aff92b6935 100644 /* Handles transforming all WINED3DSIO_M?x? opcodes for diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c -index 2c68ae5df4..ea378d90e9 100644 +index 5d60a44ef6..e9efbbf08a 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -111,6 +111,7 @@ struct wined3d_settings wined3d_settings = @@ -154,7 +238,7 @@ index 2c68ae5df4..ea378d90e9 100644 ~0U, /* No VS shader model limit by default. */ ~0U, /* No HS shader model limit by default. */ ~0U, /* No DS shader model limit by default. */ -@@ -367,6 +368,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) +@@ -362,6 +363,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) } if (!get_config_key_dword(hkey, appkey, "strict_shader_math", &wined3d_settings.strict_shader_math)) ERR_(winediag)("Setting strict shader math to %#x.\n", wined3d_settings.strict_shader_math); @@ -164,10 +248,10 @@ index 2c68ae5df4..ea378d90e9 100644 TRACE("Limiting VS shader model to %u.\n", wined3d_settings.max_sm_vs); if (!get_config_key_dword(hkey, appkey, "MaxShaderModelHS", &wined3d_settings.max_sm_hs)) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 543028551e..1282b109a1 100644 +index b786962a74..5bc0a1a0bd 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -425,6 +425,7 @@ struct wined3d_settings +@@ -427,6 +427,7 @@ struct wined3d_settings unsigned int sample_count; BOOL check_float_constants; unsigned int strict_shader_math;