wined3d: Introduce a wined3d_vertex_pipe_ops structure.

This commit is contained in:
Henri Verbeet 2013-04-25 12:16:47 +02:00 committed by Alexandre Julliard
parent 76bbf106a2
commit 471991eb9a
7 changed files with 178 additions and 68 deletions

View File

@ -327,6 +327,7 @@ struct shader_arb_priv
char *vshader_const_dirty, *pshader_const_dirty; char *vshader_const_dirty, *pshader_const_dirty;
const struct wined3d_context *last_context; const struct wined3d_context *last_context;
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe; const struct fragment_pipeline *fragment_pipe;
BOOL ffp_proj_control; 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); gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
checkGLcall("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. */ /* Context activation is done by the caller. */
@ -4837,15 +4839,24 @@ static const struct wine_rb_functions sig_tree_functions =
sig_tree_compare 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 shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
struct fragment_caps fragment_caps; 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))) if (!(fragment_priv = fragment_pipe->alloc_private(&arb_program_shader_backend, priv)))
{ {
ERR("Failed to initialize fragment pipe.\n"); ERR("Failed to initialize fragment pipe.\n");
vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv); HeapFree(GetProcessHeap(), 0, priv);
return E_FAIL; return E_FAIL;
} }
@ -4870,17 +4881,22 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct frag
goto fail; goto fail;
} }
priv->vertex_pipe = vertex_pipe;
priv->fragment_pipe = fragment_pipe;
fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps); fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
device->vertex_priv = vertex_priv;
device->fragment_priv = fragment_priv; device->fragment_priv = fragment_priv;
priv->fragment_pipe = fragment_pipe;
device->shader_priv = priv; device->shader_priv = priv;
return WINED3D_OK; return WINED3D_OK;
fail: fail:
HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty); HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty); HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
fragment_pipe->free_private(device); fragment_pipe->free_private(device);
vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv); HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY; 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->pshader_const_dirty);
HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty); HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
priv->fragment_pipe->free_private(device); priv->fragment_pipe->free_private(device);
priv->vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, device->shader_priv); HeapFree(GetProcessHeap(), 0, device->shader_priv);
} }

View File

@ -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"); TRACE("Shader private data couldn't be allocated\n");
goto err_out; goto err_out;
@ -4839,7 +4840,8 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru
struct wined3d_surface *target; struct wined3d_surface *target;
HRESULT hr; 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); ERR("Failed to allocate shader private data, hr %#x.\n", hr);
return 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]; struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
const struct fragment_pipeline *fragment_pipeline; const struct fragment_pipeline *fragment_pipeline;
const struct wined3d_vertex_pipe_ops *vertex_pipeline;
struct shader_caps shader_caps; struct shader_caps shader_caps;
struct fragment_caps ffp_caps; struct fragment_caps ffp_caps;
unsigned int i; 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->d3d_pshader_constantF = shader_caps.ps_uniform_count;
device->vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING; device->vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
vertex_pipeline = adapter->vertex_pipe;
fragment_pipeline = adapter->fragment_pipe; fragment_pipeline = adapter->fragment_pipe;
fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps); fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures; 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, && 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); ERR("Failed to compile state table, hr %#x.\n", hr);
wined3d_decref(device->wined3d); wined3d_decref(device->wined3d);

View File

@ -2839,6 +2839,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
checkGLcall("extension detection"); checkGLcall("extension detection");
adapter->shader_backend = select_shader_backend(gl_info); 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->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
adapter->blitter = select_blit_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; const struct wined3d_gl_info *gl_info = &adapter->gl_info;
struct shader_caps shader_caps; struct shader_caps shader_caps;
struct fragment_caps fragment_caps; struct fragment_caps fragment_caps;
struct wined3d_vertex_caps vertex_caps;
DWORD ckey_caps, blit_caps, fx_caps, pal_caps; DWORD ckey_caps, blit_caps, fx_caps, pal_caps;
TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n", 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_ZBIAS |
WINED3DPRASTERCAPS_MIPMAPLODBIAS; 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 | caps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
WINED3DPCMPCAPS_EQUAL | WINED3DPCMPCAPS_EQUAL |
@ -4311,26 +4303,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED; 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->MaxAnisotropy = gl_info->limits.anisotropy;
caps->MaxPointSize = gl_info->limits.pointsize_max; 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->MaxPrimitiveCount = 0xfffff; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
caps->MaxVertexIndex = 0xfffff; caps->MaxVertexIndex = 0xfffff;
caps->MaxStreams = MAX_STREAMS; 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->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_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 */ /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps; 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->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
caps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures; 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 /* 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 * are the same among all shader models. So to avoid code duplication set the shader version
* specific, but otherwise constant caps here * 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); initPixelFormatsNoGL(&adapter->gl_info);
adapter->vertex_pipe = &none_vertex_pipe;
adapter->fragment_pipe = &none_fragment_pipe; adapter->fragment_pipe = &none_fragment_pipe;
adapter->shader_backend = &none_shader_backend; adapter->shader_backend = &none_shader_backend;
adapter->blitter = &cpu_blit; adapter->blitter = &cpu_blit;

View File

@ -97,6 +97,7 @@ struct shader_glsl_priv {
GLhandleARB depth_blt_program_masked[tex_type_count]; GLhandleARB depth_blt_program_masked[tex_type_count];
UINT next_constant_version; UINT next_constant_version;
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe; const struct fragment_pipeline *fragment_pipe;
struct wine_rb_tree ffp_fragment_shaders; struct wine_rb_tree ffp_fragment_shaders;
BOOL ffp_proj_control; BOOL ffp_proj_control;
@ -5792,6 +5793,9 @@ static void shader_glsl_select(const struct wined3d_context *context, enum wined
GLhandleARB program_id = 0; GLhandleARB program_id = 0;
GLenum old_vertex_color_clamp, current_vertex_color_clamp; 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; 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); 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; 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, 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; 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)); 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, SIZE_T stack_size = wined3d_log2i(max(gl_info->limits.glsl_vs_float_constants,
gl_info->limits.glsl_ps_float_constants)) + 1; gl_info->limits.glsl_ps_float_constants)) + 1;
struct fragment_caps fragment_caps; 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))) if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv)))
{ {
ERR("Failed to initialize fragment pipe.\n"); ERR("Failed to initialize fragment pipe.\n");
vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv); HeapFree(GetProcessHeap(), 0, priv);
return E_FAIL; 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->next_constant_version = 1;
priv->vertex_pipe = vertex_pipe;
priv->fragment_pipe = fragment_pipe;
fragment_pipe->get_caps(gl_info, &fragment_caps); fragment_pipe->get_caps(gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; 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; device->shader_priv = priv;
return WINED3D_OK; return WINED3D_OK;
fail: fail:
@ -6085,6 +6101,7 @@ fail:
HeapFree(GetProcessHeap(), 0, priv->stack); HeapFree(GetProcessHeap(), 0, priv->stack);
shader_buffer_free(&priv->shader_buffer); shader_buffer_free(&priv->shader_buffer);
fragment_pipe->free_private(device); fragment_pipe->free_private(device);
vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv); HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
@ -6114,6 +6131,7 @@ static void shader_glsl_free(struct wined3d_device *device)
HeapFree(GetProcessHeap(), 0, priv->stack); HeapFree(GetProcessHeap(), 0, priv->stack);
shader_buffer_free(&priv->shader_buffer); shader_buffer_free(&priv->shader_buffer);
priv->fragment_pipe->free_private(device); priv->fragment_pipe->free_private(device);
priv->vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, device->shader_priv); HeapFree(GetProcessHeap(), 0, device->shader_priv);
device->shader_priv = NULL; device->shader_priv = NULL;

View File

@ -1498,6 +1498,7 @@ static void shader_cleanup(struct wined3d_shader *shader)
struct shader_none_priv struct shader_none_priv
{ {
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe; const struct fragment_pipeline *fragment_pipe;
BOOL ffp_proj_control; 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 wined3d_device *device = context->swapchain->device;
struct shader_none_priv *priv = device->shader_priv; 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); 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; struct fragment_caps fragment_caps;
void *vertex_priv, *fragment_priv;
struct shader_none_priv *priv; struct shader_none_priv *priv;
void *fragment_priv;
if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)))) if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if (!(fragment_priv = fragment_pipe->alloc_private(&none_shader_backend, priv))) if (!(vertex_priv = vertex_pipe->vp_alloc(&none_shader_backend, priv)))
{ {
ERR("Failed to initialize fragment pipe.\n"); ERR("Failed to initialize vertex pipe.\n");
HeapFree(GetProcessHeap(), 0, priv); HeapFree(GetProcessHeap(), 0, priv);
return E_FAIL; 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); fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
device->vertex_priv = vertex_priv;
device->fragment_priv = fragment_priv; device->fragment_priv = fragment_priv;
priv->fragment_pipe = fragment_pipe;
device->shader_priv = priv; device->shader_priv = priv;
return WINED3D_OK; return WINED3D_OK;
@ -1554,6 +1568,7 @@ static void shader_none_free(struct wined3d_device *device)
struct shader_none_priv *priv = device->shader_priv; struct shader_none_priv *priv = device->shader_priv;
priv->fragment_pipe->free_private(device); priv->fragment_pipe->free_private(device);
priv->vertex_pipe->vp_free(device);
HeapFree(GetProcessHeap(), 0, priv); HeapFree(GetProcessHeap(), 0, priv);
} }

View File

@ -5141,7 +5141,8 @@ const struct StateEntryTemplate misc_state_template[] = {
{0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, {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_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
{ STATE_VSHADER, { STATE_VDECL, NULL }, 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 }, { 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. */ /* Context activation is done by the caller. */
static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {} 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) static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{ {
caps->wined3d_caps = 0; 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; 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) static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
{ {
if (TRACE_ON(d3d)) if (TRACE_ON(d3d))
@ -5712,26 +5742,40 @@ static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
const struct fragment_pipeline ffp_fragment_pipeline = { const struct fragment_pipeline ffp_fragment_pipeline = {
ffp_enable, ffp_enable,
ffp_fragment_get_caps, ffp_fragment_get_caps,
ffp_fragment_alloc, ffp_alloc,
ffp_fragment_free, ffp_free,
ffp_color_fixup_supported, ffp_color_fixup_supported,
ffp_fragmentstate_template, 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 *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
return 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)
{
memset(caps, 0, sizeof(*caps));
}
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) static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{ {
memset(caps, 0, sizeof(*caps)); memset(caps, 0, sizeof(*caps));
} }
static void *fp_none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
return shader_priv;
}
static void fp_none_free(struct wined3d_device *device) {}
static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup) static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
{ {
return is_identity_fixup(fixup); return is_identity_fixup(fixup);
@ -5739,10 +5783,10 @@ static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
const struct fragment_pipeline none_fragment_pipe = const struct fragment_pipeline none_fragment_pipe =
{ {
fp_none_enable, none_enable,
fp_none_get_caps, fp_none_get_caps,
fp_none_alloc, none_alloc,
fp_none_free, none_free,
fp_none_color_fixup_supported, fp_none_color_fixup_supported,
NULL, 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, 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) const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
{ {
unsigned int i, type, handlers; unsigned int i, type, handlers;
@ -5904,7 +5948,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
switch(type) { switch(type) {
case 0: cur = misc; break; case 0: cur = misc; break;
case 1: cur = fragment->states; break; case 1: cur = fragment->states; break;
case 2: cur = vertex; break; case 2: cur = vertex->vp_states; break;
default: cur = NULL; /* Stupid compiler */ default: cur = NULL; /* Stupid compiler */
} }
if(!cur) continue; if(!cur) continue;

View File

@ -794,6 +794,7 @@ enum wined3d_shader_mode
struct wined3d_context; struct wined3d_context;
struct wined3d_state; struct wined3d_state;
struct fragment_pipeline; struct fragment_pipeline;
struct wined3d_vertex_pipe_ops;
struct wined3d_shader_backend_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, void (*shader_load_np2fixup_constants)(void *shader_priv, const struct wined3d_gl_info *gl_info,
const struct wined3d_state *state); const struct wined3d_state *state);
void (*shader_destroy)(struct wined3d_shader *shader); 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_free_private)(struct wined3d_device *device);
void (*shader_context_destroyed)(void *shader_priv, const struct wined3d_context *context); 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); 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; 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 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 none_fragment_pipe DECLSPEC_HIDDEN;
extern const struct fragment_pipeline ffp_fragment_pipeline DECLSPEC_HIDDEN; extern const struct fragment_pipeline ffp_fragment_pipeline DECLSPEC_HIDDEN;
extern const struct fragment_pipeline atifs_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 nvrc_fragment_pipeline DECLSPEC_HIDDEN;
extern const struct fragment_pipeline glsl_fragment_pipe 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 */ /* "Base" state table */
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs, 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; const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
enum wined3d_blit_op enum wined3d_blit_op
@ -1578,6 +1602,7 @@ struct wined3d_adapter
unsigned int UsedTextureRam; unsigned int UsedTextureRam;
LUID luid; LUID luid;
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe; const struct fragment_pipeline *fragment_pipe;
const struct wined3d_shader_backend_ops *shader_backend; const struct wined3d_shader_backend_ops *shader_backend;
const struct blit_shader *blitter; const struct blit_shader *blitter;
@ -1689,6 +1714,7 @@ struct wined3d_device
const struct wined3d_shader_backend_ops *shader_backend; const struct wined3d_shader_backend_ops *shader_backend;
void *shader_priv; void *shader_priv;
void *fragment_priv; void *fragment_priv;
void *vertex_priv;
void *blit_priv; void *blit_priv;
struct StateEntry StateTable[STATE_HIGHEST + 1]; struct StateEntry StateTable[STATE_HIGHEST + 1];
/* Array of functions for states which are handled by more than one pipeline part */ /* Array of functions for states which are handled by more than one pipeline part */