diff --git a/.github/workflows/build-aur.yml b/.github/workflows/build-aur.yml index c3b3ef9..d097d76 100644 --- a/.github/workflows/build-aur.yml +++ b/.github/workflows/build-aur.yml @@ -120,9 +120,6 @@ jobs: echo "replace#global#_generic_release=false#_generic_release=true" > ~/.customizepkg/${AUR_PACKAGE}-wow64 echo "replace#global#^_patchbase_tag=.*#_patchbase_tag=${CURRENT_TAG}" >> ~/.customizepkg/${AUR_PACKAGE}-wow64 echo "replace#global#sha512sums+=.*#sha512sums+=('SKIP')" >> ~/.customizepkg/${AUR_PACKAGE}-wow64 - echo "remove#depends#.*lib32-x265.*" > ~/.customizepkg/lib32-ffmpeg - echo "replace#build#enable-cuda#disable-cuda" >> ~/.customizepkg/lib32-ffmpeg - echo "replace#build#enable-libx265#disable-libx265" >> ~/.customizepkg/lib32-ffmpeg EOF echo -e "\n[bin]\nPreBuildCommand = customizepkg --modify" >> /etc/paru.conf @@ -141,6 +138,7 @@ jobs: run: | sudo -u builder bash << EOF cd ~ + sleep 240 paru -S --nocheck --noconfirm --mflags "--skipinteg" ${AUR_PACKAGE} --assume-installed=ntsync-dkms paru -S --nocheck --noconfirm --mflags "--skipinteg" ${AUR_PACKAGE}-wow64 --assume-installed=ntsync-dkms EOF diff --git a/0003-pending-mrs-and-backports/6285-shell32-Allow-FindExecutables-to-find-unix-files/0001-shell32-Allow-FindExecutables-to-find-unix-files.patch b/0003-pending-mrs-and-backports/6285-shell32-Allow-FindExecutables-to-find-unix-files/0001-shell32-Allow-FindExecutables-to-find-unix-files.patch new file mode 100644 index 0000000..d87eb24 --- /dev/null +++ b/0003-pending-mrs-and-backports/6285-shell32-Allow-FindExecutables-to-find-unix-files/0001-shell32-Allow-FindExecutables-to-find-unix-files.patch @@ -0,0 +1,42 @@ +From 2b4faa78340a546e709e881a2b291997a2b0df83 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 15 Aug 2024 10:33:02 +1000 +Subject: [PATCH] shell32: Allow FindExecutables to find unix files. + +--- + dlls/shell32/shlexec.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c +index 828c7168a34..607aca3a450 100644 +--- a/dlls/shell32/shlexec.c ++++ b/dlls/shell32/shlexec.c +@@ -677,7 +677,15 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, + /* The file was found in lpPath or one of the directories in the system-wide search path */ + } + else +- xlpFile[0] = '\0'; ++ { ++ /* Checking for an unix application */ ++ if( (xlpFile[0] == '/') || PathFindOnPathW(xlpFile, search_paths)) ++ { ++ lstrcpyW(lpResult, xlpFile); ++ } ++ else ++ xlpFile[0] = '\0'; ++ } + } + + attribs = GetFileAttributesW(lpFile); +@@ -1939,6 +1947,8 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) + + end: + TRACE("retval %Iu\n", retval); ++ if (retval == SE_ERR_NOASSOC) ++ SetLastError(ERROR_FILE_NOT_FOUND); + + free(wszApplicationName); + if (wszParameters != parametersBuffer) +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0001-wined3d-Feed-WINED3D-RS-POINTSIZE-through-a-push-constant-buffer.patch b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0001-wined3d-Feed-WINED3D-RS-POINTSIZE-through-a-push-constant-buffer.patch new file mode 100644 index 0000000..7ae0c6f --- /dev/null +++ b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0001-wined3d-Feed-WINED3D-RS-POINTSIZE-through-a-push-constant-buffer.patch @@ -0,0 +1,49 @@ +From 759db416c81301833740a8f43ec3ffb738f1ce4c Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 9 Jun 2024 12:50:30 -0500 +Subject: [PATCH] wined3d: Feed WINED3D_RS_POINTSIZE through a push constant + buffer. + +Not yet used by the GLSL backend, but will be needed by the HLSL backend. +--- + dlls/wined3d/stateblock.c | 3 +++ + dlls/wined3d/wined3d_private.h | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c +index 80c1a6ea5b7..c064d950ba5 100644 +--- a/dlls/wined3d/stateblock.c ++++ b/dlls/wined3d/stateblock.c +@@ -1616,6 +1616,7 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb + stateblock->changed.alpha_to_coverage = 1; + stateblock->stateblock_state.alpha_to_coverage = (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE); + } ++ stateblock->changed.point_scale = 1; + break; + + case WINED3D_RS_TEXTUREFACTOR: +@@ -3810,6 +3811,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, + { + struct wined3d_ffp_point_constants constants; + ++ constants.size = int_to_float(state->rs[WINED3D_RS_POINTSIZE]); ++ + if (state->rs[WINED3D_RS_POINTSCALEENABLE]) + { + float scale_factor = state->viewport.height * state->viewport.height; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 39a4aa5da9c..3e797b47795 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2784,7 +2784,7 @@ struct wined3d_ffp_vs_constants + struct wined3d_ffp_point_constants + { + float scale_const, scale_linear, scale_quad; +- float padding; /* For the HLSL backend. */ ++ float size; + } point; + struct wined3d_material material; + float padding[3]; /* For the HLSL backend. */ +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0002-wined3d-Implement-point-size-in-the-HLSL-FFP-pipeline.patch b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0002-wined3d-Implement-point-size-in-the-HLSL-FFP-pipeline.patch new file mode 100644 index 0000000..faaf4ae --- /dev/null +++ b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0002-wined3d-Implement-point-size-in-the-HLSL-FFP-pipeline.patch @@ -0,0 +1,46 @@ +From b197989561e8f086b0e028d255d168d48e5d2ddf Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 9 Jun 2024 12:50:30 -0500 +Subject: [PATCH] wined3d: Implement point size in the HLSL FFP pipeline. + +--- + dlls/wined3d/ffp_hlsl.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/ffp_hlsl.c b/dlls/wined3d/ffp_hlsl.c +index b662f1756c8..51a621aad6d 100644 +--- a/dlls/wined3d/ffp_hlsl.c ++++ b/dlls/wined3d/ffp_hlsl.c +@@ -201,9 +201,6 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + { + struct wined3d_string_buffer texcoord; + +- if (settings->point_size) +- FIXME("Ignoring point size.\n"); +- + if (settings->vertexblends) + FIXME("Ignoring vertex blend.\n"); + +@@ -256,6 +253,7 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + } + if (settings->fog_mode == WINED3D_FFP_VS_FOG_DEPTH || settings->fog_mode == WINED3D_FFP_VS_FOG_RANGE) + shader_addline(buffer, " float fogcoord : FOG;\n"); ++ shader_addline(buffer, " float point_size : PSIZE;\n"); + shader_addline(buffer, "};\n\n"); + + shader_addline(buffer, "float3 ffp_normalize(float3 n)\n{\n"); +@@ -350,6 +348,11 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + break; + } + ++ shader_addline(buffer, " o.point_size = %s / sqrt(c.point_params.x" ++ " + c.point_params.y * length(ec_pos.xyz)" ++ " + c.point_params.z * dot(ec_pos.xyz, ec_pos.xyz));\n", ++ settings->per_vertex_point_size ? "i.point_size" : "c.point_params.w"); ++ + shader_addline(buffer, "}\n"); + + return true; +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0003-wined3d-Implement-vertex-blending-in-the-HLSL-FFP-pipeline.patch b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0003-wined3d-Implement-vertex-blending-in-the-HLSL-FFP-pipeline.patch new file mode 100644 index 0000000..c2b888b --- /dev/null +++ b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0003-wined3d-Implement-vertex-blending-in-the-HLSL-FFP-pipeline.patch @@ -0,0 +1,78 @@ +From 7e52ea5b11b14c66aecb1aee99aedb963328fd81 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 9 Jun 2024 12:50:30 -0500 +Subject: [PATCH] wined3d: Implement vertex blending in the HLSL FFP pipeline. + +--- + dlls/wined3d/ffp_hlsl.c | 32 ++++++++++++++++++++++++-------- + 1 file changed, 24 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/ffp_hlsl.c b/dlls/wined3d/ffp_hlsl.c +index 51a621aad6d..d846a6bda26 100644 +--- a/dlls/wined3d/ffp_hlsl.c ++++ b/dlls/wined3d/ffp_hlsl.c +@@ -201,9 +201,6 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + { + struct wined3d_string_buffer texcoord; + +- if (settings->vertexblends) +- FIXME("Ignoring vertex blend.\n"); +- + /* This must be kept in sync with struct wined3d_ffp_vs_constants. */ + shader_addline(buffer, "uniform struct\n"); + shader_addline(buffer, "{\n"); +@@ -264,6 +261,8 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + shader_addline(buffer, "void main(in struct input i, out struct output o)\n"); + shader_addline(buffer, "{\n"); + ++ shader_addline(buffer, " i.blend_weight[%u] = 1.0;\n", settings->vertexblends); ++ + if (settings->transformed) + { + shader_addline(buffer, " float4 ec_pos = float4(i.pos.xyz, 1.0);\n"); +@@ -277,9 +276,12 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + } + else + { +- shader_addline(buffer, " float4 ec_pos = 0.0;\n\n"); ++ for (unsigned int i = 0; i < settings->vertexblends; ++i) ++ shader_addline(buffer, " i.blend_weight[%u] -= i.blend_weight[%u];\n", settings->vertexblends, i); + +- shader_addline(buffer, " ec_pos += mul(c.modelview_matrices[0], float4(i.pos.xyz, 1.0));\n\n"); ++ shader_addline(buffer, " float4 ec_pos = 0.0;\n\n"); ++ for (unsigned int i = 0; i < settings->vertexblends + 1; ++i) ++ shader_addline(buffer, " ec_pos += i.blend_weight[%u] * mul(c.modelview_matrices[%u], float4(i.pos.xyz, 1.0));\n", i, i); + + shader_addline(buffer, " o.pos = mul(c.projection_matrix, ec_pos);\n"); + shader_addline(buffer, " ec_pos /= ec_pos.w;\n\n"); +@@ -288,10 +290,24 @@ static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings + shader_addline(buffer, " float3 normal = 0.0;\n"); + if (settings->normal) + { +- if (settings->transformed) +- shader_addline(buffer, " normal = i.normal;\n"); ++ if (!settings->vertexblends) ++ { ++ if (settings->transformed) ++ shader_addline(buffer, " normal = i.normal;\n"); ++ else ++ shader_addline(buffer, " normal = mul((float3x3)c.modelview_matrices[1], i.normal);\n"); ++ } + else +- shader_addline(buffer, " normal = mul((float3x3)c.modelview_matrices[1], i.normal);\n"); ++ { ++ for (unsigned int i = 0; i < settings->vertexblends + 1; ++i) ++ { ++ if (settings->transformed) ++ shader_addline(buffer, " normal += i.blend_weight[%u] * i.normal;\n", i); ++ else ++ shader_addline(buffer, " normal += i.blend_weight[%u]" ++ " * mul((float3x3)c.modelview_matrices[%u], i.normal);\n", i, i); ++ } ++ } + + if (settings->normalize) + shader_addline(buffer, " normal = ffp_normalize(normal);\n"); +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0004-wined3d-Feed-bumpenv-constants-through-a-push-constant-buffer.patch b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0004-wined3d-Feed-bumpenv-constants-through-a-push-constant-buffer.patch new file mode 100644 index 0000000..bdbd6a4 --- /dev/null +++ b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0004-wined3d-Feed-bumpenv-constants-through-a-push-constant-buffer.patch @@ -0,0 +1,363 @@ +From 095f57941cefac039c155f0edf5e49d5e5706158 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 9 Jun 2024 12:50:30 -0500 +Subject: [PATCH] wined3d: Feed bumpenv constants through a push constant + buffer. + +--- + dlls/wined3d/adapter_vk.c | 50 ------------------------------- + dlls/wined3d/directx.c | 50 ------------------------------- + dlls/wined3d/ffp_gl.c | 54 ---------------------------------- + dlls/wined3d/ffp_hlsl.c | 4 +++ + dlls/wined3d/glsl_shader.c | 12 +++++--- + dlls/wined3d/stateblock.c | 35 ++++++++++++++++++++++ + dlls/wined3d/wined3d_private.h | 9 ++++++ + 7 files changed, 56 insertions(+), 158 deletions(-) + +diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c +index 8c5f75c1316..60546d86597 100644 +--- a/dlls/wined3d/adapter_vk.c ++++ b/dlls/wined3d/adapter_vk.c +@@ -44,56 +44,6 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = + {STATE_DEPTH_BOUNDS, {STATE_DEPTH_BOUNDS, state_nop}}, + {STATE_RASTERIZER, {STATE_RASTERIZER, state_nop}}, + {STATE_SCISSORRECT, {STATE_SCISSORRECT, state_nop}}, +- +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), state_nop}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00)}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE)}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), state_nop}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE)}}, +- + {STATE_VIEWPORT, {STATE_VIEWPORT, state_nop}}, + {STATE_INDEXBUFFER, {STATE_INDEXBUFFER, state_nop}}, + {STATE_RENDER(WINED3D_RS_LINEPATTERN), {STATE_RENDER(WINED3D_RS_LINEPATTERN), state_nop}}, +diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c +index f236a59f963..03f969006a8 100644 +--- a/dlls/wined3d/directx.c ++++ b/dlls/wined3d/directx.c +@@ -2799,56 +2799,6 @@ static const struct wined3d_state_entry_template misc_state_template_no3d[] = + {STATE_VDECL, {STATE_VDECL, state_nop}}, + {STATE_RASTERIZER, {STATE_VDECL}}, + {STATE_SCISSORRECT, {STATE_VDECL}}, +- +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), {STATE_VDECL}}, +- {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_VDECL}}, +- + {STATE_VIEWPORT, {STATE_VDECL}}, + {STATE_INDEXBUFFER, {STATE_VDECL}}, + {STATE_RENDER(WINED3D_RS_LINEPATTERN), {STATE_VDECL}}, +diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c +index 20f9828d0a2..ebfbce1384f 100644 +--- a/dlls/wined3d/ffp_gl.c ++++ b/dlls/wined3d/ffp_gl.c +@@ -1028,11 +1028,6 @@ static void state_shader(struct wined3d_context *context, const struct wined3d_s + context->shader_update_mask |= 1u << shader_type; + } + +-static void shader_bumpenv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +-{ +- context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV; +-} +- + void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; +@@ -1470,55 +1465,6 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = + { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer_cc }, ARB_CLIP_CONTROL }, + { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer }, WINED3D_GL_EXT_NONE }, + { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, +- { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, +- + { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart_cc}, ARB_CLIP_CONTROL }, + { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE }, + { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT }, +diff --git a/dlls/wined3d/ffp_hlsl.c b/dlls/wined3d/ffp_hlsl.c +index d846a6bda26..d2c8214020f 100644 +--- a/dlls/wined3d/ffp_hlsl.c ++++ b/dlls/wined3d/ffp_hlsl.c +@@ -701,6 +701,10 @@ static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *setti + shader_addline(buffer, " float4 texture_factor;\n"); + shader_addline(buffer, " float4 specular_enable;\n"); + shader_addline(buffer, " float4 color_key[2];\n"); ++ /* Bumpenv constants are manually packed. */ ++ shader_addline(buffer, " float4 bumpenv_matrices[%u];\n", WINED3D_MAX_FFP_TEXTURES); ++ shader_addline(buffer, " float4 bumpenv_lscale[2];\n"); ++ shader_addline(buffer, " float4 bumpenv_loffset[2];\n"); + shader_addline(buffer, "} c;\n"); + + shader_addline(buffer, "struct input\n"); +diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c +index 61b53da540a..16021210902 100644 +--- a/dlls/wined3d/glsl_shader.c ++++ b/dlls/wined3d/glsl_shader.c +@@ -1915,7 +1915,8 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, + { + static const uint32_t ps_update_mask = WINED3D_SHADER_CONST_PS_F + | WINED3D_SHADER_CONST_FFP_COLOR_KEY +- | WINED3D_SHADER_CONST_FFP_PS; ++ | WINED3D_SHADER_CONST_FFP_PS ++ | WINED3D_SHADER_CONST_PS_BUMP_ENV; + + if (context->constant_update_mask & ps_update_mask) + shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], +@@ -1938,20 +1939,23 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, + + if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV) + { ++ const struct wined3d_ffp_ps_constants *constants = wined3d_buffer_load_sysmem( ++ context_gl->c.device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], &context_gl->c); ++ + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + { + if (prog->ps.bumpenv_mat_location[i] == -1) + continue; + + GL_EXTCALL(glUniformMatrix2fv(prog->ps.bumpenv_mat_location[i], 1, 0, +- (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00])); ++ &constants->bumpenv.matrices[i]._00)); + + if (prog->ps.bumpenv_lum_scale_location[i] != -1) + { + GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_scale_location[i], 1, +- (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE])); ++ &constants->bumpenv.lscale[i])); + GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_offset_location[i], 1, +- (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET])); ++ &constants->bumpenv.loffset[i])); + } + } + +diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c +index c064d950ba5..901b45f8ae3 100644 +--- a/dlls/wined3d/stateblock.c ++++ b/dlls/wined3d/stateblock.c +@@ -68,6 +68,7 @@ struct wined3d_saved_states + uint32_t ffp_ps_settings : 1; + uint32_t rasterizer_state : 1; + uint32_t position_transformed : 1; ++ uint32_t bumpenv_constants : 1; + }; + + struct stage_state +@@ -1737,6 +1738,15 @@ void CDECL wined3d_stateblock_set_texture_stage_state(struct wined3d_stateblock + stateblock->changed.ffp_ps_settings = 1; + break; + ++ case WINED3D_TSS_BUMPENV_LOFFSET: ++ case WINED3D_TSS_BUMPENV_LSCALE: ++ case WINED3D_TSS_BUMPENV_MAT00: ++ case WINED3D_TSS_BUMPENV_MAT01: ++ case WINED3D_TSS_BUMPENV_MAT10: ++ case WINED3D_TSS_BUMPENV_MAT11: ++ stateblock->changed.bumpenv_constants = 1; ++ break; ++ + default: + break; + } +@@ -2409,6 +2419,7 @@ static void wined3d_stateblock_invalidate_initial_states(struct wined3d_stateblo + stateblock->changed.point_scale = 1; + stateblock->changed.ffp_vs_settings = 1; + stateblock->changed.ffp_ps_settings = 1; ++ stateblock->changed.bumpenv_constants = 1; + } + + static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const struct wined3d_stateblock *device_state, +@@ -3496,6 +3507,12 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, + + switch (j) + { ++ case WINED3D_TSS_BUMPENV_LOFFSET: ++ case WINED3D_TSS_BUMPENV_LSCALE: ++ case WINED3D_TSS_BUMPENV_MAT00: ++ case WINED3D_TSS_BUMPENV_MAT01: ++ case WINED3D_TSS_BUMPENV_MAT10: ++ case WINED3D_TSS_BUMPENV_MAT11: + case WINED3D_TSS_CONSTANT: + break; + +@@ -3832,6 +3849,24 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, + offsetof(struct wined3d_ffp_vs_constants, point), sizeof(constants), &constants); + } + ++ if (changed->bumpenv_constants) ++ { ++ struct wined3d_ffp_bumpenv_constants constants; ++ ++ for (unsigned int i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) ++ { ++ constants.matrices[i]._00 = int_to_float(state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00]); ++ constants.matrices[i]._01 = int_to_float(state->texture_states[i][WINED3D_TSS_BUMPENV_MAT01]); ++ constants.matrices[i]._10 = int_to_float(state->texture_states[i][WINED3D_TSS_BUMPENV_MAT10]); ++ constants.matrices[i]._11 = int_to_float(state->texture_states[i][WINED3D_TSS_BUMPENV_MAT11]); ++ constants.loffset[i] = int_to_float(state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET]); ++ constants.lscale[i] = int_to_float(state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE]); ++ } ++ ++ wined3d_device_context_push_constants(context, WINED3D_PUSH_CONSTANTS_PS_FFP, WINED3D_SHADER_CONST_PS_BUMP_ENV, ++ offsetof(struct wined3d_ffp_ps_constants, bumpenv), sizeof(constants), &constants); ++ } ++ + if (changed->ffp_ps_constants) + { + static const struct wined3d_color specular_enabled = {1.0f, 1.0f, 1.0f, 0.0f}; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 3e797b47795..12b13fc065f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2803,6 +2803,15 @@ struct wined3d_ffp_ps_constants + * specular color. */ + struct wined3d_color specular_enable; + struct wined3d_color color_key[2]; ++ struct wined3d_ffp_bumpenv_constants ++ { ++ struct ++ { ++ float _00, _01, _10, _11; ++ } matrices[WINED3D_MAX_FFP_TEXTURES]; ++ float lscale[WINED3D_MAX_FFP_TEXTURES]; ++ float loffset[WINED3D_MAX_FFP_TEXTURES]; ++ } bumpenv; + }; + + enum wined3d_push_constants +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0005-wined3d-Implement-bumpenv-mapping-in-the-HLSL-FFP-pipeline.patch b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0005-wined3d-Implement-bumpenv-mapping-in-the-HLSL-FFP-pipeline.patch new file mode 100644 index 0000000..eabc34b --- /dev/null +++ b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0005-wined3d-Implement-bumpenv-mapping-in-the-HLSL-FFP-pipeline.patch @@ -0,0 +1,55 @@ +From f372faba7f0ea93329119a74df45e24138b20931 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 9 Jun 2024 12:50:30 -0500 +Subject: [PATCH] wined3d: Implement bumpenv mapping in the HLSL FFP pipeline. + +--- + dlls/wined3d/ffp_hlsl.c | 32 +++++++++++++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/ffp_hlsl.c b/dlls/wined3d/ffp_hlsl.c +index d2c8214020f..d8e2c751a4d 100644 +--- a/dlls/wined3d/ffp_hlsl.c ++++ b/dlls/wined3d/ffp_hlsl.c +@@ -796,7 +796,37 @@ static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *setti + && (settings->op[i - 1].cop == WINED3D_TOP_BUMPENVMAP + || settings->op[i - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)) + { +- FIXME("I could not speak, and my eyes failed.\n"); ++ shader_addline(buffer, "ret.xy = mul(transpose((float2x2)c.bumpenv_matrices[%u]), tex%u.xy);\n", i - 1, i - 1); ++ ++ /* With projective textures, texbem only divides the static texture ++ * coordinate, not the displacement, so multiply the displacement ++ * with the dividing parameter before sampling. */ ++ if (settings->op[i].projected != WINED3D_PROJECTION_NONE) ++ { ++ if (settings->op[i].projected == WINED3D_PROJECTION_COUNT4) ++ { ++ shader_addline(buffer, "ret.xy = (ret.xy * texcoord[%u].w) + texcoord[%u].xy;\n", i, i); ++ shader_addline(buffer, "ret.zw = texcoord[%u].ww;\n", i); ++ } ++ else ++ { ++ shader_addline(buffer, "ret.xy = (ret.xy * texcoord[%u].z) + texcoord[%u].xy;\n", i, i); ++ shader_addline(buffer, "ret.zw = texcoord[%u].zz;\n", i); ++ } ++ } ++ else ++ { ++ shader_addline(buffer, "ret = texcoord[%u] + ret.xyxy;\n", i); ++ } ++ ++ shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ret.%s);\n", ++ i, texture_function, proj ? "proj" : "", i, coord_mask); ++ ++ if (settings->op[i - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) ++ { ++ shader_addline(buffer, "tex%u *= saturate(tex%u.z * c.bumpenv_lscale[%u][%u] + c.bumpenv_loffset[%u][%u]);\n", ++ i, i - 1, (i - 1) / 4, (i - 1) % 4, (i - 1) / 4, (i - 1) % 4); ++ } + } + else if (settings->op[i].projected == WINED3D_PROJECTION_COUNT3) + { +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0006-wined3d-Implement-colour-keying-in-the-HLSL-FFP-pipeline.patch b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0006-wined3d-Implement-colour-keying-in-the-HLSL-FFP-pipeline.patch new file mode 100644 index 0000000..cfbca21 --- /dev/null +++ b/0003-pending-mrs-and-backports/6933-wined3d-FFP-HLSL-shaders-part-3-3/0006-wined3d-Implement-colour-keying-in-the-HLSL-FFP-pipeline.patch @@ -0,0 +1,39 @@ +From 33a72b92c737c0936f1e4767d0ab3c01fc250cf1 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 9 Jun 2024 12:50:30 -0500 +Subject: [PATCH] wined3d: Implement colour keying in the HLSL FFP pipeline. + +--- + dlls/wined3d/ffp_hlsl.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/ffp_hlsl.c b/dlls/wined3d/ffp_hlsl.c +index d8e2c751a4d..a0d848a9c8f 100644 +--- a/dlls/wined3d/ffp_hlsl.c ++++ b/dlls/wined3d/ffp_hlsl.c +@@ -619,9 +619,6 @@ static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *setti + uint8_t tex_map = 0; + unsigned int i; + +- if (settings->color_key_enabled) +- FIXME("Ignoring color key.\n"); +- + /* Find out which textures are read. */ + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + { +@@ -840,6 +837,12 @@ static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *setti + } + } + ++ if (settings->color_key_enabled) ++ { ++ shader_addline(buffer, " if (all(tex0 >= c.color_key[0]) && all(tex0 < c.color_key[1]))\n"); ++ shader_addline(buffer, " discard;\n"); ++ } ++ + shader_addline(buffer, " ret = i.diffuse;\n"); + + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6978-win32u-Always-load-the-user-driver-before-entering-display-lock/0001-win32u-Skip-updating-the-cache-on-driver-load-if-we-re-already-updating-it.patch b/0003-pending-mrs-and-backports/6978-win32u-Always-load-the-user-driver-before-entering-display-lock/0001-win32u-Skip-updating-the-cache-on-driver-load-if-we-re-already-updating-it.patch deleted file mode 100644 index 7fa47d3..0000000 --- a/0003-pending-mrs-and-backports/6978-win32u-Always-load-the-user-driver-before-entering-display-lock/0001-win32u-Skip-updating-the-cache-on-driver-load-if-we-re-already-updating-it.patch +++ /dev/null @@ -1,84 +0,0 @@ -From dd354156a70cc6c4ddbdd5afbac056d81b015fb2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Sat, 7 Dec 2024 09:58:41 +0100 -Subject: [PATCH] win32u: Skip updating the cache on driver load if we're - already updating it. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57506 ---- - dlls/win32u/driver.c | 11 ++++++++++- - dlls/win32u/ntgdi_private.h | 1 + - dlls/win32u/sysparams.c | 4 ++-- - 3 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c -index e2ef78f1818..22e48fa6782 100644 ---- a/dlls/win32u/driver.c -+++ b/dlls/win32u/driver.c -@@ -1006,7 +1006,7 @@ static BOOL load_desktop_driver( HWND hwnd ) - * Each entry point simply loads the real driver and chains to it. - */ - --static const struct user_driver_funcs *load_driver(void) -+static void load_display_driver(void) - { - USEROBJECTFLAGS flags; - HWINSTA winstation; -@@ -1020,11 +1020,20 @@ static const struct user_driver_funcs *load_driver(void) - - __wine_set_user_driver( &null_user_driver, WINE_GDI_DRIVER_VERSION ); - } -+} - -+static const struct user_driver_funcs *load_driver(void) -+{ -+ load_display_driver(); - update_display_cache( FALSE ); - return user_driver; - } - -+void init_display_driver(void) -+{ -+ if (user_driver == &lazy_load_driver) load_display_driver(); -+} -+ - /********************************************************************** - * get_display_driver - */ -diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h -index 679eea6538d..ce54a6591a0 100644 ---- a/dlls/win32u/ntgdi_private.h -+++ b/dlls/win32u/ntgdi_private.h -@@ -227,6 +227,7 @@ extern const struct gdi_dc_funcs dib_driver; - extern const struct gdi_dc_funcs path_driver; - extern const struct gdi_dc_funcs font_driver; - extern const struct gdi_dc_funcs *get_display_driver(void); -+extern void init_display_driver(void); - - /* font.c */ - -diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c -index 230c3faa262..2ae72397bc5 100644 ---- a/dlls/win32u/sysparams.c -+++ b/dlls/win32u/sysparams.c -@@ -2243,6 +2243,8 @@ static BOOL lock_display_devices( BOOL force ) - WCHAR name[MAX_PATH]; - BOOL ret = TRUE; - -+ init_display_driver(); /* make sure to load the driver before anything else */ -+ - /* services do not have any adapters, only a virtual monitor */ - if (NtUserGetObjectInformation( winstation, UOI_NAME, name, sizeof(name), NULL ) - && !wcscmp( name, wine_service_station_name )) -@@ -2254,8 +2256,6 @@ static BOOL lock_display_devices( BOOL force ) - return TRUE; - } - -- if (!force) get_display_driver(); /* make sure at least to load the user driver */ -- - pthread_mutex_lock( &display_lock ); - - if (!force && !update_display_cache_from_registry()) force = TRUE; --- -GitLab - diff --git a/0003-pending-mrs-and-backports/6983-wined3d-Add-B4G4R4A4-and-B5G5R5A1-support-in-Vulkan/0001-wined3d-Support-WINED3DFMT-B5G5R5A1-UNORM-in-the-Vulkan-backend.patch b/0003-pending-mrs-and-backports/6983-wined3d-Add-B4G4R4A4-and-B5G5R5A1-support-in-Vulkan/0001-wined3d-Support-WINED3DFMT-B5G5R5A1-UNORM-in-the-Vulkan-backend.patch new file mode 100644 index 0000000..5935e3b --- /dev/null +++ b/0003-pending-mrs-and-backports/6983-wined3d-Add-B4G4R4A4-and-B5G5R5A1-support-in-Vulkan/0001-wined3d-Support-WINED3DFMT-B5G5R5A1-UNORM-in-the-Vulkan-backend.patch @@ -0,0 +1,25 @@ +From dd48dddb9c080f19955ee8c84ddec2fa59ab8d0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 6 Dec 2024 19:14:36 +0300 +Subject: [PATCH] wined3d: Support WINED3DFMT_B5G5R5A1_UNORM in the Vulkan + backend. + +--- + dlls/wined3d/utils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c +index dea43836f06..8256e387b22 100644 +--- a/dlls/wined3d/utils.c ++++ b/dlls/wined3d/utils.c +@@ -4261,6 +4261,7 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, + {WINED3DFMT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, "XYZ1"}, + {WINED3DFMT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, "XYZ1"}, + {WINED3DFMT_B5G6R5_UNORM, VK_FORMAT_R5G6B5_UNORM_PACK16, }, ++ {WINED3DFMT_B5G5R5A1_UNORM, VK_FORMAT_A1R5G5B5_UNORM_PACK16, }, + {WINED3DFMT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, }, + {WINED3DFMT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, }, + {WINED3DFMT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK, }, +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6983-wined3d-Add-B4G4R4A4-and-B5G5R5A1-support-in-Vulkan/0002-wined3d-Use-VK-FORMAT-R4G4B4A4-UNORM-PACK16-for-WINED3DFMT-B4G4R4A4-UNORM.patch b/0003-pending-mrs-and-backports/6983-wined3d-Add-B4G4R4A4-and-B5G5R5A1-support-in-Vulkan/0002-wined3d-Use-VK-FORMAT-R4G4B4A4-UNORM-PACK16-for-WINED3DFMT-B4G4R4A4-UNORM.patch new file mode 100644 index 0000000..df88869 --- /dev/null +++ b/0003-pending-mrs-and-backports/6983-wined3d-Add-B4G4R4A4-and-B5G5R5A1-support-in-Vulkan/0002-wined3d-Use-VK-FORMAT-R4G4B4A4-UNORM-PACK16-for-WINED3DFMT-B4G4R4A4-UNORM.patch @@ -0,0 +1,36 @@ +From 315391acf9075a6addb97cdf2d974cf29070d3c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 6 Dec 2024 19:16:40 +0300 +Subject: [PATCH] wined3d: Use VK_FORMAT_R4G4B4A4_UNORM_PACK16 for + WINED3DFMT_B4G4R4A4_UNORM. + +We can query support for this format without checking for an extension. +VK_EXT_4444_formats introduces VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, +which is a native fit, but we have to introduce extension checks to +vulkan_formats[]. I'll wait until after the release to submit this. + +--- + +Not all Vulkan implementations support 16 bit packed formats. Notably +Metal on Intel/AMD GPUs doesn't expose any of them (but MoltenVK knows +the enums, so we can call vkGetPhysicalDeviceFormatProperties()). We'll +need to do conversion similarly to the GL backend. +--- + dlls/wined3d/utils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c +index 8256e387b22..f4036eed726 100644 +--- a/dlls/wined3d/utils.c ++++ b/dlls/wined3d/utils.c +@@ -4262,6 +4262,7 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, + {WINED3DFMT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, "XYZ1"}, + {WINED3DFMT_B5G6R5_UNORM, VK_FORMAT_R5G6B5_UNORM_PACK16, }, + {WINED3DFMT_B5G5R5A1_UNORM, VK_FORMAT_A1R5G5B5_UNORM_PACK16, }, ++ {WINED3DFMT_B4G4R4A4_UNORM, VK_FORMAT_R4G4B4A4_UNORM_PACK16, "YZWX"}, + {WINED3DFMT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, }, + {WINED3DFMT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, }, + {WINED3DFMT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK, }, +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6984-msvcrt-Don-t-leak-find-handle-or-error-in-findfirst-/0001-msvcrt-Don-t-leak-find-handle-or-error-in-findfirst-.patch b/0003-pending-mrs-and-backports/6984-msvcrt-Don-t-leak-find-handle-or-error-in-findfirst-/0001-msvcrt-Don-t-leak-find-handle-or-error-in-findfirst-.patch deleted file mode 100644 index aea3d62..0000000 --- a/0003-pending-mrs-and-backports/6984-msvcrt-Don-t-leak-find-handle-or-error-in-findfirst-/0001-msvcrt-Don-t-leak-find-handle-or-error-in-findfirst-.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 435ffe8163d793604fc1cff7bd6a34ee29c2ecb7 Mon Sep 17 00:00:00 2001 -From: Piotr Caban -Date: Mon, 9 Dec 2024 11:36:32 +0100 -Subject: [PATCH] msvcrt: Don't leak find handle or error in _findfirst(). - ---- - dlls/msvcrt/dir.c | 18 +++++++++++++++--- - 1 file changed, 15 insertions(+), 3 deletions(-) - -diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c -index 7a36b74ee6b..a047ca47aab 100644 ---- a/dlls/msvcrt/dir.c -+++ b/dlls/msvcrt/dir.c -@@ -391,7 +391,11 @@ intptr_t CDECL _findfirst32(const char *fspec, struct _finddata32_t *ft) - if (fspec && !(fspecW = wstrdupa_utf8(fspec))) return -1; - ret = _wfindfirst32(fspecW, &wft); - free(fspecW); -- if (!finddata32_wtoa(&wft, ft)) return -1; -+ if (ret != -1 && !finddata32_wtoa(&wft, ft)) -+ { -+ _findclose(ret); -+ return -1; -+ } - return ret; - } - -@@ -461,7 +465,11 @@ intptr_t CDECL _findfirst64(const char *fspec, struct _finddata64_t *ft) - if (fspec && !(fspecW = wstrdupa_utf8(fspec))) return -1; - ret = _wfindfirst64(fspecW, &wft); - free(fspecW); -- if (!finddata64_wtoa(&wft, ft)) return -1; -+ if (ret != -1 && !finddata64_wtoa(&wft, ft)) -+ { -+ _findclose(ret); -+ return -1; -+ } - return ret; - } - -@@ -510,7 +518,11 @@ intptr_t CDECL _findfirst64i32(const char *fspec, struct _finddata64i32_t *ft) - if (fspec && !(fspecW = wstrdupa_utf8(fspec))) return -1; - ret = _wfindfirst64i32(fspecW, &wft); - free(fspecW); -- if (!finddata64i32_wtoa(&wft, ft)) return -1; -+ if (ret != -1 && !finddata64i32_wtoa(&wft, ft)) -+ { -+ _findclose(ret); -+ return -1; -+ } - return ret; - } - --- -GitLab - diff --git a/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0001-mf-Propagate-errors-from-session-collect-nodes-to-the-caller-of-session-set-current-topology-.patch b/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0001-mf-Propagate-errors-from-session-collect-nodes-to-the-caller-of-session-set-current-topology-.patch new file mode 100644 index 0000000..9472c69 --- /dev/null +++ b/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0001-mf-Propagate-errors-from-session-collect-nodes-to-the-caller-of-session-set-current-topology-.patch @@ -0,0 +1,27 @@ +From c2c888f9bf74a6848e9d84788801f770bc4b6511 Mon Sep 17 00:00:00 2001 +From: Conor McCarthy +Date: Tue, 10 Dec 2024 00:19:53 +1000 +Subject: [PATCH] mf: Propagate errors from session_collect_nodes() to the + caller of session_set_current_topology(). + +--- + dlls/mf/session.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/dlls/mf/session.c b/dlls/mf/session.c +index cb45fceb714..fa6938ca193 100644 +--- a/dlls/mf/session.c ++++ b/dlls/mf/session.c +@@ -1992,7 +1992,8 @@ static HRESULT session_set_current_topology(struct media_session *session, IMFTo + + session->source_shutdown_handled = FALSE; + +- session_collect_nodes(session); ++ if (FAILED(hr = session_collect_nodes(session))) ++ return hr; + + LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) + { +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0002-mf-Do-not-set-the-topo-status-if-a-source-has-been-shut-down.patch b/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0002-mf-Do-not-set-the-topo-status-if-a-source-has-been-shut-down.patch new file mode 100644 index 0000000..16967ba --- /dev/null +++ b/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0002-mf-Do-not-set-the-topo-status-if-a-source-has-been-shut-down.patch @@ -0,0 +1,30 @@ +From 73ad0a9cb6fb2c0a794ce77a92095159563c73ae Mon Sep 17 00:00:00 2001 +From: Conor McCarthy +Date: Tue, 10 Dec 2024 00:23:16 +1000 +Subject: [PATCH] mf: Do not set the topo status if a source has been shut + down. + +The status must remain MF_TOPOSTATUS_INVALID because the topology is +invalid and must be handled as such in session_start(). + +Fixes a regression introduced by efb369f5755067829df2aafe9b270d59cf5090ac. +--- + dlls/mf/session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/mf/session.c b/dlls/mf/session.c +index fa6938ca193..5b711f7712d 100644 +--- a/dlls/mf/session.c ++++ b/dlls/mf/session.c +@@ -516,7 +516,7 @@ static void session_set_topo_status(struct media_session *session, HRESULT statu + IMFMediaEvent *event; + PROPVARIANT param; + +- if (topo_status == MF_TOPOSTATUS_INVALID) ++ if (topo_status == MF_TOPOSTATUS_INVALID || status == MF_E_SHUTDOWN) + return; + + if (list_empty(&session->topologies)) +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0003-mf-tests-Add-a-test-for-source-shutdown-after-setting-the-topology.patch b/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0003-mf-tests-Add-a-test-for-source-shutdown-after-setting-the-topology.patch new file mode 100644 index 0000000..e9641df --- /dev/null +++ b/0003-pending-mrs-and-backports/6986-mf-Fix-a-regression-in-unexpected-source-shutdown-handling/0003-mf-tests-Add-a-test-for-source-shutdown-after-setting-the-topology.patch @@ -0,0 +1,53 @@ +From a6fe24a55d048272bb00cc809c469cae0cb75a01 Mon Sep 17 00:00:00 2001 +From: Conor McCarthy +Date: Tue, 10 Dec 2024 00:30:14 +1000 +Subject: [PATCH] mf/tests: Add a test for source shutdown after setting the + topology. + +This test would hang if added before the regression fix. +--- + dlls/mf/tests/mf.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c +index 73526802b63..faf82f676db 100644 +--- a/dlls/mf/tests/mf.c ++++ b/dlls/mf/tests/mf.c +@@ -6453,6 +6453,7 @@ static void test_media_session_source_shutdown(void) + HRESULT hr; + enum + { ++ TEST_TOPOLOGY, + TEST_START, + TEST_RESTART, + TEST_PAUSE, +@@ -6465,7 +6466,7 @@ static void test_media_session_source_shutdown(void) + + /* These tests don't cover asynchronous shutdown, which is difficult to consistently test. */ + +- for (shutdown_point = TEST_START; shutdown_point <= TEST_CLOSE; ++shutdown_point) ++ for (shutdown_point = TEST_TOPOLOGY; shutdown_point <= TEST_CLOSE; ++shutdown_point) + { + winetest_push_context("Test %d", shutdown_point); + +@@ -6489,6 +6490,8 @@ static void test_media_session_source_shutdown(void) + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + topology = create_test_topology(source, sink_activate, &duration); ++ if (shutdown_point == TEST_TOPOLOGY) ++ IMFMediaSource_Shutdown(source); + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFTopology_Release(topology); +@@ -6501,7 +6504,7 @@ static void test_media_session_source_shutdown(void) + IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); +- ok(hr == (shutdown_point == TEST_START ? MF_E_INVALIDREQUEST : S_OK), "Unexpected hr %#lx.\n", hr); ++ ok(hr == (shutdown_point <= TEST_START ? MF_E_INVALIDREQUEST : S_OK), "Unexpected hr %#lx.\n", hr); + + switch (shutdown_point) + { +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0001-winex11-Check-HDC-clipping-region-according-to-window-style.patch b/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0001-winex11-Check-HDC-clipping-region-according-to-window-style.patch new file mode 100644 index 0000000..85d7e94 --- /dev/null +++ b/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0001-winex11-Check-HDC-clipping-region-according-to-window-style.patch @@ -0,0 +1,38 @@ +From a97f099b192d4ae49987e9b87808c9ccd5cfefad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Fri, 13 Dec 2024 19:30:20 +0100 +Subject: [PATCH] winex11: Check HDC clipping region according to window style. + +--- + dlls/winex11.drv/init.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c +index ddb8101a2f7..b8184e59bb1 100644 +--- a/dlls/winex11.drv/init.c ++++ b/dlls/winex11.drv/init.c +@@ -198,7 +198,7 @@ static BOOL needs_client_window_clipping( HWND hwnd ) + { + struct x11drv_win_data *data; + RECT rect, client; +- UINT ret = 0; ++ UINT ret = 0, clip_flags = 0, style; + HRGN region; + HDC hdc; + +@@ -207,7 +207,11 @@ static BOOL needs_client_window_clipping( HWND hwnd ) + release_win_data( data ); + OffsetRect( &client, -client.left, -client.top ); + +- if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_CLIPCHILDREN ))) return FALSE; ++ style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); ++ if (style & WS_CLIPCHILDREN) clip_flags |= DCX_CLIPCHILDREN; ++ if (style & WS_CLIPSIBLINGS) clip_flags |= DCX_CLIPSIBLINGS; ++ ++ if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | clip_flags ))) return FALSE; + if ((region = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) + { + ret = NtGdiGetRandomRgn( hdc, region, SYSRGN | NTGDI_RGN_MONITOR_DPI ); +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0002-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION.patch b/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0002-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION.patch new file mode 100644 index 0000000..faabb40 --- /dev/null +++ b/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0002-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION.patch @@ -0,0 +1,33 @@ +From 84cf4a9f54e71da29f7919f1a1549d941ff67e8d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Fri, 13 Dec 2024 19:30:51 +0100 +Subject: [PATCH] winex11: Move GL/VK offscreen if the clipping region is + NULLREGION. + +NULLREGION means that the entire window should be clipped out, and its +children displayed instead. The change broke some offscreening decisions +when both parent and children have a GL drawable created but drawing +actually happens on the child window. + +Fixes: 786d9d1685ac220081b10cc779d4d331ddd2fc52 +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57503 +--- + dlls/winex11.drv/init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c +index b8184e59bb1..274ed51f585 100644 +--- a/dlls/winex11.drv/init.c ++++ b/dlls/winex11.drv/init.c +@@ -215,7 +215,7 @@ static BOOL needs_client_window_clipping( HWND hwnd ) + if ((region = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) + { + ret = NtGdiGetRandomRgn( hdc, region, SYSRGN | NTGDI_RGN_MONITOR_DPI ); +- if (ret > 0 && (ret = NtGdiGetRgnBox( region, &rect )) <= NULLREGION) ret = 0; ++ if (ret > 0 && (ret = NtGdiGetRgnBox( region, &rect )) < NULLREGION) ret = 0; + if (ret == SIMPLEREGION && EqualRect( &rect, &client )) ret = 0; + NtGdiDeleteObjectApp( region ); + } +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/9999-misc-loose/0003-ps5483-server-Correctly-align-64-bit-integer-types.patch b/0003-pending-mrs-and-backports/9999-misc-loose/0003-ps5483-server-Correctly-align-64-bit-integer-types.patch index ee608b7..0cdc87b 100644 --- a/0003-pending-mrs-and-backports/9999-misc-loose/0003-ps5483-server-Correctly-align-64-bit-integer-types.patch +++ b/0003-pending-mrs-and-backports/9999-misc-loose/0003-ps5483-server-Correctly-align-64-bit-integer-types.patch @@ -138,13 +138,14 @@ This allows adding 64-bit fields at unaligned offset in the future, without triggering struct layout mismatch between Unix and PE due to inserted padding (which exists on PE but not on Unix). --- - server/protocol.def | 38 +++++++++++++++++++------------------- + server/protocol.def | 44 ++++++++++++++++++++++---------------------- server/trace.c | 18 +++++++++--------- - tools/make_requests | 4 ---- - 3 files changed, 28 insertions(+), 32 deletions(-) + server/user.h | 2 +- + tools/make_requests | 6 +----- + 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/server/protocol.def b/server/protocol.def -index 55dda2d7636..1fcde5704ce 100644 +index 9f9972f76a3..7ff463691ce 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -39,13 +39,13 @@ typedef unsigned int process_id_t; @@ -168,7 +169,7 @@ index 55dda2d7636..1fcde5704ce 100644 typedef client_ptr_t mod_handle_t; struct request_header -@@ -134,18 +134,18 @@ typedef struct +@@ -143,18 +143,18 @@ struct context_data union { struct { unsigned int eip, ebp, esp, eflags, cs, ss; } i386_regs; @@ -192,7 +193,7 @@ index 55dda2d7636..1fcde5704ce 100644 } integer; /* selected by SERVER_CTX_INTEGER */ union { -@@ -156,16 +156,16 @@ typedef struct +@@ -165,16 +165,16 @@ struct context_data { struct { unsigned int ctrl, status, tag, err_off, err_sel, data_off, data_sel, cr0npx; unsigned char regs[80]; } i386_regs; @@ -214,16 +215,16 @@ index 55dda2d7636..1fcde5704ce 100644 } debug; /* selected by SERVER_CTX_DEBUG_REGISTERS */ union { -@@ -173,7 +173,7 @@ typedef struct - } ext; /* selected by SERVER_CTX_EXTENDED_REGISTERS */ +@@ -186,7 +186,7 @@ struct context_data + } exec_space; /* selected by SERVER_CTX_EXEC_SPACE */ union { - struct { struct { unsigned __int64 low, high; } ymm_high[16]; } regs; + struct { struct { UINT64 low, high; } ymm_high[16]; } regs; } ymm; /* selected by SERVER_CTX_YMM_REGISTERS */ - } context_t; + }; -@@ -201,11 +201,11 @@ struct wake_up_reply +@@ -215,11 +215,11 @@ struct wake_up_reply }; /* NT-style timeout, in 100ns units, negative means relative timeout */ @@ -236,12 +237,30 @@ index 55dda2d7636..1fcde5704ce 100644 +typedef INT64 abstime_t; /* structure for process startup info */ - typedef struct + struct startup_info_data +@@ -979,7 +979,7 @@ typedef volatile struct + unsigned int flags; /* desktop flags */ + struct shared_cursor cursor; /* global cursor information */ + unsigned char keystate[256]; /* asynchronous key state */ +- unsigned __int64 monitor_serial; /* winstation monitor update counter */ ++ UINT64 monitor_serial; /* winstation monitor update counter */ + } desktop_shm_t; + + typedef volatile struct +@@ -2910,7 +2910,7 @@ enum coords_relative + int increment; /* force increment the monitor update counter */ + VARARG(infos,monitor_infos); /* window station monitors */ + @REPLY +- unsigned __int64 serial; /* winstation monitor update counter */ ++ UINT64 serial; /* winstation monitor update counter */ + @END + + diff --git a/server/trace.c b/server/trace.c -index efb4bb03c4a..c88006cbecb 100644 +index 23117b9c313..23e15802594 100644 --- a/server/trace.c +++ b/server/trace.c -@@ -95,7 +95,7 @@ static void dump_abstime( const char *prefix, const abstime_t *when ) +@@ -118,7 +118,7 @@ static void dump_abstime( const char *prefix, const abstime_t *when ) dump_timeout( prefix, &timeout ); } @@ -250,7 +269,7 @@ index efb4bb03c4a..c88006cbecb 100644 { if ((unsigned int)*val != *val) fprintf( stderr, "%s%x%08x", prefix, (unsigned int)(*val >> 32), (unsigned int)*val ); -@@ -103,9 +103,9 @@ static void dump_uint64( const char *prefix, const unsigned __int64 *val ) +@@ -126,9 +126,9 @@ static void dump_uint64( const char *prefix, const unsigned __int64 *val ) fprintf( stderr, "%s%08x", prefix, (unsigned int)*val ); } @@ -262,7 +281,7 @@ index efb4bb03c4a..c88006cbecb 100644 if ((unsigned int)high != high) fprintf( stderr, "%s%x%08x%08x%08x", prefix, (unsigned int)(high >> 32), (unsigned int)high, -@@ -119,7 +119,7 @@ static void dump_uint128( const char *prefix, const unsigned __int64 val[2] ) +@@ -142,7 +142,7 @@ static void dump_uint128( const char *prefix, const unsigned __int64 val[2] ) fprintf( stderr, "%s%x", prefix, (unsigned int)low ); } @@ -271,7 +290,7 @@ index efb4bb03c4a..c88006cbecb 100644 { fprintf( stderr, "%s{", prefix ); if (len-- > 0) dump_uint64( "", ptr++ ); -@@ -503,7 +503,7 @@ static void dump_varargs_uints( const char *prefix, data_size_t size ) +@@ -534,7 +534,7 @@ static void dump_varargs_uints( const char *prefix, data_size_t size ) static void dump_varargs_uints64( const char *prefix, data_size_t size ) { @@ -280,7 +299,7 @@ index efb4bb03c4a..c88006cbecb 100644 dump_uints64( prefix, data, size / sizeof(*data) ); remove_data( size ); -@@ -682,7 +682,7 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) +@@ -732,7 +732,7 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) ctx.fp.i386_regs.data_off, ctx.fp.i386_regs.data_sel, ctx.fp.i386_regs.cr0npx ); for (i = 0; i < 8; i++) { @@ -289,7 +308,7 @@ index efb4bb03c4a..c88006cbecb 100644 memset( reg, 0, sizeof(reg) ); memcpy( reg, &ctx.fp.i386_regs.regs[10 * i], 10 ); fprintf( stderr, ",fp.reg%u=", i ); -@@ -696,7 +696,7 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) +@@ -746,7 +746,7 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) for (i = 0; i < 16; i++) { fprintf( stderr, ",ymm%u=", i ); @@ -298,7 +317,7 @@ index efb4bb03c4a..c88006cbecb 100644 } break; case IMAGE_FILE_MACHINE_AMD64: -@@ -743,13 +743,13 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) +@@ -793,13 +793,13 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) for (i = 0; i < 32; i++) { fprintf( stderr, ",fp%u=", i ); @@ -314,11 +333,33 @@ index efb4bb03c4a..c88006cbecb 100644 } break; case IMAGE_FILE_MACHINE_ARMNT: +diff --git a/server/user.h b/server/user.h +index dbd634de003..9c2b5c55385 100644 +--- a/server/user.h ++++ b/server/user.h +@@ -57,7 +57,7 @@ struct winstation + struct namespace *desktop_names; /* namespace for desktops of this winstation */ + unsigned int monitor_count; /* number of monitors */ + struct monitor_info *monitors; /* window station monitors */ +- unsigned __int64 monitor_serial; /* winstation monitor update counter */ ++ UINT64 monitor_serial; /* winstation monitor update counter */ + }; + + struct key_repeat diff --git a/tools/make_requests b/tools/make_requests -index 6148f072919..ea3a4978305 100755 +index 4b6c3596aad..020f67601ab 100755 --- a/tools/make_requests +++ b/tools/make_requests -@@ -501,10 +501,6 @@ foreach my $type (sort keys %formats) +@@ -34,7 +34,7 @@ my %formats = + "atom_t" => [ 4, 4, "%04x" ], + "process_id_t" => [ 4, 4, "%04x" ], + "thread_id_t" => [ 4, 4, "%04x" ], +- "unsigned __int64" => [ 8, 8, "&uint64" ], ++ "UINT64" => [ 8, 8, "&uint64" ], + "timeout_t" => [ 8, 8 ], + "abstime_t" => [ 8, 8 ], + "ioctl_code_t" => [ 4, 4 ], +@@ -498,10 +498,6 @@ foreach my $type (sort keys %formats) my ($size, $align) = @{$formats{$type}}; die "$type: invalid size $size for alignment $align" if $size % $align; push @request_lines, "C_ASSERT( sizeof($type) == $size );\n"; @@ -328,21 +369,6 @@ index 6148f072919..ea3a4978305 100755 - } push @request_lines, "C_ASSERT( TYPE_ALIGNMENT($type) == $align );\n"; } - push @request_lines, @asserts; + -- GitLab - -fixup for 75e2ec479beff86c52bebdab6d5e8b78c8f6ca8d -diff --git a/tools/make_requests b/tools/make_requests -index 11111111111..11111111111 100755 ---- a/tools/make_requests -+++ b/tools/make_requests -@@ -34,7 +34,7 @@ my %formats = - "atom_t" => [ 4, 4, "%04x" ], - "process_id_t" => [ 4, 4, "%04x" ], - "thread_id_t" => [ 4, 4, "%04x" ], -- "unsigned __int64" => [ 8, 8, "&uint64" ], -+ "UINT64" => [ 8, 8, "&uint64" ], - "timeout_t" => [ 8, 8 ], - "abstime_t" => [ 8, 8 ], - "rectangle_t" => [ 16, 4 ], diff --git a/0004-build-fix-undebug-optimize/5700-include-Allow-YieldProcessor-on-Clang-MSVC-mode.patch b/0004-build-fix-undebug-optimize/5700-include-Allow-YieldProcessor-on-Clang-MSVC-mode.patch deleted file mode 100644 index f488c28..0000000 --- a/0004-build-fix-undebug-optimize/5700-include-Allow-YieldProcessor-on-Clang-MSVC-mode.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 829b3ddcb329400add3cc8304876d39721d79c67 Mon Sep 17 00:00:00 2001 -From: William Horvath -Date: Thu, 5 Dec 2024 18:30:00 -0800 -Subject: [PATCH] include: Allow YieldProcessor() on Clang MSVC mode. - ---- - include/winnt.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/winnt.h b/include/winnt.h -index 883ca26d409..d2ca7967be5 100644 ---- a/include/winnt.h -+++ b/include/winnt.h -@@ -7478,7 +7478,7 @@ static FORCEINLINE unsigned char InterlockedCompareExchange128( volatile __int64 - - static FORCEINLINE void YieldProcessor(void) - { --#ifdef __GNUC__ -+#if defined(__GNUC__) || defined(__clang__) - #if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__( "rep; nop" : : : "memory" ); - #elif defined(__arm__) || defined(__aarch64__) --- -2.47.1 - diff --git a/0004-build-fix-undebug-optimize/8000-msvcrt-Use-builtin-math-functions.patch b/0004-build-fix-undebug-optimize/8000-msvcrt-Use-builtin-math-functions.patch new file mode 100644 index 0000000..5dc1f36 --- /dev/null +++ b/0004-build-fix-undebug-optimize/8000-msvcrt-Use-builtin-math-functions.patch @@ -0,0 +1,103 @@ +From 3d448bd6d697734492ed6e34eabde82355a691a9 Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Tue, 10 Dec 2024 12:17:46 -0800 +Subject: [PATCH] msvcrt: Use builtin math functions. + +--- + include/msvcrt/math.h | 46 ++++++++++++++++--------------------------- + 1 file changed, 17 insertions(+), 29 deletions(-) + +diff --git a/include/msvcrt/math.h b/include/msvcrt/math.h +index 4f9840b3a02..0eb068d59fe 100644 +--- a/include/msvcrt/math.h ++++ b/include/msvcrt/math.h +@@ -280,6 +280,15 @@ static const union { + #define FP_SUBNORMAL -2 + #define FP_ZERO 0 + ++#define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \ ++ FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x) ++#define signbit(x) __builtin_signbit(x) ++#define isinf(x) __builtin_isinf(x) ++#define isnan(x) __builtin_isnan(x) ++#define isnormal(x) __builtin_isnormal(x) ++#define signbit(x) __builtin_signbit(x) ++#define isfinite(x) __builtin_isfinite(x) ++ + #define _C2 1 + #define FP_ILOGB0 (-0x7fffffff - _C2) + #define FP_ILOGBNAN 0x7fffffff +@@ -306,62 +315,41 @@ _ACRTIMP short __cdecl _fdclass(float); + _ACRTIMP int __cdecl _dsign(double); + _ACRTIMP int __cdecl _fdsign(float); + +-#define fpclassify(x) (sizeof(x) == sizeof(float) ? _fdclass(x) : _dclass(x)) +-#define signbit(x) (sizeof(x) == sizeof(float) ? _fdsign(x) : _dsign(x)) +-#define isinf(x) (fpclassify(x) == FP_INFINITE) +-#define isnan(x) (fpclassify(x) == FP_NAN) +-#define isnormal(x) (fpclassify(x) == FP_NORMAL) +-#define isfinite(x) (fpclassify(x) <= 0) +- + #else + + static inline int __isnanf(float x) + { +- union { float x; unsigned int i; } u = { x }; +- return (u.i & 0x7fffffff) > 0x7f800000; ++ return isnan(x); + } + static inline int __isnan(double x) + { +- union { double x; unsigned __int64 i; } u = { x }; +- return (u.i & ~0ull >> 1) > 0x7ffull << 52; ++ return isnan(x); + } + static inline int __isinff(float x) + { +- union { float x; unsigned int i; } u = { x }; +- return (u.i & 0x7fffffff) == 0x7f800000; ++ return isinf(x); + } + static inline int __isinf(double x) + { +- union { double x; unsigned __int64 i; } u = { x }; +- return (u.i & ~0ull >> 1) == 0x7ffull << 52; ++ return isinf(x); + } + static inline int __isnormalf(float x) + { +- union { float x; unsigned int i; } u = { x }; +- return ((u.i + 0x00800000) & 0x7fffffff) >= 0x01000000; ++ return isnormal(x); + } + static inline int __isnormal(double x) + { +- union { double x; unsigned __int64 i; } u = { x }; +- return ((u.i + (1ull << 52)) & ~0ull >> 1) >= 1ull << 53; ++ return isnormal(x); + } + static inline int __signbitf(float x) + { +- union { float x; unsigned int i; } u = { x }; +- return (int)(u.i >> 31); ++ return signbit(x); + } + static inline int __signbit(double x) + { +- union { double x; unsigned __int64 i; } u = { x }; +- return (int)(u.i >> 63); ++ return signbit(x); + } + +-#define isinf(x) (sizeof(x) == sizeof(float) ? __isinff(x) : __isinf(x)) +-#define isnan(x) (sizeof(x) == sizeof(float) ? __isnanf(x) : __isnan(x)) +-#define isnormal(x) (sizeof(x) == sizeof(float) ? __isnormalf(x) : __isnormal(x)) +-#define signbit(x) (sizeof(x) == sizeof(float) ? __signbitf(x) : __signbit(x)) +-#define isfinite(x) (!isinf(x) && !isnan(x)) +- + #endif + + #ifdef _UCRT +-- +2.47.1 + diff --git a/0007-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch b/0007-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch new file mode 100644 index 0000000..27b9c15 --- /dev/null +++ b/0007-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch @@ -0,0 +1,56 @@ +From 6b5fee6b3749d71a0249137819eee6aedfd116d6 Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Tue, 10 Dec 2024 01:31:27 -0800 +Subject: [PATCH] esync, fsync: Prevent div-by-zero pagesize in + init->create->get_shm + +--- + dlls/ntdll/unix/esync.c | 3 +-- + dlls/ntdll/unix/fsync.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c +index 3074f7c72ea..4ae04aca2fd 100644 +--- a/dlls/ntdll/unix/esync.c ++++ b/dlls/ntdll/unix/esync.c +@@ -1312,6 +1312,7 @@ NTSTATUS esync_signal_and_wait( HANDLE signal, HANDLE wait, BOOLEAN alertable, + void esync_init(void) + { + struct stat st; ++ pagesize = sysconf( _SC_PAGESIZE ); + + if (!do_esync()) + { +@@ -1347,8 +1348,6 @@ void esync_init(void) + exit(1); + } + +- pagesize = sysconf( _SC_PAGESIZE ); +- + shm_addrs = calloc( 128, sizeof(shm_addrs[0]) ); + shm_addrs_size = 128; + } +diff --git a/dlls/ntdll/unix/fsync.c b/dlls/ntdll/unix/fsync.c +index a51c919163a..9831fa4e8ee 100644 +--- a/dlls/ntdll/unix/fsync.c ++++ b/dlls/ntdll/unix/fsync.c +@@ -451,6 +451,7 @@ static NTSTATUS open_fsync( enum fsync_type type, HANDLE *handle, + void fsync_init(void) + { + struct stat st; ++ pagesize = sysconf( _SC_PAGESIZE ); + + if (!do_fsync()) + { +@@ -486,8 +487,6 @@ void fsync_init(void) + exit(1); + } + +- pagesize = sysconf( _SC_PAGESIZE ); +- + shm_addrs = calloc( 128, sizeof(shm_addrs[0]) ); + shm_addrs_size = 128; + } +-- +2.47.1 + diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0021-winex11-Improved-osu-childwindow-hack.patch b/0009-windowing-system-integration/0001-misc-osu-related/0021-winex11-Improved-osu-childwindow-hack.patch deleted file mode 100644 index fbf7597..0000000 --- a/0009-windowing-system-integration/0001-misc-osu-related/0021-winex11-Improved-osu-childwindow-hack.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 4a56dd38de058abe98c9e76c50c90031745394f6 Mon Sep 17 00:00:00 2001 -From: William Horvath -Date: Wed, 6 Nov 2024 13:51:46 -0800 -Subject: [PATCH] winex11: Improved osu! childwindow hack. - -'WindowsForms10.Window.808.app.0.360e033_r26_ad1' is the name of the editor -window class, so just look around to see if it's visible to determine whether -or not we really need to render offscreen. If not, we can maintain -the composition-free page-flipping rendering path instead of blitting. ---- - dlls/ntdll/unix/loader.c | 9 +++++ - dlls/winex11.drv/init.c | 69 +++++++++++++++++++++++++++++++++++++-- - dlls/winex11.drv/x11drv.h | 12 +++++++ - 3 files changed, 87 insertions(+), 3 deletions(-) - -diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c -index 6e432a943cc..190d3332c7f 100644 ---- a/dlls/ntdll/unix/loader.c -+++ b/dlls/ntdll/unix/loader.c -@@ -1869,6 +1869,15 @@ static void hacks_init(void) - ERR( "HACK: ram_reporting_bias %lldMB.\n", ram_reporting_bias / (1024 * 1024) ); - } - -+ if (main_argc > 1 && (strstr(main_argv[1], "osu!.exe"))) -+ { -+ env_str = getenv("WINE_DISABLE_GLCHILD_HACK"); -+ if (!(env_str && *env_str != '\0' && *env_str != '0')) -+ { -+ setenv( "OSU_HACKS_ENABLED", "1", 0 ); -+ } -+ } -+ - env_str = getenv("WINE_SIMULATE_ASYNC_READ"); - if (env_str) - ac_odyssey = !!atoi(env_str); -diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c -index 0f5b91d469e..0eb24f7dbc0 100644 ---- a/dlls/winex11.drv/init.c -+++ b/dlls/winex11.drv/init.c -@@ -194,12 +194,75 @@ static HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags ) - return dev->funcs->pSelectFont( dev, hfont, aa_flags ); - } - -+enum osu_window_type -+{ -+ GAME, -+ EDITOR -+}; -+ -+static BOOL class_matches( HWND hwnd, enum osu_window_type type ) -+{ -+ static const WCHAR editor_class[] = {'W','i','n','d','o','w','s','F','o','r','m','s','1','0','.','W','i','n','d','o','w','.','8','0','8','.','a','p','p','.', 0}; -+ static const WCHAR game_class[] = {'W','i','n','d','o','w','s','F','o','r','m','s','1','0','.','W','i','n','d','o','w','.','2','b','.','a','p','p','.', 0}; -+ -+ WCHAR buffer[256]; -+ UNICODE_STRING name = { .Buffer = buffer, .MaximumLength = sizeof(buffer) }; -+ -+ INT length = NtUserGetClassName( hwnd, FALSE, &name ); -+ -+ if (length > 0) -+ { -+ if (type == EDITOR) -+ return wcsncmp( buffer, editor_class, wcslen(editor_class) - 1 ) == 0; -+ else /* GAME */ -+ return wcsncmp( buffer, game_class, wcslen(game_class) - 1 ) == 0; -+ } -+ return FALSE; -+} -+ -+static BOOL window_visible( HWND current, enum osu_window_type type ) -+{ -+ while (current) -+ { -+ if (class_matches( current, type )) -+ return TRUE; -+ -+ HWND child = NtUserGetWindowRelative( current, GW_CHILD ); -+ if (child) -+ { -+ if (window_visible( child, type )) -+ return TRUE; -+ } -+ current = NtUserGetWindowRelative( current, GW_HWNDNEXT ); -+ } -+ return FALSE; -+} -+ -+static BOOL osu_rendering_bypass( HWND hwnd ) -+{ -+ if (!use_osu_child_hack()) -+ return FALSE; -+ -+ if (//!window_visible( NtUserGetDesktopWindow(), GAME ) || -+ NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED /* translucent windows don't like to be rendered onscreen */ -+ || window_visible( NtUserGetDesktopWindow(), EDITOR )) -+ { -+ TRACE("osu! onscreen bypass disabled or not needed for %p\n", hwnd); -+ return FALSE; -+ } -+ TRACE("osu! onscreen bypass enabled for %p\n", hwnd); -+ return TRUE; -+} -+ - BOOL needs_offscreen_rendering( HWND hwnd, BOOL known_child ) - { - if (NtUserGetDpiForWindow( hwnd ) != NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI )) return TRUE; /* needs DPI scaling */ -- if (NtUserGetAncestor( hwnd, GA_PARENT ) != NtUserGetDesktopWindow()) return TRUE; /* child window, needs compositing */ -- if (NtUserGetWindowRelative( hwnd, GW_CHILD )) return TRUE; /* window has children, needs compositing */ -- if (known_child) return TRUE; /* window is/have children, needs compositing */ -+ if (!osu_rendering_bypass( hwnd )) -+ { -+ if (NtUserGetAncestor( hwnd, GA_PARENT ) != NtUserGetDesktopWindow()) return TRUE; /* child window, needs compositing */ -+ if (NtUserGetWindowRelative( hwnd, GW_CHILD )) return TRUE; /* window has children, needs compositing */ -+ if (known_child) return TRUE; /* window is/have children, needs compositing */ -+ } - return FALSE; - } - -diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h -index c54a33c43a7..637afaa5e3b 100644 ---- a/dlls/winex11.drv/x11drv.h -+++ b/dlls/winex11.drv/x11drv.h -@@ -962,6 +962,18 @@ static inline BOOL disable_glXWaitForSbcOML(void) - } - /* registry helpers */ - -+static inline BOOL use_osu_child_hack(void) -+{ -+ static int cache = -1; -+ if (cache == -1) -+ { -+ const char *e = getenv("OSU_HACKS_ENABLED"); -+ if (e && !!atoi(e)) cache = 1; -+ else cache = 0; -+ } -+ return !!cache; -+} -+ - extern HKEY open_hkcu_key( const char *name ); - extern ULONG query_reg_value( HKEY hkey, const WCHAR *name, - KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ); --- -2.47.0 - diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0000-proton-detect-WM-plus-kwin-fix.patch b/0009-windowing-system-integration/0001-misc/0000-proton-detect-WM-plus-kwin-fix.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0000-proton-detect-WM-plus-kwin-fix.patch rename to 0009-windowing-system-integration/0001-misc/0000-proton-detect-WM-plus-kwin-fix.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0001-proton-focusin-focusout-workarounds.patch b/0009-windowing-system-integration/0001-misc/0001-proton-focusin-focusout-workarounds.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0001-proton-focusin-focusout-workarounds.patch rename to 0009-windowing-system-integration/0001-misc/0001-proton-focusin-focusout-workarounds.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0002-HACK-Fix-osu-alt-tab-with-WM-detection.patch b/0009-windowing-system-integration/0001-misc/0002-HACK-Fix-osu-alt-tab-with-WM-detection.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0002-HACK-Fix-osu-alt-tab-with-WM-detection.patch rename to 0009-windowing-system-integration/0001-misc/0002-HACK-Fix-osu-alt-tab-with-WM-detection.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0003-winex11-Xshape-GNOME-workaround.patch b/0009-windowing-system-integration/0001-misc/0003-winex11-Xshape-GNOME-workaround.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0003-winex11-Xshape-GNOME-workaround.patch rename to 0009-windowing-system-integration/0001-misc/0003-winex11-Xshape-GNOME-workaround.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0008-ps0115-winex11.drv-optimize-repeated-ClipCursor-calls.patch b/0009-windowing-system-integration/0001-misc/0008-ps0115-winex11.drv-optimize-repeated-ClipCursor-calls.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0008-ps0115-winex11.drv-optimize-repeated-ClipCursor-calls.patch rename to 0009-windowing-system-integration/0001-misc/0008-ps0115-winex11.drv-optimize-repeated-ClipCursor-calls.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0013-winex11-Don-t-unmap-the-clip-window-more-than-once.patch b/0009-windowing-system-integration/0001-misc/0013-winex11-Don-t-unmap-the-clip-window-more-than-once.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0013-winex11-Don-t-unmap-the-clip-window-more-than-once.patch rename to 0009-windowing-system-integration/0001-misc/0013-winex11-Don-t-unmap-the-clip-window-more-than-once.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0015-winewayland-Round-display-refresh-rate.patch b/0009-windowing-system-integration/0001-misc/0015-winewayland-Round-display-refresh-rate.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0015-winewayland-Round-display-refresh-rate.patch rename to 0009-windowing-system-integration/0001-misc/0015-winewayland-Round-display-refresh-rate.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0018-winex11-child-window-styles.patch b/0009-windowing-system-integration/0001-misc/0018-winex11-child-window-styles.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0018-winex11-child-window-styles.patch rename to 0009-windowing-system-integration/0001-misc/0018-winex11-child-window-styles.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0019-winex11-Force-disable-glXWaitForSbcOML-AMD-on-Waylan.patch b/0009-windowing-system-integration/0001-misc/0019-winex11-Force-disable-glXWaitForSbcOML-AMD-on-Waylan.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0019-winex11-Force-disable-glXWaitForSbcOML-AMD-on-Waylan.patch rename to 0009-windowing-system-integration/0001-misc/0019-winex11-Force-disable-glXWaitForSbcOML-AMD-on-Waylan.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0020-comctl32-listview-Skip-scrolling-to-the-start-of-the.patch b/0009-windowing-system-integration/0001-misc/0020-comctl32-listview-Skip-scrolling-to-the-start-of-the.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0020-comctl32-listview-Skip-scrolling-to-the-start-of-the.patch rename to 0009-windowing-system-integration/0001-misc/0020-comctl32-listview-Skip-scrolling-to-the-start-of-the.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0022-winex11-Disable-update_user_time-if-the-WM-doesn-t-s.patch b/0009-windowing-system-integration/0001-misc/0022-winex11-Disable-update_user_time-if-the-WM-doesn-t-s.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0022-winex11-Disable-update_user_time-if-the-WM-doesn-t-s.patch rename to 0009-windowing-system-integration/0001-misc/0022-winex11-Disable-update_user_time-if-the-WM-doesn-t-s.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0023-win32u-Adjust-inexplicable-off-by-one-height-in-osu-.patch b/0009-windowing-system-integration/0001-misc/0023-win32u-Adjust-inexplicable-off-by-one-height-in-osu-.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0023-win32u-Adjust-inexplicable-off-by-one-height-in-osu-.patch rename to 0009-windowing-system-integration/0001-misc/0023-win32u-Adjust-inexplicable-off-by-one-height-in-osu-.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0024-winewayland-Stop-trying-to-ensure-contents-repeatedl.patch b/0009-windowing-system-integration/0001-misc/0024-winewayland-Stop-trying-to-ensure-contents-repeatedl.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0024-winewayland-Stop-trying-to-ensure-contents-repeatedl.patch rename to 0009-windowing-system-integration/0001-misc/0024-winewayland-Stop-trying-to-ensure-contents-repeatedl.patch diff --git a/0009-windowing-system-integration/0001-misc-osu-related/0030-winex11.drv-Do-not-enable-disable-XInput2-when-clipp.patch b/0009-windowing-system-integration/0001-misc/0030-winex11.drv-Do-not-enable-disable-XInput2-when-clipp.patch similarity index 100% rename from 0009-windowing-system-integration/0001-misc-osu-related/0030-winex11.drv-Do-not-enable-disable-XInput2-when-clipp.patch rename to 0009-windowing-system-integration/0001-misc/0030-winex11.drv-Do-not-enable-disable-XInput2-when-clipp.patch diff --git a/0009-windowing-system-integration/0001-misc/0040-winecfg-Add-a-checkbox-to-enable-virtual-desktop-taskbar.patch b/0009-windowing-system-integration/0001-misc/0040-winecfg-Add-a-checkbox-to-enable-virtual-desktop-taskbar.patch new file mode 100644 index 0000000..97c91ea --- /dev/null +++ b/0009-windowing-system-integration/0001-misc/0040-winecfg-Add-a-checkbox-to-enable-virtual-desktop-taskbar.patch @@ -0,0 +1,179 @@ +From 2f1de1c78dcb32cde3d7673a9345cc616ec72e09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Tue, 10 Dec 2024 22:12:41 +0100 +Subject: [PATCH] winecfg: Add a checkbox to enable virtual desktop taskbar. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57515 +--- + programs/winecfg/libraries.c | 2 +- + programs/winecfg/resource.h | 1 + + programs/winecfg/winecfg.c | 30 ++++++++++++++++++++++++++++++ + programs/winecfg/winecfg.h | 5 +++-- + programs/winecfg/winecfg.rc | 4 +++- + programs/winecfg/x11drvdlg.c | 14 +++++++++++++- + 6 files changed, 51 insertions(+), 5 deletions(-) + +diff --git a/programs/winecfg/libraries.c b/programs/winecfg/libraries.c +index 09fd397ab63..8980b1691df 100644 +--- a/programs/winecfg/libraries.c ++++ b/programs/winecfg/libraries.c +@@ -439,7 +439,7 @@ static void on_add_combo_change(HWND dialog) + + if (buffer[0] || len>0) + { +- enable(IDC_DLLS_ADDDLL) ++ enable(IDC_DLLS_ADDDLL); + SendMessageW(GetParent(dialog), DM_SETDEFID, IDC_DLLS_ADDDLL, 0); + } + else +diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h +index cd7eaaf711e..a35775931d4 100644 +--- a/programs/winecfg/resource.h ++++ b/programs/winecfg/resource.h +@@ -105,6 +105,7 @@ + #define IDS_DRIVE_NO_C 1075 + #define IDC_BUTTON_SHOW_HIDE_ADVANCED 1076 + #define IDC_STATIC_TYPE 1077 ++#define IDC_ENABLE_SHELL 1078 + #define IDC_SHOW_DOT_FILES 1080 + + #define IDS_DRIVE_UNKNOWN 8200 +diff --git a/programs/winecfg/winecfg.c b/programs/winecfg/winecfg.c +index 17104fa7dbd..a8b7016f7fd 100644 +--- a/programs/winecfg/winecfg.c ++++ b/programs/winecfg/winecfg.c +@@ -236,6 +236,36 @@ static void free_setting(struct setting *setting) + free(setting); + } + ++DWORD get_reg_key_dword(HKEY root, const WCHAR *path, const WCHAR *name, DWORD def) ++{ ++ struct list *cursor; ++ struct setting *s; ++ DWORD val, size = sizeof(val); ++ ++ WINE_TRACE("path=%s, name=%s, def=%lu\n", wine_dbgstr_w(path), ++ wine_dbgstr_w(name), def); ++ ++ LIST_FOR_EACH( cursor, &settings ) ++ { ++ s = LIST_ENTRY(cursor, struct setting, entry); ++ ++ if (root != s->root) continue; ++ if (lstrcmpiW(path, s->path) != 0) continue; ++ if (!s->name) continue; ++ if (lstrcmpiW(name, s->name) != 0) continue; ++ ++ WINE_TRACE("found %s:%s in settings list, returning %s\n", ++ wine_dbgstr_w(path), wine_dbgstr_w(name), ++ wine_dbgstr_w(s->value)); ++ return *(DWORD *)s->value; ++ } ++ ++ if (RegGetValueW( root, path, name, RRF_RT_REG_DWORD, NULL, &val, &size )) ++ val = def; ++ WINE_TRACE("returning %lu\n", val); ++ return val; ++} ++ + /** + * Returns the contents of the value at path. If not in the settings + * list, it will be fetched from the registry - failing that, the +diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h +index f3f3ad2addf..236438d0753 100644 +--- a/programs/winecfg/winecfg.h ++++ b/programs/winecfg/winecfg.h +@@ -54,6 +54,7 @@ extern WCHAR* current_app; /* NULL means editing global settings */ + + void set_reg_key(HKEY root, const WCHAR *path, const WCHAR *name, const WCHAR *value); + void set_reg_key_dword(HKEY root, const WCHAR *path, const WCHAR *name, DWORD value); ++DWORD get_reg_key_dword(HKEY root, const WCHAR *path, const WCHAR *name, DWORD def); + WCHAR *get_reg_key(HKEY root, const WCHAR *path, const WCHAR *name, const WCHAR *def) + __WINE_DEALLOC(free) __WINE_MALLOC; + +@@ -121,8 +122,8 @@ BOOL browse_for_unix_folder(HWND dialog, WCHAR *pszPath); + extern struct drive drives[26]; /* one for each drive letter */ + + /* Some basic utilities to make win32 suck less */ +-#define disable(id) EnableWindow(GetDlgItem(dialog, id), 0); +-#define enable(id) EnableWindow(GetDlgItem(dialog, id), 1); ++#define disable(id) EnableWindow(GetDlgItem(dialog, id), 0) ++#define enable(id) EnableWindow(GetDlgItem(dialog, id), 1) + void PRINTERROR(void); /* WINE_TRACE() the plaintext error message from GetLastError() */ + + /* create a unicode string from a string in Unix locale */ +diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc +index 779a2f900e3..e642c71ed61 100644 +--- a/programs/winecfg/winecfg.rc ++++ b/programs/winecfg/winecfg.rc +@@ -175,7 +175,9 @@ BEGIN + CONTROL "Allow the window manager to &decorate the windows",IDC_ENABLE_DECORATED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,20,230,10 + CONTROL "Allow the &window manager to control the windows",IDC_ENABLE_MANAGED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,32,230,10 + CONTROL "&Emulate a virtual desktop",IDC_ENABLE_DESKTOP,"Button", +- BS_AUTOCHECKBOX | WS_TABSTOP,15,44,230,10 ++ BS_AUTOCHECKBOX | WS_TABSTOP,15,44,100,10 ++ CONTROL "&with a taskbar",IDC_ENABLE_SHELL,"Button", ++ BS_AUTOCHECKBOX | WS_TABSTOP,120,44,100,10,WS_DISABLED + LTEXT "Desktop &size:",IDC_DESKTOP_SIZE,15,58,64,16,WS_DISABLED + LTEXT "#msgctxt#do not translate#X",IDC_DESKTOP_BY,129,58,8,8,WS_DISABLED + EDITTEXT IDC_DESKTOP_WIDTH,84,56,40,12,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED +diff --git a/programs/winecfg/x11drvdlg.c b/programs/winecfg/x11drvdlg.c +index aea52717a78..f184bff9030 100644 +--- a/programs/winecfg/x11drvdlg.c ++++ b/programs/winecfg/x11drvdlg.c +@@ -61,10 +61,12 @@ static void update_gui_for_desktop_mode(HWND dialog) + { + WCHAR *buf, *bufindex; + const WCHAR *desktop_name = current_app ? current_app : L"Default"; ++ WCHAR buffer[MAX_PATH]; + + WINE_TRACE("\n"); + updating_ui = TRUE; + ++ swprintf( buffer, ARRAY_SIZE(buffer), L"Explorer\\Desktops\\%s", desktop_name ); + buf = get_reg_key(config_key, L"Explorer\\Desktops", desktop_name, NULL); + if (buf && (bufindex = wcschr(buf, 'x'))) + { +@@ -81,7 +83,11 @@ static void update_gui_for_desktop_mode(HWND dialog) + /* do we have desktop mode enabled? */ + if (reg_key_exists(config_key, keypath(L"Explorer"), L"Desktop")) + { +- CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED); ++ BOOL enable_shell = get_reg_key_dword(config_key, buffer, L"EnableShell", 0); ++ CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED); ++ CheckDlgButton(dialog, IDC_ENABLE_SHELL, enable_shell ? BST_CHECKED : BST_UNCHECKED); ++ if (enable_shell) enable(IDC_ENABLE_SHELL); ++ else enable(IDC_ENABLE_SHELL); + enable(IDC_DESKTOP_WIDTH); + enable(IDC_DESKTOP_HEIGHT); + enable(IDC_DESKTOP_SIZE); +@@ -90,6 +96,8 @@ static void update_gui_for_desktop_mode(HWND dialog) + else + { + CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_UNCHECKED); ++ CheckDlgButton(dialog, IDC_ENABLE_SHELL, BST_UNCHECKED); ++ disable(IDC_ENABLE_SHELL); + disable(IDC_DESKTOP_WIDTH); + disable(IDC_DESKTOP_HEIGHT); + disable(IDC_DESKTOP_SIZE); +@@ -183,6 +191,9 @@ static void set_from_desktop_edits(HWND dialog) + set_reg_key(config_key, L"Explorer\\Desktops", desktop_name, buffer); + set_reg_key(config_key, keypath(L"Explorer"), L"Desktop", desktop_name); + ++ swprintf( buffer, ARRAY_SIZE(buffer), L"Explorer\\Desktops\\%s", desktop_name ); ++ set_reg_key_dword(config_key, buffer, L"EnableShell", IsDlgButtonChecked(dialog, IDC_ENABLE_SHELL) == BST_CHECKED); ++ + free(width); + free(height); + } +@@ -380,6 +391,7 @@ GraphDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) + SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0); + switch(LOWORD(wParam)) { + case IDC_ENABLE_DESKTOP: on_enable_desktop_clicked(hDlg); break; ++ case IDC_ENABLE_SHELL: on_enable_desktop_clicked(hDlg); break; + case IDC_ENABLE_MANAGED: on_enable_managed_clicked(hDlg); break; + case IDC_ENABLE_DECORATED: on_enable_decorated_clicked(hDlg); break; + case IDC_FULLSCREEN_GRAB: on_fullscreen_grab_clicked(hDlg); break; +-- +GitLab + diff --git a/0009-windowing-system-integration/0003-rendering/0004-ps5145-opengl32-speed-up-wow64-mapping.patch b/0009-windowing-system-integration/0001-misc/0050-ps5145-opengl32-speed-up-wow64-mapping.patch similarity index 100% rename from 0009-windowing-system-integration/0003-rendering/0004-ps5145-opengl32-speed-up-wow64-mapping.patch rename to 0009-windowing-system-integration/0001-misc/0050-ps5145-opengl32-speed-up-wow64-mapping.patch diff --git a/0009-windowing-system-integration/0003-rendering/0050-user32-Send-WM_NCPAINT-as-notify-message-in-send_ncp.patch b/0009-windowing-system-integration/0003-rendering/0050-user32-Send-WM_NCPAINT-as-notify-message-in-send_ncp.patch deleted file mode 100644 index d223a9e..0000000 --- a/0009-windowing-system-integration/0003-rendering/0050-user32-Send-WM_NCPAINT-as-notify-message-in-send_ncp.patch +++ /dev/null @@ -1,27 +0,0 @@ -From edb36b7614415ba1f3039e71fafca82284c533f7 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Wed, 13 Jul 2022 19:56:49 -0500 -Subject: [PATCH 0855/1793] user32: Send WM_NCPAINT as notify message in - send_ncpaint(). - -CW-Bug-Id: #20969 ---- - dlls/win32u/dce.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c -index f70a2a32be9..649b82cdb6b 100644 ---- a/dlls/win32u/dce.c -+++ b/dlls/win32u/dce.c -@@ -1208,7 +1208,7 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags ) - if (style & WS_VSCROLL) - set_standard_scroll_painted( hwnd, SB_VERT, FALSE ); - -- send_message( hwnd, WM_NCPAINT, (WPARAM)whole_rgn, 0 ); -+ send_notify_message( hwnd, WM_NCPAINT, (WPARAM)whole_rgn, 0, FALSE ); - } - if (whole_rgn > (HRGN)1) NtGdiDeleteObjectApp( whole_rgn ); - } --- -2.46.0 - diff --git a/0009-windowing-system-integration/0003-rendering/0205-user32-Allow-using-surface-to-paint-the-client-area-.patch b/0009-windowing-system-integration/0003-rendering/0205-user32-Allow-using-surface-to-paint-the-client-area-.patch deleted file mode 100644 index 8a2d791..0000000 --- a/0009-windowing-system-integration/0003-rendering/0205-user32-Allow-using-surface-to-paint-the-client-area-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From bb4bbce23d1a6ac910b527cf8828022a1167c753 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Fri, 10 Sep 2021 21:51:14 +0300 -Subject: [PATCH 0205/2346] user32: Allow using surface to paint the client - area of OpenGL windows. - -CW-Bug-ID: #19216 ---- - dlls/win32u/dce.c | 16 +++++----------- - server/window.c | 3 ++- - 2 files changed, 7 insertions(+), 12 deletions(-) - -diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c -index 5df30550cae..f70a2a32be9 100644 ---- a/dlls/win32u/dce.c -+++ b/dlls/win32u/dce.c -@@ -463,7 +463,6 @@ static void update_visible_region( struct dce *dce ) - HRGN vis_rgn = 0; - HWND top_win = 0; - DWORD flags = dce->flags; -- DWORD paint_flags = 0; - size_t size = 256; - RECT win_rect, top_rect; - WND *win; -@@ -500,7 +499,6 @@ static void update_visible_region( struct dce *dce ) - top_win = wine_server_ptr_handle( reply->top_win ); - win_rect = wine_server_get_rect( reply->win_rect ); - top_rect = wine_server_get_rect( reply->top_rect ); -- paint_flags = reply->paint_flags; - } - else size = reply->total_size; - } -@@ -515,16 +513,12 @@ static void update_visible_region( struct dce *dce ) - if (dce->clip_rgn) NtGdiCombineRgn( vis_rgn, vis_rgn, dce->clip_rgn, - (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ); - -- /* don't use a surface to paint the client area of OpenGL windows */ -- if (!(paint_flags & SET_WINPOS_PIXEL_FORMAT) || (flags & DCX_WINDOW)) -+ win = get_win_ptr( top_win ); -+ if (win && win != WND_DESKTOP && win != WND_OTHER_PROCESS) - { -- win = get_win_ptr( top_win ); -- if (win && win != WND_DESKTOP && win != WND_OTHER_PROCESS) -- { -- surface = win->surface; -- if (surface) window_surface_add_ref( surface ); -- release_win_ptr( win ); -- } -+ surface = win->surface; -+ if (surface) window_surface_add_ref( surface ); -+ release_win_ptr( win ); - } - - if (!surface) SetRectEmpty( &top_rect ); -diff --git a/server/window.c b/server/window.c -index 242e93f303a..a2b277d413a 100644 ---- a/server/window.c -+++ b/server/window.c -@@ -1248,7 +1248,8 @@ static struct region *get_surface_region( struct window *win ) - set_region_rect( clip, &win->client_rect ); - if (win->win_region && !intersect_window_region( clip, win )) goto error; - -- if ((win->paint_flags & PAINT_HAS_PIXEL_FORMAT) && !subtract_region( region, region, clip )) -+ if (!(win->ex_style & WS_EX_LAYERED) && (win->paint_flags & PAINT_HAS_PIXEL_FORMAT) -+ && !subtract_region( region, region, clip )) - goto error; - - /* clip children */ --- -2.47.0 - diff --git a/0009-windowing-system-integration/0003-rendering/0856-user32-Flush-driver-display-in-ReleaseDC-for-other-p.patch b/0009-windowing-system-integration/0003-rendering/0856-user32-Flush-driver-display-in-ReleaseDC-for-other-p.patch deleted file mode 100644 index d3cd1c4..0000000 --- a/0009-windowing-system-integration/0003-rendering/0856-user32-Flush-driver-display-in-ReleaseDC-for-other-p.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c6fc9aac47ffdc5644f9aace4ad365e66bb1fbce Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Tue, 24 May 2022 16:27:08 -0500 -Subject: [PATCH 0856/2346] user32: Flush driver display in ReleaseDC() for - other process window. - -CW-Bug-Id: #19779 ---- - dlls/win32u/dce.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c -index 649b82cdb6b..d7aa75b3039 100644 ---- a/dlls/win32u/dce.c -+++ b/dlls/win32u/dce.c -@@ -1020,6 +1020,9 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags ) - */ - INT WINAPI NtUserReleaseDC( HWND hwnd, HDC hdc ) - { -+ if (hwnd && !is_current_process_window( hwnd )) -+ user_driver->pProcessEvents( 0 ); -+ - return release_dc( hwnd, hdc, FALSE ); - } - --- -2.47.0 - diff --git a/0013-server-optimization/0001-misc/ps0050-oleaut32-CoMsgWaitForMultipleHandles-message-pump.patch b/0013-server-optimization/0001-misc/ps0050-oleaut32-CoMsgWaitForMultipleHandles-message-pump.patch new file mode 100644 index 0000000..13b89e4 --- /dev/null +++ b/0013-server-optimization/0001-misc/ps0050-oleaut32-CoMsgWaitForMultipleHandles-message-pump.patch @@ -0,0 +1,509 @@ +From: Kevin Puetz +Subject: [PATCH] oleaut32: CoMsgWaitForMultipleHandles message pump. +Message-Id: <20201124231833.11578-1-PuetzKevinA@JohnDeere.com> +Date: Tue, 24 Nov 2020 17:18:32 -0600 + +Check for completion (handles/APC) before pumping any messages, and +again after each message is dispatched, returning as soon as the wait +condition is satisfied. This matches windows behavior and obsoletes +the previous "100 message" workaround for WM_PAINT. + +Only report timeout before/during sleep, not while actively working. +The previous code had a narrow race (particularly for timeout=0): +if GetTickCount incremented between start_time and the loop body +it could WAIT_TIMEOUT even if the handles were already signaled. +No test; I couldn't think of a way to provoke this consistently. + +NOTE: this means CoWaitForMultipleHandles does not time out while +there are still queued messages, and will livelock (and never time out) +if dispatching of messages continuously posts additional messages. +It will exit (successfully) if the handles eventually become signaled. +The latter is the only case tested, since I don't know how to write +a successful test for "this will livelock and hang the process". +But windows does do the same. + +Notify IMessageFilter::MessagePending only for messages that wake +CoWait from MsgWait (sleeping on an empty queue), but not for +messages already posted before it sleeps. + +Add tests for IMessageFilter::MessagePending -> PENDINGMSG_CANCELCALL +One of these is todo_wine, as was the existing MessageFilter test. +The bug is the same: windows does not call MessagePending for DDE/RPC +messages, but wine (still) does. I'm not sure what the right structure +is to fix this, but it's a separate (and preexisting) issue. +--- + dlls/combase/combase.c | 173 +++++++++++++++++++------------------ + dlls/ole32/tests/compobj.c | 164 +++++++++++++++++++++++++++++++++++ + 2 files changed, 253 insertions(+), 84 deletions(-) + +diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c +index 11111111111..11111111111 100644 +--- a/dlls/combase/combase.c ++++ b/dlls/combase/combase.c +@@ -2050,12 +2050,13 @@ static BOOL com_peek_message(struct apartment *apt, MSG *msg) + HRESULT WINAPI CoWaitForMultipleHandles(DWORD flags, DWORD timeout, ULONG handle_count, HANDLE *handles, + DWORD *index) + { +- BOOL check_apc = !!(flags & COWAIT_ALERTABLE), message_loop; ++ BOOL message_loop; + struct { BOOL post; UINT code; } quit = { .post = FALSE }; + DWORD start_time, wait_flags = 0; + struct tlsdata *tlsdata; + struct apartment *apt; + HRESULT hr; ++ DWORD res; + + TRACE("%#lx, %#lx, %lu, %p, %p\n", flags, timeout, handle_count, handles, index); + +@@ -2084,113 +2085,117 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD flags, DWORD timeout, ULONG handle + + start_time = GetTickCount(); + +- while (TRUE) ++ if (message_loop) + { +- DWORD now = GetTickCount(), res; +- +- if (now - start_time > timeout) ++ while (TRUE) + { +- hr = RPC_S_CALLPENDING; +- break; +- } ++ MSG msg; + +- if (message_loop) +- { + TRACE("waiting for rpc completion or window message\n"); + +- res = WAIT_TIMEOUT; ++ res = WaitForMultipleObjectsEx(handle_count, handles, ++ !!(flags & COWAIT_WAITALL), 0, !!(flags & COWAIT_ALERTABLE)); + +- if (check_apc) ++ if (res != WAIT_TIMEOUT) + { +- res = WaitForMultipleObjectsEx(handle_count, handles, !!(flags & COWAIT_WAITALL), 0, TRUE); +- check_apc = FALSE; ++ break; + } + +- if (res == WAIT_TIMEOUT) +- res = MsgWaitForMultipleObjectsEx(handle_count, handles, +- timeout == INFINITE ? INFINITE : start_time + timeout - now, +- QS_SENDMESSAGE | QS_ALLPOSTMESSAGE | QS_PAINT, wait_flags); +- +- if (res == WAIT_OBJECT_0 + handle_count) /* messages available */ ++ if (!apt->win) + { +- int msg_count = 0; +- MSG msg; +- +- /* call message filter */ ++ /* If window is NULL on apartment, peek at messages so that it will not trigger ++ * MsgWaitForMultipleObjects next time. */ ++ PeekMessageW(NULL, NULL, 0, 0, PM_QS_POSTMESSAGE | PM_NOREMOVE | PM_NOYIELD); ++ } + +- if (apt->filter) ++ if (com_peek_message(apt, &msg)) ++ { ++ if (msg.message == WM_QUIT) + { +- PENDINGTYPE pendingtype = tlsdata->pending_call_count_server ? PENDINGTYPE_NESTED : PENDINGTYPE_TOPLEVEL; +- DWORD be_handled = IMessageFilter_MessagePending(apt->filter, 0 /* FIXME */, now - start_time, pendingtype); +- +- TRACE("IMessageFilter_MessagePending returned %ld\n", be_handled); +- +- switch (be_handled) +- { +- case PENDINGMSG_CANCELCALL: +- WARN("call canceled\n"); +- hr = RPC_E_CALL_CANCELED; +- break; +- case PENDINGMSG_WAITNOPROCESS: +- case PENDINGMSG_WAITDEFPROCESS: +- default: +- /* FIXME: MSDN is very vague about the difference +- * between WAITNOPROCESS and WAITDEFPROCESS - there +- * appears to be none, so it is possibly a left-over +- * from the 16-bit world. */ +- break; +- } ++ TRACE("Received WM_QUIT message\n"); ++ quit.post = TRUE; ++ quit.code = msg.wParam; + } +- +- if (!apt->win) ++ else + { +- /* If window is NULL on apartment, peek at messages so that it will not trigger +- * MsgWaitForMultipleObjects next time. */ +- PeekMessageW(NULL, NULL, 0, 0, PM_QS_POSTMESSAGE | PM_NOREMOVE | PM_NOYIELD); ++ TRACE("Received message whilst waiting for RPC: 0x%04x\n", msg.message); ++ TranslateMessage(&msg); ++ DispatchMessageW(&msg); ++ } ++ } ++ else ++ { ++ DWORD now = GetTickCount(); ++ if (now - start_time > timeout) ++ { ++ /* res really is WAIT_TIMEOUT (not just from the dwMilliseconds=0 polling of handles) */ ++ break; + } + +- /* Some apps (e.g. Visio 2010) don't handle WM_PAINT properly and loop forever, +- * so after processing 100 messages we go back to checking the wait handles */ +- while (msg_count++ < 100 && com_peek_message(apt, &msg)) ++ /* not done, no messages pending, sleep for the remaining time (or until something happens) */ ++ res = MsgWaitForMultipleObjectsEx(handle_count, handles, ++ timeout == INFINITE ? INFINITE : start_time + timeout - now, ++ QS_SENDMESSAGE | QS_ALLPOSTMESSAGE | QS_PAINT, wait_flags); ++ ++ if (res == WAIT_OBJECT_0 + handle_count) /* messages available */ + { +- if (msg.message == WM_QUIT) +- { +- TRACE("Received WM_QUIT message\n"); +- quit.post = TRUE; +- quit.code = msg.wParam; +- } +- else ++ /* call message filter */ ++ ++ if (apt->filter) + { +- TRACE("Received message whilst waiting for RPC: 0x%04x\n", msg.message); +- TranslateMessage(&msg); +- DispatchMessageW(&msg); ++ PENDINGTYPE pendingtype = tlsdata->pending_call_count_server ? PENDINGTYPE_NESTED : PENDINGTYPE_TOPLEVEL; ++ DWORD be_handled = IMessageFilter_MessagePending(apt->filter, 0 /* FIXME */, now - start_time, pendingtype); ++ ++ TRACE("IMessageFilter_MessagePending returned %d\n", be_handled); ++ ++ switch (be_handled) ++ { ++ case PENDINGMSG_CANCELCALL: ++ WARN("call canceled\n"); ++ hr = RPC_E_CALL_CANCELED; ++ goto done; ++ break; ++ case PENDINGMSG_WAITNOPROCESS: ++ case PENDINGMSG_WAITDEFPROCESS: ++ default: ++ /* FIXME: MSDN is very vague about the difference ++ * between WAITNOPROCESS and WAITDEFPROCESS - there ++ * appears to be none, so it is possibly a left-over ++ * from the 16-bit world. */ ++ break; ++ } + } + } +- continue; ++ else ++ { ++ break; ++ } + } + } +- else +- { +- TRACE("Waiting for rpc completion\n"); ++ } ++ else ++ { ++ TRACE("Waiting for rpc completion\n"); + +- res = WaitForMultipleObjectsEx(handle_count, handles, !!(flags & COWAIT_WAITALL), +- (timeout == INFINITE) ? INFINITE : start_time + timeout - now, !!(flags & COWAIT_ALERTABLE)); +- } ++ res = WaitForMultipleObjectsEx(handle_count, handles, !!(flags & COWAIT_WAITALL), ++ timeout, !!(flags & COWAIT_ALERTABLE)); ++ } + +- switch (res) +- { +- case WAIT_TIMEOUT: +- hr = RPC_S_CALLPENDING; +- break; +- case WAIT_FAILED: +- hr = HRESULT_FROM_WIN32(GetLastError()); +- break; +- default: +- *index = res; +- break; +- } ++ switch (res) ++ { ++ case WAIT_TIMEOUT: ++ hr = RPC_S_CALLPENDING; ++ break; ++ case WAIT_FAILED: ++ hr = HRESULT_FROM_WIN32(GetLastError()); ++ break; ++ default: ++ hr = S_OK; ++ *index = res; + break; + } ++ ++done: + if (quit.post) PostQuitMessage(quit.code); + + TRACE("-- %#lx\n", hr); +diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c +index 11111111111..11111111111 100644 +--- a/dlls/ole32/tests/compobj.c ++++ b/dlls/ole32/tests/compobj.c +@@ -975,6 +975,16 @@ static DWORD WINAPI MessageFilter_MessagePending( + return PENDINGMSG_WAITNOPROCESS; + } + ++static DWORD WINAPI MessageFilter_MessagePending_cancel( ++ IMessageFilter *iface, ++ HTASK threadIDCallee, ++ DWORD dwTickCount, ++ DWORD dwPendingType) ++{ ++ trace("MessagePending(cancel)\n"); ++ return PENDINGMSG_CANCELCALL; ++} ++ + static const IMessageFilterVtbl MessageFilter_Vtbl = + { + MessageFilter_QueryInterface, +@@ -987,6 +997,18 @@ static const IMessageFilterVtbl MessageFilter_Vtbl = + + static IMessageFilter MessageFilter = { &MessageFilter_Vtbl }; + ++static const IMessageFilterVtbl MessageFilter_Vtbl_cancel = ++{ ++ MessageFilter_QueryInterface, ++ MessageFilter_AddRef, ++ MessageFilter_Release, ++ MessageFilter_HandleInComingCall, ++ MessageFilter_RetryRejectedCall, ++ MessageFilter_MessagePending_cancel ++}; ++ ++static IMessageFilter MessageFilter_cancel = { &MessageFilter_Vtbl_cancel }; ++ + static void test_CoRegisterMessageFilter(void) + { + HRESULT hr; +@@ -2611,6 +2633,22 @@ static DWORD CALLBACK post_message_thread(LPVOID arg) + return 0; + } + ++static DWORD CALLBACK post_input_later_thread(LPVOID arg) ++{ ++ HWND hWnd = arg; ++ Sleep(50); ++ PostMessageA(hWnd, WM_CHAR, VK_ESCAPE, 0); ++ return 0; ++} ++ ++static DWORD CALLBACK post_dde_later_thread(LPVOID arg) ++{ ++ HWND hWnd = arg; ++ Sleep(50); ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ return 0; ++} ++ + static const char cls_name[] = "cowait_test_class"; + + static UINT cowait_msgs[100], cowait_msgs_first, cowait_msgs_last; +@@ -2668,6 +2706,18 @@ static LRESULT CALLBACK cowait_window_proc(HWND hwnd, UINT msg, WPARAM wparam, L + cowait_msgs[cowait_msgs_last++] = msg; + if(msg == WM_DDE_FIRST) + return 6; ++ if(msg == WM_DDE_EXECUTE && lparam) ++ { ++ const char* command = (const char *)GlobalLock((HGLOBAL)lparam); ++ if(strcmp(command,"[apc]") == 0) ++ QueueUserAPC(apc_test_proc, GetCurrentThread(), 0); ++ else if(strcmp(command,"[postmessage]") == 0) ++ PostMessageA(hwnd,msg,wparam,lparam); /* post the same message again (trigges livelock) */ ++ else if(strcmp(command,"[semaphore]") == 0) ++ ReleaseSemaphore(GetPropA(hwnd,"semaphore"), 1, NULL); ++ GlobalUnlock((HGLOBAL)lparam); ++ return 0; ++ } + return DefWindowProcA(hwnd, msg, wparam, lparam); + } + +@@ -2749,6 +2799,27 @@ static DWORD CALLBACK test_CoWaitForMultipleHandles_thread(LPVOID arg) + success = PeekMessageA(&msg, NULL, uMSG, uMSG, PM_REMOVE); + ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); + ++ hr = CoRegisterMessageFilter(&MessageFilter_cancel, NULL); ++ ok(hr == S_OK, "CoRegisterMessageFilter failed: %08x\n", hr); ++ ++ /* a message which arrives during the wait calls IMessageFilter::PendingMessage, ++ * which can cancel the wait (without pumping the message) */ ++ thread = CreateThread(NULL, 0, post_input_later_thread, hWnd, 0, &tid); ++ hr = CoWaitForMultipleHandles(0, 200, 2, handles, &index); ++ ok(hr == RPC_E_CALL_CANCELED, "expected RPC_E_CALL_CANCELED, got 0x%08x\n", hr); ++ success = PeekMessageA(&msg, hWnd, WM_CHAR, WM_CHAR, PM_REMOVE); ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ CloseHandle(thread); ++ ++ /* DDE/RPC messages shouldn't go to IMessageFilter::PendingMessage */ ++ thread = CreateThread(NULL, 0, post_dde_later_thread, hWnd, 0, &tid); ++ hr = CoWaitForMultipleHandles(0, 200, 2, handles, &index); ++ todo_wine ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ CloseHandle(thread); ++ ++ hr = CoRegisterMessageFilter(NULL, NULL); ++ ok(hr == S_OK, "CoRegisterMessageFilter failed: %08x\n", hr); ++ + DestroyWindow(hWnd); + CoUninitialize(); + +@@ -2788,6 +2859,15 @@ static DWORD CALLBACK test_CoWaitForMultipleHandles_thread(LPVOID arg) + return 0; + } + ++static HGLOBAL globalalloc_string(const char *s) { ++ UINT len = strlen(s); ++ HGLOBAL ret = GlobalAlloc(GMEM_FIXED,len+1); ++ void *ptr = GlobalLock(ret); ++ strcpy(ptr,s); ++ GlobalUnlock(ret); ++ return ret; ++} ++ + static void test_CoWaitForMultipleHandles(void) + { + HANDLE handles[2], thread; +@@ -2797,6 +2877,10 @@ static void test_CoWaitForMultipleHandles(void) + HRESULT hr; + HWND hWnd; + MSG msg; ++ HGLOBAL execute_apc = globalalloc_string("[apc]"); ++ HGLOBAL execute_postmessage = globalalloc_string("[postmessage]"); ++ HGLOBAL execute_semaphore = globalalloc_string("[semaphore]"); ++ DWORD start_time; + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + ok(hr == S_OK, "CoInitializeEx failed with error 0x%08lx\n", hr); +@@ -2819,6 +2903,8 @@ static void test_CoWaitForMultipleHandles(void) + handles[1] = CreateSemaphoreA(NULL, 1, 1, NULL); + ok(handles[1] != 0, "CreateSemaphoreA failed %lu\n", GetLastError()); + ++ SetPropA(hWnd,"semaphore",handles[0]); ++ + /* test without flags */ + + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); +@@ -2867,6 +2953,31 @@ static void test_CoWaitForMultipleHandles(void) + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); + ++ /* test CoWaitForMultipleHandles stops pumping messages as soon as its handles are signaled */ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_EXECUTE, 0, (LPARAM)execute_semaphore); ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 1, handles, &index); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ cowait_msgs_expect_queued(hWnd,WM_DDE_FIRST); /* WM_DDE_EXECUTE already pumped*/ ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump enough messages\n"); ++ ++ /* test CoWaitForMultipleHandles will keep pumping even beyond timeout if the queue ++ * still has messages (e.g. pumping messages just posts more mesages), ++ * but will still exit if the handles handles become signaled */ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_EXECUTE, 0, (LPARAM)execute_postmessage); ++ start_time = GetTickCount(); ++ thread = CreateThread(NULL, 0, release_semaphore_thread, handles[0], 0, &tid); ++ hr = CoWaitForMultipleHandles(0, 50, 1, handles, &index); ++ ok(GetTickCount() - start_time >= 200, "CoWaitForMultipleHandles exited too soon\n"); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ cowait_msgs_expect_queued(hWnd,WM_DDE_EXECUTE); /* each pumped execute_postmessage added one more back */ ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump enough messages\n"); ++ + /* test PostMessageA/SendMessageA from a different thread */ + + index = 0xdeadbeef; +@@ -2914,6 +3025,45 @@ static void test_CoWaitForMultipleHandles(void) + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); + ++ ReleaseSemaphore(handles[0], 1, NULL); ++ ++ /* COWAIT_ALL will get time out even if the handles became signaled while it waits ++ * in MsgWaitForMultipleObjects(...,MWIO_WAITALL), as it demands a posted message too */ ++ index = 0xdeadbeef; ++ thread = CreateThread(NULL, 0, release_semaphore_thread, handles[1], 0, &tid); ++ hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 500, 2, handles, &index); ++ ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ /* but will succeed (without any further wait time) if the handles are avilable right away ++ * i.e. that it checks the handles first before calling MsgWaitForMultipleObjects */ ++ hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 0, 2, handles, &index); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ ++ ReleaseSemaphore(handles[1], 1, NULL); ++ ++ /* COWAIT_ALL will pump message which are already in the queue, ++ * (but no longer QS_ALLPOSTMESSAGE), before blocking in MsgWaitForMultipleObjectsEx */ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_EXECUTE, 0, (LPARAM)execute_semaphore); ++ PeekMessageA(&msg, hWnd, 0, 0, PM_NOREMOVE); // clear QS_ALLPOSTMESSAGE ++ hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 50, 1, handles, &index); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); ++ ++ ReleaseSemaphore(handles[1], 1, NULL); ++ ++ /* test early completion (rather than blocking in MsgWaitForMultipleObjectsEx again) ++ * if pumping a message results in all handles becoming signaled) */ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_EXECUTE, 0, (LPARAM)execute_semaphore); ++ hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 50, 2, handles, &index); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); ++ + ReleaseSemaphore(handles[0], 1, NULL); + ReleaseSemaphore(handles[1], 1, NULL); + +@@ -2953,6 +3103,16 @@ static void test_CoWaitForMultipleHandles(void) + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); + ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_EXECUTE, 0, (LPARAM)execute_apc); ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 1, handles, &index); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ ok(index == WAIT_IO_COMPLETION, "expected index WAIT_IO_COMPLETION, got %u\n", index); ++ cowait_msgs_expect_queued(hWnd,WM_DDE_FIRST); /* WM_DDE_EXECUTE already pumped*/ ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump enough messages\n"); ++ + /* test with COWAIT_INPUTAVAILABLE (semaphores are still locked) */ + + index = 0xdeadbeef; +@@ -3165,6 +3325,10 @@ static void test_CoWaitForMultipleHandles(void) + + CoUninitialize(); + ++ RemovePropA(hWnd,"semaphore"); ++ GlobalFree(execute_apc); ++ GlobalFree(execute_postmessage); ++ GlobalFree(execute_semaphore); + CloseHandle(handles[0]); + CloseHandle(handles[1]); + DestroyWindow(hWnd); + diff --git a/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch b/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch index 3580823..81e726d 100644 --- a/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch +++ b/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch @@ -13,7 +13,7 @@ indicates whether it is dynamically spinning critical section. v2: Enable dynamic spinning by default on Windows >= 8, which seems to be what Windows does (https://stackoverflow.com/questions/54765280/windows-critical-section-how-to-disable-spinning-completely) - - Default spincount of 256 if unspecified is just a random guess + - Default spincount to 8 if unspecified, it will dynamically adjust pretty quickly - 4096 seems to be used by Windows (https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializecriticalsectionandspincount), so that should be a safe maximum @@ -32,7 +32,7 @@ index 11111111111..11111111111 100644 +#define IS_DYNAMIC_SPIN crit->SpinCount >> 31 == 1 ? TRUE : FALSE +#define MAX_ADAPTIVE_SPIN_COUNT 4096 -+#define DEFAULT_ADAPTIVE_SPIN_COUNT 256 ++#define DEFAULT_ADAPTIVE_SPIN_COUNT 8 +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif diff --git a/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch b/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch index 24dfbd1..59cca18 100644 --- a/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch +++ b/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch @@ -158,7 +158,7 @@ index 11111111111..11111111111 100644 + unsigned char object_type; + unsigned char handle_flags; + unsigned short handle_value; -+ unsigned __int64 object_pointer; ++ UINT64 object_pointer; + unsigned int access_mask; +}; + @@ -176,9 +176,9 @@ index 11111111111..11111111111 100644 + +struct system_handle_entry_ex_64 +{ -+ unsigned __int64 object; -+ unsigned __int64 unique_process_id; -+ unsigned __int64 handle_value; ++ UINT64 object; ++ UINT64 unique_process_id; ++ UINT64 handle_value; + unsigned int granted_access; + unsigned short creator_back_trace_index; + unsigned short object_type_index; diff --git a/0013-server-optimization/0001-misc/ps0741-ntdll-Implement-NtFlushProcessWriteBuffers.patch b/0013-server-optimization/0001-misc/ps0741-ntdll-Implement-NtFlushProcessWriteBuffers.patch index 1952ddc..b7d7b85 100644 --- a/0013-server-optimization/0001-misc/ps0741-ntdll-Implement-NtFlushProcessWriteBuffers.patch +++ b/0013-server-optimization/0001-misc/ps0741-ntdll-Implement-NtFlushProcessWriteBuffers.patch @@ -1,76 +1,69 @@ -From 7f0f004f441bb5a4098fcf9cc980e9f2dddda616 Mon Sep 17 00:00:00 2001 +From c1720fc3ab35df2aa9c02f14a3214a4cc9370fdd Mon Sep 17 00:00:00 2001 From: Torge Matthies -Date: Tue, 28 Mar 2023 12:53:25 +0200 -Subject: [PATCH 1/3] ntdll: Add MADV_DONTNEED-based implementation of +Date: Tue, 20 Feb 2024 16:45:49 +0100 +Subject: [PATCH 1/4] ntdll: Add mprotect-based implementation of NtFlushProcessWriteBuffers. -Credits to Avi Kivity (scylladb) and Aliaksei Kandratsenka (gperftools) for this trick, see [1]. - -[1] https://github.com/scylladb/seastar/commit/77a58e4dc020233f66fccb8d9e8f7a8b7f9210c4 --- - dlls/ntdll/unix/virtual.c | 52 +++++++++++++++++++++++++++++++++++++- - tools/winapi/nativeapi.dat | 1 + - 2 files changed, 52 insertions(+), 1 deletion(-) + dlls/ntdll/unix/virtual.c | 51 +++++++++++++++++++++++++++++++++++++-- + 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 0faf3e343e3..a6fb19c807a 100644 +index 2b6ce543531..219a0339933 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -216,6 +216,9 @@ struct range_entry +@@ -219,6 +219,9 @@ struct range_entry static struct range_entry *free_ranges; static struct range_entry *free_ranges_end; -+static void *dontneed_page; -+static pthread_mutex_t dontneed_page_mutex = PTHREAD_MUTEX_INITIALIZER; ++static void *dummy_page; ++static pthread_mutex_t dummy_page_mutex = PTHREAD_MUTEX_INITIALIZER; + static inline BOOL is_beyond_limit( const void *addr, size_t size, const void *limit ) { -@@ -5170,13 +5173,60 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T +@@ -6073,14 +6076,58 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T } -+static BOOL try_madvise( void ) ++static BOOL try_mprotect( void ) +{ -+#ifdef __aarch64__ ++#if !defined(__i386__) && !defined(__x86_64__) + static int once = 0; +#endif + BOOL success = FALSE; + char *mem; + -+ pthread_mutex_lock(&dontneed_page_mutex); -+ /* Credits to Avi Kivity (scylladb) and Aliaksei Kandratsenka (gperftools) for this trick, -+ see https://github.com/scylladb/seastar/commit/77a58e4dc020233f66fccb8d9e8f7a8b7f9210c4 */ -+ mem = dontneed_page; ++ pthread_mutex_lock(&dummy_page_mutex); ++ mem = dummy_page; + if (!mem) + { -+ int ret; -+ /* Allocate one page of memory that we can call madvise() on */ ++ /* Allocate one page of memory that we can call mprotect() on */ + mem = anon_mmap_alloc( page_size, PROT_READ | PROT_WRITE ); + if (mem == MAP_FAILED) + goto failed; -+ /* If the memory is locked, e.g. by a call to mlockall(MCL_FUTURE), the madvise() call below -+ will fail with error EINVAL, so unlock it here */ -+ ret = munlock( mem, page_size ); -+ /* munlock() may fail on old kernels if we don't have sufficient permissions, but that is not -+ a problem since in that case we didn't have permission to lock the memory either */ -+ if (ret && errno != EPERM) ++ /* Lock page into memory so that it is not unmapped between the calls to mprotect() below */ ++ if (mlock( mem, page_size )) + goto failed; -+ dontneed_page = mem; ++ dummy_page = mem; + } -+ /* Force the page into memory to make madvise() have real work to do */ -+ *mem = 3; -+ /* Evict the page from memory to force the kernel to send an IPI to all threads of this process, ++ /* Make dummy page writable */ ++ success = !mprotect( mem, page_size, PROT_READ | PROT_WRITE ); ++ if (!success) ++ goto failed; ++ /* Make the page dirty to prevent the kernel from skipping the global TLB flush */ ++ InterlockedIncrement((volatile LONG*)mem); ++ /* Change the page protection to PROT_NONE to force the kernel to send an IPI to all threads of this process, + which has the side effect of executing a memory barrier in those threads */ -+ success = !madvise( mem, page_size, MADV_DONTNEED ); -+#ifdef __aarch64__ ++ success = !mprotect( mem, page_size, PROT_NONE ); ++#if !defined(__i386__) && !defined(__x86_64__) + /* Some ARMv8 processors can broadcast TLB invalidations using the TLBI instruction, -+ the madvise trick does not work on those */ ++ the madvise trick does not work on those. Print a fixme on all non-x86 architectures. */ + if (success && !once++) + FIXME( "memory barrier may not work on this platform\n" ); +#endif +failed: -+ pthread_mutex_unlock(&dontneed_page_mutex); ++ pthread_mutex_unlock(&dummy_page_mutex); + return success; +} + @@ -82,32 +75,22 @@ index 0faf3e343e3..a6fb19c807a 100644 { static int once = 0; - if (!once++) FIXME( "stub\n" ); -+ if (try_madvise()) +- return STATUS_SUCCESS; ++ if (try_mprotect()) + return STATUS_SUCCESS; + if (!once++) FIXME( "no implementation available on this platform\n" ); - return STATUS_SUCCESS; ++ return STATUS_NOT_IMPLEMENTED; } -diff --git a/tools/winapi/nativeapi.dat b/tools/winapi/nativeapi.dat -index ade20b5ee68..5512c4f1833 100644 ---- a/tools/winapi/nativeapi.dat -+++ b/tools/winapi/nativeapi.dat -@@ -134,6 +134,7 @@ log10 - logb - longjmp - lseek -+madvise - malloc - mblen - memccpy + -- GitLab -From 014e78a433f147bf81cd5a94f7dcb7bbceecde60 Mon Sep 17 00:00:00 2001 +From 5014d210649a65e6e46c1dd3363e65d1a304eb5f Mon Sep 17 00:00:00 2001 From: Torge Matthies -Date: Tue, 28 Mar 2023 12:53:25 +0200 -Subject: [PATCH 2/3] ntdll: Add sys_membarrier-based implementation of +Date: Tue, 20 Feb 2024 16:45:49 +0100 +Subject: [PATCH 2/4] ntdll: Add sys_membarrier-based implementation of NtFlushProcessWriteBuffers. Uses the MEMBARRIER_CMD_PRIVATE_EXPEDITED membarrier command introduced in Linux 4.14. @@ -116,7 +99,7 @@ Uses the MEMBARRIER_CMD_PRIVATE_EXPEDITED membarrier command introduced in Linux 1 file changed, 47 insertions(+) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index a6fb19c807a..ee2a12ecd54 100644 +index 219a0339933..8c53ce00e9f 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -39,6 +39,9 @@ @@ -129,7 +112,7 @@ index a6fb19c807a..ee2a12ecd54 100644 #ifdef HAVE_SYS_SYSCTL_H # include #endif -@@ -216,6 +219,11 @@ struct range_entry +@@ -219,6 +222,11 @@ struct range_entry static struct range_entry *free_ranges; static struct range_entry *free_ranges_end; @@ -138,10 +121,10 @@ index a6fb19c807a..ee2a12ecd54 100644 +static pthread_once_t membarrier_init_once = PTHREAD_ONCE_INIT; +#endif + - static void *dontneed_page; - static pthread_mutex_t dontneed_page_mutex = PTHREAD_MUTEX_INITIALIZER; + static void *dummy_page; + static pthread_mutex_t dummy_page_mutex = PTHREAD_MUTEX_INITIALIZER; -@@ -5173,6 +5181,43 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T +@@ -6076,6 +6084,43 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T } @@ -182,34 +165,34 @@ index a6fb19c807a..ee2a12ecd54 100644 +#endif /* defined(__linux__) && defined(__NR_membarrier) */ + + - static BOOL try_madvise( void ) + static BOOL try_mprotect( void ) { - #ifdef __aarch64__ -@@ -5224,6 +5269,8 @@ failed: + #if !defined(__i386__) && !defined(__x86_64__) +@@ -6124,6 +6169,8 @@ failed: NTSTATUS WINAPI NtFlushProcessWriteBuffers(void) { static int once = 0; + if (try_exp_membarrier()) + return STATUS_SUCCESS; - if (try_madvise()) + if (try_mprotect()) return STATUS_SUCCESS; if (!once++) FIXME( "no implementation available on this platform\n" ); -- GitLab -From e9df595359e846e3596c9268f7856b29e4fb628d Mon Sep 17 00:00:00 2001 +From 1dff2a4385d92b9afba435e0a6f2c2116de162a2 Mon Sep 17 00:00:00 2001 From: Torge Matthies -Date: Tue, 28 Mar 2023 12:53:26 +0200 -Subject: [PATCH 3/3] ntdll: Add thread_get_register_pointer_values-based +Date: Tue, 20 Feb 2024 16:45:49 +0100 +Subject: [PATCH 3/4] ntdll: Add thread_get_register_pointer_values-based implementation of NtFlushProcessWriteBuffers. --- - dlls/ntdll/unix/virtual.c | 70 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 70 insertions(+) + dlls/ntdll/unix/virtual.c | 64 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index ee2a12ecd54..7a5778a6d8c 100644 +index 8c53ce00e9f..155367b605f 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -65,6 +65,9 @@ @@ -222,7 +205,7 @@ index ee2a12ecd54..7a5778a6d8c 100644 #endif #include "ntstatus.h" -@@ -219,6 +222,11 @@ struct range_entry +@@ -222,6 +225,11 @@ struct range_entry static struct range_entry *free_ranges; static struct range_entry *free_ranges_end; @@ -234,7 +217,7 @@ index ee2a12ecd54..7a5778a6d8c 100644 #if defined(__linux__) && defined(__NR_membarrier) static BOOL membarrier_exp_available; static pthread_once_t membarrier_init_once = PTHREAD_ONCE_INIT; -@@ -5181,6 +5189,66 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T +@@ -6084,6 +6092,60 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T } @@ -250,8 +233,8 @@ index ee2a12ecd54..7a5778a6d8c 100644 + /* Taken from https://github.com/dotnet/runtime/blob/7be37908e5a1cbb83b1062768c1649827eeaceaa/src/coreclr/pal/src/thread/process.cpp#L2799 */ + mach_msg_type_number_t count, i = 0; + thread_act_array_t threads; ++ BOOL success = TRUE; + kern_return_t kret; -+ BOOL success = FALSE; + + pthread_once(&tgrpvs_init_once, tgrpvs_init); + if (!p_thread_get_register_pointer_values) @@ -274,18 +257,12 @@ index ee2a12ecd54..7a5778a6d8c 100644 + /* This function always fails when querying Rosetta's exception handling thread, so we only treat + KERN_INSUFFICIENT_BUFFER_SIZE as an error, like .NET core does. */ + if (kret == KERN_INSUFFICIENT_BUFFER_SIZE) -+ goto fail; ++ success = FALSE; + + /* Deallocate thread reference once we're done with it */ -+ kret = mach_port_deallocate( mach_task_self(), threads[i++] ); -+ if (kret) -+ goto fail; -+ } -+ success = TRUE; -+fail: -+ /* Deallocate remaining thread references */ -+ while (i < count) + mach_port_deallocate( mach_task_self(), threads[i++] ); ++ } ++ + /* Deallocate thread list */ + vm_deallocate( mach_task_self(), (vm_address_t)threads, count * sizeof(threads[0]) ); + return success; @@ -301,7 +278,7 @@ index ee2a12ecd54..7a5778a6d8c 100644 #if defined(__linux__) && defined(__NR_membarrier) #define MEMBARRIER_CMD_QUERY 0x00 -@@ -5269,6 +5337,8 @@ failed: +@@ -6169,6 +6231,8 @@ failed: NTSTATUS WINAPI NtFlushProcessWriteBuffers(void) { static int once = 0; @@ -309,7 +286,61 @@ index ee2a12ecd54..7a5778a6d8c 100644 + return STATUS_SUCCESS; if (try_exp_membarrier()) return STATUS_SUCCESS; - if (try_madvise()) + if (try_mprotect()) +-- +GitLab + + +From 2249604e53b9f72478d3886f250720db957454cf Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Tue, 20 Feb 2024 16:51:50 +0100 +Subject: [PATCH 4/4] ntdll/tests: Add basic NtFlushProcessWriteBuffers test. + +--- + dlls/ntdll/tests/virtual.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c +index 3628cec89e8..748ce9c4bb8 100644 +--- a/dlls/ntdll/tests/virtual.c ++++ b/dlls/ntdll/tests/virtual.c +@@ -46,6 +46,7 @@ static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE, HANDLE, PVOID *, const L + static NTSTATUS (WINAPI *pNtSetInformationVirtualMemory)(HANDLE, VIRTUAL_MEMORY_INFORMATION_CLASS, + ULONG_PTR, PMEMORY_RANGE_ENTRY, + PVOID, ULONG); ++static NTSTATUS (WINAPI *pNtFlushProcessWriteBuffers)(void); + + static const BOOL is_win64 = sizeof(void*) != sizeof(int); + static BOOL is_wow64; +@@ -2705,6 +2706,14 @@ static void test_query_image_information(void) + NtClose( file ); + } + ++static void test_flush_write_buffers(void) ++{ ++ NTSTATUS status; ++ ++ status = pNtFlushProcessWriteBuffers(); ++ ok( status == STATUS_SUCCESS, "Unexpected status %08lx\n", status ); ++} ++ + START_TEST(virtual) + { + HMODULE mod; +@@ -2737,6 +2746,7 @@ START_TEST(virtual) + pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx"); + pNtMapViewOfSectionEx = (void *)GetProcAddress(mod, "NtMapViewOfSectionEx"); + pNtSetInformationVirtualMemory = (void *)GetProcAddress(mod, "NtSetInformationVirtualMemory"); ++ pNtFlushProcessWriteBuffers = (void *)GetProcAddress(mod, "NtFlushProcessWriteBuffers"); + + NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL); + trace("system page size %#lx\n", sbi.PageSize); +@@ -2755,4 +2765,5 @@ START_TEST(virtual) + test_query_image_information(); + test_exec_memory_writes(); + test_massive_memory_reservation(); ++ test_flush_write_buffers(); + } -- GitLab diff --git a/0013-server-optimization/0001-misc/ps6666-win32u-check-for-driver-events-every-0.1ms-instead-o.patch b/0013-server-optimization/0001-misc/ps6666-win32u-check-for-driver-events-every-0.1ms-instead-o.patch deleted file mode 100644 index 8171940..0000000 --- a/0013-server-optimization/0001-misc/ps6666-win32u-check-for-driver-events-every-0.1ms-instead-o.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: William Horvath -Date: Mon, 9 Dec 2024 03:26:27 -0800 -Subject: [PATCH] win32u: check for driver events every 0.1ms instead of 1ms - -alternative workaround for https://bugs.winehq.org/show_bug.cgi?id=57442 - -v2: use fast USD (it's updating at 0.1ms anyways) instead of yet another clock_gettime call ---- - dlls/win32u/message.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c -index 11111111111..11111111111 100644 ---- a/dlls/win32u/message.c -+++ b/dlls/win32u/message.c -@@ -26,6 +26,8 @@ - - #include - #include "ntstatus.h" -+#include "winternl.h" -+#include "ddk/wdm.h" - #define WIN32_NO_STATUS - #include "win32u_private.h" - #include "ntuser_private.h" -@@ -40,6 +42,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msg); - WINE_DECLARE_DEBUG_CHANNEL(key); - WINE_DECLARE_DEBUG_CHANNEL(relay); - -+static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000; -+ - #define MAX_WINPROC_RECURSION 64 - - #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE -@@ -354,6 +358,11 @@ static const unsigned int message_pointer_flags[] = - SET(WM_ASKCBFORMATNAME) - }; - -+static inline DWORD __wine_get_hires_tick_count(void) -+{ -+ return (DWORD)(user_shared_data->InterruptTime.LowPart / 1000); -+} -+ - /* check whether a given message type includes pointers */ - static inline BOOL is_pointer_message( UINT message, WPARAM wparam ) - { -@@ -3064,11 +3073,11 @@ static HANDLE get_server_queue_handle(void) - /* check for driver events if we detect that the app is not properly consuming messages */ - static inline void check_for_driver_events(void) - { -- if (get_user_thread_info()->last_driver_time != NtGetTickCount()) -+ if (get_user_thread_info()->last_driver_time != __wine_get_hires_tick_count()) - { - flush_window_surfaces( FALSE ); - user_driver->pProcessEvents( QS_ALLINPUT ); -- get_user_thread_info()->last_driver_time = NtGetTickCount(); -+ get_user_thread_info()->last_driver_time = __wine_get_hires_tick_count(); - } - } - -@@ -3110,7 +3119,7 @@ static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DW - } - - if (ret == WAIT_TIMEOUT && !count && !timeout) NtYieldExecution(); -- if (ret == count - 1) get_user_thread_info()->last_driver_time = NtGetTickCount(); -+ if (ret == count - 1) get_user_thread_info()->last_driver_time = __wine_get_hires_tick_count(); - - KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len ); - --- -0.0.0 - diff --git a/0013-server-optimization/0003-qpc/0002-ntdll-Use-rdtsc-p-for-RtlQueryPerformanceCounter-whe.patch b/0013-server-optimization/0003-qpc/0002-ntdll-Use-rdtsc-p-for-RtlQueryPerformanceCounter-whe.patch index f8d29f2..255dc71 100644 --- a/0013-server-optimization/0003-qpc/0002-ntdll-Use-rdtsc-p-for-RtlQueryPerformanceCounter-whe.patch +++ b/0013-server-optimization/0003-qpc/0002-ntdll-Use-rdtsc-p-for-RtlQueryPerformanceCounter-whe.patch @@ -26,7 +26,7 @@ index 11111111111..11111111111 100644 { + if (user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED) + { -+ unsigned __int64 tsc; ++ UINT64 tsc; + unsigned int aux; + + if (user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_RDTSCP) diff --git a/0013-server-optimization/0003-qpc/9300-qpc-support-hardcode-with-old-kernel-check.patch b/0013-server-optimization/0003-qpc/9300-qpc-support-hardcode-with-old-kernel-check.patch index 895d073..e54cd52 100644 --- a/0013-server-optimization/0003-qpc/9300-qpc-support-hardcode-with-old-kernel-check.patch +++ b/0013-server-optimization/0003-qpc/9300-qpc-support-hardcode-with-old-kernel-check.patch @@ -9,7 +9,7 @@ index 11111111111..11111111111 100644 - if (user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED) + if (1 || user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED) { - unsigned __int64 tsc; + UINT64 tsc; unsigned int aux; - if (user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_RDTSCP) @@ -102,7 +102,7 @@ index 11111111111..11111111111 100644 +#endif + user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED) { - unsigned __int64 tsc; + UINT64 tsc; unsigned int aux; - if (1 || user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_RDTSCP) diff --git a/0013-server-optimization/0004-time-wait/0008-ntdll-win32u-Use-some-higher-resolution-clock-ticks.patch b/0013-server-optimization/0004-time-wait/0008-ntdll-win32u-Use-some-higher-resolution-clock-ticks.patch new file mode 100644 index 0000000..8ebca25 --- /dev/null +++ b/0013-server-optimization/0004-time-wait/0008-ntdll-win32u-Use-some-higher-resolution-clock-ticks.patch @@ -0,0 +1,113 @@ +From aff19ed0d63afdb35cf070a41a02057fc1c432ef Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Thu, 12 Dec 2024 03:26:33 -0800 +Subject: [PATCH] ntdll, win32u: Use some higher resolution clock + ticks. + +--- + dlls/ntdll/ntdll.spec | 1 + + dlls/ntdll/time.c | 8 ++++++++ + dlls/ntdll/unix/sync.c | 7 +++++++ + dlls/win32u/message.c | 6 +++----------- + include/winternl.h | 1 + + 5 files changed, 23 insertions(+), 11 deletions(-) + +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index dafeb2d2e0b..95d70830bb6 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -1768,3 +1768,4 @@ + + # Time + @ cdecl __wine_get_tsc_calibration(ptr ptr) ++@ stdcall __wine_get_hires_tick_count() +diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c +index 951687ca5e5..e0b4eb5bbb6 100644 +--- a/dlls/ntdll/time.c ++++ b/dlls/ntdll/time.c +@@ -459,6 +459,14 @@ ULONG WINAPI DECLSPEC_HOTPATCH NtGetTickCount(void) + return user_shared_data->TickCount.LowPart; + } + ++/****************************************************************************** ++ * __wine_get_hires_tick_count (NTDLL.@) ++ */ ++DWORD WINAPI __wine_get_hires_tick_count(void) ++{ ++ return user_shared_data->InterruptTime.LowPart / 1000; ++} ++ + /*********************************************************************** + * RtlQueryTimeZoneInformation [NTDLL.@] + * +diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +index 4c39decfe13..489b8babd28 100644 +--- a/dlls/ntdll/unix/sync.c ++++ b/dlls/ntdll/unix/sync.c +@@ -1961,6 +1961,13 @@ ULONG WINAPI NtGetTickCount(void) + return user_shared_data->TickCount.LowPart; + } + ++/****************************************************************************** ++ * __wine_get_hires_tick_count (NTDLL.@) ++ */ ++DWORD WINAPI __wine_get_hires_tick_count(void) ++{ ++ return user_shared_data->InterruptTime.LowPart / 1000; ++} + + /****************************************************************************** + * RtlGetSystemTimePrecise (NTDLL.@) +diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c +index 8aae1d0da71..d26b717bcca 100644 +--- a/dlls/win32u/message.c ++++ b/dlls/win32u/message.c +@@ -3059,22 +3059,14 @@ static HANDLE get_server_queue_handle(void) + return ret; + } + +-/* monotonic timer tick for throttling driver event checks */ +-static inline LONGLONG get_driver_check_time(void) +-{ +- LARGE_INTEGER counter, freq; +- NtQueryPerformanceCounter( &counter, &freq ); +- return counter.QuadPart * 8000 / freq.QuadPart; /* 8kHz */ +-} +- + /* check for driver events if we detect that the app is not properly consuming messages */ + static inline void check_for_driver_events(void) + { +- if (get_user_thread_info()->last_driver_time != get_driver_check_time()) ++ if (get_user_thread_info()->last_driver_time != __wine_get_hires_tick_count()) + { + flush_window_surfaces( FALSE ); + user_driver->pProcessEvents( QS_ALLINPUT ); +- get_user_thread_info()->last_driver_time = get_driver_check_time(); ++ get_user_thread_info()->last_driver_time = __wine_get_hires_tick_count(); + } + } + +@@ -3116,7 +3108,7 @@ static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DW + } + + if (ret == WAIT_TIMEOUT && !count && !timeout) NtYieldExecution(); +- if (ret == count - 1) get_user_thread_info()->last_driver_time = get_driver_check_time(); ++ if (ret == count - 1) get_user_thread_info()->last_driver_time = __wine_get_hires_tick_count(); + + KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len ); + +diff --git a/include/winternl.h b/include/winternl.h +index 1ae37134ade..aed99fa677b 100644 +--- a/include/winternl.h ++++ b/include/winternl.h +@@ -5372,6 +5372,7 @@ static inline PLIST_ENTRY RemoveTailList(PLIST_ENTRY le) + + NTSYSAPI NTSTATUS WINAPI __wine_unix_spawnvp( char * const argv[], int wait ); + NTSYSAPI NTSTATUS __cdecl __wine_get_tsc_calibration( ULONGLONG *frequency, LONGLONG *offset ); ++NTSYSAPI DWORD WINAPI __wine_get_hires_tick_count(void); + + /* The thread information for 16-bit threads */ + /* NtCurrentTeb()->SubSystemTib points to this */ +-- +2.47.1 + diff --git a/0013-server-optimization/0004-time-wait/0013-kernel32-Reorganize-GetTickCount64.patch b/0013-server-optimization/0004-time-wait/0013-kernel32-Reorganize-GetTickCount64.patch index 3c730cb..5a6b34d 100644 --- a/0013-server-optimization/0004-time-wait/0013-kernel32-Reorganize-GetTickCount64.patch +++ b/0013-server-optimization/0004-time-wait/0013-kernel32-Reorganize-GetTickCount64.patch @@ -1,41 +1,29 @@ -From 2a202070cd467fdf41b91fb0fdbbce0fc19a313c Mon Sep 17 00:00:00 2001 From: William Horvath Date: Sun, 13 Oct 2024 20:23:16 -0700 Subject: [PATCH] kernel32: Reorganize GetTickCount64. -Miniscule consistency improvements from a rdtscp benchmark. ---- - dlls/kernel32/sync.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c -index 44fd01002d4..27030642ef2 100644 +index 11111111111..11111111111 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c -@@ -82,16 +82,18 @@ static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING +@@ -82,16 +82,7 @@ static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING */ ULONGLONG WINAPI DECLSPEC_HOTPATCH GetTickCount64(void) { - ULONG high, low; -+ ULONG high1, low, high2; - - do - { +- +- do +- { - high = user_shared_data->TickCount.High1Time; - low = user_shared_data->TickCount.LowPart; -+ high1 = *(volatile ULONG *)((char *)user_shared_data + offsetof(struct _KUSER_SHARED_DATA, TickCount.High1Time)); -+ low = *(volatile ULONG *)((char *)user_shared_data + offsetof(struct _KUSER_SHARED_DATA, TickCount.LowPart)); -+ high2 = *(volatile ULONG *)((char *)user_shared_data + offsetof(struct _KUSER_SHARED_DATA, TickCount.High2Time)); - } +- } - while (high != user_shared_data->TickCount.High2Time); -+ while (high1 != high2); - /* note: we ignore TickCountMultiplier */ +- /* note: we ignore TickCountMultiplier */ - return (ULONGLONG)high << 32 | low; -+ -+ return ((ULONGLONG)high1 << 32) | low; ++ return __atomic_load_n( &user_shared_data->TickCountQuad, __ATOMIC_ACQUIRE ); } /*********************************************************************** -- -2.47.0 +0.0.0 diff --git a/0013-server-optimization/0008-shm-opts/ps3000-win32u-Avoid-calling-server-in-NtUserGetKeyState.patch b/0013-server-optimization/0008-shm-opts/ps3000-win32u-Avoid-calling-server-in-NtUserGetKeyState.patch index e8375a7..c702439 100644 --- a/0013-server-optimization/0008-shm-opts/ps3000-win32u-Avoid-calling-server-in-NtUserGetKeyState.patch +++ b/0013-server-optimization/0008-shm-opts/ps3000-win32u-Avoid-calling-server-in-NtUserGetKeyState.patch @@ -45,9 +45,9 @@ index b258a25074c..7bf34756425 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -914,6 +914,7 @@ typedef volatile struct - unsigned int flags; /* desktop flags */ struct shared_cursor cursor; /* global cursor information */ unsigned char keystate[256]; /* asynchronous key state */ + UINT64 monitor_serial; /* winstation monitor update counter */ + INT64 update_serial; } desktop_shm_t; @@ -101,9 +101,9 @@ index 75324f8b3a7..fcc15f5fb82 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -319,6 +319,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned - shared->cursor.clip.right = 0; shared->cursor.clip.bottom = 0; memset( (void *)shared->keystate, 0, sizeof(shared->keystate) ); + shared->monitor_serial = winstation->monitor_serial; + shared->update_serial = 1; } SHARED_WRITE_END; diff --git a/9000-misc-additions/HACK-proton-wineboot-Don-t-show-updating-prefix-wind.patch b/9000-misc-additions/HACK-proton-wineboot-Don-t-show-updating-prefix-wind.patch index 3808c40..f1e9c38 100644 --- a/9000-misc-additions/HACK-proton-wineboot-Don-t-show-updating-prefix-wind.patch +++ b/9000-misc-additions/HACK-proton-wineboot-Don-t-show-updating-prefix-wind.patch @@ -9,29 +9,56 @@ Subject: [PATCH 0030/2346] HACK: proton: wineboot: Don't show "updating 1 file changed, 33 deletions(-) diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c -index c16446cf289..2a8f2edb141 100644 +index f256f617e64..8429e1cf065 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c -@@ -1425,37 +1425,6 @@ static BOOL start_services_process(void) +@@ -1741,64 +1741,6 @@ static BOOL start_services_process(void) return TRUE; } +-static void set_wait_dialog_text( HWND hwnd, HWND text, const WCHAR *string ) +-{ +- RECT win_rect, old_rect, new_rect; +- HDC hdc = GetDC( text ); +- +- GetClientRect( text, &old_rect ); +- new_rect = old_rect; +- SelectObject( hdc, (HFONT)SendMessageW( text, WM_GETFONT, 0, 0 )); +- DrawTextW( hdc, string, -1, &new_rect, DT_CALCRECT | DT_EDITCONTROL | DT_WORDBREAK | DT_NOPREFIX ); +- ReleaseDC( text, hdc ); +- if (new_rect.bottom > old_rect.bottom) +- { +- GetWindowRect( hwnd, &win_rect ); +- win_rect.bottom += new_rect.bottom - old_rect.bottom; +- SetWindowPos( hwnd, 0, 0, 0, win_rect.right - win_rect.left, win_rect.bottom - win_rect.top, +- SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); +- SetWindowPos( text, 0, 0, 0, new_rect.right, new_rect.bottom, +- SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); +- } +- SendMessageW( text, WM_SETTEXT, 0, (LPARAM)string ); +-} +- -static INT_PTR CALLBACK wait_dlgproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) -{ - switch (msg) - { - case WM_INITDIALOG: - { -- DWORD len; +- DWORD len, icon_size; +- RECT rect; - WCHAR *buffer, text[1024]; - const WCHAR *name = (WCHAR *)lp; -- HICON icon = LoadImageW( 0, (LPCWSTR)IDI_WINLOGO, IMAGE_ICON, 48, 48, LR_SHARED ); +- HICON icon; +- +- GetClientRect( GetDlgItem( hwnd, IDC_WAITICON ), &rect ); +- icon_size = min( rect.right, rect.bottom ); +- icon = LoadImageW( 0, (LPCWSTR)IDI_WINLOGO, IMAGE_ICON, icon_size, icon_size, LR_SHARED ); - SendDlgItemMessageW( hwnd, IDC_WAITICON, STM_SETICON, (WPARAM)icon, 0 ); - SendDlgItemMessageW( hwnd, IDC_WAITTEXT, WM_GETTEXT, 1024, (LPARAM)text ); - len = lstrlenW(text) + lstrlenW(name) + 1; - buffer = malloc( len * sizeof(WCHAR) ); - swprintf( buffer, len, text, name ); -- SendDlgItemMessageW( hwnd, IDC_WAITTEXT, WM_SETTEXT, 0, (LPARAM)buffer ); +- set_wait_dialog_text( hwnd, GetDlgItem( hwnd, IDC_WAITTEXT ), buffer ); - free( buffer ); - } - break; @@ -50,7 +77,7 @@ index c16446cf289..2a8f2edb141 100644 static HANDLE start_rundll32( const WCHAR *inf_path, const WCHAR *install, WORD machine ) { WCHAR app[MAX_PATH + ARRAY_SIZE(L"\\rundll32.exe" )]; -@@ -1606,7 +1575,6 @@ static void update_wineprefix( BOOL force ) +@@ -1950,7 +1892,6 @@ static void update_wineprefix( BOOL force ) if ((process = start_rundll32( inf_path, L"PreInstall", IMAGE_FILE_MACHINE_TARGET_HOST ))) { @@ -58,7 +85,7 @@ index c16446cf289..2a8f2edb141 100644 for (;;) { if (process) -@@ -1627,7 +1595,6 @@ static void update_wineprefix( BOOL force ) +@@ -1971,7 +1912,6 @@ static void update_wineprefix( BOOL force ) process = start_rundll32( inf_path, L"Wow64Install", machines[count].Machine ); count++; } diff --git a/9000-misc-additions/Revert-ntdll-Report-the-space-completely-outside-of-.patch b/9000-misc-additions/Revert-ntdll-Report-the-space-completely-outside-of-.patch new file mode 100644 index 0000000..578867c --- /dev/null +++ b/9000-misc-additions/Revert-ntdll-Report-the-space-completely-outside-of-.patch @@ -0,0 +1,61 @@ +From b962e1fd1f8a4eb3a599940b3ae50034fcf31953 Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Tue, 10 Dec 2024 01:12:10 -0800 +Subject: [PATCH] Revert "ntdll: Report the space completely outside of + reserved areas as allocated on i386." + +This reverts commit 233f6f288c8a6aa5aae127660ab00f392fe2cf67. + +The commit breaks osu! when WINE_BLOCK_GET_VERSION=0, because it fixes the bug +that the game tries to work around when it knows it's running under wine. +--- + dlls/ntdll/unix/virtual.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index 7330519bbb5..e2c3eb7c339 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -5603,7 +5603,6 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR + * so that the app doesn't believe it's fully available */ + { + struct reserved_area *area; +- BOOL in_reserved = FALSE; + + LIST_FOR_EACH_ENTRY( area, &reserved_areas, struct reserved_area, entry ) + { +@@ -5618,7 +5617,6 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR + if (area_start <= base || area_start <= (char *)address_space_start) + { + if (area_end < alloc_end) info->RegionSize = area_end - base; +- in_reserved = TRUE; + break; + } + /* report the remaining part of the 64K after the view as free */ +@@ -5629,22 +5627,18 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR + if (base < next) + { + info->RegionSize = min( next, alloc_end ) - base; +- in_reserved = TRUE; + break; + } + else alloc_base = base; + } + /* pretend it's allocated */ + if (area_start < alloc_end) info->RegionSize = area_start - base; +- break; +- } +- if (!in_reserved) +- { + info->State = MEM_RESERVE; + info->Protect = PAGE_NOACCESS; + info->AllocationBase = alloc_base; + info->AllocationProtect = PAGE_NOACCESS; + info->Type = MEM_PRIVATE; ++ break; + } + } + #endif +-- +2.47.1 + diff --git a/9000-misc-additions/combase-Perform-a-magic-trick-to-allow-osu-to-work-w.patch b/9000-misc-additions/combase-Perform-a-magic-trick-to-allow-osu-to-work-w.patch index 77b5f8f..2e08a89 100644 --- a/9000-misc-additions/combase-Perform-a-magic-trick-to-allow-osu-to-work-w.patch +++ b/9000-misc-additions/combase-Perform-a-magic-trick-to-allow-osu-to-work-w.patch @@ -17,7 +17,7 @@ index 02d9e0b536e..116b17f9a7e 100644 ROPARAMIIDHANDLE *hiid) { FIXME("stub: %d %p %p %p %p\n", name_element_count, name_elements, meta_data_locator, iid, hiid); -+ if (getenv("OSU_HACKS_ENABLED")) return S_OK; ++ return S_OK; if (iid) *iid = GUID_NULL; if (hiid) *hiid = INVALID_HANDLE_VALUE; return E_NOTIMPL; diff --git a/9000-misc-additions/ntdll-Always-start-the-initial-process-through-start.patch b/9000-misc-additions/ntdll-Always-start-the-initial-process-through-start.patch deleted file mode 100644 index 1e3badd..0000000 --- a/9000-misc-additions/ntdll-Always-start-the-initial-process-through-start.patch +++ /dev/null @@ -1,60 +0,0 @@ -## osu! fix: patch from server-default-integrity patchset from wine-staging removed in commit -## 9e265ac738bfd89b50071e9d0d881fe97f652c16 (9.4) needed to fix osu:// protocol links crashing in c0000135. - -From 643461bc989bd848363241dcfa04187e8d3a84d1 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Fri, 21 May 2021 21:52:06 -0500 -Subject: [PATCH] ntdll: Always start the initial process through start.exe. - -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/unix/env.c | 26 +++----------------------- - 1 file changed, 3 insertions(+), 23 deletions(-) - -diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c -index 30782a70eb0..959bafb28b7 100644 ---- a/dlls/ntdll/unix/env.c -+++ b/dlls/ntdll/unix/env.c -@@ -1909,6 +1909,7 @@ static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module ) - */ - static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) - { -+ static const char *args[] = { "start.exe", "/exec" }; - static const WCHAR valueW[] = {'1',0}; - static const WCHAR pathW[] = {'P','A','T','H'}; - RTL_USER_PROCESS_PARAMETERS *params = NULL; -@@ -1937,29 +1938,8 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) - add_registry_environment( &env, &env_pos, &env_size ); - env[env_pos++] = 0; - -- status = load_main_exe( NULL, main_argv[1], curdir, 0, &image, module ); -- if (!status) -- { -- char *loader; -- -- if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; -- /* if we have to use a different loader, fall back to start.exe */ -- if ((loader = get_alternate_wineloader( main_image_info.Machine ))) -- { -- free( loader ); -- status = STATUS_INVALID_IMAGE_FORMAT; -- } -- } -- -- if (status) /* try launching it through start.exe */ -- { -- static const char *args[] = { "start.exe", "/exec" }; -- free( image ); -- if (*module) NtUnmapViewOfSection( GetCurrentProcess(), *module ); -- load_start_exe( &image, module ); -- prepend_argv( args, 2 ); -- } -- else rebuild_argv(); -+ load_start_exe( &image, module ); -+ prepend_argv( args, 2 ); - - main_wargv = build_wargv( get_dos_path( image )); - cmdline = build_command_line( main_wargv ); --- -2.40.1 - diff --git a/9000-misc-additions/opengl32-windowscodecs-winepulse-free-on-process-exit.patch b/9000-misc-additions/opengl32-windowscodecs-winepulse-free-on-process-exit.patch deleted file mode 100644 index 6bc56ee..0000000 --- a/9000-misc-additions/opengl32-windowscodecs-winepulse-free-on-process-exit.patch +++ /dev/null @@ -1,73 +0,0 @@ -reverts f03c3a167c2e4abe92b1e1bf2ea5f7c31a07fc3b 6e9728bee52ac7e1f5a3d3bfe3bfaf5d9d1e01c1 505455de69acbc1390d2bf69313f1e76a19100ea ---- b/dlls/ntdll/unix/virtual.c -+++ a/dlls/ntdll/unix/virtual.c -@@ -4397,8 +4397,7 @@ - if (is_wow64()) - user_space_wow_limit = ((main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) ? limit_4g : limit_2g) - 1; - #ifndef __APPLE__ /* don't free the zerofill section on macOS */ -- else if ((main_image_info.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) && -- (main_image_info.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)) -+ else - free_reserved_memory( 0, (char *)0x7ffe0000 ); - #endif - } ---- b/dlls/opengl32/wgl.c -+++ a/dlls/opengl32/wgl.c -@@ -1281,7 +1281,6 @@ - break; - - case DLL_PROCESS_DETACH: -- if (reserved) break; - UNIX_CALL( process_detach, NULL ); - #ifndef _WIN64 - cleanup_wow64_strings(); ---- b/dlls/windowscodecs/main.c -+++ a/dlls/windowscodecs/main.c -@@ -44,7 +44,6 @@ - windowscodecs_module = hinstDLL; - break; - case DLL_PROCESS_DETACH: -- if (lpvReserved) break; - ReleaseComponentInfos(); - break; - } ---- b/dlls/winepulse.drv/mmdevdrv.c -+++ a/dlls/winepulse.drv/mmdevdrv.c -@@ -72,12 +72,10 @@ - - BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved) - { -+ if (reason == DLL_PROCESS_ATTACH) { -+ WCHAR buf[MAX_PATH]; -+ WCHAR *filename; -- WCHAR buf[MAX_PATH]; -- WCHAR *filename; - -- switch (reason) -- { -- case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(dll); - if (__wine_init_unix_call()) - return FALSE; -@@ -89,16 +87,11 @@ - - swprintf(drv_key_devicesW, ARRAY_SIZE(drv_key_devicesW), - L"Software\\Wine\\Drivers\\%s\\devices", filename); -+ } else if (reason == DLL_PROCESS_DETACH) { -+ struct device_cache *device, *device_next; -+ -+ LIST_FOR_EACH_ENTRY_SAFE(device, device_next, &g_devices_cache, struct device_cache, entry) -+ free(device); -- break; -- case DLL_PROCESS_DETACH: -- if (!reserved) -- { -- struct device_cache *device, *device_next; -- -- LIST_FOR_EACH_ENTRY_SAFE(device, device_next, &g_devices_cache, struct device_cache, entry) -- free(device); -- } -- break; - } - return TRUE; - } diff --git a/9000-misc-additions/reshuffle-rawinput-events.patch b/9000-misc-additions/reshuffle-rawinput-events.patch deleted file mode 100644 index c382fa8..0000000 --- a/9000-misc-additions/reshuffle-rawinput-events.patch +++ /dev/null @@ -1,95 +0,0 @@ -diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c -index 11111111111..11111111111 100644 ---- a/dlls/winex11.drv/event.c -+++ b/dlls/winex11.drv/event.c -@@ -336,38 +336,42 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) - return MERGE_KEEP; - } - break; -- case MotionNotify: -+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -+ case GenericEvent: -+ if (prev->xcookie.extension != xinput2_opcode) break; -+ if (prev->xcookie.evtype != XI_RawMotion) break; -+ if (thread_data->xinput2_rawinput) break; - switch (next->type) - { -- case MotionNotify: -- if (prev->xany.window == next->xany.window) -- { -- TRACE( "discarding duplicate MotionNotify for window %lx\n", prev->xany.window ); -- return MERGE_DISCARD; -- } -- break; --#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H - case GenericEvent: - if (next->xcookie.extension != xinput2_opcode) break; - if (next->xcookie.evtype != XI_RawMotion) break; -- if (thread_data->xinput2_rawinput) break; - if (thread_data->warp_serial) break; -- return MERGE_KEEP; -+ return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data ); - } - break; -- case GenericEvent: -- if (prev->xcookie.extension != xinput2_opcode) break; -- if (prev->xcookie.evtype != XI_RawMotion) break; -- if (thread_data->xinput2_rawinput) break; -+#endif -+ case MotionNotify: -+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H - switch (next->type) - { - case GenericEvent: - if (next->xcookie.extension != xinput2_opcode) break; - if (next->xcookie.evtype != XI_RawMotion) break; -+ if (thread_data->xinput2_rawinput) break; - if (thread_data->warp_serial) break; -- return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data ); -+ return MERGE_KEEP; -+ case MotionNotify: - #endif -+ if (prev->xany.window == next->xany.window) -+ { -+ TRACE( "discarding duplicate MotionNotify for window %lx\n", prev->xany.window ); -+ return MERGE_DISCARD; -+ } -+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -+ break; - } -+#endif - break; - } - return MERGE_HANDLE; -diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c -index 010495b174c..95b1be20bcc 100644 ---- a/dlls/winex11.drv/event.c -+++ b/dlls/winex11.drv/event.c -@@ -225,6 +225,13 @@ static Bool filter_event( Display *display, XEvent *event, char *arg ) - - switch(event->type) - { -+#ifdef GenericEvent -+ case GenericEvent: -+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -+ if (event->xcookie.extension == xinput2_opcode) return (mask & QS_INPUT) != 0; -+#endif -+ /* fallthrough */ -+#endif - case KeyPress: - case KeyRelease: - case KeymapNotify: -@@ -247,13 +254,6 @@ static Bool filter_event( Display *display, XEvent *event, char *arg ) - case PropertyNotify: - case ClientMessage: - return (mask & QS_POSTMESSAGE) != 0; --#ifdef GenericEvent -- case GenericEvent: --#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -- if (event->xcookie.extension == xinput2_opcode) return (mask & QS_INPUT) != 0; --#endif -- /* fallthrough */ --#endif - default: - return (mask & QS_SENDMESSAGE) != 0; - } diff --git a/staging-commit b/staging-commit index b83db7e..8cc838a 100644 --- a/staging-commit +++ b/staging-commit @@ -1 +1 @@ -4f96088b1e12db6134dff4090797c3d61b05833d \ No newline at end of file +c8d46d4ca3c505014f55cc92296592119abf84f1 \ No newline at end of file diff --git a/wine-commit b/wine-commit index d6639d8..5e33d68 100644 --- a/wine-commit +++ b/wine-commit @@ -1 +1 @@ -4161e62e478f61fdcd0365d9bd7b21e3b1a5197b \ No newline at end of file +5bfbeb677f472d30c5dc5d855b0a045a7157cc43 \ No newline at end of file