wined3d: Force ARB shader programs reselection on bool/int constant changes.
The ARB shader backend hardcodes some constant-dependent state in the shader itself (e.g. branch taken/not taken). So, we have to make sure to update the selected ARB shader when the application modifies non-float constants.
This commit is contained in:
parent
f89f30e0c0
commit
7cc4f47afe
|
@ -625,6 +625,8 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
|
||||||
checkGLcall("Load vs int consts");
|
checkGLcall("Load vs int consts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
|
* Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
|
||||||
*
|
*
|
||||||
|
@ -632,13 +634,38 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
|
||||||
* worry about the Integers or Booleans
|
* worry about the Integers or Booleans
|
||||||
*/
|
*/
|
||||||
/* GL locking is done by the caller (state handler) */
|
/* GL locking is done by the caller (state handler) */
|
||||||
static void shader_arb_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader)
|
static void shader_arb_load_constants_internal(const struct wined3d_context *context,
|
||||||
|
char usePixelShader, char useVertexShader, BOOL from_shader_select)
|
||||||
{
|
{
|
||||||
struct wined3d_device *device = context->swapchain->device;
|
struct wined3d_device *device = context->swapchain->device;
|
||||||
const struct wined3d_state *state = &device->stateBlock->state;
|
const struct wined3d_stateblock *stateblock = device->stateBlock;
|
||||||
|
const struct wined3d_state *state = &stateblock->state;
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
struct shader_arb_priv *priv = device->shader_priv;
|
struct shader_arb_priv *priv = device->shader_priv;
|
||||||
|
|
||||||
|
if (!from_shader_select)
|
||||||
|
{
|
||||||
|
const struct wined3d_shader *vshader = state->vertex_shader, *pshader = state->pixel_shader;
|
||||||
|
if (vshader
|
||||||
|
&& (stateblock->changed.vertexShaderConstantsB & vshader->reg_maps.boolean_constants
|
||||||
|
|| (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]
|
||||||
|
&& (stateblock->changed.vertexShaderConstantsI
|
||||||
|
& vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts))))
|
||||||
|
{
|
||||||
|
TRACE("bool/integer vertex shader constants potentially modified, forcing shader reselection.\n");
|
||||||
|
shader_arb_select(context, usePixelShader, useVertexShader);
|
||||||
|
}
|
||||||
|
else if (pshader
|
||||||
|
&& (stateblock->changed.pixelShaderConstantsB & pshader->reg_maps.boolean_constants
|
||||||
|
|| (!gl_info->supported[NV_FRAGMENT_PROGRAM_OPTION]
|
||||||
|
&& (stateblock->changed.pixelShaderConstantsI
|
||||||
|
& pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts))))
|
||||||
|
{
|
||||||
|
TRACE("bool/integer pixel shader constants potentially modified, forcing shader reselection.\n");
|
||||||
|
shader_arb_select(context, usePixelShader, useVertexShader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (context != priv->last_context)
|
if (context != priv->last_context)
|
||||||
{
|
{
|
||||||
memset(priv->vshader_const_dirty, 1,
|
memset(priv->vshader_const_dirty, 1,
|
||||||
|
@ -676,6 +703,11 @@ static void shader_arb_load_constants(const struct wined3d_context *context, cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void shader_arb_load_constants(const struct wined3d_context *context, char ps, char vs)
|
||||||
|
{
|
||||||
|
shader_arb_load_constants_internal(context, ps, vs, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
|
static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
|
||||||
{
|
{
|
||||||
struct wined3d_context *context = context_get_current();
|
struct wined3d_context *context = context_get_current();
|
||||||
|
@ -4662,7 +4694,7 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
|
||||||
priv->pshader_const_dirty[i] = 1;
|
priv->pshader_const_dirty[i] = 1;
|
||||||
}
|
}
|
||||||
/* Also takes care of loading local constants */
|
/* Also takes care of loading local constants */
|
||||||
shader_arb_load_constants(context, TRUE, FALSE);
|
shader_arb_load_constants_internal(context, TRUE, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue