From 471991eb9a56858b585a48b9a85d7663eb63699e Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 25 Apr 2013 12:16:47 +0200 Subject: [PATCH] wined3d: Introduce a wined3d_vertex_pipe_ops structure. --- 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 c3500c05bd..967a057f70 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 7b6a253bff..3eb7852bab 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 392c7eba79..3743968349 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 6d4ef6bdc6..7750eab960 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 4936afef24..c3534b315c 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 38b4153675..84e8b72620 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 73862cc246..f8364852c1 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 */ -- 2.32.0.93.g670b81a890