From bab383452b082fef17980a98c701d8f3d42c307d Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 22 Aug 2017 01:52:47 +0200 Subject: [PATCH] Added patch to implement dual source blending in wined3d. --- patches/patchinstall.sh | 133 +++++---- patches/wined3d-CSMT_Helper/definition | 1 + ...9-wined3d-Wrap-GL-BOs-in-a-structure.patch | 48 ++-- .../wined3d-CSMT_Main/9999-IfDefined.patch | 12 +- ...ed3d-Unroll-glsl-pixel-shader-output.patch | 167 +++++++++++ ...sts-Add-basic-dual-source-blend-test.patch | 197 +++++++++++++ ...ned3d-Implement-dual-source-blending.patch | 262 ++++++++++++++++++ .../wined3d-Dual_Source_Blending/definition | 2 + 8 files changed, 743 insertions(+), 79 deletions(-) create mode 100644 patches/wined3d-Dual_Source_Blending/0001-wined3d-Unroll-glsl-pixel-shader-output.patch create mode 100644 patches/wined3d-Dual_Source_Blending/0002-d3d11-tests-Add-basic-dual-source-blend-test.patch create mode 100644 patches/wined3d-Dual_Source_Blending/0003-wined3d-Implement-dual-source-blending.patch create mode 100644 patches/wined3d-Dual_Source_Blending/definition diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 50fa72e9..89d30c25 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -451,6 +451,7 @@ patch_enable_all () enable_wined3d_Core_Context="$1" enable_wined3d_DXTn="$1" enable_wined3d_DrawIndirect="$1" + enable_wined3d_Dual_Source_Blending="$1" enable_wined3d_GTX_560M="$1" enable_wined3d_Limit_Vram="$1" enable_wined3d_QUERY_Stubs="$1" @@ -1627,6 +1628,9 @@ patch_enable () wined3d-DrawIndirect) enable_wined3d_DrawIndirect="$2" ;; + wined3d-Dual_Source_Blending) + enable_wined3d_Dual_Source_Blending="$2" + ;; wined3d-GTX_560M) enable_wined3d_GTX_560M="$2" ;; @@ -2227,13 +2231,6 @@ if test "$enable_wined3d_WINED3D_RS_COLORWRITEENABLE" -eq 1; then enable_d3d11_Depth_Bias=1 fi -if test "$enable_wined3d_Viewports" -eq 1; then - if test "$enable_wined3d_Core_Context" -gt 1; then - abort "Patchset wined3d-Core_Context disabled, but wined3d-Viewports depends on that." - fi - enable_wined3d_Core_Context=1 -fi - if test "$enable_wined3d_DrawIndirect" -eq 1; then if test "$enable_wined3d_draw_primitive_arrays" -gt 1; then abort "Patchset wined3d-draw_primitive_arrays disabled, but wined3d-DrawIndirect depends on that." @@ -2241,13 +2238,6 @@ if test "$enable_wined3d_DrawIndirect" -eq 1; then enable_wined3d_draw_primitive_arrays=1 fi -if test "$enable_wined3d_Core_Context" -eq 1; then - if test "$enable_d3d11_Depth_Bias" -gt 1; then - abort "Patchset d3d11-Depth_Bias disabled, but wined3d-Core_Context depends on that." - fi - enable_d3d11_Depth_Bias=1 -fi - if test "$enable_wined3d_CSMT_Helper" -eq 1; then if test "$enable_d3d11_Deferred_Context" -gt 1; then abort "Patchset d3d11-Deferred_Context disabled, but wined3d-CSMT_Helper depends on that." @@ -2273,6 +2263,9 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then if test "$enable_wined3d_DXTn" -gt 1; then abort "Patchset wined3d-DXTn disabled, but wined3d-CSMT_Helper depends on that." fi + if test "$enable_wined3d_Dual_Source_Blending" -gt 1; then + abort "Patchset wined3d-Dual_Source_Blending disabled, but wined3d-CSMT_Helper depends on that." + fi if test "$enable_wined3d_QUERY_Stubs" -gt 1; then abort "Patchset wined3d-QUERY_Stubs disabled, but wined3d-CSMT_Helper depends on that." fi @@ -2293,12 +2286,34 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then enable_wined3d_Accounting=1 enable_wined3d_Copy_Resource_Typeless=1 enable_wined3d_DXTn=1 + enable_wined3d_Dual_Source_Blending=1 enable_wined3d_QUERY_Stubs=1 enable_wined3d_Revert_Buffer_Upload=1 enable_wined3d_Silence_FIXMEs=1 enable_wined3d_UAV_Counters=1 fi +if test "$enable_wined3d_Dual_Source_Blending" -eq 1; then + if test "$enable_wined3d_Viewports" -gt 1; then + abort "Patchset wined3d-Viewports disabled, but wined3d-Dual_Source_Blending depends on that." + fi + enable_wined3d_Viewports=1 +fi + +if test "$enable_wined3d_Viewports" -eq 1; then + if test "$enable_wined3d_Core_Context" -gt 1; then + abort "Patchset wined3d-Core_Context disabled, but wined3d-Viewports depends on that." + fi + enable_wined3d_Core_Context=1 +fi + +if test "$enable_wined3d_Core_Context" -eq 1; then + if test "$enable_d3d11_Depth_Bias" -gt 1; then + abort "Patchset d3d11-Depth_Bias disabled, but wined3d-Core_Context depends on that." + fi + enable_d3d11_Depth_Bias=1 +fi + if test "$enable_wined3d_Copy_Resource_Typeless" -eq 1; then if test "$enable_d3d11_Depth_Bias" -gt 1; then abort "Patchset d3d11-Depth_Bias disabled, but wined3d-Copy_Resource_Typeless depends on that." @@ -9591,6 +9606,57 @@ if test "$enable_wined3d_Copy_Resource_Typeless" -eq 1; then ) >> "$patchlist" fi +# Patchset wined3d-Core_Context +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * d3d11-Depth_Bias +# | +# | Modified files: +# | * dlls/dxgi/factory.c, dlls/wined3d/directx.c, include/wine/wined3d.h +# | +if test "$enable_wined3d_Core_Context" -eq 1; then + patch_apply wined3d-Core_Context/0001-wined3d-Use-OpenGL-core-context-for-D3D10-11-when-ne.patch + ( + printf '%s\n' '+ { "Michael Müller", "wined3d: Use OpenGL core context for D3D10/11 when necessary.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset wined3d-Viewports +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * d3d11-Depth_Bias, wined3d-Core_Context +# | +# | Modified files: +# | * dlls/d3d11/tests/d3d11.c, dlls/d3d8/directx.c, dlls/d3d9/directx.c, dlls/ddraw/ddraw_private.h, dlls/wined3d/state.c, +# | include/wine/wined3d.h +# | +if test "$enable_wined3d_Viewports" -eq 1; then + patch_apply wined3d-Viewports/0001-wined3d-Allow-arbitrary-viewports-for-d3d11.patch + ( + printf '%s\n' '+ { "Michael Müller", "wined3d: Allow arbitrary viewports for d3d11.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset wined3d-Dual_Source_Blending +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * d3d11-Depth_Bias, wined3d-Core_Context, wined3d-Viewports +# | +# | Modified files: +# | * dlls/d3d11/tests/d3d11.c, dlls/wined3d/context.c, dlls/wined3d/directx.c, dlls/wined3d/glsl_shader.c, +# | dlls/wined3d/shader.c, dlls/wined3d/state.c, dlls/wined3d/wined3d_private.h +# | +if test "$enable_wined3d_Dual_Source_Blending" -eq 1; then + patch_apply wined3d-Dual_Source_Blending/0001-wined3d-Unroll-glsl-pixel-shader-output.patch + patch_apply wined3d-Dual_Source_Blending/0002-d3d11-tests-Add-basic-dual-source-blend-test.patch + patch_apply wined3d-Dual_Source_Blending/0003-wined3d-Implement-dual-source-blending.patch + ( + printf '%s\n' '+ { "Michael Müller", "wined3d: Unroll glsl pixel shader output.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "d3d11/tests: Add basic dual source blend test.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "wined3d: Implement dual source blending.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wined3d-QUERY_Stubs # | # | This patchset fixes the following Wine bugs: @@ -9653,8 +9719,8 @@ fi # | This patchset has the following (direct or indirect) dependencies: # | * d3d11-Deferred_Context, d3d9-Tests, makedep-PARENTSPEC, ntdll-Attach_Process_DLLs, ntdll-DllOverrides_WOW64, ntdll- # | Loader_Machine_Type, ntdll-DllRedirects, wined3d-1DTextures, wined3d-Accounting, d3d11-Depth_Bias, wined3d- -# | Copy_Resource_Typeless, wined3d-DXTn, wined3d-QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs, -# | wined3d-UAV_Counters +# | Copy_Resource_Typeless, wined3d-DXTn, wined3d-Core_Context, wined3d-Viewports, wined3d-Dual_Source_Blending, wined3d- +# | QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs, wined3d-UAV_Counters # | # | Modified files: # | * configure.ac, dlls/wined3d-csmt/Makefile.in, dlls/wined3d-csmt/version.rc @@ -9666,21 +9732,6 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then ) >> "$patchlist" fi -# Patchset wined3d-Core_Context -# | -# | This patchset has the following (direct or indirect) dependencies: -# | * d3d11-Depth_Bias -# | -# | Modified files: -# | * dlls/dxgi/factory.c, dlls/wined3d/directx.c, include/wine/wined3d.h -# | -if test "$enable_wined3d_Core_Context" -eq 1; then - patch_apply wined3d-Core_Context/0001-wined3d-Use-OpenGL-core-context-for-D3D10-11-when-ne.patch - ( - printf '%s\n' '+ { "Michael Müller", "wined3d: Use OpenGL core context for D3D10/11 when necessary.", 1 },'; - ) >> "$patchlist" -fi - # Patchset wined3d-draw_primitive_arrays # | # | Modified files: @@ -9745,22 +9796,6 @@ if test "$enable_wined3d_Limit_Vram" -eq 1; then ) >> "$patchlist" fi -# Patchset wined3d-Viewports -# | -# | This patchset has the following (direct or indirect) dependencies: -# | * d3d11-Depth_Bias, wined3d-Core_Context -# | -# | Modified files: -# | * dlls/d3d11/tests/d3d11.c, dlls/d3d8/directx.c, dlls/d3d9/directx.c, dlls/ddraw/ddraw_private.h, dlls/wined3d/state.c, -# | include/wine/wined3d.h -# | -if test "$enable_wined3d_Viewports" -eq 1; then - patch_apply wined3d-Viewports/0001-wined3d-Allow-arbitrary-viewports-for-d3d11.patch - ( - printf '%s\n' '+ { "Michael Müller", "wined3d: Allow arbitrary viewports for d3d11.", 1 },'; - ) >> "$patchlist" -fi - # Patchset wined3d-WINED3DFMT_R32G32_UINT # | # | Modified files: @@ -9857,8 +9892,8 @@ fi # | This patchset has the following (direct or indirect) dependencies: # | * d3d11-Deferred_Context, d3d9-Tests, makedep-PARENTSPEC, ntdll-Attach_Process_DLLs, ntdll-DllOverrides_WOW64, ntdll- # | Loader_Machine_Type, ntdll-DllRedirects, wined3d-1DTextures, wined3d-Accounting, d3d11-Depth_Bias, wined3d- -# | Copy_Resource_Typeless, wined3d-DXTn, wined3d-QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs, -# | wined3d-UAV_Counters, wined3d-CSMT_Helper +# | Copy_Resource_Typeless, wined3d-DXTn, wined3d-Core_Context, wined3d-Viewports, wined3d-Dual_Source_Blending, wined3d- +# | QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs, wined3d-UAV_Counters, wined3d-CSMT_Helper # | # | This patchset fixes the following Wine bugs: # | * [#11674] Support for CSMT (command stream) to increase graphic performance diff --git a/patches/wined3d-CSMT_Helper/definition b/patches/wined3d-CSMT_Helper/definition index 0965ea1a..6000b4fe 100644 --- a/patches/wined3d-CSMT_Helper/definition +++ b/patches/wined3d-CSMT_Helper/definition @@ -6,6 +6,7 @@ Depends: wined3d-Silence_FIXMEs Depends: wined3d-Revert_Buffer_Upload Depends: wined3d-Copy_Resource_Typeless Depends: wined3d-UAV_Counters +Depends: wined3d-Dual_Source_Blending Depends: d3d9-Tests Depends: d3d11-Deferred_Context Depends: makedep-PARENTSPEC diff --git a/patches/wined3d-CSMT_Main/0019-wined3d-Wrap-GL-BOs-in-a-structure.patch b/patches/wined3d-CSMT_Main/0019-wined3d-Wrap-GL-BOs-in-a-structure.patch index 8321eeb5..83152fca 100644 --- a/patches/wined3d-CSMT_Main/0019-wined3d-Wrap-GL-BOs-in-a-structure.patch +++ b/patches/wined3d-CSMT_Main/0019-wined3d-Wrap-GL-BOs-in-a-structure.patch @@ -1,4 +1,4 @@ -From 685ac4b76854b8e8960338c81a5f33d7e6d40fb2 Mon Sep 17 00:00:00 2001 +From ae25b3f25d761c757cf6170dfd674e9395eafaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Fri, 30 Aug 2013 17:00:35 +0200 Subject: wined3d: Wrap GL BOs in a structure @@ -13,10 +13,10 @@ them for DISCARD maps. 4 files changed, 93 insertions(+), 35 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index c05c8c51f2..0c81eeaced 100644 +index 0c6160a37e2..cc570c53f48 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c -@@ -5092,3 +5092,56 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL +@@ -5274,3 +5274,56 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL else return CallWindowProcA(proc, window, message, wparam, lparam); } @@ -74,10 +74,10 @@ index c05c8c51f2..0c81eeaced 100644 + wined3d_device_destroy_bo(device, context, bo); +} diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 1eea0e8bb0..f1a089e88f 100644 +index bf720295adc..3e5a0519da4 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -2405,7 +2405,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface, +@@ -2410,7 +2410,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface, /* Don't use PBOs for converted surfaces. During PBO conversion we look at * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is * getting called. */ @@ -87,10 +87,10 @@ index 1eea0e8bb0..f1a089e88f 100644 TRACE("Removing the pbo attached to surface %p.\n", surface); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 700e587f8d..0bcf64b87a 100644 +index b487f52ee34..f26d502a18e 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c -@@ -333,7 +333,7 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su +@@ -294,7 +294,7 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su if (locations & WINED3D_LOCATION_BUFFER) { data->addr = NULL; @@ -99,7 +99,7 @@ index 700e587f8d..0bcf64b87a 100644 return; } if (locations & WINED3D_LOCATION_USER_MEMORY) -@@ -434,18 +434,17 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc +@@ -395,18 +395,17 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc /* Context activation is done by the caller. */ static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, @@ -125,7 +125,7 @@ index 700e587f8d..0bcf64b87a 100644 } static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) -@@ -465,7 +464,7 @@ static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) +@@ -426,7 +425,7 @@ static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) && !wined3d_texture_load_location(texture, i, context, map_binding)) ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding)); if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER) @@ -134,7 +134,7 @@ index 700e587f8d..0bcf64b87a 100644 } if (context) -@@ -622,28 +621,25 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) +@@ -583,28 +582,25 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) unsigned int sub_count = texture->level_count * texture->layer_count; struct wined3d_device *device = texture->resource.device; struct wined3d_context *context = NULL; @@ -168,7 +168,7 @@ index 700e587f8d..0bcf64b87a 100644 } if (context) context_release(context); -@@ -1458,22 +1454,19 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT +@@ -1411,22 +1407,19 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT /* Context activation is done by the caller. */ static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, @@ -196,7 +196,7 @@ index 700e587f8d..0bcf64b87a 100644 } static void wined3d_texture_force_reload(struct wined3d_texture *texture) -@@ -1599,7 +1592,7 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned +@@ -1552,7 +1545,7 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned return TRUE; case WINED3D_LOCATION_BUFFER: @@ -205,7 +205,7 @@ index 700e587f8d..0bcf64b87a 100644 return TRUE; case WINED3D_LOCATION_TEXTURE_RGB: -@@ -1899,7 +1892,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in +@@ -1853,7 +1846,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in } else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) { @@ -214,7 +214,7 @@ index 700e587f8d..0bcf64b87a 100644 wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); -@@ -1944,7 +1937,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in +@@ -1898,7 +1891,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in case WINED3D_LOCATION_BUFFER: if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { @@ -223,7 +223,7 @@ index 700e587f8d..0bcf64b87a 100644 if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) wined3d_texture_bind_and_dirtify(texture, context, FALSE); -@@ -2238,8 +2231,8 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) +@@ -2192,8 +2185,8 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED); } @@ -234,7 +234,7 @@ index 700e587f8d..0bcf64b87a 100644 if (resource->type == WINED3D_RTYPE_TEXTURE_2D) { -@@ -3024,7 +3017,7 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in +@@ -2969,7 +2962,7 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in } else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) { @@ -243,7 +243,7 @@ index 700e587f8d..0bcf64b87a 100644 wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); -@@ -3070,7 +3063,7 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in +@@ -3015,7 +3008,7 @@ static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned in case WINED3D_LOCATION_BUFFER: if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { @@ -253,12 +253,12 @@ index 700e587f8d..0bcf64b87a 100644 if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) wined3d_texture_bind_and_dirtify(texture, context, FALSE); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ab73b02b11..11831b3d1f 100644 +index 079f18cf5d6..1d31146482b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2624,6 +2624,14 @@ struct wined3d_state - struct wined3d_rasterizer_state *rasterizer_state; - }; +@@ -2846,6 +2846,14 @@ static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, + return FALSE; + } +struct wined3d_gl_bo +{ @@ -271,7 +271,7 @@ index ab73b02b11..11831b3d1f 100644 #define WINED3D_UNMAPPED_STAGE ~0u /* Multithreaded flag. Removed from the public header to signal that -@@ -2735,6 +2743,10 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL +@@ -2957,6 +2965,10 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; @@ -282,7 +282,7 @@ index ab73b02b11..11831b3d1f 100644 static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) { -@@ -2926,7 +2938,7 @@ struct wined3d_texture +@@ -3144,7 +3156,7 @@ struct wined3d_texture unsigned int map_count; DWORD locations; @@ -292,5 +292,5 @@ index ab73b02b11..11831b3d1f 100644 }; -- -2.11.0 +2.14.1 diff --git a/patches/wined3d-CSMT_Main/9999-IfDefined.patch b/patches/wined3d-CSMT_Main/9999-IfDefined.patch index 240d8e04..7bee7985 100644 --- a/patches/wined3d-CSMT_Main/9999-IfDefined.patch +++ b/patches/wined3d-CSMT_Main/9999-IfDefined.patch @@ -619,9 +619,9 @@ diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2826,6 +2826,16 @@ struct wined3d_state - struct wined3d_rasterizer_state *rasterizer_state; - }; +@@ -2846,6 +2846,16 @@ static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, + return FALSE; + } +#if defined(STAGING_CSMT) +struct wined3d_gl_bo @@ -636,7 +636,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h #define WINED3D_UNMAPPED_STAGE ~0u /* Multithreaded flag. Removed from the public header to signal that -@@ -2937,6 +2947,12 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL +@@ -2957,6 +2967,12 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; @@ -649,7 +649,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) { -@@ -3124,7 +3140,11 @@ struct wined3d_texture +@@ -3144,7 +3160,11 @@ struct wined3d_texture unsigned int map_count; DWORD locations; @@ -661,7 +661,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h } sub_resources[1]; }; -@@ -3439,6 +3459,9 @@ struct wined3d_cs_queue +@@ -3459,6 +3479,9 @@ struct wined3d_cs_queue struct wined3d_cs_ops { diff --git a/patches/wined3d-Dual_Source_Blending/0001-wined3d-Unroll-glsl-pixel-shader-output.patch b/patches/wined3d-Dual_Source_Blending/0001-wined3d-Unroll-glsl-pixel-shader-output.patch new file mode 100644 index 00000000..0e7121ef --- /dev/null +++ b/patches/wined3d-Dual_Source_Blending/0001-wined3d-Unroll-glsl-pixel-shader-output.patch @@ -0,0 +1,167 @@ +From a69ce71584c83365fd9be94b5faef8d96937fa06 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 18 Aug 2017 19:55:37 +0200 +Subject: wined3d: Unroll glsl pixel shader output. + +--- + dlls/wined3d/glsl_shader.c | 58 ++++++++++++++++++++++++++-------------------- + 1 file changed, 33 insertions(+), 25 deletions(-) + +diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c +index 0f2f3052ec1..02f9fc1c7d1 100644 +--- a/dlls/wined3d/glsl_shader.c ++++ b/dlls/wined3d/glsl_shader.c +@@ -2142,11 +2142,6 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_ + declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", element_count); + } + +-static const char *get_fragment_output(const struct wined3d_gl_info *gl_info) +-{ +- return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out"; +-} +- + static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) + { + switch (primitive_type) +@@ -2904,7 +2899,8 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * + WARN("Write to render target %u, only %d supported.\n", + reg->idx[0].offset, gl_info->limits.buffers); + +- sprintf(register_name, "%s[%u]", get_fragment_output(gl_info), reg->idx[0].offset); ++ sprintf(register_name, needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[%u]" : "ps_out%u", ++ reg->idx[0].offset); + break; + + case WINED3DSPR_RASTOUT: +@@ -7153,20 +7149,20 @@ static void shader_glsl_generate_patch_constant_setup(struct wined3d_string_buff + static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info) + { +- const char *output = get_fragment_output(gl_info); ++ const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; + +- shader_addline(buffer, "tmp0.xyz = pow(%s[0].xyz, vec3(srgb_const0.x));\n", output); ++ shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(srgb_const0.x));\n", output); + shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n"); +- shader_addline(buffer, "tmp1.xyz = %s[0].xyz * vec3(srgb_const0.w);\n", output); +- shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s[0].xyz, vec3(srgb_const1.x));\n", output); +- shader_addline(buffer, "%s[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); +- shader_addline(buffer, "%s[0] = clamp(%s[0], 0.0, 1.0);\n", output, output); ++ shader_addline(buffer, "tmp1.xyz = %s.xyz * vec3(srgb_const0.w);\n", output); ++ shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s.xyz, vec3(srgb_const1.x));\n", output); ++ shader_addline(buffer, "%s.xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); ++ shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", output, output); + } + + static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode) + { +- const char *output = get_fragment_output(gl_info); ++ const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; + + switch (mode) + { +@@ -7191,13 +7187,15 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, + return; + } + +- shader_addline(buffer, "%s[0].xyz = mix(ffp_fog.color.xyz, %s[0].xyz, clamp(fog, 0.0, 1.0));\n", ++ shader_addline(buffer, "%s.xyz = mix(ffp_fog.color.xyz, %s.xyz, clamp(fog, 0.0, 1.0));\n", + output, output); + } + + static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func) + { ++ const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; ++ + /* alpha_func is the PASS condition, not the DISCARD condition. Instead of + * flipping all the operators here, just negate the comparison below. */ + static const char * const comparison_operator[] = +@@ -7216,8 +7214,8 @@ static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer + return; + + if (alpha_func != WINED3D_CMP_NEVER) +- shader_addline(buffer, "if (!(%s[0].a %s alpha_test_ref))\n", +- get_fragment_output(gl_info), comparison_operator[alpha_func - WINED3D_CMP_NEVER]); ++ shader_addline(buffer, "if (!(%s.a %s alpha_test_ref))\n", ++ output, comparison_operator[alpha_func - WINED3D_CMP_NEVER]); + shader_addline(buffer, " discard;\n"); + } + +@@ -7259,10 +7257,11 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in + const struct ps_compile_args *args) + { + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; ++ const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; + + /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */ + if (reg_maps->shader_version.major < 2) +- shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info)); ++ shader_addline(buffer, "%s = R0;\n", output); + + if (args->srgb_correction) + shader_glsl_generate_srgb_write_correction(buffer, gl_info); +@@ -7451,9 +7450,12 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context + + if (!needs_legacy_glsl_syntax(gl_info)) + { +- if (shader_glsl_use_explicit_attrib_location(gl_info)) +- shader_addline(buffer, "layout(location = 0) "); +- shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers); ++ for (i = 0; i < gl_info->limits.buffers; i++) ++ { ++ if (shader_glsl_use_explicit_attrib_location(gl_info)) ++ shader_addline(buffer, "layout(location = %u) ", i); ++ shader_addline(buffer, "out vec4 ps_out%u;\n", i); ++ } + } + + if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants) +@@ -9017,6 +9019,7 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un + static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv, + const struct ffp_frag_settings *settings, const struct wined3d_context *context) + { ++ const char *output = needs_legacy_glsl_syntax(context->gl_info) ? "gl_FragData[0]" : "ps_out0"; + struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers); + enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; +@@ -9105,7 +9108,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * + { + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = 0) "); +- shader_addline(buffer, "out vec4 ps_out[1];\n"); ++ shader_addline(buffer, "out vec4 ps_out0;\n"); + } + + shader_addline(buffer, "vec4 tmp0, tmp1;\n"); +@@ -9436,8 +9439,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * + } + } + +- shader_addline(buffer, "%s[0] = ffp_varying_specular * specular_enable + ret;\n", +- get_fragment_output(gl_info)); ++ shader_addline(buffer, "%s = ffp_varying_specular * specular_enable + ret;\n", output); + + if (settings->sRGB_write) + shader_glsl_generate_srgb_write_correction(buffer, gl_info); +@@ -9981,8 +9983,14 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const + + if (!needs_legacy_glsl_syntax(gl_info)) + { +- GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out")); +- checkGLcall("glBindFragDataLocation"); ++ for (i = 0; i < gl_info->limits.buffers; i++) ++ { ++ char var[12]; ++ ++ sprintf(var, "ps_out%u", i); ++ GL_EXTCALL(glBindFragDataLocation(program_id, i, var)); ++ checkGLcall("glBindFragDataLocation"); ++ } + } + } + +-- +2.14.1 + diff --git a/patches/wined3d-Dual_Source_Blending/0002-d3d11-tests-Add-basic-dual-source-blend-test.patch b/patches/wined3d-Dual_Source_Blending/0002-d3d11-tests-Add-basic-dual-source-blend-test.patch new file mode 100644 index 00000000..b1aa297b --- /dev/null +++ b/patches/wined3d-Dual_Source_Blending/0002-d3d11-tests-Add-basic-dual-source-blend-test.patch @@ -0,0 +1,197 @@ +From ef0eb02d3a0da38521d8024fd7abb8b4b7660247 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 18 Aug 2017 23:22:16 +0200 +Subject: d3d11/tests: Add basic dual source blend test. + +--- + dlls/d3d11/tests/d3d11.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 169 insertions(+) + +diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c +index b1bc6620c7f..0fd66957feb 100644 +--- a/dlls/d3d11/tests/d3d11.c ++++ b/dlls/d3d11/tests/d3d11.c +@@ -22101,6 +22101,174 @@ static void test_early_depth_stencil(void) + release_test_context(&test_context); + } + ++static void test_dual_blending(void) ++{ ++ struct d3d11_test_context test_context; ++ D3D11_TEXTURE2D_DESC texture_desc; ++ ID3D11Texture2D *render_target; ++ ID3D11RenderTargetView *rtv[2]; ++ ID3D11BlendState *blend_state; ++ ID3D11DeviceContext *context; ++ ID3D11VertexShader *vs; ++ ID3D11PixelShader *ps; ++ D3D11_BLEND_DESC desc; ++ ID3D11Device *device; ++ HRESULT hr; ++ ++ static const DWORD vs_code[] = ++ { ++#if 0 ++ struct output ++ { ++ float4 position : SV_PoSiTion; ++ float4 color0 : COLOR0; ++ float4 color1 : COLOR1; ++ }; ++ ++ void main(uint id : SV_VertexID, out output o) ++ { ++ float2 coords = float2((id << 1) & 2, id & 2); ++ o.position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); ++ o.color0 = float4(1.0f, 0.0f, 0.0f, 1.0f); ++ o.color1 = float4(0.0f, 1.0f, 0.0f, 1.0f); ++ } ++#endif ++ 0x43425844, 0x93c216a1, 0xbaa7e8d4, 0xd5368c6a, 0x4e889e07, 0x00000001, 0x00000224, 0x00000003, ++ 0x0000002c, 0x00000060, 0x000000cc, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, ++ 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978, ++ 0x4e47534f, 0x00000064, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003, ++ 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, ++ 0x0000005c, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5469536f, ++ 0x006e6f69, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000150, 0x00010040, 0x00000054, 0x04000060, ++ 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, ++ 0x001020f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000001, 0x07000029, ++ 0x00100012, 0x00000000, 0x0010100a, 0x00000000, 0x00004001, 0x00000001, 0x07000001, 0x00100012, ++ 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000002, 0x07000001, 0x00100042, 0x00000000, ++ 0x0010100a, 0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, 0x00000000, 0x00100086, ++ 0x00000000, 0x0f000032, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x00004002, 0x40000000, ++ 0xc0000000, 0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, ++ 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, ++ 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, ++ 0x08000036, 0x001020f2, 0x00000002, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, ++ 0x0100003e, ++ }; ++ static const DWORD ps_code[] = ++ { ++#if 0 ++ struct input ++ { ++ float4 position : SV_PoSiTiOn; ++ float4 color1 : COLOR1; ++ float4 color0 : COLOR0; ++ }; ++ ++ struct output ++ { ++ float4 target0 : SV_Target0; ++ float4 target1 : SV_Target1; ++ }; ++ ++ void main(const in input i, out output o) ++ { ++ o.target0 = i.color0; ++ o.target1 = i.color1; ++ } ++#endif ++ 0x43425844, 0x620ef963, 0xed8f19fe, 0x7b3a0a53, 0x126ce021, 0x00000001, 0x00000150, 0x00000003, ++ 0x0000002c, 0x00000098, 0x000000e4, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050, ++ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000001, 0x00000000, ++ 0x00000003, 0x00000001, 0x00000f0f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000002, ++ 0x00000f0f, 0x505f5653, 0x5469536f, 0x006e4f69, 0x4f4c4f43, 0xabab0052, 0x4e47534f, 0x00000044, ++ 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, ++ 0x00000038, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x545f5653, 0x65677261, ++ 0xabab0074, 0x52444853, 0x00000064, 0x00000040, 0x00000019, 0x03001062, 0x001010f2, 0x00000001, ++ 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, ++ 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, 0x05000036, 0x001020f2, ++ 0x00000001, 0x00101e46, 0x00000001, 0x0100003e, ++ }; ++ ++ static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; ++ ++ if (!init_test_context(&test_context, NULL)) ++ return; ++ ++ device = test_context.device; ++ context = test_context.immediate_context; ++ ++ hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs); ++ ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); ++ hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); ++ ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); ++ ++ ID3D11Texture2D_GetDesc(test_context.backbuffer, &texture_desc); ++ hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &render_target); ++ ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); ++ ++ rtv[0] = test_context.backbuffer_rtv; ++ hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)render_target, NULL, &rtv[1]); ++ ok(SUCCEEDED(hr), "Failed to create render target view, hr %#x.\n", hr); ++ ++ ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); ++ ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); ++ ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ++ ID3D11DeviceContext_OMSetRenderTargets(context, 2, rtv, NULL); ++ ++ ID3D11DeviceContext_ClearRenderTargetView(context, rtv[0], white); ++ ID3D11DeviceContext_ClearRenderTargetView(context, rtv[1], white); ++ ID3D11DeviceContext_Draw(context, 3, 0); ++ ++ check_texture_color(test_context.backbuffer, 0xff00ff00, 0); ++ check_texture_color(render_target, 0xff0000ff, 0); ++ ++ memset(&desc, 0, sizeof(desc)); ++ desc.AlphaToCoverageEnable = FALSE; ++ desc.IndependentBlendEnable = FALSE; ++ desc.RenderTarget[0].BlendEnable = TRUE; ++ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_COLOR; ++ desc.RenderTarget[0].DestBlend = D3D11_BLEND_SRC1_COLOR; ++ desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; ++ desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; ++ desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC1_ALPHA; ++ desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; ++ desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; ++ ++ hr = ID3D11Device_CreateBlendState(device, &desc, &blend_state); ++ ok(SUCCEEDED(hr), "Failed to create blend state, hr %#x.\n", hr); ++ ++ ID3D11DeviceContext_OMSetBlendState(context, blend_state, NULL, D3D11_DEFAULT_SAMPLE_MASK); ++ ID3D11DeviceContext_ClearRenderTargetView(context, rtv[0], white); ++ ID3D11DeviceContext_ClearRenderTargetView(context, rtv[1], white); ++ ID3D11DeviceContext_Draw(context, 3, 0); ++ ++ todo_wine check_texture_color(test_context.backbuffer, 0xff00ffff, 0); ++ todo_wine check_texture_color(render_target, 0xff0000ff, 0); ++ ++ ID3D11BlendState_Release(blend_state); ++ ++ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; ++ desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; ++ desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; ++ desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; ++ hr = ID3D11Device_CreateBlendState(device, &desc, &blend_state); ++ ok(SUCCEEDED(hr), "Failed to create blend state, hr %#x.\n", hr); ++ ++ ID3D11DeviceContext_OMSetBlendState(context, blend_state, NULL, D3D11_DEFAULT_SAMPLE_MASK); ++ ID3D11DeviceContext_ClearRenderTargetView(context, rtv[0], white); ++ ID3D11DeviceContext_ClearRenderTargetView(context, rtv[1], white); ++ ID3D11DeviceContext_Draw(context, 3, 0); ++ ++ check_texture_color(test_context.backbuffer, 0xff00ff00, 0); ++ check_texture_color(render_target, 0xff0000ff, 0); ++ ++ ID3D11BlendState_Release(blend_state); ++ ++ ID3D11RenderTargetView_Release(rtv[1]); ++ ID3D11Texture2D_Release(render_target); ++ ID3D11PixelShader_Release(ps); ++ ID3D11VertexShader_Release(vs); ++ release_test_context(&test_context); ++} ++ + START_TEST(d3d11) + { + test_create_device(); +@@ -22204,4 +22372,5 @@ START_TEST(d3d11) + test_fractional_viewports(); + test_negative_viewports(); + test_early_depth_stencil(); ++ test_dual_blending(); + } +-- +2.14.1 + diff --git a/patches/wined3d-Dual_Source_Blending/0003-wined3d-Implement-dual-source-blending.patch b/patches/wined3d-Dual_Source_Blending/0003-wined3d-Implement-dual-source-blending.patch new file mode 100644 index 00000000..6c48bc22 --- /dev/null +++ b/patches/wined3d-Dual_Source_Blending/0003-wined3d-Implement-dual-source-blending.patch @@ -0,0 +1,262 @@ +From ca21ad9fba3f8b30d42f8a69d72ccd4c75c9538a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 18 Aug 2017 23:51:59 +0200 +Subject: wined3d: Implement dual source blending. + +--- + dlls/d3d11/tests/d3d11.c | 2 +- + dlls/wined3d/context.c | 10 +++++++++- + dlls/wined3d/directx.c | 10 ++++++++++ + dlls/wined3d/glsl_shader.c | 45 ++++++++++++++++++++++++++++++++---------- + dlls/wined3d/shader.c | 2 ++ + dlls/wined3d/state.c | 12 ++++++++++- + dlls/wined3d/wined3d_private.h | 24 ++++++++++++++++++++-- + 7 files changed, 90 insertions(+), 15 deletions(-) + +diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c +index 4b956259462..c2192717eee 100644 +--- a/dlls/d3d11/tests/d3d11.c ++++ b/dlls/d3d11/tests/d3d11.c +@@ -21397,7 +21397,7 @@ static void test_dual_blending(void) + ID3D11DeviceContext_ClearRenderTargetView(context, rtv[1], white); + ID3D11DeviceContext_Draw(context, 3, 0); + +- todo_wine check_texture_color(test_context.backbuffer, 0xff00ffff, 0); ++ check_texture_color(test_context.backbuffer, 0xff00ffff, 0); + todo_wine check_texture_color(render_target, 0xff0000ff, 0); + + ID3D11BlendState_Release(blend_state); +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +index a2c0ba4080c..2ef75cf458b 100644 +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -3077,8 +3077,16 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const + else if (!context->render_offscreen) + return context_generate_rt_mask_from_resource(rts[0]->resource); + ++ /* If we attach more buffers than supported in dual blend mode, the NVIDIA ++ * driver generates the following error: ++ * GL_INVALID_OPERATION error generated. State(s) are invalid: blend. ++ * DX11 does not treat this configuration as invalid, so disable the unused ones. ++ */ + rt_mask = ps ? ps->reg_maps.rt_mask : 1; +- rt_mask &= context->d3d_info->valid_rt_mask; ++ if (wined3d_dualblend_enabled(state, context->gl_info)) ++ rt_mask &= context->d3d_info->valid_dual_rt_mask; ++ else ++ rt_mask &= context->d3d_info->valid_rt_mask; + rt_mask_bits = rt_mask; + i = 0; + while (rt_mask_bits) +diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c +index 962485b688a..bfd64b8f73c 100644 +--- a/dlls/wined3d/directx.c ++++ b/dlls/wined3d/directx.c +@@ -3500,6 +3500,12 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) + gl_info->limits.buffers = gl_max; + TRACE("Max draw buffers: %u.\n", gl_max); + } ++ if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) ++ { ++ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &gl_max); ++ gl_info->limits.dual_buffers = gl_max; ++ TRACE("Max dual source draw buffers: %u.\n", gl_max); ++ } + if (gl_info->supported[ARB_MULTITEXTURE]) + { + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) +@@ -4261,6 +4267,10 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, + for (i = 0; i < gl_info->limits.buffers; ++i) + adapter->d3d_info.valid_rt_mask |= (1u << i); + ++ adapter->d3d_info.valid_dual_rt_mask = 0; ++ for (i = 0; i < gl_info->limits.dual_buffers; ++i) ++ adapter->d3d_info.valid_dual_rt_mask |= (1u << i); ++ + if (!adapter->d3d_info.shader_color_key) + { + /* We do not want to deal with re-creating immutable texture storage for color keying emulation. */ +diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c +index eb6e539ed9d..8c9fae7432f 100644 +--- a/dlls/wined3d/glsl_shader.c ++++ b/dlls/wined3d/glsl_shader.c +@@ -2887,6 +2887,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * + break; + + case WINED3DSPR_COLOROUT: ++ /* FIXME: should check dual_buffers when dual blending is enabled */ + if (reg->idx[0].offset >= gl_info->limits.buffers) + WARN("Write to render target %u, only %d supported.\n", + reg->idx[0].offset, gl_info->limits.buffers); +@@ -7384,11 +7385,23 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context + + if (!needs_legacy_glsl_syntax(gl_info)) + { +- for (i = 0; i < gl_info->limits.buffers; i++) ++ if (args->dual_source_blend) + { +- if (shader_glsl_use_explicit_attrib_location(gl_info)) +- shader_addline(buffer, "layout(location = %u) ", i); +- shader_addline(buffer, "out vec4 ps_out%u;\n", i); ++ for (i = 0; i < gl_info->limits.dual_buffers * 2; i++) ++ { ++ if (shader_glsl_use_explicit_attrib_location(gl_info)) ++ shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2); ++ shader_addline(buffer, "out vec4 ps_out%u;\n", i); ++ } ++ } ++ else ++ { ++ for (i = 0; i < gl_info->limits.buffers; i++) ++ { ++ if (shader_glsl_use_explicit_attrib_location(gl_info)) ++ shader_addline(buffer, "layout(location = %u) ", i); ++ shader_addline(buffer, "out vec4 ps_out%u;\n", i); ++ } + } + } + +@@ -9917,13 +9930,25 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const + + if (!needs_legacy_glsl_syntax(gl_info)) + { +- for (i = 0; i < gl_info->limits.buffers; i++) +- { +- char var[12]; ++ char var[12]; + +- sprintf(var, "ps_out%u", i); +- GL_EXTCALL(glBindFragDataLocation(program_id, i, var)); +- checkGLcall("glBindFragDataLocation"); ++ if (wined3d_dualblend_enabled(state, gl_info)) ++ { ++ for (i = 0; i < gl_info->limits.dual_buffers * 2; i++) ++ { ++ sprintf(var, "ps_out%u", i); ++ GL_EXTCALL(glBindFragDataLocationIndexed(program_id, i / 2, i % 2, var)); ++ checkGLcall("glBindFragDataLocationIndexed"); ++ } ++ } ++ else ++ { ++ for (i = 0; i < gl_info->limits.buffers; i++) ++ { ++ sprintf(var, "ps_out%u", i); ++ GL_EXTCALL(glBindFragDataLocation(program_id, i, var)); ++ checkGLcall("glBindFragDataLocation"); ++ } + } + } + } +diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c +index 8ed2cb9ed97..be25be3c093 100644 +--- a/dlls/wined3d/shader.c ++++ b/dlls/wined3d/shader.c +@@ -3916,6 +3916,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 + + args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] + ? context->render_offscreen : 0; ++ ++ args->dual_source_blend = wined3d_dualblend_enabled(state, gl_info); + } + + static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, +diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c +index 53be418a623..c9148a51d40 100644 +--- a/dlls/wined3d/state.c ++++ b/dlls/wined3d/state.c +@@ -472,10 +472,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st + const struct wined3d_format *rt_format; + GLenum src_blend, dst_blend; + unsigned int rt_fmt_flags; ++ BOOL enable_dual_blend; + BOOL enable_blend; + + enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE]; +- if (enable_blend) ++ enable_dual_blend = wined3d_dualblend_enabled(state, context->gl_info); ++ ++ if (enable_blend && !enable_dual_blend) + { + rt_format = state->fb->render_targets[0]->format; + rt_fmt_flags = state->fb->render_targets[0]->format_flags; +@@ -487,6 +490,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st + enable_blend = FALSE; + } + ++ /* Dual state blending changes the assignment of the output variables */ ++ if (context->last_was_dual_blend != enable_dual_blend) ++ { ++ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; ++ context->last_was_dual_blend = enable_dual_blend; ++ } ++ + if (!enable_blend) + { + gl_info->gl_ops.gl.p_glDisable(GL_BLEND); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 74043d0a102..e1a764a0f35 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -191,6 +191,7 @@ struct wined3d_d3d_info + BOOL vs_clipping; + BOOL shader_color_key; + DWORD valid_rt_mask; ++ DWORD valid_dual_rt_mask; + DWORD wined3d_creation_flags; + BOOL shader_double_precision; + }; +@@ -1337,7 +1338,8 @@ struct ps_compile_args { + DWORD flatshading : 1; + DWORD alpha_test_func : 3; + DWORD render_offscreen : 1; +- DWORD padding : 26; ++ DWORD dual_source_blend : 1; ++ DWORD padding : 25; + }; + + enum fog_src_type { +@@ -1859,7 +1861,8 @@ struct wined3d_context + DWORD destroy_delayed : 1; + DWORD transform_feedback_active : 1; + DWORD transform_feedback_paused : 1; +- DWORD padding : 7; ++ DWORD last_was_dual_blend : 1; ++ DWORD padding : 6; + DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */ + DWORD shader_update_mask; + DWORD constant_update_mask; +@@ -2463,6 +2466,7 @@ struct wined3d_fbo_ops + struct wined3d_gl_limits + { + UINT buffers; ++ UINT dual_buffers; + UINT lights; + UINT textures; + UINT texture_coords; +@@ -2797,6 +2801,22 @@ struct wined3d_state + struct wined3d_rasterizer_state *rasterizer_state; + }; + ++static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, const struct wined3d_gl_info *gl_info) ++{ ++ if (!state->fb->render_targets[0]) return FALSE; ++ if (!state->render_states[WINED3D_RS_ALPHABLENDENABLE]) return FALSE; ++ if (!gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) return FALSE; ++ ++#define IS_DUAL_SOURCE_BLEND(x) ((x) >= WINED3D_BLEND_SRC1COLOR && (x) <= WINED3D_BLEND_INVSRC1ALPHA) ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLEND])) return TRUE; ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLEND])) return TRUE; ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLENDALPHA])) return TRUE; ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLENDALPHA])) return TRUE; ++#undef IS_DUAL_SOURCE_BLEND ++ ++ return FALSE; ++} ++ + #define WINED3D_UNMAPPED_STAGE ~0u + + /* Multithreaded flag. Removed from the public header to signal that +-- +2.14.1 + diff --git a/patches/wined3d-Dual_Source_Blending/definition b/patches/wined3d-Dual_Source_Blending/definition new file mode 100644 index 00000000..8a98c44e --- /dev/null +++ b/patches/wined3d-Dual_Source_Blending/definition @@ -0,0 +1,2 @@ +Fixes: Implement dual source blending in wined3d +Depends: wined3d-Viewports