From db88c8fc7440ddab35c8916c4986d536c338ff2e Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Feb 2019 15:05:12 +0300
Subject: [PATCH 4/5] wined3d: Support SWVP vertex shader constants limit in
 state tracking.

Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
 dlls/d3d9/tests/device.c       |  5 -----
 dlls/d3d9/tests/visual.c       |  1 -
 dlls/wined3d/device.c          | 16 ++++++++++++----
 dlls/wined3d/glsl_shader.c     |  2 +-
 dlls/wined3d/stateblock.c      |  6 +++---
 dlls/wined3d/wined3d_private.h |  8 ++++----
 6 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index f79f26125c..463ad3b34c 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -6437,13 +6437,10 @@ static void test_vertex_shader_constant(void)
     ok(consts_swvp == 8192, "Unexpected consts_swvp %u.\n", consts_swvp);
 
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
-    todo_wine
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
-    todo_wine
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
-    todo_wine
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
@@ -6468,7 +6465,6 @@ static void test_vertex_shader_constant(void)
 
     IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
-    todo_wine
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
@@ -6476,7 +6472,6 @@ static void test_vertex_shader_constant(void)
     IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
 
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
-    todo_wine
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 8be58bfc63..740c4c565f 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -24705,7 +24705,6 @@ static void test_mvp_software_vertex_shaders(void)
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
-    todo_wine
     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
 
     hr = IDirect3DDevice9_BeginScene(device);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 23796f712d..393f515796 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2533,13 +2533,17 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device,
         unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants)
 {
     const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+    unsigned int constants_count;
     unsigned int i;
 
     TRACE("device %p, start_idx %u, count %u, constants %p.\n",
             device, start_idx, count, constants);
 
-    if (!constants || start_idx >= d3d_info->limits.vs_uniform_count
-            || count > d3d_info->limits.vs_uniform_count - start_idx)
+    constants_count = device->create_parms.flags
+            & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING)
+            ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count;
+    if (!constants || start_idx >= constants_count
+            || count > constants_count - start_idx)
         return WINED3DERR_INVALIDCALL;
 
     memcpy(&device->update_stateblock_state->vs_consts_f[start_idx], constants, count * sizeof(*constants));
@@ -2566,12 +2570,16 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device
         unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants)
 {
     const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+    unsigned int constants_count;
 
     TRACE("device %p, start_idx %u, count %u, constants %p.\n",
             device, start_idx, count, constants);
 
-    if (!constants || start_idx >= d3d_info->limits.vs_uniform_count
-            || count > d3d_info->limits.vs_uniform_count - start_idx)
+    constants_count = device->create_parms.flags
+            & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING)
+            ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count;
+    if (!constants || start_idx >= constants_count
+            || count > constants_count - start_idx)
         return WINED3DERR_INVALIDCALL;
 
     memcpy(constants, &device->state.vs_consts_f[start_idx], count * sizeof(*constants));
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 2298d75cef..d0da94b553 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2170,7 +2170,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev
     if (priv->consts_ubo)
         return;
 
-    for (i = start; i < count + start; ++i)
+    for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i)
     {
         update_heap_entry(heap, i, priv->next_constant_version);
     }
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index ec79e68eeb..5f87d864d7 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -316,7 +316,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
         }
     }
 
-    for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
+    for (i = 0; i < d3d_info->limits.vs_uniform_count_swvp; ++i)
     {
         if (stateblock->changed.vs_consts_f[i])
         {
@@ -1579,7 +1579,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
             stateblock_init_lights(stateblock->stateblock_state.light_state.light_map,
                     device->stateblock_state.light_state.light_map);
             stateblock_savedstates_set_all(&stateblock->changed,
-                    d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count);
+                    d3d_info->limits.vs_uniform_count_swvp, d3d_info->limits.ps_uniform_count);
             break;
 
         case WINED3D_SBT_PIXEL_STATE:
@@ -1591,7 +1591,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
             stateblock_init_lights(stateblock->stateblock_state.light_state.light_map,
                     device->stateblock_state.light_state.light_map);
             stateblock_savedstates_set_vertex(&stateblock->changed,
-                    d3d_info->limits.vs_uniform_count);
+                    d3d_info->limits.vs_uniform_count_swvp);
             break;
 
         default:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 49746f3dfd..8170869bc9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2975,7 +2975,7 @@ struct wined3d_state
 
     BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
     struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
-    struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
 
     BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
     struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
@@ -3031,7 +3031,7 @@ struct wined3d_stateblock_state
     int base_vertex_index;
 
     struct wined3d_shader *vs;
-    struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
     struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
     BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
 
@@ -3625,7 +3625,7 @@ struct wined3d_saved_states
     BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
     WORD vertexShaderConstantsB;                /* WINED3D_MAX_CONSTS_B, 16 */
     WORD vertexShaderConstantsI;                /* WINED3D_MAX_CONSTS_I, 16 */
-    BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
     DWORD textures : 20;                        /* WINED3D_MAX_COMBINED_SAMPLERS, 20 */
     DWORD indices : 1;
     DWORD material : 1;
@@ -3661,7 +3661,7 @@ struct wined3d_stateblock
     unsigned int              num_contained_vs_consts_i;
     DWORD                     contained_vs_consts_b[WINED3D_MAX_CONSTS_B];
     unsigned int              num_contained_vs_consts_b;
-    DWORD                     contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    DWORD                     contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
     unsigned int              num_contained_vs_consts_f;
     DWORD                     contained_ps_consts_i[WINED3D_MAX_CONSTS_I];
     unsigned int              num_contained_ps_consts_i;
-- 
2.20.1

