Commit 5059da9e authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

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.
parent 435e5c89
......@@ -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. */
......
......@@ -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. */
......
......@@ -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;
......
......@@ -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) {}
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment