wined3d: Move the ARB shader program constant handling to the backend where it belongs.
This commit is contained in:
parent
89d0d3ffd8
commit
7aac0159a9
|
@ -312,6 +312,10 @@ struct shader_arb_priv
|
|||
|
||||
struct wine_rb_tree signature_tree;
|
||||
DWORD ps_sig_number;
|
||||
|
||||
unsigned int highest_dirty_ps_const, highest_dirty_vs_const;
|
||||
char *vshader_const_dirty, *pshader_const_dirty;
|
||||
const struct wined3d_context *last_context;
|
||||
};
|
||||
|
||||
/* GL locking for state handlers is done by the caller. */
|
||||
|
@ -633,14 +637,27 @@ static void shader_arb_load_constants(const struct wined3d_context *context, cha
|
|||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
struct shader_arb_priv *priv = device->shader_priv;
|
||||
|
||||
if (context != priv->last_context)
|
||||
{
|
||||
memset(priv->vshader_const_dirty, 1,
|
||||
sizeof(*priv->vshader_const_dirty) * device->d3d_vshader_constantF);
|
||||
priv->highest_dirty_vs_const = device->d3d_vshader_constantF;
|
||||
|
||||
memset(priv->pshader_const_dirty, 1,
|
||||
sizeof(*priv->pshader_const_dirty) * device->d3d_pshader_constantF);
|
||||
priv->highest_dirty_ps_const = device->d3d_pshader_constantF;
|
||||
|
||||
priv->last_context = context;
|
||||
}
|
||||
|
||||
if (useVertexShader)
|
||||
{
|
||||
struct wined3d_shader *vshader = state->vertex_shader;
|
||||
const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog;
|
||||
|
||||
/* Load DirectX 9 float constants for vertex shader */
|
||||
device->highest_dirty_vs_const = shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
device->highest_dirty_vs_const, state->vs_consts_f, context->vshader_const_dirty);
|
||||
priv->highest_dirty_vs_const = shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
priv->highest_dirty_vs_const, state->vs_consts_f, priv->vshader_const_dirty);
|
||||
shader_arb_vs_local_constants(gl_shader, context, state);
|
||||
}
|
||||
|
||||
|
@ -651,8 +668,8 @@ static void shader_arb_load_constants(const struct wined3d_context *context, cha
|
|||
UINT rt_height = state->fb->render_targets[0]->resource.height;
|
||||
|
||||
/* Load DirectX 9 float constants for pixel shader */
|
||||
device->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
|
||||
device->highest_dirty_ps_const, state->ps_consts_f, context->pshader_const_dirty);
|
||||
priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
|
||||
priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty);
|
||||
shader_arb_ps_local_constants(gl_shader, context, state, rt_height);
|
||||
}
|
||||
}
|
||||
|
@ -660,25 +677,27 @@ static void shader_arb_load_constants(const struct wined3d_context *context, cha
|
|||
static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
|
||||
{
|
||||
struct wined3d_context *context = context_get_current();
|
||||
struct shader_arb_priv *priv = device->shader_priv;
|
||||
|
||||
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
|
||||
* context. On a context switch the old context will be fully dirtified */
|
||||
if (!context || context->swapchain->device != device) return;
|
||||
|
||||
memset(context->vshader_const_dirty + start, 1, sizeof(*context->vshader_const_dirty) * count);
|
||||
device->highest_dirty_vs_const = max(device->highest_dirty_vs_const, start + count);
|
||||
memset(priv->vshader_const_dirty + start, 1, sizeof(*priv->vshader_const_dirty) * count);
|
||||
priv->highest_dirty_vs_const = max(priv->highest_dirty_vs_const, start + count);
|
||||
}
|
||||
|
||||
static void shader_arb_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
|
||||
{
|
||||
struct wined3d_context *context = context_get_current();
|
||||
struct shader_arb_priv *priv = device->shader_priv;
|
||||
|
||||
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
|
||||
* context. On a context switch the old context will be fully dirtified */
|
||||
if (!context || context->swapchain->device != device) return;
|
||||
|
||||
memset(context->pshader_const_dirty + start, 1, sizeof(*context->pshader_const_dirty) * count);
|
||||
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, start + count);
|
||||
memset(priv->pshader_const_dirty + start, 1, sizeof(*priv->pshader_const_dirty) * count);
|
||||
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count);
|
||||
}
|
||||
|
||||
static DWORD *local_const_mapping(const struct wined3d_shader *shader)
|
||||
|
@ -4602,10 +4621,10 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
|
|||
if (priv->last_ps_const_clamped != ((struct arb_pshader_private *)ps->backend_data)->clamp_consts)
|
||||
{
|
||||
priv->last_ps_const_clamped = ((struct arb_pshader_private *)ps->backend_data)->clamp_consts;
|
||||
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, 8);
|
||||
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, 8);
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
context->pshader_const_dirty[i] = 1;
|
||||
priv->pshader_const_dirty[i] = 1;
|
||||
}
|
||||
/* Also takes care of loading local constants */
|
||||
shader_arb_load_constants(context, TRUE, FALSE);
|
||||
|
@ -4799,14 +4818,34 @@ static const struct wine_rb_functions sig_tree_functions =
|
|||
static HRESULT shader_arb_alloc(struct wined3d_device *device)
|
||||
{
|
||||
struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
|
||||
|
||||
priv->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(*priv->vshader_const_dirty) * device->d3d_vshader_constantF);
|
||||
if (!priv->vshader_const_dirty)
|
||||
goto fail;
|
||||
memset(priv->vshader_const_dirty, 1,
|
||||
sizeof(*priv->vshader_const_dirty) * device->d3d_vshader_constantF);
|
||||
|
||||
priv->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(*priv->pshader_const_dirty) * device->d3d_pshader_constantF);
|
||||
if (!priv->pshader_const_dirty)
|
||||
goto fail;
|
||||
memset(priv->pshader_const_dirty, 1,
|
||||
sizeof(*priv->pshader_const_dirty) * device->d3d_pshader_constantF);
|
||||
|
||||
if(wine_rb_init(&priv->signature_tree, &sig_tree_functions) == -1)
|
||||
{
|
||||
ERR("RB tree init failed\n");
|
||||
HeapFree(GetProcessHeap(), 0, priv);
|
||||
return E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
device->shader_priv = priv;
|
||||
return WINED3D_OK;
|
||||
|
||||
fail:
|
||||
HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, priv);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
static void release_signature(struct wine_rb_entry *entry, void *context)
|
||||
|
@ -4846,12 +4885,17 @@ static void shader_arb_free(struct wined3d_device *device)
|
|||
LEAVE_GL();
|
||||
|
||||
wine_rb_destroy(&priv->signature_tree, release_signature, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, device->shader_priv);
|
||||
}
|
||||
|
||||
static BOOL shader_arb_dirty_const(void)
|
||||
static void shader_arb_context_destroyed(void *shader_priv, const struct wined3d_context *context)
|
||||
{
|
||||
return TRUE;
|
||||
struct shader_arb_priv *priv = shader_priv;
|
||||
|
||||
if (priv->last_context == context)
|
||||
priv->last_context = NULL;
|
||||
}
|
||||
|
||||
static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
|
||||
|
@ -5481,7 +5525,7 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend =
|
|||
shader_arb_destroy,
|
||||
shader_arb_alloc,
|
||||
shader_arb_free,
|
||||
shader_arb_dirty_const,
|
||||
shader_arb_context_destroyed,
|
||||
shader_arb_get_caps,
|
||||
shader_arb_color_fixup_supported,
|
||||
};
|
||||
|
@ -5612,10 +5656,13 @@ static void state_texfactor_arbfp(struct wined3d_context *context,
|
|||
* otherwise we'll overwrite application provided constants. */
|
||||
if (device->shader_backend == &arb_program_shader_backend)
|
||||
{
|
||||
struct shader_arb_priv *priv;
|
||||
|
||||
if (use_ps(state)) return;
|
||||
|
||||
context->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
|
||||
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1);
|
||||
priv = device->shader_priv;
|
||||
priv->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
|
||||
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1);
|
||||
}
|
||||
|
||||
D3DCOLORTOGLFLOAT4(state->render_states[WINED3DRS_TEXTUREFACTOR], col);
|
||||
|
@ -5635,10 +5682,13 @@ static void state_arb_specularenable(struct wined3d_context *context,
|
|||
*/
|
||||
if (device->shader_backend == &arb_program_shader_backend)
|
||||
{
|
||||
struct shader_arb_priv *priv;
|
||||
|
||||
if (use_ps(state)) return;
|
||||
|
||||
context->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
|
||||
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
|
||||
priv = device->shader_priv;
|
||||
priv->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
|
||||
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
|
||||
}
|
||||
|
||||
if (state->render_states[WINED3DRS_SPECULARENABLE])
|
||||
|
@ -5676,9 +5726,12 @@ static void set_bumpmat_arbfp(struct wined3d_context *context, const struct wine
|
|||
/* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
|
||||
return;
|
||||
}
|
||||
} else if(device->shader_backend == &arb_program_shader_backend) {
|
||||
context->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
|
||||
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_BUMPMAT(stage) + 1);
|
||||
}
|
||||
else if (device->shader_backend == &arb_program_shader_backend)
|
||||
{
|
||||
struct shader_arb_priv *priv = device->shader_priv;
|
||||
priv->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
|
||||
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_BUMPMAT(stage) + 1);
|
||||
}
|
||||
|
||||
mat[0][0] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT00]);
|
||||
|
@ -5713,9 +5766,12 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context,
|
|||
/* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
|
||||
return;
|
||||
}
|
||||
} else if(device->shader_backend == &arb_program_shader_backend) {
|
||||
context->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
|
||||
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_LUMINANCE(stage) + 1);
|
||||
}
|
||||
else if (device->shader_backend == &arb_program_shader_backend)
|
||||
{
|
||||
struct shader_arb_priv *priv = device->shader_priv;
|
||||
priv->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
|
||||
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_LUMINANCE(stage) + 1);
|
||||
}
|
||||
|
||||
param[0] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVLSCALE]);
|
||||
|
|
|
@ -1340,25 +1340,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (device->shader_backend->shader_dirtifyable_constants())
|
||||
{
|
||||
/* Create the dirty constants array and initialize them to dirty */
|
||||
ret->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF);
|
||||
if (!ret->vshader_const_dirty)
|
||||
goto out;
|
||||
|
||||
ret->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF);
|
||||
if (!ret->pshader_const_dirty)
|
||||
goto out;
|
||||
|
||||
memset(ret->vshader_const_dirty, 1,
|
||||
sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF);
|
||||
memset(ret->pshader_const_dirty, 1,
|
||||
sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF);
|
||||
}
|
||||
|
||||
ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
gl_info->limits.buffers * sizeof(*ret->blit_targets));
|
||||
if (!ret->blit_targets)
|
||||
|
@ -1655,8 +1636,6 @@ out:
|
|||
HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
|
||||
HeapFree(GetProcessHeap(), 0, ret->draw_buffers);
|
||||
HeapFree(GetProcessHeap(), 0, ret->blit_targets);
|
||||
HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, ret);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1682,8 +1661,6 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont
|
|||
|
||||
HeapFree(GetProcessHeap(), 0, context->draw_buffers);
|
||||
HeapFree(GetProcessHeap(), 0, context->blit_targets);
|
||||
HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
|
||||
HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
|
||||
device_context_remove(device, context);
|
||||
if (destroy) HeapFree(GetProcessHeap(), 0, context);
|
||||
}
|
||||
|
@ -2455,7 +2432,7 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d
|
|||
}
|
||||
|
||||
/* Do not call while under the GL lock. */
|
||||
struct wined3d_context *context_acquire(struct wined3d_device *device, struct wined3d_surface *target)
|
||||
struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target)
|
||||
{
|
||||
struct wined3d_context *current_context = context_get_current();
|
||||
struct wined3d_context *context;
|
||||
|
@ -2522,19 +2499,6 @@ struct wined3d_context *context_acquire(struct wined3d_device *device, struct wi
|
|||
device->frag_pipe->enable_extension(!context->last_was_blit);
|
||||
LEAVE_GL();
|
||||
}
|
||||
|
||||
if (context->vshader_const_dirty)
|
||||
{
|
||||
memset(context->vshader_const_dirty, 1,
|
||||
sizeof(*context->vshader_const_dirty) * device->d3d_vshader_constantF);
|
||||
device->highest_dirty_vs_const = device->d3d_vshader_constantF;
|
||||
}
|
||||
if (context->pshader_const_dirty)
|
||||
{
|
||||
memset(context->pshader_const_dirty, 1,
|
||||
sizeof(*context->pshader_const_dirty) * device->d3d_pshader_constantF);
|
||||
device->highest_dirty_ps_const = device->d3d_pshader_constantF;
|
||||
}
|
||||
}
|
||||
else if (context->restore_ctx)
|
||||
{
|
||||
|
|
|
@ -1351,8 +1351,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
|
|||
|
||||
if (wined3d_settings.logo)
|
||||
device_load_logo(device, wined3d_settings.logo);
|
||||
device->highest_dirty_ps_const = 0;
|
||||
device->highest_dirty_vs_const = 0;
|
||||
return WINED3D_OK;
|
||||
|
||||
err_out:
|
||||
|
|
|
@ -4909,11 +4909,7 @@ static void shader_glsl_free(struct wined3d_device *device)
|
|||
device->shader_priv = NULL;
|
||||
}
|
||||
|
||||
static BOOL shader_glsl_dirty_const(void)
|
||||
{
|
||||
/* TODO: GL_EXT_bindable_uniform can be used to share constants across shaders */
|
||||
return FALSE;
|
||||
}
|
||||
static void shader_glsl_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
|
||||
|
||||
static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
|
||||
{
|
||||
|
@ -5109,7 +5105,7 @@ const struct wined3d_shader_backend_ops glsl_shader_backend =
|
|||
shader_glsl_destroy,
|
||||
shader_glsl_alloc,
|
||||
shader_glsl_free,
|
||||
shader_glsl_dirty_const,
|
||||
shader_glsl_context_destroyed,
|
||||
shader_glsl_get_caps,
|
||||
shader_glsl_color_fixup_supported,
|
||||
};
|
||||
|
|
|
@ -1502,7 +1502,7 @@ static void shader_none_load_np2fixup_constants(void *shader_priv,
|
|||
static void shader_none_destroy(struct wined3d_shader *shader) {}
|
||||
static HRESULT shader_none_alloc(struct wined3d_device *device) {return WINED3D_OK;}
|
||||
static void shader_none_free(struct wined3d_device *device) {}
|
||||
static BOOL shader_none_dirty_const(void) {return FALSE;}
|
||||
static void shader_none_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
|
||||
|
||||
static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
|
||||
{
|
||||
|
@ -1547,7 +1547,7 @@ const struct wined3d_shader_backend_ops none_shader_backend =
|
|||
shader_none_destroy,
|
||||
shader_none_alloc,
|
||||
shader_none_free,
|
||||
shader_none_dirty_const,
|
||||
shader_none_context_destroyed,
|
||||
shader_none_get_caps,
|
||||
shader_none_color_fixup_supported,
|
||||
};
|
||||
|
|
|
@ -762,7 +762,7 @@ struct wined3d_shader_backend_ops
|
|||
void (*shader_destroy)(struct wined3d_shader *shader);
|
||||
HRESULT (*shader_alloc_private)(struct wined3d_device *device);
|
||||
void (*shader_free_private)(struct wined3d_device *device);
|
||||
BOOL (*shader_dirtifyable_constants)(void);
|
||||
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);
|
||||
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
|
||||
};
|
||||
|
@ -1093,8 +1093,6 @@ struct wined3d_context
|
|||
DWORD active_texture;
|
||||
DWORD texture_type[MAX_COMBINED_SAMPLERS];
|
||||
|
||||
char *vshader_const_dirty, *pshader_const_dirty;
|
||||
|
||||
/* The actual opengl context */
|
||||
UINT level;
|
||||
HGLRC restore_ctx;
|
||||
|
@ -1228,7 +1226,8 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
|
|||
struct wined3d_surface *src_surface, const RECT *src_rect,
|
||||
struct wined3d_surface *dst_surface, const RECT *dst_rect) DECLSPEC_HIDDEN;
|
||||
|
||||
struct wined3d_context *context_acquire(struct wined3d_device *device, struct wined3d_surface *target) DECLSPEC_HIDDEN;
|
||||
struct wined3d_context *context_acquire(const struct wined3d_device *device,
|
||||
struct wined3d_surface *target) DECLSPEC_HIDDEN;
|
||||
void context_alloc_event_query(struct wined3d_context *context,
|
||||
struct wined3d_event_query *query) DECLSPEC_HIDDEN;
|
||||
void context_alloc_occlusion_query(struct wined3d_context *context,
|
||||
|
@ -1705,7 +1704,6 @@ struct wined3d_device
|
|||
|
||||
struct list resources; /* a linked list to track resources created by the device */
|
||||
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
|
||||
unsigned int highest_dirty_ps_const, highest_dirty_vs_const;
|
||||
|
||||
/* Render Target Support */
|
||||
DWORD valid_rt_mask;
|
||||
|
|
Loading…
Reference in New Issue