[PATCH 2/5] wined3d: Introduce a wined3d_vertex_pipe_ops structure.

Henri Verbeet hverbeet at codeweavers.com
Thu Apr 25 05:16:47 CDT 2013


Similar to the already existing fragment pipe. This will allow additional
implementations of D3D fixed function functionality besides the existing one
on top of OpenGL fixed function functionality.

This supersedes patch 95877.
---
 dlls/wined3d/arb_program_shader.c | 23 +++++++++--
 dlls/wined3d/device.c             | 13 ++++--
 dlls/wined3d/directx.c            | 39 ++++++------------
 dlls/wined3d/glsl_shader.c        | 26 ++++++++++--
 dlls/wined3d/shader.c             | 21 ++++++++--
 dlls/wined3d/state.c              | 84 +++++++++++++++++++++++++++++----------
 dlls/wined3d/wined3d_private.h    | 32 +++++++++++++--
 7 files changed, 174 insertions(+), 64 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index c3500c0..967a057 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -327,6 +327,7 @@ struct shader_arb_priv
     char *vshader_const_dirty, *pshader_const_dirty;
     const struct wined3d_context *last_context;
 
+    const struct wined3d_vertex_pipe_ops *vertex_pipe;
     const struct fragment_pipeline *fragment_pipe;
     BOOL ffp_proj_control;
 };
@@ -4716,6 +4717,7 @@ static void shader_arb_select(const struct wined3d_context *context, enum wined3
         gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
         checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
     }
+    priv->vertex_pipe->vp_enable(gl_info, vertex_mode == WINED3D_SHADER_MODE_FFP);
 }
 
 /* Context activation is done by the caller. */
@@ -4837,15 +4839,24 @@ static const struct wine_rb_functions sig_tree_functions =
     sig_tree_compare
 };
 
-static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
+static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+        const struct fragment_pipeline *fragment_pipe)
 {
     struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
     struct fragment_caps fragment_caps;
-    void *fragment_priv;
+    void *vertex_priv, *fragment_priv;
+
+    if (!(vertex_priv = vertex_pipe->vp_alloc(&arb_program_shader_backend, priv)))
+    {
+        ERR("Failed to initialize vertex pipe.\n");
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_FAIL;
+    }
 
     if (!(fragment_priv = fragment_pipe->alloc_private(&arb_program_shader_backend, priv)))
     {
         ERR("Failed to initialize fragment pipe.\n");
+        vertex_pipe->vp_free(device);
         HeapFree(GetProcessHeap(), 0, priv);
         return E_FAIL;
     }
@@ -4870,17 +4881,22 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct frag
         goto fail;
     }
 
+    priv->vertex_pipe = vertex_pipe;
+    priv->fragment_pipe = fragment_pipe;
     fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
     priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+    device->vertex_priv = vertex_priv;
     device->fragment_priv = fragment_priv;
-    priv->fragment_pipe = fragment_pipe;
     device->shader_priv = priv;
+
     return WINED3D_OK;
 
 fail:
     HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
     HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
     fragment_pipe->free_private(device);
+    vertex_pipe->vp_free(device);
     HeapFree(GetProcessHeap(), 0, priv);
     return E_OUTOFMEMORY;
 }
@@ -4923,6 +4939,7 @@ static void shader_arb_free(struct wined3d_device *device)
     HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
     HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
     priv->fragment_pipe->free_private(device);
+    priv->vertex_pipe->vp_free(device);
     HeapFree(GetProcessHeap(), 0, device->shader_priv);
 }
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7b6a253..3eb7852 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1141,7 +1141,8 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
         }
     }
 
-    if (FAILED(hr = device->shader_backend->shader_alloc_private(device, device->adapter->fragment_pipe)))
+    if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
+            device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
     {
         TRACE("Shader private data couldn't be allocated\n");
         goto err_out;
@@ -4839,7 +4840,8 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru
     struct wined3d_surface *target;
     HRESULT hr;
 
-    if (FAILED(hr = device->shader_backend->shader_alloc_private(device, device->adapter->fragment_pipe)))
+    if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
+            device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
     {
         ERR("Failed to allocate shader private data, hr %#x.\n", hr);
         return hr;
@@ -5405,6 +5407,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
 {
     struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
     const struct fragment_pipeline *fragment_pipeline;
+    const struct wined3d_vertex_pipe_ops *vertex_pipeline;
     struct shader_caps shader_caps;
     struct fragment_caps ffp_caps;
     unsigned int i;
@@ -5434,13 +5437,15 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
     device->d3d_pshader_constantF = shader_caps.ps_uniform_count;
     device->vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
 
+    vertex_pipeline = adapter->vertex_pipe;
+
     fragment_pipeline = adapter->fragment_pipe;
     fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
     device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
 
-    if (fragment_pipeline->states
+    if (vertex_pipeline->vp_states && fragment_pipeline->states
             && FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs,
-            &adapter->gl_info, ffp_vertexstate_template, fragment_pipeline, misc_state_template)))
+            &adapter->gl_info, vertex_pipeline, fragment_pipeline, misc_state_template)))
     {
         ERR("Failed to compile state table, hr %#x.\n", hr);
         wined3d_decref(device->wined3d);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 392c7eb..3743968 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2839,6 +2839,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     checkGLcall("extension detection");
 
     adapter->shader_backend = select_shader_backend(gl_info);
+    adapter->vertex_pipe = &ffp_vertex_pipe;
     adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
     adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend);
 
@@ -3968,6 +3969,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     struct shader_caps shader_caps;
     struct fragment_caps fragment_caps;
+    struct wined3d_vertex_caps vertex_caps;
     DWORD ckey_caps, blit_caps, fx_caps, pal_caps;
 
     TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n",
@@ -4052,16 +4054,6 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
                              WINED3DPRASTERCAPS_ZBIAS         |
                              WINED3DPRASTERCAPS_MIPMAPLODBIAS;
     }
-    if (gl_info->supported[NV_FOG_DISTANCE])
-    {
-        caps->RasterCaps          |= WINED3DPRASTERCAPS_FOGRANGE;
-    }
-                        /* FIXME Add:
-                           WINED3DPRASTERCAPS_COLORPERSPECTIVE
-                           WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
-                           WINED3DPRASTERCAPS_ANTIALIASEDGES
-                           WINED3DPRASTERCAPS_ZBUFFERLESSHSR
-                           WINED3DPRASTERCAPS_WBUFFER */
 
     caps->ZCmpCaps =  WINED3DPCMPCAPS_ALWAYS       |
                       WINED3DPCMPCAPS_EQUAL        |
@@ -4311,26 +4303,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
         caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
     }
 
-    caps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
-
-    caps->MaxUserClipPlanes = gl_info->limits.clipplanes;
-    caps->MaxActiveLights = gl_info->limits.lights;
-
-    caps->MaxVertexBlendMatrices = gl_info->limits.blends;
-    caps->MaxVertexBlendMatrixIndex   = 0;
-
     caps->MaxAnisotropy = gl_info->limits.anisotropy;
     caps->MaxPointSize = gl_info->limits.pointsize_max;
 
-
-    /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
-    caps->VertexProcessingCaps  = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
-                                  WINED3DVTXPCAPS_MATERIALSOURCE7   |
-                                  WINED3DVTXPCAPS_POSITIONALLIGHTS  |
-                                  WINED3DVTXPCAPS_LOCALVIEWER       |
-                                  WINED3DVTXPCAPS_VERTEXFOG         |
-                                  WINED3DVTXPCAPS_TEXGEN;
-
     caps->MaxPrimitiveCount   = 0xfffff; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
     caps->MaxVertexIndex      = 0xfffff;
     caps->MaxStreams          = MAX_STREAMS;
@@ -4354,6 +4329,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
 
     adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
     adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
+    adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps);
 
     /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
     caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
@@ -4368,6 +4344,14 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
     caps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
     caps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
 
+    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;
+    caps->VertexProcessingCaps             = vertex_caps.vertex_processing_caps;
+    caps->FVFCaps                          = vertex_caps.fvf_caps;
+    caps->RasterCaps                      |= vertex_caps.raster_caps;
+
     /* The following caps are shader specific, but they are things we cannot detect, or which
      * are the same among all shader models. So to avoid code duplication set the shader version
      * specific, but otherwise constant caps here
@@ -5029,6 +5013,7 @@ static void wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordi
 
     initPixelFormatsNoGL(&adapter->gl_info);
 
+    adapter->vertex_pipe = &none_vertex_pipe;
     adapter->fragment_pipe = &none_fragment_pipe;
     adapter->shader_backend = &none_shader_backend;
     adapter->blitter = &cpu_blit;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 6d4ef6b..7750eab 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -97,6 +97,7 @@ struct shader_glsl_priv {
     GLhandleARB depth_blt_program_masked[tex_type_count];
     UINT next_constant_version;
 
+    const struct wined3d_vertex_pipe_ops *vertex_pipe;
     const struct fragment_pipeline *fragment_pipe;
     struct wine_rb_tree ffp_fragment_shaders;
     BOOL ffp_proj_control;
@@ -5792,6 +5793,9 @@ static void shader_glsl_select(const struct wined3d_context *context, enum wined
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
 
+    priv->vertex_pipe->vp_enable(gl_info, vertex_mode == WINED3D_SHADER_MODE_FFP);
+    priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
+
     old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vs.vertex_color_clamp : GL_FIXED_ONLY_ARB;
     set_glsl_shader_program(context, device, vertex_mode, fragment_mode);
     current_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vs.vertex_color_clamp : GL_FIXED_ONLY_ARB;
@@ -6023,18 +6027,27 @@ static const struct wine_rb_functions wined3d_glsl_program_rb_functions =
     glsl_program_key_compare,
 };
 
-static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
+static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+        const struct fragment_pipeline *fragment_pipe)
 {
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
     SIZE_T stack_size = wined3d_log2i(max(gl_info->limits.glsl_vs_float_constants,
             gl_info->limits.glsl_ps_float_constants)) + 1;
     struct fragment_caps fragment_caps;
-    void *fragment_priv;
+    void *vertex_priv, *fragment_priv;
+
+    if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
+    {
+        ERR("Failed to initialize vertex pipe.\n");
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_FAIL;
+    }
 
     if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv)))
     {
         ERR("Failed to initialize fragment pipe.\n");
+        vertex_pipe->vp_free(device);
         HeapFree(GetProcessHeap(), 0, priv);
         return E_FAIL;
     }
@@ -6071,12 +6084,15 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct fra
     }
 
     priv->next_constant_version = 1;
+    priv->vertex_pipe = vertex_pipe;
+    priv->fragment_pipe = fragment_pipe;
     fragment_pipe->get_caps(gl_info, &fragment_caps);
     priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
-    device->fragment_priv = fragment_priv;
-    priv->fragment_pipe = fragment_pipe;
 
+    device->vertex_priv = vertex_priv;
+    device->fragment_priv = fragment_priv;
     device->shader_priv = priv;
+
     return WINED3D_OK;
 
 fail:
@@ -6085,6 +6101,7 @@ fail:
     HeapFree(GetProcessHeap(), 0, priv->stack);
     shader_buffer_free(&priv->shader_buffer);
     fragment_pipe->free_private(device);
+    vertex_pipe->vp_free(device);
     HeapFree(GetProcessHeap(), 0, priv);
     return E_OUTOFMEMORY;
 }
@@ -6114,6 +6131,7 @@ static void shader_glsl_free(struct wined3d_device *device)
     HeapFree(GetProcessHeap(), 0, priv->stack);
     shader_buffer_free(&priv->shader_buffer);
     priv->fragment_pipe->free_private(device);
+    priv->vertex_pipe->vp_free(device);
 
     HeapFree(GetProcessHeap(), 0, device->shader_priv);
     device->shader_priv = NULL;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 4936afe..c3534b3 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1498,6 +1498,7 @@ static void shader_cleanup(struct wined3d_shader *shader)
 
 struct shader_none_priv
 {
+    const struct wined3d_vertex_pipe_ops *vertex_pipe;
     const struct fragment_pipeline *fragment_pipe;
     BOOL ffp_proj_control;
 };
@@ -1521,29 +1522,42 @@ static void shader_none_select(const struct wined3d_context *context, enum wined
     struct wined3d_device *device = context->swapchain->device;
     struct shader_none_priv *priv = device->shader_priv;
 
+    priv->vertex_pipe->vp_enable(gl_info, vertex_mode == WINED3D_SHADER_MODE_FFP);
     priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
 }
 
-static HRESULT shader_none_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
+static HRESULT shader_none_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+        const struct fragment_pipeline *fragment_pipe)
 {
     struct fragment_caps fragment_caps;
+    void *vertex_priv, *fragment_priv;
     struct shader_none_priv *priv;
-    void *fragment_priv;
 
     if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
         return E_OUTOFMEMORY;
 
+    if (!(vertex_priv = vertex_pipe->vp_alloc(&none_shader_backend, priv)))
+    {
+        ERR("Failed to initialize vertex pipe.\n");
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_FAIL;
+    }
+
     if (!(fragment_priv = fragment_pipe->alloc_private(&none_shader_backend, priv)))
     {
         ERR("Failed to initialize fragment pipe.\n");
+        vertex_pipe->vp_free(device);
         HeapFree(GetProcessHeap(), 0, priv);
         return E_FAIL;
     }
 
+    priv->vertex_pipe = vertex_pipe;
+    priv->fragment_pipe = fragment_pipe;
     fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
     priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+    device->vertex_priv = vertex_priv;
     device->fragment_priv = fragment_priv;
-    priv->fragment_pipe = fragment_pipe;
     device->shader_priv = priv;
 
     return WINED3D_OK;
@@ -1554,6 +1568,7 @@ static void shader_none_free(struct wined3d_device *device)
     struct shader_none_priv *priv = device->shader_priv;
 
     priv->fragment_pipe->free_private(device);
+    priv->vertex_pipe->vp_free(device);
     HeapFree(GetProcessHeap(), 0, priv);
 }
 
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 38b4153..84e8b72 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -5141,7 +5141,8 @@ const struct StateEntryTemplate misc_state_template[] = {
     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 
-const struct StateEntryTemplate ffp_vertexstate_template[] = {
+const struct StateEntryTemplate vp_ffp_states[] =
+{
     { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, WINED3D_GL_EXT_NONE             },
     { STATE_VSHADER,                                      { STATE_VDECL,                                        NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_MATERIAL,                                     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            NULL                }, WINED3D_GL_EXT_NONE             },
@@ -5643,6 +5644,41 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
 /* Context activation is done by the caller. */
 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
 
+static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+    return shader_priv;
+}
+
+static void ffp_free(struct wined3d_device *device) {}
+
+static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+    caps->max_active_lights = gl_info->limits.lights;
+    caps->max_vertex_blend_matrices = gl_info->limits.blends;
+    caps->max_vertex_blend_matrix_index = 0;
+    /* FIXME: Add  D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
+    caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
+            | WINED3DVTXPCAPS_MATERIALSOURCE7
+            | WINED3DVTXPCAPS_POSITIONALLIGHTS
+            | WINED3DVTXPCAPS_LOCALVIEWER
+            | WINED3DVTXPCAPS_VERTEXFOG
+            | WINED3DVTXPCAPS_TEXGEN;
+    caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
+    caps->max_user_clip_planes = gl_info->limits.clipplanes;
+    caps->raster_caps = 0;
+    if (gl_info->supported[NV_FOG_DISTANCE])
+        caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
+}
+
+const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
+{
+    ffp_enable,
+    vp_ffp_get_caps,
+    ffp_alloc,
+    ffp_free,
+    vp_ffp_states,
+};
+
 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
 {
     caps->wined3d_caps = 0;
@@ -5684,12 +5720,6 @@ static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct
     caps->MaxSimultaneousTextures = gl_info->limits.textures;
 }
 
-static void *ffp_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
-{
-    return shader_priv;
-}
-
-static void ffp_fragment_free(struct wined3d_device *device) {}
 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
 {
     if (TRACE_ON(d3d))
@@ -5712,25 +5742,39 @@ static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
 const struct fragment_pipeline ffp_fragment_pipeline = {
     ffp_enable,
     ffp_fragment_get_caps,
-    ffp_fragment_alloc,
-    ffp_fragment_free,
+    ffp_alloc,
+    ffp_free,
     ffp_color_fixup_supported,
     ffp_fragmentstate_template,
 };
 
-static void fp_none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
+static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
 
-static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
 {
-    memset(caps, 0, sizeof(*caps));
+    return shader_priv;
 }
 
-static void *fp_none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+static void none_free(struct wined3d_device *device) {}
+
+static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
 {
-    return shader_priv;
+    memset(caps, 0, sizeof(*caps));
 }
 
-static void fp_none_free(struct wined3d_device *device) {}
+const struct wined3d_vertex_pipe_ops none_vertex_pipe =
+{
+    none_enable,
+    vp_none_get_caps,
+    none_alloc,
+    none_free,
+    NULL,
+};
+
+static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+    memset(caps, 0, sizeof(*caps));
+}
 
 static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
 {
@@ -5739,10 +5783,10 @@ static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
 
 const struct fragment_pipeline none_fragment_pipe =
 {
-    fp_none_enable,
+    none_enable,
     fp_none_get_caps,
-    fp_none_alloc,
-    fp_none_free,
+    none_alloc,
+    none_free,
     fp_none_color_fixup_supported,
     NULL,
 };
@@ -5884,7 +5928,7 @@ static void validate_state_table(struct StateEntry *state_table)
 }
 
 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
-        const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
+        const struct wined3d_gl_info *gl_info, const struct wined3d_vertex_pipe_ops *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
 {
     unsigned int i, type, handlers;
@@ -5904,7 +5948,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
         switch(type) {
             case 0: cur = misc; break;
             case 1: cur = fragment->states; break;
-            case 2: cur = vertex; break;
+            case 2: cur = vertex->vp_states; break;
             default: cur = NULL; /* Stupid compiler */
         }
         if(!cur) continue;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 73862cc..f836485 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -794,6 +794,7 @@ enum wined3d_shader_mode
 struct wined3d_context;
 struct wined3d_state;
 struct fragment_pipeline;
+struct wined3d_vertex_pipe_ops;
 
 struct wined3d_shader_backend_ops
 {
@@ -809,7 +810,8 @@ struct wined3d_shader_backend_ops
     void (*shader_load_np2fixup_constants)(void *shader_priv, const struct wined3d_gl_info *gl_info,
             const struct wined3d_state *state);
     void (*shader_destroy)(struct wined3d_shader *shader);
-    HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe);
+    HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+            const struct fragment_pipeline *fragment_pipe);
     void (*shader_free_private)(struct wined3d_device *device);
     void (*shader_context_destroyed)(void *shader_priv, const struct wined3d_context *context);
     void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
@@ -1184,8 +1186,27 @@ struct fragment_pipeline
     const struct StateEntryTemplate *states;
 };
 
+struct wined3d_vertex_caps
+{
+    DWORD max_active_lights;
+    DWORD max_vertex_blend_matrices;
+    DWORD max_vertex_blend_matrix_index;
+    DWORD vertex_processing_caps;
+    DWORD fvf_caps;
+    DWORD max_user_clip_planes;
+    DWORD raster_caps;
+};
+
+struct wined3d_vertex_pipe_ops
+{
+    void (*vp_enable)(const struct wined3d_gl_info *gl_info, BOOL enable);
+    void (*vp_get_caps)(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps);
+    void *(*vp_alloc)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
+    void (*vp_free)(struct wined3d_device *device);
+    const struct StateEntryTemplate *vp_states;
+};
+
 extern const struct StateEntryTemplate misc_state_template[] DECLSPEC_HIDDEN;
-extern const struct StateEntryTemplate ffp_vertexstate_template[] DECLSPEC_HIDDEN;
 extern const struct fragment_pipeline none_fragment_pipe DECLSPEC_HIDDEN;
 extern const struct fragment_pipeline ffp_fragment_pipeline DECLSPEC_HIDDEN;
 extern const struct fragment_pipeline atifs_fragment_pipeline DECLSPEC_HIDDEN;
@@ -1194,9 +1215,12 @@ extern const struct fragment_pipeline nvts_fragment_pipeline DECLSPEC_HIDDEN;
 extern const struct fragment_pipeline nvrc_fragment_pipeline DECLSPEC_HIDDEN;
 extern const struct fragment_pipeline glsl_fragment_pipe DECLSPEC_HIDDEN;
 
+extern const struct wined3d_vertex_pipe_ops none_vertex_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops ffp_vertex_pipe DECLSPEC_HIDDEN;
+
 /* "Base" state table */
 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
-        const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
+        const struct wined3d_gl_info *gl_info, const struct wined3d_vertex_pipe_ops *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
 
 enum wined3d_blit_op
@@ -1578,6 +1602,7 @@ struct wined3d_adapter
     unsigned int            UsedTextureRam;
     LUID luid;
 
+    const struct wined3d_vertex_pipe_ops *vertex_pipe;
     const struct fragment_pipeline *fragment_pipe;
     const struct wined3d_shader_backend_ops *shader_backend;
     const struct blit_shader *blitter;
@@ -1689,6 +1714,7 @@ struct wined3d_device
     const struct wined3d_shader_backend_ops *shader_backend;
     void *shader_priv;
     void *fragment_priv;
+    void *vertex_priv;
     void *blit_priv;
     struct StateEntry StateTable[STATE_HIGHEST + 1];
     /* Array of functions for states which are handled by more than one pipeline part */
-- 
1.8.1.5




More information about the wine-patches mailing list