[PATCH 2/5] wined3d: Introduce a wined3d_vertex_pipe_ops structure.
Henri Verbeet
hverbeet at codeweavers.com
Thu Apr 25 02:59:43 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.
---
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..336eb9d 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");
+ fragment_pipe->free_private(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