diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index e4420f13b73..6fc0aa40c00 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -50,7 +50,6 @@ struct atifs_ffp_desc struct atifs_private_data { - struct shader_arb_priv parent; struct list fragment_shaders; /* A linked list to track fragment pipeline replacement shaders */ }; @@ -782,7 +781,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi IWineD3DDeviceImpl *This = stateblock->wineD3DDevice; struct atifs_ffp_desc *desc; struct texture_stage_op op[MAX_TEXTURES]; - struct atifs_private_data *priv = (struct atifs_private_data *) This->shader_priv; + struct atifs_private_data *priv = (struct atifs_private_data *) This->fragment_priv; DWORD mapped_stage; unsigned int i; @@ -1019,64 +1018,24 @@ static void atifs_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, str caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; } -const struct fragment_pipeline atifs_fragment_pipeline = { - atifs_enable, - atifs_get_caps, - atifs_fragmentstate_template -}; - -/* GL_ATI_fragment_shader backend.It borrows a lot from a the - * ARB shader backend, currently the whole vertex processing - * code. This code would also forward pixel shaders, but if - * GL_ARB_fragment_program is supported, the atifs shader backend - * is not used. - */ -static void shader_atifs_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { - arb_program_shader_backend.shader_select(iface, usePS, useVS); -} - -static void shader_atifs_select_depth_blt(IWineD3DDevice *iface) { - arb_program_shader_backend.shader_select_depth_blt(iface); -} - -static void shader_atifs_deselect_depth_blt(IWineD3DDevice *iface) { - arb_program_shader_backend.shader_deselect_depth_blt(iface); -} - -static void shader_atifs_load_constants(IWineD3DDevice *iface, char usePS, char useVS) { - arb_program_shader_backend.shader_load_constants(iface, usePS, useVS); -} - -static void shader_atifs_cleanup(IWineD3DDevice *iface) { - arb_program_shader_backend.shader_cleanup(iface); -} - -static void shader_atifs_color_correction(SHADER_OPCODE_ARG* arg) { - arb_program_shader_backend.shader_color_correction(arg); -} - -static void shader_atifs_destroy(IWineD3DBaseShader *iface) { - arb_program_shader_backend.shader_destroy(iface); -} - -static HRESULT shader_atifs_alloc(IWineD3DDevice *iface) { +static HRESULT atifs_alloc(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - HRESULT hr; struct atifs_private_data *priv; - hr = arb_program_shader_backend.shader_alloc_private(iface); - if(FAILED(hr)) return hr; - This->shader_priv = HeapReAlloc(GetProcessHeap(), 0, This->shader_priv, - sizeof(struct atifs_private_data)); - priv = (struct atifs_private_data *) This->shader_priv; + This->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct atifs_private_data)); + if(!This->fragment_priv) { + ERR("Out of memory\n"); + return E_OUTOFMEMORY; + } + priv = (struct atifs_private_data *) This->fragment_priv; list_init(&priv->fragment_shaders); return WINED3D_OK; } #define GLINFO_LOCATION This->adapter->gl_info -static void shader_atifs_free(IWineD3DDevice *iface) { +static void atifs_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - struct atifs_private_data *priv = (struct atifs_private_data *) This->shader_priv; + struct atifs_private_data *priv = (struct atifs_private_data *) This->fragment_priv; struct ffp_desc *entry, *entry2; struct atifs_ffp_desc *entry_ati; @@ -1089,42 +1048,15 @@ static void shader_atifs_free(IWineD3DDevice *iface) { HeapFree(GetProcessHeap(), 0, entry); } LEAVE_GL(); - - /* Not actually needed, but revert what we've done before */ - This->shader_priv = HeapReAlloc(GetProcessHeap(), 0, This->shader_priv, - sizeof(struct shader_arb_priv)); - arb_program_shader_backend.shader_free_private(iface); + HeapFree(GetProcessHeap(), 0, priv); + This->fragment_priv = NULL; } #undef GLINFO_LOCATION -static BOOL shader_atifs_dirty_const(IWineD3DDevice *iface) { - return arb_program_shader_backend.shader_dirtifyable_constants(iface); -} - -static void shader_atifs_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps) { - arb_program_shader_backend.shader_get_caps(devtype, gl_info, caps); -} - -static void shader_atifs_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) { - ERR("Should not get here\n"); -} - -static void shader_atifs_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) { - arb_program_shader_backend.shader_generate_vshader(iface, buffer); -} - -const shader_backend_t atifs_shader_backend = { - shader_atifs_select, - shader_atifs_select_depth_blt, - shader_atifs_deselect_depth_blt, - shader_atifs_load_constants, - shader_atifs_cleanup, - shader_atifs_color_correction, - shader_atifs_destroy, - shader_atifs_alloc, - shader_atifs_free, - shader_atifs_dirty_const, - shader_atifs_generate_pshader, - shader_atifs_generate_vshader, - shader_atifs_get_caps, +const struct fragment_pipeline atifs_fragment_pipeline = { + atifs_enable, + atifs_get_caps, + atifs_alloc, + atifs_free, + atifs_fragmentstate_template }; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 998f95066f9..6c78ec4516d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2131,6 +2131,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR TRACE("Shader private data couldn't be allocated\n"); goto err_out; } + hr = This->frag_pipe->alloc_private(iface); + if(FAILED(hr)) { + TRACE("Fragment pipeline private data couldn't be allocated\n"); + goto err_out; + } /* Set up some starting GL setup */ @@ -2216,6 +2221,7 @@ err_out: This->stateBlock = NULL; } This->shader_backend->shader_free_private(iface); + This->frag_pipe->free_private(iface); return hr; } @@ -2305,6 +2311,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ This->shader_backend->shader_free_private(iface); + This->frag_pipe->free_private(iface); /* Release the buffers (with sanity checks)*/ TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); @@ -7220,6 +7227,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE This->depth_blt_rb_h = 0; } This->shader_backend->shader_free_private(iface); + This->frag_pipe->free_private(iface); for (i = 0; i < GL_LIMITS(textures); i++) { /* Textures are recreated below */ @@ -7328,6 +7336,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE ERR("Failed to recreate shader private data\n"); return hr; } + hr = This->frag_pipe->alloc_private(iface); + if(FAILED(hr)) { + TRACE("Fragment pipeline private data couldn't be allocated\n"); + return hr; + } /* All done. There is no need to reload resources or shaders, this will happen automatically on the * first use diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 9992ee24ea3..a88f443faf4 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2879,9 +2879,6 @@ static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYP select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode); if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) { ret = &glsl_shader_backend; - } else if (vs_selected_mode == SHADER_ARB && ps_selected_mode != SHADER_NONE && - !GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) { - ret = &atifs_shader_backend; } else if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) { ret = &arb_program_shader_backend; } else { diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 0ea627c7cf1..3e4594225e6 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4534,11 +4534,16 @@ static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_in } +static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } +static void ffp_fragment_free(IWineD3DDevice *iface) {} + #undef GLINFO_LOCATION const struct fragment_pipeline ffp_fragment_pipeline = { nvts_enable, ffp_fragment_get_caps, + ffp_fragment_alloc, + ffp_fragment_free, ffp_fragmentstate_template }; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 327a14f6d9c..d5352eac31d 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -551,6 +551,8 @@ struct fragment_caps { struct fragment_pipeline { void (*enable_extension)(IWineD3DDevice *iface, BOOL enable); void (*get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *caps); + HRESULT (*alloc_private)(IWineD3DDevice *iface); + void (*free_private)(IWineD3DDevice *iface); const struct StateEntryTemplate *states; }; @@ -788,6 +790,7 @@ struct IWineD3DDeviceImpl int ps_selected_mode; const shader_backend_t *shader_backend; void *shader_priv; + void *fragment_priv; struct StateEntry StateTable[STATE_HIGHEST + 1]; /* Array of functions for states which are handled by more than one pipeline part */ APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];