[PATCH 5/5] wined3d: Don't depend on device internals in fragment_pipeline.alloc_private().

Henri Verbeet hverbeet at codeweavers.com
Sun Oct 28 14:54:54 CDT 2012


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;
-- 
1.7.8.6




More information about the wine-patches mailing list