Module: wine Branch: master Commit: 5059da9e32a16bc7a036c75e40f0c3b66550d940 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5059da9e32a16bc7a036c75e40...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Sun Oct 28 20:54:54 2012 +0100
wined3d: Don't depend on device internals in fragment_pipeline.alloc_private().
In particular, device->shader_backend and device->shader_priv aren't initialized yet when the fragment pipe is initialized.
---
dlls/wined3d/arb_program_shader.c | 43 ++++++++++++++++----------------- dlls/wined3d/ati_fragment_shader.c | 17 ++++++------- dlls/wined3d/glsl_shader.c | 9 ++++--- dlls/wined3d/nvidia_texture_shader.c | 6 ++++- dlls/wined3d/shader.c | 9 ++++--- dlls/wined3d/state.c | 6 ++++- dlls/wined3d/wined3d_private.h | 2 +- 7 files changed, 50 insertions(+), 42 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 86b2c2f..3db3b54 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4881,13 +4881,13 @@ static const struct wine_rb_functions sig_tree_functions = static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe) { struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv)); - HRESULT hr; + void *fragment_priv;
- if (FAILED(hr = fragment_pipe->alloc_private(device))) + if (!(fragment_priv = fragment_pipe->alloc_private(&arb_program_shader_backend, priv))) { - ERR("Failed to initialize fragment pipe, hr %#x.\n", hr); + ERR("Failed to initialize fragment pipe.\n"); HeapFree(GetProcessHeap(), 0, priv); - return hr; + return E_FAIL; }
priv->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, @@ -4909,6 +4909,7 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct frag ERR("RB tree init failed\n"); goto fail; } + device->fragment_priv = fragment_priv; priv->fragment_pipe = fragment_pipe; device->shader_priv = priv; return WINED3D_OK; @@ -5665,31 +5666,29 @@ static void arbfp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) } }
-static HRESULT arbfp_alloc(struct wined3d_device *device) +static void *arbfp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { struct shader_arb_priv *priv; - /* Share private data between the shader backend and the pipeline replacement, if both - * are the arb implementation. This is needed to figure out whether ARBfp should be disabled - * if no pixel shader is bound or not - */ - if (device->shader_backend == &arb_program_shader_backend) - { - device->fragment_priv = device->shader_priv; - } - else - { - device->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv)); - if (!device->fragment_priv) return E_OUTOFMEMORY; - } - priv = device->fragment_priv; + + /* Share private data between the shader backend and the pipeline + * replacement, if both are the arb implementation. This is needed to + * figure out whether ARBfp should be disabled if no pixel shader is bound + * or not. */ + if (shader_backend == &arb_program_shader_backend) + priv = shader_priv; + else if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv)))) + return NULL; + if (wine_rb_init(&priv->fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1) { ERR("Failed to initialize rbtree.\n"); - HeapFree(GetProcessHeap(), 0, device->fragment_priv); - return E_OUTOFMEMORY; + if (priv != shader_priv) + HeapFree(GetProcessHeap(), 0, priv); + return NULL; } priv->use_arbfp_fixed_func = TRUE; - return WINED3D_OK; + + return priv; }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index bc816fb..5e04878 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1154,24 +1154,23 @@ static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen caps->MaxSimultaneousTextures = 6; }
-static HRESULT atifs_alloc(struct wined3d_device *device) +static void *atifs_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { struct atifs_private_data *priv;
- device->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct atifs_private_data)); - if (!device->fragment_priv) + if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv)))) { - ERR("Out of memory\n"); - return E_OUTOFMEMORY; + ERR("Out of memory.\n"); + return NULL; } - priv = device->fragment_priv; if (wine_rb_init(&priv->fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1) { ERR("Failed to initialize rbtree.\n"); - HeapFree(GetProcessHeap(), 0, device->fragment_priv); - return E_OUTOFMEMORY; + HeapFree(GetProcessHeap(), 0, priv); + return NULL; } - return WINED3D_OK; + + return priv; }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index bf06aee..d7d7e3c 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -5233,13 +5233,13 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct fra 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; - HRESULT hr; + void *fragment_priv;
- if (FAILED(hr = fragment_pipe->alloc_private(device))) + if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv))) { - ERR("Failed to initialize fragment pipe, hr %#x.\n", hr); + ERR("Failed to initialize fragment pipe.\n"); HeapFree(GetProcessHeap(), 0, priv); - return hr; + return E_FAIL; }
if (!shader_buffer_init(&priv->shader_buffer)) @@ -5274,6 +5274,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct fra }
priv->next_constant_version = 1; + device->fragment_priv = fragment_priv; priv->fragment_pipe = fragment_pipe;
device->shader_priv = priv; diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index bc38cb8..9a77e1d 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -720,7 +720,11 @@ static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct caps->MaxSimultaneousTextures = gl_info->limits.textures; }
-static HRESULT nvrc_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; } +static void *nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) +{ + return shader_priv; +} + /* Context activation is done by the caller. */ static void nvrc_fragment_free(struct wined3d_device *device) {}
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 1ca79ce..6143ac5 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1473,7 +1473,7 @@ static void shader_none_context_destroyed(void *shader_priv, const struct wined3 static HRESULT shader_none_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe) { struct shader_none_priv *priv; - HRESULT hr; + void *fragment_priv;
if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)))) { @@ -1481,13 +1481,14 @@ static HRESULT shader_none_alloc(struct wined3d_device *device, const struct fra return E_OUTOFMEMORY; }
- if (FAILED(hr = fragment_pipe->alloc_private(device))) + if (!(fragment_priv = fragment_pipe->alloc_private(&none_shader_backend, priv))) { - ERR("Failed to initialize fragment pipe, hr %#x.\n", hr); + ERR("Failed to initialize fragment pipe.\n"); HeapFree(GetProcessHeap(), 0, priv); - return hr; + return E_FAIL; }
+ device->fragment_priv = fragment_priv; priv->fragment_pipe = fragment_pipe; device->shader_priv = priv;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index cab31f8..32e6d73 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -5701,7 +5701,11 @@ static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct caps->MaxSimultaneousTextures = gl_info->limits.textures; }
-static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; } +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) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4a3779f..c189963 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1183,7 +1183,7 @@ struct fragment_pipeline { void (*enable_extension)(const struct wined3d_gl_info *gl_info, BOOL enable); void (*get_caps)(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps); - HRESULT (*alloc_private)(struct wined3d_device *device); + void *(*alloc_private)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv); void (*free_private)(struct wined3d_device *device); BOOL (*color_fixup_supported)(struct color_fixup_desc fixup); const struct StateEntryTemplate *states;