wined3d: Enforce a stable texture units mapping.
The GLSL shader backend hardcodes the sampler uniforms at program link time, it can't handle a change in the mapping between draws with the same shader program. Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
750dc790b7
commit
d6c8146633
|
@ -2542,6 +2542,7 @@ static void context_map_stage(struct wined3d_context *context, DWORD stage, DWOR
|
||||||
DWORD i = context->rev_tex_unit_map[unit];
|
DWORD i = context->rev_tex_unit_map[unit];
|
||||||
DWORD j = context->tex_unit_map[stage];
|
DWORD j = context->tex_unit_map[stage];
|
||||||
|
|
||||||
|
TRACE("Mapping stage %u to unit %u.\n", stage, unit);
|
||||||
context->tex_unit_map[stage] = unit;
|
context->tex_unit_map[stage] = unit;
|
||||||
if (i != WINED3D_UNMAPPED_STAGE && i != stage)
|
if (i != WINED3D_UNMAPPED_STAGE && i != stage)
|
||||||
context->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE;
|
context->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE;
|
||||||
|
@ -2688,8 +2689,7 @@ static void context_map_psamplers(struct wined3d_context *context, const struct
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
|
static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
|
||||||
const struct wined3d_shader_resource_info *ps_resource_info,
|
const struct wined3d_shader_resource_info *ps_resource_info, DWORD unit)
|
||||||
const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
|
|
||||||
{
|
{
|
||||||
DWORD current_mapping = context->rev_tex_unit_map[unit];
|
DWORD current_mapping = context->rev_tex_unit_map[unit];
|
||||||
|
|
||||||
|
@ -2711,8 +2711,7 @@ static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
|
||||||
return !ps_resource_info[current_mapping].type;
|
return !ps_resource_info[current_mapping].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used by a vertex sampler */
|
return TRUE;
|
||||||
return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
|
static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
|
||||||
|
@ -2738,18 +2737,15 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
|
||||||
DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
|
DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
|
||||||
if (vs_resource_info[i].type)
|
if (vs_resource_info[i].type)
|
||||||
{
|
{
|
||||||
if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
|
|
||||||
{
|
|
||||||
/* Already mapped somewhere */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (start >= 0)
|
while (start >= 0)
|
||||||
{
|
{
|
||||||
if (context_unit_free_for_vs(context, ps_resource_info, vs_resource_info, start))
|
if (context_unit_free_for_vs(context, ps_resource_info, start))
|
||||||
|
{
|
||||||
|
if (context->tex_unit_map[vsampler_idx] != start)
|
||||||
{
|
{
|
||||||
context_map_stage(context, vsampler_idx, start);
|
context_map_stage(context, vsampler_idx, start);
|
||||||
context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
|
context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
|
||||||
|
}
|
||||||
|
|
||||||
--start;
|
--start;
|
||||||
break;
|
break;
|
||||||
|
@ -2757,6 +2753,8 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
|
||||||
|
|
||||||
--start;
|
--start;
|
||||||
}
|
}
|
||||||
|
if (context->tex_unit_map[vsampler_idx] == WINED3D_UNMAPPED_STAGE)
|
||||||
|
WARN("Couldn't find a free texture unit for vertex sampler %u.\n", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2765,13 +2763,12 @@ static void context_update_tex_unit_map(struct wined3d_context *context, const s
|
||||||
{
|
{
|
||||||
BOOL vs = use_vs(state);
|
BOOL vs = use_vs(state);
|
||||||
BOOL ps = use_ps(state);
|
BOOL ps = use_ps(state);
|
||||||
/*
|
|
||||||
* Rules are:
|
/* Try to go for a 1:1 mapping of the samplers when possible. Pixel shaders
|
||||||
* -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but
|
* need a 1:1 map at the moment.
|
||||||
* that would be really messy and require shader recompilation
|
* When the mapping of a stage is changed, sampler and ALL texture stage
|
||||||
* -> When the mapping of a stage is changed, sampler and ALL texture stage states have
|
* states have to be reset. */
|
||||||
* to be reset. Because of that try to work with a 1:1 mapping as much as possible
|
|
||||||
*/
|
|
||||||
if (ps)
|
if (ps)
|
||||||
context_map_psamplers(context, state);
|
context_map_psamplers(context, state);
|
||||||
else
|
else
|
||||||
|
|
|
@ -7095,13 +7095,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
|
||||||
GL_EXTCALL(glUseProgram(program_id));
|
GL_EXTCALL(glUseProgram(program_id));
|
||||||
checkGLcall("glUseProgram");
|
checkGLcall("glUseProgram");
|
||||||
|
|
||||||
/* Load the vertex and pixel samplers now. The function that finds the mappings makes sure
|
/* Texture unit mapping is set up to be the same each time the shader
|
||||||
* that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If
|
* program is used so we can hardcode the sampler uniform values. */
|
||||||
* a pshader with fixed function pipeline is used there are no vertex samplers, and if a
|
|
||||||
* vertex shader with fixed function pixel processing is used we make sure that the card
|
|
||||||
* supports enough samplers to allow the max number of vertex samplers with all possible
|
|
||||||
* fixed function fragment processing setups. So once the program is linked these samplers
|
|
||||||
* won't change. */
|
|
||||||
shader_glsl_load_samplers(gl_info, priv, context->tex_unit_map, program_id);
|
shader_glsl_load_samplers(gl_info, priv, context->tex_unit_map, program_id);
|
||||||
|
|
||||||
entry->constant_update_mask = 0;
|
entry->constant_update_mask = 0;
|
||||||
|
|
Loading…
Reference in New Issue