Added patch to implement dual source blending in wined3d.

This commit is contained in:
Sebastian Lackner 2017-08-22 01:52:47 +02:00
parent 9fbebe7a46
commit bab383452b
8 changed files with 743 additions and 79 deletions

View File

@ -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

View File

@ -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

View File

@ -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?= <stefan@codeweavers.com>
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

View File

@ -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
{

View File

@ -0,0 +1,167 @@
From a69ce71584c83365fd9be94b5faef8d96937fa06 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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

View File

@ -0,0 +1,197 @@
From ef0eb02d3a0da38521d8024fd7abb8b4b7660247 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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

View File

@ -0,0 +1,262 @@
From ca21ad9fba3f8b30d42f8a69d72ccd4c75c9538a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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

View File

@ -0,0 +1,2 @@
Fixes: Implement dual source blending in wined3d
Depends: wined3d-Viewports