Added patch to implement support for indexed vertex blending.

This commit is contained in:
Sebastian Lackner 2017-09-02 04:31:04 +02:00
parent 7ad83e6e14
commit 83e5c37f16
12 changed files with 2081 additions and 25 deletions

View File

@ -452,6 +452,7 @@ patch_enable_all ()
enable_wined3d_DrawIndirect="$1"
enable_wined3d_Dual_Source_Blending="$1"
enable_wined3d_GTX_560M="$1"
enable_wined3d_Indexed_Vertex_Blending="$1"
enable_wined3d_Limit_Vram="$1"
enable_wined3d_QUERY_Stubs="$1"
enable_wined3d_Revert_Buffer_Upload="$1"
@ -1632,6 +1633,9 @@ patch_enable ()
wined3d-GTX_560M)
enable_wined3d_GTX_560M="$2"
;;
wined3d-Indexed_Vertex_Blending)
enable_wined3d_Indexed_Vertex_Blending="$2"
;;
wined3d-Limit_Vram)
enable_wined3d_Limit_Vram="$2"
;;
@ -2228,6 +2232,17 @@ if test "$enable_wined3d_conservative_depth" -eq 1; then
enable_wined3d_Copy_Resource_Typeless=1
fi
if test "$enable_wined3d_Indexed_Vertex_Blending" -eq 1; then
if test "$enable_wined3d_DrawIndirect" -gt 1; then
abort "Patchset wined3d-DrawIndirect disabled, but wined3d-Indexed_Vertex_Blending depends on that."
fi
if test "$enable_wined3d_WINED3D_RS_COLORWRITEENABLE" -gt 1; then
abort "Patchset wined3d-WINED3D_RS_COLORWRITEENABLE disabled, but wined3d-Indexed_Vertex_Blending depends on that."
fi
enable_wined3d_DrawIndirect=1
enable_wined3d_WINED3D_RS_COLORWRITEENABLE=1
fi
if test "$enable_wined3d_WINED3D_RS_COLORWRITEENABLE" -eq 1; then
if test "$enable_d3d11_Depth_Bias" -gt 1; then
abort "Patchset d3d11-Depth_Bias disabled, but wined3d-WINED3D_RS_COLORWRITEENABLE depends on that."
@ -9745,6 +9760,58 @@ if test "$enable_wined3d_GTX_560M" -eq 1; then
) >> "$patchlist"
fi
# Patchset wined3d-WINED3D_RS_COLORWRITEENABLE
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * d3d11-Depth_Bias
# |
# | Modified files:
# | * dlls/d3d11/device.c, dlls/d3d11/state.c, dlls/wined3d/context.c, dlls/wined3d/device.c, dlls/wined3d/drawprim.c,
# | dlls/wined3d/state.c, dlls/wined3d/stateblock.c, dlls/wined3d/surface.c, dlls/wined3d/utils.c,
# | dlls/wined3d/wined3d_private.h, include/wine/wined3d.h
# |
if test "$enable_wined3d_WINED3D_RS_COLORWRITEENABLE" -eq 1; then
patch_apply wined3d-WINED3D_RS_COLORWRITEENABLE/0001-wined3d-Implement-all-8-d3d11-color-write-masks.patch
(
printf '%s\n' '+ { "Michael Müller", "wined3d: Implement all 8 d3d11 color write masks.", 1 },';
) >> "$patchlist"
fi
# Patchset wined3d-Indexed_Vertex_Blending
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * wined3d-draw_primitive_arrays, wined3d-DrawIndirect, d3d11-Depth_Bias, wined3d-WINED3D_RS_COLORWRITEENABLE
# |
# | This patchset fixes the following Wine bugs:
# | * [#39057] Support for indexed vertex blending
# |
# | Modified files:
# | * dlls/d3d9/tests/visual.c, dlls/wined3d/device.c, dlls/wined3d/directx.c, dlls/wined3d/drawprim.c,
# | dlls/wined3d/glsl_shader.c, dlls/wined3d/utils.c, dlls/wined3d/vertexdeclaration.c, dlls/wined3d/wined3d_private.h
# |
if test "$enable_wined3d_Indexed_Vertex_Blending" -eq 1; then
patch_apply wined3d-Indexed_Vertex_Blending/0001-d3d9-tests-Add-test-for-indexed-vertex-blending.patch
patch_apply wined3d-Indexed_Vertex_Blending/0002-wined3d-Implement-hardware-indexed-vertex-blending-w.patch
patch_apply wined3d-Indexed_Vertex_Blending/0003-d3d9-tests-Test-normal-calculation-when-indexed-vert.patch
patch_apply wined3d-Indexed_Vertex_Blending/0004-wined3d-Fix-calculation-of-normal-when-vertex-blendi.patch
patch_apply wined3d-Indexed_Vertex_Blending/0005-wined3d-Move-matrix-inversion-functions-into-utils.c.patch
patch_apply wined3d-Indexed_Vertex_Blending/0006-wined3d-Implement-software-processing-for-indexed-ve.patch
patch_apply wined3d-Indexed_Vertex_Blending/0007-d3d9-tests-Check-MaxVertexBlendMatrixIndex-capabilit.patch
patch_apply wined3d-Indexed_Vertex_Blending/0008-wined3d-Report-correct-number-of-blend-matrices-when.patch
patch_apply wined3d-Indexed_Vertex_Blending/0009-wined3d-Track-updates-of-vertex-blend-matrices-separ.patch
(
printf '%s\n' '+ { "Paul Gofman", "d3d9/tests: Add test for indexed vertex blending.", 1 },';
printf '%s\n' '+ { "Paul Gofman", "wined3d: Implement hardware indexed vertex blending with 9 matrices.", 1 },';
printf '%s\n' '+ { "Michael Müller", "d3d9/tests: Test normal calculation when indexed vertex blending is enabled.", 1 },';
printf '%s\n' '+ { "Michael Müller", "wined3d: Fix calculation of normal when vertex blending is enabled.", 1 },';
printf '%s\n' '+ { "Michael Müller", "wined3d: Move matrix inversion functions into utils.c.", 1 },';
printf '%s\n' '+ { "Michael Müller", "wined3d: Implement software processing for indexed vertex blending.", 1 },';
printf '%s\n' '+ { "Michael Müller", "d3d9/tests: Check MaxVertexBlendMatrixIndex capability.", 1 },';
printf '%s\n' '+ { "Michael Müller", "wined3d: Report correct number of blend matrices when software vertex processing is used.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "wined3d: Track updates of vertex blend matrices separately.", 1 },';
) >> "$patchlist"
fi
# Patchset wined3d-Limit_Vram
# |
# | Modified files:
@ -9781,23 +9848,6 @@ if test "$enable_wined3d_WINED3DFMT_R32G32_UINT" -eq 1; then
) >> "$patchlist"
fi
# Patchset wined3d-WINED3D_RS_COLORWRITEENABLE
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * d3d11-Depth_Bias
# |
# | Modified files:
# | * dlls/d3d11/device.c, dlls/d3d11/state.c, dlls/wined3d/context.c, dlls/wined3d/device.c, dlls/wined3d/drawprim.c,
# | dlls/wined3d/state.c, dlls/wined3d/stateblock.c, dlls/wined3d/surface.c, dlls/wined3d/utils.c,
# | dlls/wined3d/wined3d_private.h, include/wine/wined3d.h
# |
if test "$enable_wined3d_WINED3D_RS_COLORWRITEENABLE" -eq 1; then
patch_apply wined3d-WINED3D_RS_COLORWRITEENABLE/0001-wined3d-Implement-all-8-d3d11-color-write-masks.patch
(
printf '%s\n' '+ { "Michael Müller", "wined3d: Implement all 8 d3d11 color write masks.", 1 },';
) >> "$patchlist"
fi
# Patchset wined3d-buffer_create
# |
# | Modified files:

View File

@ -198,7 +198,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
wined3d_device_delete_opengl_contexts(device);
if (device->fb.depth_stencil)
@@ -4220,6 +4223,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
@@ -4211,6 +4214,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
return WINED3DERR_INVALIDCALL;
}
@ -206,7 +206,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
if (dst_texture->sub_resources[dst_sub_resource_idx].map_count)
{
WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx);
@@ -4230,6 +4234,19 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
@@ -4221,6 +4225,19 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
{
WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx);
return WINED3DERR_INVALIDCALL;
@ -226,7 +226,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
}
if (!src_box)
@@ -4323,8 +4340,10 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
@@ -4314,8 +4331,10 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
return;
}
@ -237,7 +237,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
}
@@ -5273,3 +5292,58 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
@@ -5264,3 +5283,58 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
else
return CallWindowProcA(proc, window, message, wparam, lparam);
}
@ -619,7 +619,7 @@ 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
@@ -2846,6 +2846,16 @@ static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state,
@@ -2849,6 +2849,16 @@ static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state,
return FALSE;
}
@ -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
@@ -2957,6 +2967,12 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
@@ -2960,6 +2970,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)
{
@@ -3144,7 +3160,11 @@ struct wined3d_texture
@@ -3147,7 +3163,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];
};
@@ -3459,6 +3479,9 @@ struct wined3d_cs_queue
@@ -3462,6 +3482,9 @@ struct wined3d_cs_queue
struct wined3d_cs_ops
{

View File

@ -0,0 +1,282 @@
From f007c8f6a7fc3498d525c70a7f6e6540faf425c1 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Thu, 17 Aug 2017 17:46:50 +0300
Subject: d3d9/tests: Add test for indexed vertex blending.
---
dlls/d3d9/tests/visual.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 252 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 1de7e5d186b..9b845b5ad44 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19715,6 +19715,257 @@ done:
DestroyWindow(window);
}
+static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char *test_id_str)
+{
+ D3DCAPS9 caps;
+ D3DCOLOR color;
+ HRESULT hr;
+ unsigned int i;
+
+ static const D3DMATRIX view_mat =
+ {{{
+ 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ }}},
+ upper_left =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -4.0f, 4.0f, 0.0f, 1.0f
+ }}},
+ lower_left =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -4.0f, -4.0f, 0.0f, 1.0f
+ }}},
+ upper_right =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 4.0f, 4.0f, 0.0f, 1.0f
+ }}},
+ lower_right =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 4.0f, -4.0f, 0.0f, 1.0f
+ }}};
+
+ static const POINT quad_upper_right_points[] =
+ {
+ {576, 48}, {-1, -1},
+ },
+ quad_upper_right_empty_points[] =
+ {
+ {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
+ },
+ quad_center_points[] =
+ {
+ {320, 240}, {-1, -1}
+ },
+ quad_center_empty_points[] =
+ {
+ {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
+ },
+ quad_upper_center_points[] =
+ {
+ {320, 48}, {-1, -1}
+ },
+ quad_upper_center_empty_points[] =
+ {
+ {320, 240}, {64, 48}, {576, 48}, {-1, -1}
+ },
+ quad_fullscreen_points[] =
+ {
+ {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
+ },
+ quad_fullscreen_empty_points[] =
+ {
+ {-1, -1}
+ };
+
+ static const struct
+ {
+ struct
+ {
+ struct vec3 position;
+ struct vec3 blendweights;
+ DWORD matrixIndices;
+ }
+ vertex_data[4];
+ const POINT *quad_points;
+ const POINT *empty_points;
+ }
+ tests[] =
+ {
+ /* upper right */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405}},
+ quad_upper_right_points, quad_upper_right_empty_points
+ },
+ /* center */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405}},
+ quad_center_points, quad_center_empty_points
+ },
+ /* upper center */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405}},
+ quad_upper_center_points, quad_upper_center_empty_points
+ },
+ /* full screen */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405}},
+ quad_fullscreen_points, quad_fullscreen_empty_points
+ }
+ };
+
+ memset(&caps, 0, sizeof(caps));
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ if (caps.MaxVertexBlendMatrixIndex < 7 || caps.MaxVertexBlendMatrices < 4)
+ {
+ todo_wine win_skip("(%s) Too few vertex blend matrices supported: MaxVertexBlendMatrices=%u, MaxVertexBlendMatrixIndex=%u.\n",
+ test_id_str, caps.MaxVertexBlendMatrices, caps.MaxVertexBlendMatrixIndex);
+ return;
+ }
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x.\n", hr);
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x.\n", hr);
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(5), &upper_left);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x.\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(4), &lower_left);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x.\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(7), &lower_right);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x.\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(6), &upper_right);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x.\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetRenderState failed %08x.\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetRenderState D3DRS_INDEXEDVERTEXBLENDENABLE failed %08x.\n",
+ test_id_str, hr);
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
+ {
+ const POINT *point;
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
+ ok(SUCCEEDED(hr), "Failed to clear, hr %08x.\n", hr);
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4);
+ ok(SUCCEEDED(hr), "(%s) Failed to set FVF, hr %#x.\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data,
+ 6 * sizeof(float) + sizeof(DWORD));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ point = tests[i].quad_points;
+ while (point->x != -1 && point->y != -1)
+ {
+ color = getPixelColor(device, point->x, point->y);
+ ok(color_match(color, 0x00ffffff, 1), "(%s) Expected quad at %dx%d.\n", test_id_str, point->x, point->y);
+ ++point;
+ }
+
+ point = tests[i].empty_points;
+ while (point->x != -1 && point->y != -1)
+ {
+ color = getPixelColor(device, point->x, point->y);
+ ok(color_match(color, 0x00000000, 1), "(%s) Unexpected quad at %dx%d.\n", test_id_str, point->x, point->y);
+ ++point;
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
+ }
+}
+
+static void test_indexed_vertex_blending(void)
+{
+ D3DPRESENT_PARAMETERS present_parameters = {0};
+ IDirect3DDevice9 *device;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ HWND window;
+
+ window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 0, 0, 640, 480, NULL, NULL, NULL, NULL);
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+
+ present_parameters.Windowed = TRUE;
+ present_parameters.hDeviceWindow = window;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ present_parameters.BackBufferWidth = 640;
+ present_parameters.BackBufferHeight = 480;
+ present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
+ present_parameters.EnableAutoDepthStencil = TRUE;
+ present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
+
+ if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
+ {
+ do_test_indexed_vertex_blending(device,"IVB hardware");
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ }
+ else
+ skip("Failed to create a HAL device, skipping test.\n");
+
+ if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
+ {
+ do_test_indexed_vertex_blending(device,"IVB software");
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ }
+ else
+ skip("Failed to create a HAL device with software processing, skipping test.\n");
+
+ if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
+ {
+ do_test_indexed_vertex_blending(device,"IVB mixed");
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ }
+ else
+ skip("Failed to create a HAL device with mixed processing, skipping tests.\n");
+
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
static void test_updatetexture(void)
{
BOOL r32f_supported, ati2n_supported, do_visual_test;
@@ -22971,6 +23222,7 @@ START_TEST(visual)
test_multisample_mismatch();
test_texcoordindex();
test_vertex_blending();
+ test_indexed_vertex_blending();
test_updatetexture();
test_depthbias();
test_flip();
--
2.14.1

View File

@ -0,0 +1,218 @@
From 0b8b0f04a03d358ee4560502568a695641368812 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Sat, 26 Aug 2017 00:59:29 +0200
Subject: wined3d: Implement hardware indexed vertex blending with 9 matrices.
---
dlls/d3d9/tests/visual.c | 2 +-
dlls/wined3d/glsl_shader.c | 31 +++++++++++++++++++++----------
dlls/wined3d/utils.c | 3 +++
dlls/wined3d/vertexdeclaration.c | 9 +++++++++
dlls/wined3d/wined3d_private.h | 18 +++++++++++++++++-
5 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 9b845b5ad44..3575b0be2e8 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19844,7 +19844,7 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
if (caps.MaxVertexBlendMatrixIndex < 7 || caps.MaxVertexBlendMatrices < 4)
{
- todo_wine win_skip("(%s) Too few vertex blend matrices supported: MaxVertexBlendMatrices=%u, MaxVertexBlendMatrixIndex=%u.\n",
+ win_skip("(%s) Too few vertex blend matrices supported: MaxVertexBlendMatrices=%u, MaxVertexBlendMatrixIndex=%u.\n",
test_id_str, caps.MaxVertexBlendMatrices, caps.MaxVertexBlendMatrixIndex);
return;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 1aa23ee33ad..3e84ad0d717 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -144,7 +144,7 @@ struct glsl_vs_program
GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
GLint pos_fixup_location;
- GLint modelview_matrix_location[MAX_VERTEX_BLENDS];
+ GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS];
GLint projection_matrix_location;
GLint normal_matrix_location;
GLint texture_matrix_location[MAX_TEXTURES];
@@ -1786,7 +1786,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
{
struct wined3d_matrix mat;
- for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
+ for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
{
if (prog->vs.modelview_matrix_location[i] == -1)
break;
@@ -8519,8 +8519,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
{
{"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */
{"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */
- /* TODO: Indexed vertex blending */
- {"float", ""}, /* WINED3D_FFP_BLENDINDICES */
+ {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */
{"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */
{"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */
{"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */
@@ -8532,6 +8531,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
BOOL legacy_lighting = priv->legacy_lighting;
GLuint shader_obj;
unsigned int i;
+ char var[64];
string_buffer_clear(buffer);
@@ -8550,7 +8550,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
}
shader_addline(buffer, "\n");
- shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS);
+ shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n");
shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES);
@@ -8642,7 +8642,10 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
for (i = 0; i < settings->vertexblends + 1; ++i)
- shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i);
+ {
+ sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var);
+ }
shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
if (settings->clipping)
@@ -8666,7 +8669,10 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
else
{
for (i = 0; i < settings->vertexblends + 1; ++i)
- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i);
+ {
+ sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%s]) * ffp_attrib_normal);\n", i, var);
+ }
}
if (settings->normalize)
@@ -9539,7 +9545,7 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
- for (i = 0; i < MAX_VERTEX_BLENDS; ++i)
+ for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
{
string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
@@ -10114,7 +10120,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
| WINED3D_SHADER_CONST_FFP_PROJ;
- for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
+ for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
{
if (entry->vs.modelview_matrix_location[i] != -1)
{
@@ -11076,7 +11082,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info,
caps->ffp_generic_attributes = TRUE;
caps->max_active_lights = MAX_ACTIVE_LIGHTS;
caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
- caps->max_vertex_blend_matrix_index = 0;
+ caps->max_vertex_blend_matrix_index = MAX_VERTEX_INDEX_BLENDS - 1;
caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
| WINED3DVTXPCAPS_MATERIALSOURCE7
| WINED3DVTXPCAPS_VERTEXFOG
@@ -11494,6 +11500,11 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE },
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 5e29e7cd7a5..847429511b9 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -5810,6 +5810,9 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
break;
}
+ if (use_indexed_vertex_blending(state, si))
+ settings->vb_indices = 1;
+
settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE];
settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL));
diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
index 4fa6d54c37d..c6ab0ea09c9 100644
--- a/dlls/wined3d/vertexdeclaration.c
+++ b/dlls/wined3d/vertexdeclaration.c
@@ -119,6 +119,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e
return FALSE;
}
+ case WINED3D_DECL_USAGE_BLEND_INDICES:
+ switch(element->format)
+ {
+ case WINED3DFMT_R8G8B8A8_UINT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
case WINED3D_DECL_USAGE_NORMAL:
switch(element->format)
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2c40b2d9838..7c20934ad40 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -272,6 +272,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
#define MAX_UNORDERED_ACCESS_VIEWS 8
#define MAX_TGSM_REGISTERS 8192
#define MAX_VERTEX_BLENDS 4
+#define MAX_VERTEX_INDEX_BLENDS 9
#define MAX_MULTISAMPLE_TYPES 8
#define MAX_RENDER_TARGETS 8
@@ -2723,7 +2724,8 @@ struct wined3d_ffp_vs_settings
DWORD ortho_fog : 1;
DWORD flatshading : 1;
DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */
- DWORD padding : 2;
+ DWORD vb_indices : 1;
+ DWORD padding : 1;
DWORD texgen[MAX_TEXTURES];
};
@@ -4299,6 +4301,20 @@ static inline void *wined3d_calloc(SIZE_T count, SIZE_T size)
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * size);
}
+static inline BOOL use_indexed_vertex_blending(const struct wined3d_state *state, const struct wined3d_stream_info *si)
+{
+ if (!state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE])
+ return FALSE;
+
+ if (state->render_states[WINED3D_RS_VERTEXBLEND] == WINED3D_VBF_DISABLE)
+ return FALSE;
+
+ if (!(si->use_map & (1 << WINED3D_FFP_BLENDINDICES)) || !(si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT)))
+ return FALSE;
+
+ return TRUE;
+}
+
static inline BOOL use_vs(const struct wined3d_state *state)
{
/* Check state->vertex_declaration to allow this to be used before the
--
2.14.1

View File

@ -0,0 +1,221 @@
From ca7e96f08d1a718817dcb6f0527a5348161daf82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 31 Aug 2017 00:23:43 +0200
Subject: d3d9/tests: Test normal calculation when indexed vertex blending is
enabled.
---
dlls/d3d9/tests/visual.c | 115 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 93 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 3575b0be2e8..863a3c513de 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19717,6 +19717,7 @@ done:
static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char *test_id_str)
{
+ IDirect3DPixelShader9 *ps;
D3DCAPS9 caps;
D3DCOLOR color;
HRESULT hr;
@@ -19733,31 +19734,49 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
{{{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f, 0.0f,
-4.0f, 4.0f, 0.0f, 1.0f
}}},
lower_left =
{{{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f, 0.0f,
-4.0f, -4.0f, 0.0f, 1.0f
}}},
upper_right =
{{{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f, 0.0f,
4.0f, 4.0f, 0.0f, 1.0f
}}},
lower_right =
{{{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f, 0.0f,
4.0f, -4.0f, 0.0f, 1.0f
+ }}},
+ identity =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
}}};
+ static const DWORD normal_ps[] =
+ {
+ 0xffff0200, /* ps_2_0 */
+ 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
+ 0x0200001f, 0x80000000, 0xb0070000, /* dcl t0.xyz */
+ 0x02000001, 0x80170000, 0xb0e40000, /* mov_sat r0.xyz, t0 */
+ 0x02000001, 0x80080000, 0xa0000000, /* mov r0.w, c0.x */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+
static const POINT quad_upper_right_points[] =
{
{576, 48}, {-1, -1},
@@ -19798,6 +19817,7 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
struct vec3 position;
struct vec3 blendweights;
DWORD matrixIndices;
+ struct vec3 normal;
}
vertex_data[4];
const POINT *quad_points;
@@ -19807,34 +19827,34 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
{
/* upper right */
{
- {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
- {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
- {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
- {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405}},
+ {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}}},
quad_upper_right_points, quad_upper_right_empty_points
},
/* center */
{
- {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
- {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
- {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
- {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405}},
+ {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405, {0.0f, 0.0f, 1.0f}}},
quad_center_points, quad_center_empty_points
},
/* upper center */
{
- {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
- {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
- {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
- {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405}},
+ {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}}},
quad_upper_center_points, quad_upper_center_empty_points
},
/* full screen */
{
- {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, 0x06070405},
- {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0x06070405},
- {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 0x06070405},
- {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405}},
+ {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405, {0.0f, 0.0f, 1.0f}}},
quad_fullscreen_points, quad_fullscreen_empty_points
}
};
@@ -19869,21 +19889,32 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetRenderState D3DRS_INDEXEDVERTEXBLENDENABLE failed %08x.\n",
test_id_str, hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL | 1);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTextureStageState failed %08x.\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x.\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_CreatePixelShader(device, normal_ps, &ps);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_CreatePixelShader failed %08x.\n", test_id_str, hr);
+
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
{
const POINT *point;
+ hr = IDirect3DDevice9_SetPixelShader(device, NULL);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetPixelShader failed %08x.\n", test_id_str, hr);
+
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
ok(SUCCEEDED(hr), "Failed to clear, hr %08x.\n", hr);
hr = IDirect3DDevice9_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL);
ok(SUCCEEDED(hr), "(%s) Failed to set FVF, hr %#x.\n", test_id_str, hr);
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data,
- 6 * sizeof(float) + sizeof(DWORD));
+ 9 * sizeof(float) + sizeof(DWORD));
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
hr = IDirect3DDevice9_EndScene(device);
@@ -19907,7 +19938,47 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetPixelShader(device, ps);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetPixelShader failed %08x.\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
+ ok(SUCCEEDED(hr), "Failed to clear %08x.\n", hr);
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL);
+ ok(SUCCEEDED(hr), "(%s) Failed to set FVF, hr %#x.\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data,
+ 9 * sizeof(float) + sizeof(DWORD));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ point = tests[i].quad_points;
+ while (point->x != -1 && point->y != -1)
+ {
+ color = getPixelColor(device, point->x, point->y);
+ todo_wine ok(color_match(color, 0x0000007f, 1), "(%s) Expected color 0x0000007f at %dx%d, got 0x%08x.\n", test_id_str, point->x, point->y, color);
+ ++point;
+ }
+
+ point = tests[i].empty_points;
+ while (point->x != -1 && point->y != -1)
+ {
+ color = getPixelColor(device, point->x, point->y);
+ ok(color_match(color, 0x00000000, 1), "(%s) Expected color 0x00000000 at %dx%d, got 0x%08x", test_id_str, point->x, point->y, color);
+ ++point;
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
}
+
+ IDirect3DVertexShader9_Release(ps);
}
static void test_indexed_vertex_blending(void)
--
2.14.1

View File

@ -0,0 +1,173 @@
From c0e0cc096b8e0dab0b7734424816dc70dca35261 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 31 Aug 2017 01:00:04 +0200
Subject: wined3d: Fix calculation of normal when vertex blending is enabled.
---
dlls/d3d9/tests/visual.c | 2 +-
dlls/wined3d/glsl_shader.c | 76 +++++++++++++++++++++-------------------------
2 files changed, 36 insertions(+), 42 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 863a3c513de..49d519befb5 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19962,7 +19962,7 @@ static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char
while (point->x != -1 && point->y != -1)
{
color = getPixelColor(device, point->x, point->y);
- todo_wine ok(color_match(color, 0x0000007f, 1), "(%s) Expected color 0x0000007f at %dx%d, got 0x%08x.\n", test_id_str, point->x, point->y, color);
+ ok(color_match(color, 0x0000007f, 1), "(%s) Expected color 0x0000007f at %dx%d, got 0x%08x.\n", test_id_str, point->x, point->y, color);
++point;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 3e84ad0d717..2aa0d0db0a4 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -145,8 +145,8 @@ struct glsl_vs_program
GLint pos_fixup_location;
GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS];
+ GLint normal_matrix_location[MAX_VERTEX_INDEX_BLENDS];
GLint projection_matrix_location;
- GLint normal_matrix_location;
GLint texture_matrix_location[MAX_TEXTURES];
GLint material_ambient_location;
GLint material_diffuse_location;
@@ -1496,33 +1496,6 @@ static BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m)
return TRUE;
}
-static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context *context,
- const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- float mat[3 * 3];
- struct wined3d_matrix mv;
- unsigned int i, j;
-
- if (prog->vs.normal_matrix_location == -1)
- return;
-
- get_modelview_matrix(context, state, 0, &mv);
- if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
- invert_matrix_3d(&mv, &mv);
- else
- invert_matrix(&mv, &mv);
- /* Tests show that singular modelview matrices are used unchanged as normal
- * matrices on D3D3 and older. There seems to be no clearly consistent
- * behavior on newer D3D versions so always follow older ddraw behavior. */
- for (i = 0; i < 3; ++i)
- for (j = 0; j < 3; ++j)
- mat[i * 3 + j] = (&mv._11)[j * 4 + i];
-
- GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat));
- checkGLcall("glUniformMatrix3fv");
-}
-
static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context,
const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog)
{
@@ -1715,6 +1688,23 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps
GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r));
}
+/* Context activation is done by the caller. */
+static void get_normal_matrix(struct wined3d_context *context, struct wined3d_matrix *mat, float *normal)
+{
+ int i, j;
+
+ if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
+ invert_matrix_3d(mat, mat);
+ else
+ invert_matrix(mat, mat);
+ /* Tests show that singular modelview matrices are used unchanged as normal
+ * matrices on D3D3 and older. There seems to be no clearly consistent
+ * behavior on newer D3D versions so always follow older ddraw behavior. */
+ for (i = 0; i < 3; ++i)
+ for (j = 0; j < 3; ++j)
+ normal[i * 3 + j] = (&mat->_11)[j * 4 + i];
+}
+
/* Context activation is done by the caller (state handler). */
static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context,
const struct wined3d_state *state)
@@ -1725,6 +1715,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
const struct wined3d_gl_info *gl_info = context->gl_info;
struct shader_glsl_priv *priv = shader_priv;
float position_fixup[4];
+ float normal[3 * 3];
DWORD update_mask;
struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
@@ -1779,7 +1770,9 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11));
checkGLcall("glUniformMatrix4fv");
- shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog);
+ get_normal_matrix(context, &mat, normal);
+ GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[0], 1, FALSE, normal));
+ checkGLcall("glUniformMatrix3fv");
}
if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND)
@@ -1794,6 +1787,10 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
get_modelview_matrix(context, state, i, &mat);
GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
checkGLcall("glUniformMatrix4fv");
+
+ get_normal_matrix(context, &mat, normal);
+ GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1, FALSE, normal));
+ checkGLcall("glUniformMatrix3fv");
}
}
@@ -8551,8 +8548,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
shader_addline(buffer, "\n");
shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
+ shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
- shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n");
shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES);
shader_addline(buffer, "uniform struct\n{\n");
@@ -8662,17 +8659,10 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
if (settings->normal)
{
- if (!settings->vertexblends)
- {
- shader_addline(buffer, "normal = ffp_normal_matrix * ffp_attrib_normal;\n");
- }
- else
+ for (i = 0; i < settings->vertexblends + 1; ++i)
{
- for (i = 0; i < settings->vertexblends + 1; ++i)
- {
- sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%s]) * ffp_attrib_normal);\n", i, var);
- }
+ sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var);
}
if (settings->normalize)
@@ -9550,8 +9540,12 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
}
+ for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
+ {
+ string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i);
+ vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+ }
vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix"));
- vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix"));
for (i = 0; i < MAX_TEXTURES; ++i)
{
string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i);
--
2.14.1

View File

@ -0,0 +1,599 @@
From fadcafb0c6505447ba086d8dc4a6a024a040c61e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 31 Aug 2017 01:07:25 +0200
Subject: wined3d: Move matrix inversion functions into utils.c
---
dlls/wined3d/glsl_shader.c | 275 -----------------------------------------
dlls/wined3d/utils.c | 275 +++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 2 +
3 files changed, 277 insertions(+), 275 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 2aa0d0db0a4..aaca2f63441 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1221,281 +1221,6 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps
GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx));
}
-/* Taken and adapted from Mesa. */
-static BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
-{
- float pos, neg, t, det;
- struct wined3d_matrix temp;
-
- /* Calculate the determinant of upper left 3x3 submatrix and
- * determine if the matrix is singular. */
- pos = neg = 0.0f;
- t = in->_11 * in->_22 * in->_33;
- if (t >= 0.0f)
- pos += t;
- else
- neg += t;
-
- t = in->_21 * in->_32 * in->_13;
- if (t >= 0.0f)
- pos += t;
- else
- neg += t;
- t = in->_31 * in->_12 * in->_23;
- if (t >= 0.0f)
- pos += t;
- else
- neg += t;
-
- t = -in->_31 * in->_22 * in->_13;
- if (t >= 0.0f)
- pos += t;
- else
- neg += t;
- t = -in->_21 * in->_12 * in->_33;
- if (t >= 0.0f)
- pos += t;
- else
- neg += t;
-
- t = -in->_11 * in->_32 * in->_23;
- if (t >= 0.0f)
- pos += t;
- else
- neg += t;
-
- det = pos + neg;
-
- if (fabsf(det) < 1e-25f)
- return FALSE;
-
- det = 1.0f / det;
- temp._11 = (in->_22 * in->_33 - in->_32 * in->_23) * det;
- temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det;
- temp._13 = (in->_12 * in->_23 - in->_22 * in->_13) * det;
- temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det;
- temp._22 = (in->_11 * in->_33 - in->_31 * in->_13) * det;
- temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det;
- temp._31 = (in->_21 * in->_32 - in->_31 * in->_22) * det;
- temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det;
- temp._33 = (in->_11 * in->_22 - in->_21 * in->_12) * det;
-
- *out = temp;
- return TRUE;
-}
-
-static void swap_rows(float **a, float **b)
-{
- float *tmp = *a;
-
- *a = *b;
- *b = tmp;
-}
-
-static BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m)
-{
- float wtmp[4][8];
- float m0, m1, m2, m3, s;
- float *r0, *r1, *r2, *r3;
-
- r0 = wtmp[0];
- r1 = wtmp[1];
- r2 = wtmp[2];
- r3 = wtmp[3];
-
- r0[0] = m->_11;
- r0[1] = m->_12;
- r0[2] = m->_13;
- r0[3] = m->_14;
- r0[4] = 1.0f;
- r0[5] = r0[6] = r0[7] = 0.0f;
-
- r1[0] = m->_21;
- r1[1] = m->_22;
- r1[2] = m->_23;
- r1[3] = m->_24;
- r1[5] = 1.0f;
- r1[4] = r1[6] = r1[7] = 0.0f;
-
- r2[0] = m->_31;
- r2[1] = m->_32;
- r2[2] = m->_33;
- r2[3] = m->_34;
- r2[6] = 1.0f;
- r2[4] = r2[5] = r2[7] = 0.0f;
-
- r3[0] = m->_41;
- r3[1] = m->_42;
- r3[2] = m->_43;
- r3[3] = m->_44;
- r3[7] = 1.0f;
- r3[4] = r3[5] = r3[6] = 0.0f;
-
- /* Choose pivot - or die. */
- if (fabsf(r3[0]) > fabsf(r2[0]))
- swap_rows(&r3, &r2);
- if (fabsf(r2[0]) > fabsf(r1[0]))
- swap_rows(&r2, &r1);
- if (fabsf(r1[0]) > fabsf(r0[0]))
- swap_rows(&r1, &r0);
- if (r0[0] == 0.0f)
- return FALSE;
-
- /* Eliminate first variable. */
- m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
- s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
- s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
- s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
- s = r0[4];
- if (s != 0.0f)
- {
- r1[4] -= m1 * s;
- r2[4] -= m2 * s;
- r3[4] -= m3 * s;
- }
- s = r0[5];
- if (s != 0.0f)
- {
- r1[5] -= m1 * s;
- r2[5] -= m2 * s;
- r3[5] -= m3 * s;
- }
- s = r0[6];
- if (s != 0.0f)
- {
- r1[6] -= m1 * s;
- r2[6] -= m2 * s;
- r3[6] -= m3 * s;
- }
- s = r0[7];
- if (s != 0.0f)
- {
- r1[7] -= m1 * s;
- r2[7] -= m2 * s;
- r3[7] -= m3 * s;
- }
-
- /* Choose pivot - or die. */
- if (fabsf(r3[1]) > fabsf(r2[1]))
- swap_rows(&r3, &r2);
- if (fabsf(r2[1]) > fabsf(r1[1]))
- swap_rows(&r2, &r1);
- if (r1[1] == 0.0f)
- return FALSE;
-
- /* Eliminate second variable. */
- m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
- r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
- r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
- s = r1[4];
- if (s != 0.0f)
- {
- r2[4] -= m2 * s;
- r3[4] -= m3 * s;
- }
- s = r1[5];
- if (s != 0.0f)
- {
- r2[5] -= m2 * s;
- r3[5] -= m3 * s;
- }
- s = r1[6];
- if (s != 0.0f)
- {
- r2[6] -= m2 * s;
- r3[6] -= m3 * s;
- }
- s = r1[7];
- if (s != 0.0f)
- {
- r2[7] -= m2 * s;
- r3[7] -= m3 * s;
- }
-
- /* Choose pivot - or die. */
- if (fabsf(r3[2]) > fabsf(r2[2]))
- swap_rows(&r3, &r2);
- if (r2[2] == 0.0f)
- return FALSE;
-
- /* Eliminate third variable. */
- m3 = r3[2] / r2[2];
- r3[3] -= m3 * r2[3];
- r3[4] -= m3 * r2[4];
- r3[5] -= m3 * r2[5];
- r3[6] -= m3 * r2[6];
- r3[7] -= m3 * r2[7];
-
- /* Last check. */
- if (r3[3] == 0.0f)
- return FALSE;
-
- /* Back substitute row 3. */
- s = 1.0f / r3[3];
- r3[4] *= s;
- r3[5] *= s;
- r3[6] *= s;
- r3[7] *= s;
-
- /* Back substitute row 2. */
- m2 = r2[3];
- s = 1.0f / r2[2];
- r2[4] = s * (r2[4] - r3[4] * m2);
- r2[5] = s * (r2[5] - r3[5] * m2);
- r2[6] = s * (r2[6] - r3[6] * m2);
- r2[7] = s * (r2[7] - r3[7] * m2);
- m1 = r1[3];
- r1[4] -= r3[4] * m1;
- r1[5] -= r3[5] * m1;
- r1[6] -= r3[6] * m1;
- r1[7] -= r3[7] * m1;
- m0 = r0[3];
- r0[4] -= r3[4] * m0;
- r0[5] -= r3[5] * m0;
- r0[6] -= r3[6] * m0;
- r0[7] -= r3[7] * m0;
-
- /* Back substitute row 1. */
- m1 = r1[2];
- s = 1.0f / r1[1];
- r1[4] = s * (r1[4] - r2[4] * m1);
- r1[5] = s * (r1[5] - r2[5] * m1);
- r1[6] = s * (r1[6] - r2[6] * m1);
- r1[7] = s * (r1[7] - r2[7] * m1);
- m0 = r0[2];
- r0[4] -= r2[4] * m0;
- r0[5] -= r2[5] * m0;
- r0[6] -= r2[6] * m0;
- r0[7] -= r2[7] * m0;
-
- /* Back substitute row 0. */
- m0 = r0[1];
- s = 1.0f / r0[0];
- r0[4] = s * (r0[4] - r1[4] * m0);
- r0[5] = s * (r0[5] - r1[5] * m0);
- r0[6] = s * (r0[6] - r1[6] * m0);
- r0[7] = s * (r0[7] - r1[7] * m0);
-
- out->_11 = r0[4];
- out->_12 = r0[5];
- out->_13 = r0[6];
- out->_14 = r0[7];
- out->_21 = r1[4];
- out->_22 = r1[5];
- out->_23 = r1[6];
- out->_24 = r1[7];
- out->_31 = r2[4];
- out->_32 = r2[5];
- out->_33 = r2[6];
- out->_34 = r2[7];
- out->_41 = r3[4];
- out->_42 = r3[5];
- out->_43 = r3[6];
- out->_44 = r3[7];
-
- return TRUE;
-}
-
static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context,
const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog)
{
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 847429511b9..b2effb5c2ec 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -5234,6 +5234,281 @@ void multiply_matrix(struct wined3d_matrix *dst, const struct wined3d_matrix *sr
*dst = tmp;
}
+/* Taken and adapted from Mesa. */
+BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
+{
+ float pos, neg, t, det;
+ struct wined3d_matrix temp;
+
+ /* Calculate the determinant of upper left 3x3 submatrix and
+ * determine if the matrix is singular. */
+ pos = neg = 0.0f;
+ t = in->_11 * in->_22 * in->_33;
+ if (t >= 0.0f)
+ pos += t;
+ else
+ neg += t;
+
+ t = in->_21 * in->_32 * in->_13;
+ if (t >= 0.0f)
+ pos += t;
+ else
+ neg += t;
+ t = in->_31 * in->_12 * in->_23;
+ if (t >= 0.0f)
+ pos += t;
+ else
+ neg += t;
+
+ t = -in->_31 * in->_22 * in->_13;
+ if (t >= 0.0f)
+ pos += t;
+ else
+ neg += t;
+ t = -in->_21 * in->_12 * in->_33;
+ if (t >= 0.0f)
+ pos += t;
+ else
+ neg += t;
+
+ t = -in->_11 * in->_32 * in->_23;
+ if (t >= 0.0f)
+ pos += t;
+ else
+ neg += t;
+
+ det = pos + neg;
+
+ if (fabsf(det) < 1e-25f)
+ return FALSE;
+
+ det = 1.0f / det;
+ temp._11 = (in->_22 * in->_33 - in->_32 * in->_23) * det;
+ temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det;
+ temp._13 = (in->_12 * in->_23 - in->_22 * in->_13) * det;
+ temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det;
+ temp._22 = (in->_11 * in->_33 - in->_31 * in->_13) * det;
+ temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det;
+ temp._31 = (in->_21 * in->_32 - in->_31 * in->_22) * det;
+ temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det;
+ temp._33 = (in->_11 * in->_22 - in->_21 * in->_12) * det;
+
+ *out = temp;
+ return TRUE;
+}
+
+static void swap_rows(float **a, float **b)
+{
+ float *tmp = *a;
+
+ *a = *b;
+ *b = tmp;
+}
+
+BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m)
+{
+ float wtmp[4][8];
+ float m0, m1, m2, m3, s;
+ float *r0, *r1, *r2, *r3;
+
+ r0 = wtmp[0];
+ r1 = wtmp[1];
+ r2 = wtmp[2];
+ r3 = wtmp[3];
+
+ r0[0] = m->_11;
+ r0[1] = m->_12;
+ r0[2] = m->_13;
+ r0[3] = m->_14;
+ r0[4] = 1.0f;
+ r0[5] = r0[6] = r0[7] = 0.0f;
+
+ r1[0] = m->_21;
+ r1[1] = m->_22;
+ r1[2] = m->_23;
+ r1[3] = m->_24;
+ r1[5] = 1.0f;
+ r1[4] = r1[6] = r1[7] = 0.0f;
+
+ r2[0] = m->_31;
+ r2[1] = m->_32;
+ r2[2] = m->_33;
+ r2[3] = m->_34;
+ r2[6] = 1.0f;
+ r2[4] = r2[5] = r2[7] = 0.0f;
+
+ r3[0] = m->_41;
+ r3[1] = m->_42;
+ r3[2] = m->_43;
+ r3[3] = m->_44;
+ r3[7] = 1.0f;
+ r3[4] = r3[5] = r3[6] = 0.0f;
+
+ /* Choose pivot - or die. */
+ if (fabsf(r3[0]) > fabsf(r2[0]))
+ swap_rows(&r3, &r2);
+ if (fabsf(r2[0]) > fabsf(r1[0]))
+ swap_rows(&r2, &r1);
+ if (fabsf(r1[0]) > fabsf(r0[0]))
+ swap_rows(&r1, &r0);
+ if (r0[0] == 0.0f)
+ return FALSE;
+
+ /* Eliminate first variable. */
+ m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
+ s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
+ s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
+ s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
+ s = r0[4];
+ if (s != 0.0f)
+ {
+ r1[4] -= m1 * s;
+ r2[4] -= m2 * s;
+ r3[4] -= m3 * s;
+ }
+ s = r0[5];
+ if (s != 0.0f)
+ {
+ r1[5] -= m1 * s;
+ r2[5] -= m2 * s;
+ r3[5] -= m3 * s;
+ }
+ s = r0[6];
+ if (s != 0.0f)
+ {
+ r1[6] -= m1 * s;
+ r2[6] -= m2 * s;
+ r3[6] -= m3 * s;
+ }
+ s = r0[7];
+ if (s != 0.0f)
+ {
+ r1[7] -= m1 * s;
+ r2[7] -= m2 * s;
+ r3[7] -= m3 * s;
+ }
+
+ /* Choose pivot - or die. */
+ if (fabsf(r3[1]) > fabsf(r2[1]))
+ swap_rows(&r3, &r2);
+ if (fabsf(r2[1]) > fabsf(r1[1]))
+ swap_rows(&r2, &r1);
+ if (r1[1] == 0.0f)
+ return FALSE;
+
+ /* Eliminate second variable. */
+ m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
+ r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
+ r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
+ s = r1[4];
+ if (s != 0.0f)
+ {
+ r2[4] -= m2 * s;
+ r3[4] -= m3 * s;
+ }
+ s = r1[5];
+ if (s != 0.0f)
+ {
+ r2[5] -= m2 * s;
+ r3[5] -= m3 * s;
+ }
+ s = r1[6];
+ if (s != 0.0f)
+ {
+ r2[6] -= m2 * s;
+ r3[6] -= m3 * s;
+ }
+ s = r1[7];
+ if (s != 0.0f)
+ {
+ r2[7] -= m2 * s;
+ r3[7] -= m3 * s;
+ }
+
+ /* Choose pivot - or die. */
+ if (fabsf(r3[2]) > fabsf(r2[2]))
+ swap_rows(&r3, &r2);
+ if (r2[2] == 0.0f)
+ return FALSE;
+
+ /* Eliminate third variable. */
+ m3 = r3[2] / r2[2];
+ r3[3] -= m3 * r2[3];
+ r3[4] -= m3 * r2[4];
+ r3[5] -= m3 * r2[5];
+ r3[6] -= m3 * r2[6];
+ r3[7] -= m3 * r2[7];
+
+ /* Last check. */
+ if (r3[3] == 0.0f)
+ return FALSE;
+
+ /* Back substitute row 3. */
+ s = 1.0f / r3[3];
+ r3[4] *= s;
+ r3[5] *= s;
+ r3[6] *= s;
+ r3[7] *= s;
+
+ /* Back substitute row 2. */
+ m2 = r2[3];
+ s = 1.0f / r2[2];
+ r2[4] = s * (r2[4] - r3[4] * m2);
+ r2[5] = s * (r2[5] - r3[5] * m2);
+ r2[6] = s * (r2[6] - r3[6] * m2);
+ r2[7] = s * (r2[7] - r3[7] * m2);
+ m1 = r1[3];
+ r1[4] -= r3[4] * m1;
+ r1[5] -= r3[5] * m1;
+ r1[6] -= r3[6] * m1;
+ r1[7] -= r3[7] * m1;
+ m0 = r0[3];
+ r0[4] -= r3[4] * m0;
+ r0[5] -= r3[5] * m0;
+ r0[6] -= r3[6] * m0;
+ r0[7] -= r3[7] * m0;
+
+ /* Back substitute row 1. */
+ m1 = r1[2];
+ s = 1.0f / r1[1];
+ r1[4] = s * (r1[4] - r2[4] * m1);
+ r1[5] = s * (r1[5] - r2[5] * m1);
+ r1[6] = s * (r1[6] - r2[6] * m1);
+ r1[7] = s * (r1[7] - r2[7] * m1);
+ m0 = r0[2];
+ r0[4] -= r2[4] * m0;
+ r0[5] -= r2[5] * m0;
+ r0[6] -= r2[6] * m0;
+ r0[7] -= r2[7] * m0;
+
+ /* Back substitute row 0. */
+ m0 = r0[1];
+ s = 1.0f / r0[0];
+ r0[4] = s * (r0[4] - r1[4] * m0);
+ r0[5] = s * (r0[5] - r1[5] * m0);
+ r0[6] = s * (r0[6] - r1[6] * m0);
+ r0[7] = s * (r0[7] - r1[7] * m0);
+
+ out->_11 = r0[4];
+ out->_12 = r0[5];
+ out->_13 = r0[6];
+ out->_14 = r0[7];
+ out->_21 = r1[4];
+ out->_22 = r1[5];
+ out->_23 = r1[6];
+ out->_24 = r1[7];
+ out->_31 = r2[4];
+ out->_32 = r2[5];
+ out->_33 = r2[6];
+ out->_34 = r2[7];
+ out->_41 = r3[4];
+ out->_42 = r3[5];
+ out->_43 = r3[6];
+ out->_44 = r3[7];
+
+ return TRUE;
+}
+
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
DWORD size = 0;
int i;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7c20934ad40..08f4f01f7e6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3889,6 +3889,8 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DE
/* Math utils */
void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
const struct wined3d_matrix *src2) DECLSPEC_HIDDEN;
+BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in) DECLSPEC_HIDDEN;
+BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m) DECLSPEC_HIDDEN;
void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN;
--
2.14.1

View File

@ -0,0 +1,310 @@
From 97d6b11b95d8cdcc0d777b11f6f00e9d6054adfb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 31 Aug 2017 01:26:38 +0200
Subject: wined3d: Implement software processing for indexed vertex blending.
---
dlls/wined3d/device.c | 16 ------
dlls/wined3d/drawprim.c | 107 +++++++++++++++++++++++++++++++++++++++--
dlls/wined3d/glsl_shader.c | 32 ++++++++----
dlls/wined3d/utils.c | 7 ++-
dlls/wined3d/wined3d_private.h | 16 +++++-
5 files changed, 148 insertions(+), 30 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index d3ee3b0a839..31c7ea431d8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3963,31 +3963,15 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device
void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software)
{
- static BOOL warned;
-
TRACE("device %p, software %#x.\n", device, software);
- if (!warned)
- {
- FIXME("device %p, software %#x stub!\n", device, software);
- warned = TRUE;
- }
-
device->softwareVertexProcessing = software;
}
BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device *device)
{
- static BOOL warned;
-
TRACE("device %p.\n", device);
- if (!warned)
- {
- TRACE("device %p stub!\n", device);
- warned = TRUE;
- }
-
return device->softwareVertexProcessing;
}
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 51460e54d1a..6adb7934134 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -200,6 +200,101 @@ static void draw_primitive_arrays_indirect(struct wined3d_context *context, cons
checkGLcall("draw indirect");
}
+static const BYTE *software_vertex_blending(struct wined3d_context *context,
+ const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ unsigned int element_idx, unsigned int stride_idx, float *result)
+{
+#define SI_FORMAT(idx) (si->elements[(idx)].format->emit_idx)
+#define SI_PTR(idx1, idx2) (si->elements[(idx1)].data.addr + si->elements[(idx1)].stride * (idx2))
+
+ const float *data = (const float *)SI_PTR(element_idx, stride_idx);
+ float vector[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float cur_weight, weight_sum = 0.0f;
+ struct wined3d_matrix m;
+ const BYTE *blend_index;
+ const float *weights;
+ int i, num_weights;
+
+ if (element_idx != WINED3D_FFP_POSITION && element_idx != WINED3D_FFP_NORMAL)
+ return (BYTE *)data;
+
+ if (!use_indexed_vertex_blending(state, si) || !use_software_vertex_processing(context->device))
+ return (BYTE *)data;
+
+ if (!si->elements[WINED3D_FFP_BLENDINDICES].data.addr ||
+ !si->elements[WINED3D_FFP_BLENDWEIGHT].data.addr)
+ {
+ FIXME("no blend indices / weights set\n");
+ return (BYTE *)data;
+ }
+
+ if (SI_FORMAT(WINED3D_FFP_BLENDINDICES) != WINED3D_FFP_EMIT_UBYTE4)
+ {
+ FIXME("unsupported blend index format: %u\n", SI_FORMAT(WINED3D_FFP_BLENDINDICES));
+ return (BYTE *)data;
+ }
+
+ /* FIXME: validate weight format */
+ switch (state->render_states[WINED3D_RS_VERTEXBLEND])
+ {
+ case WINED3D_VBF_0WEIGHTS: num_weights = 0; break;
+ case WINED3D_VBF_1WEIGHTS: num_weights = 1; break;
+ case WINED3D_VBF_2WEIGHTS: num_weights = 2; break;
+ case WINED3D_VBF_3WEIGHTS: num_weights = 3; break;
+ default:
+ FIXME("unsupported vertex blend render state: %u\n", state->render_states[WINED3D_RS_VERTEXBLEND]);
+ return (BYTE *)data;
+ }
+
+ switch (SI_FORMAT(element_idx))
+ {
+ case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3];
+ case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2];
+ case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1];
+ case WINED3D_FFP_EMIT_FLOAT1: vector[0] = data[0]; break;
+ default:
+ FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx));
+ return (BYTE *)data;
+ }
+
+ blend_index = SI_PTR(WINED3D_FFP_BLENDINDICES, stride_idx);
+ weights = (const float *)SI_PTR(WINED3D_FFP_BLENDWEIGHT, stride_idx);
+ result[0] = result[1] = result[2] = result[3] = 0.0f;
+
+ for (i = 0; i < num_weights + 1; i++)
+ {
+ cur_weight = (i < num_weights) ? weights[i] : 1.0f - weight_sum;
+ get_modelview_matrix(context, state, blend_index[i], &m);
+
+ if (element_idx == WINED3D_FFP_POSITION)
+ {
+ result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._21 + vector[2] * m._31 + vector[3] * m._41);
+ result[1] += cur_weight * (vector[0] * m._12 + vector[1] * m._22 + vector[2] * m._32 + vector[3] * m._42);
+ result[2] += cur_weight * (vector[0] * m._13 + vector[1] * m._23 + vector[2] * m._33 + vector[3] * m._43);
+ result[3] += cur_weight * (vector[0] * m._14 + vector[1] * m._24 + vector[2] * m._34 + vector[3] * m._44);
+ }
+ else
+ {
+ if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
+ invert_matrix_3d(&m, &m);
+ else
+ invert_matrix(&m, &m);
+
+ /* multiply with transposed M */
+ result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._12 + vector[2] * m._13);
+ result[1] += cur_weight * (vector[0] * m._21 + vector[1] * m._22 + vector[2] * m._23);
+ result[2] += cur_weight * (vector[0] * m._31 + vector[1] * m._32 + vector[2] * m._33);
+ }
+
+ weight_sum += weights[i];
+ }
+
+#undef SI_FORMAT
+#undef SI_PTR
+
+ return (BYTE *)result;
+}
+
static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size,
unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx)
{
@@ -228,6 +323,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
BOOL specular_fog = FALSE;
BOOL ps = use_ps(state);
const void *ptr;
+ float tmp[4];
static unsigned int once;
@@ -264,7 +360,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
if (!(use_map & 1u << element_idx))
continue;
- ptr = si->elements[element_idx].data.addr + si->elements[element_idx].stride * stride_idx;
+ ptr = software_vertex_blending(context, state, si, element_idx, stride_idx, tmp);
ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr);
}
}
@@ -376,7 +472,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
if (normal)
{
- ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride;
+ ptr = software_vertex_blending(context, state, si, WINED3D_FFP_NORMAL, stride_idx, tmp);
ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr);
}
@@ -421,7 +517,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
if (position)
{
- ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride;
+ ptr = software_vertex_blending(context, state, si, WINED3D_FFP_POSITION, stride_idx, tmp);
ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr);
}
}
@@ -636,6 +732,11 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
emulation = TRUE;
}
+ else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device))
+ {
+ WARN_(d3d_perf)("Using software emulation because application requested SVP.\n");
+ emulation = TRUE;
+ }
if (emulation)
{
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index aaca2f63441..a3050590dfb 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -8359,14 +8359,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
}
else
{
- for (i = 0; i < settings->vertexblends; ++i)
- shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
+ if (!settings->sw_blending)
+ {
+ for (i = 0; i < settings->vertexblends; ++i)
+ shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
- shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
- for (i = 0; i < settings->vertexblends + 1; ++i)
+ shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
+ for (i = 0; i < settings->vertexblends + 1; ++i)
+ {
+ sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var);
+ }
+ }
+ else
{
- sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
- shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var);
+ shader_addline(buffer, "vec4 ec_pos = ffp_attrib_position;\n");
}
shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
@@ -8384,10 +8391,17 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
if (settings->normal)
{
- for (i = 0; i < settings->vertexblends + 1; ++i)
+ if (!settings->sw_blending)
+ {
+ for (i = 0; i < settings->vertexblends + 1; ++i)
+ {
+ sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
+ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var);
+ }
+ }
+ else
{
- sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var);
+ shader_addline(buffer, "normal = ffp_attrib_normal;\n");
}
if (settings->normalize)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index b2effb5c2ec..438dfc6fef3 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6086,7 +6086,12 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
}
if (use_indexed_vertex_blending(state, si))
- settings->vb_indices = 1;
+ {
+ if (use_software_vertex_processing(context->device))
+ settings->sw_blending = 1;
+ else
+ settings->vb_indices = 1;
+ }
settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE];
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 08f4f01f7e6..a2be7326834 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2725,7 +2725,7 @@ struct wined3d_ffp_vs_settings
DWORD flatshading : 1;
DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */
DWORD vb_indices : 1;
- DWORD padding : 1;
+ DWORD sw_blending : 1;
DWORD texgen[MAX_TEXTURES];
};
@@ -4317,6 +4317,20 @@ static inline BOOL use_indexed_vertex_blending(const struct wined3d_state *state
return TRUE;
}
+static inline BOOL use_software_vertex_processing(const struct wined3d_device *device)
+{
+ if (device->shader_backend != &glsl_shader_backend)
+ return FALSE;
+
+ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
+ return TRUE;
+
+ if (!(device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING))
+ return FALSE;
+
+ return device->softwareVertexProcessing;
+}
+
static inline BOOL use_vs(const struct wined3d_state *state)
{
/* Check state->vertex_declaration to allow this to be used before the
--
2.14.1

View File

@ -0,0 +1,68 @@
From 910fbdd6cd674e2ba1c9ca201787540db9de10f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 31 Aug 2017 01:47:49 +0200
Subject: d3d9/tests: Check MaxVertexBlendMatrixIndex capability.
---
dlls/d3d9/tests/visual.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 49d519befb5..e7e6cf6e9e9 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19987,7 +19987,9 @@ static void test_indexed_vertex_blending(void)
IDirect3DDevice9 *device;
IDirect3D9 *d3d;
ULONG refcount;
+ D3DCAPS9 caps;
HWND window;
+ HRESULT hr;
window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480, NULL, NULL, NULL, NULL);
@@ -20016,7 +20018,14 @@ static void test_indexed_vertex_blending(void)
if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
{
+ memset(&caps, 0, sizeof(caps));
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ todo_wine ok(caps.MaxVertexBlendMatrixIndex == 255, "Expected 255 as maximum blend matrix index, got %u.\n",
+ caps.MaxVertexBlendMatrixIndex);
+
do_test_indexed_vertex_blending(device,"IVB software");
+
refcount = IDirect3DDevice9_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
}
@@ -20026,7 +20035,26 @@ static void test_indexed_vertex_blending(void)
if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
{
+ memset(&caps, 0, sizeof(caps));
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ ok(caps.MaxVertexBlendMatrixIndex < 255, "Expected less than 255 as maximum blend matrix index, got %u.\n",
+ caps.MaxVertexBlendMatrixIndex);
+
+ hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, TRUE);
+ ok(SUCCEEDED(hr), "Failed to enable software processing, hr %#x.\n", hr);
+
+ memset(&caps, 0, sizeof(caps));
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ todo_wine ok(caps.MaxVertexBlendMatrixIndex == 255, "Expected 255 as maximum blend matrix index, got %u.\n",
+ caps.MaxVertexBlendMatrixIndex);
+
+ hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable software processing, hr %#x.\n", hr);
+
do_test_indexed_vertex_blending(device,"IVB mixed");
+
refcount = IDirect3DDevice9_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
}
--
2.14.1

View File

@ -0,0 +1,76 @@
From 405f1ca63e69fb5d9143ea26ec375ffef815e0a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 31 Aug 2017 01:54:22 +0200
Subject: wined3d: Report correct number of blend matrices when software vertex
processing is used.
---
dlls/d3d9/tests/visual.c | 4 ++--
dlls/wined3d/device.c | 9 ++++++++-
dlls/wined3d/directx.c | 5 ++++-
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index e7e6cf6e9e9..1c219ab7cf4 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -20021,7 +20021,7 @@ static void test_indexed_vertex_blending(void)
memset(&caps, 0, sizeof(caps));
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
- todo_wine ok(caps.MaxVertexBlendMatrixIndex == 255, "Expected 255 as maximum blend matrix index, got %u.\n",
+ ok(caps.MaxVertexBlendMatrixIndex == 255, "Expected 255 as maximum blend matrix index, got %u.\n",
caps.MaxVertexBlendMatrixIndex);
do_test_indexed_vertex_blending(device,"IVB software");
@@ -20047,7 +20047,7 @@ static void test_indexed_vertex_blending(void)
memset(&caps, 0, sizeof(caps));
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
- todo_wine ok(caps.MaxVertexBlendMatrixIndex == 255, "Expected 255 as maximum blend matrix index, got %u.\n",
+ ok(caps.MaxVertexBlendMatrixIndex == 255, "Expected 255 as maximum blend matrix index, got %u.\n",
caps.MaxVertexBlendMatrixIndex);
hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, FALSE);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 31c7ea431d8..6b92bc679c2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3530,10 +3530,17 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
{
+ HRESULT hr;
+
TRACE("device %p, caps %p.\n", device, caps);
- return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
+ hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
device->create_parms.device_type, caps);
+
+ if (SUCCEEDED(hr) && use_software_vertex_processing(device))
+ caps->MaxVertexBlendMatrixIndex = 255;
+
+ return hr;
}
HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index a34ead003cc..fe12e81b915 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -5981,7 +5981,10 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
caps->MaxUserClipPlanes = vertex_caps.max_user_clip_planes;
caps->MaxActiveLights = vertex_caps.max_active_lights;
caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices;
- caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index;
+ if (device_type == WINED3D_DEVICE_TYPE_HAL)
+ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index;
+ else
+ caps->MaxVertexBlendMatrixIndex = 255;
caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps;
caps->FVFCaps = vertex_caps.fvf_caps;
caps->RasterCaps |= vertex_caps.raster_caps;
--
2.14.1

View File

@ -0,0 +1,56 @@
From 8a4c30330dab1a81ffd0bd51215ffdd2f6bf9a61 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 31 Aug 2017 07:42:31 +0200
Subject: wined3d: Track updates of vertex blend matrices separately.
---
dlls/wined3d/glsl_shader.c | 5 ++++-
dlls/wined3d/wined3d_private.h | 3 ++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index a3050590dfb..31b892faf65 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1508,6 +1508,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
{
if (prog->vs.modelview_matrix_location[i] == -1)
break;
+ if (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i)))
+ continue;
get_modelview_matrix(context, state, i, &mat);
GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
@@ -11002,7 +11004,8 @@ static void glsl_vertex_pipe_world(struct wined3d_context *context,
static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
- context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
+ int i = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
+ context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i);
}
static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a2be7326834..5089e6b8c32 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -435,13 +435,14 @@ enum wined3d_shader_resource_type
#define WINED3D_SHADER_CONST_PS_Y_CORR 0x00001000
#define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00002000
#define WINED3D_SHADER_CONST_FFP_MODELVIEW 0x00004000
-#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0x00008000
#define WINED3D_SHADER_CONST_FFP_PROJ 0x00010000
#define WINED3D_SHADER_CONST_FFP_TEXMATRIX 0x00020000
#define WINED3D_SHADER_CONST_FFP_MATERIAL 0x00040000
#define WINED3D_SHADER_CONST_FFP_LIGHTS 0x00080000
#define WINED3D_SHADER_CONST_FFP_PS 0x00100000
#define WINED3D_SHADER_CONST_FFP_COLOR_KEY 0x00200000
+#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0xff000000
+#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i) (0x01000000 << ((i) - 1))
enum wined3d_shader_register_type
{
--
2.14.1

View File

@ -0,0 +1,3 @@
Fixes: [39057] Support for indexed vertex blending
Depends: wined3d-WINED3D_RS_COLORWRITEENABLE
Depends: wined3d-DrawIndirect