Module: wine
Branch: master
Commit: d6c814663353d4449e67b6392dce203ffd32b8f4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d6c814663353d4449e67b6392…
Author: Matteo Bruni <mbruni(a)codeweavers.com>
Date: Thu Nov 12 23:06:42 2015 +0100
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(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/wined3d/context.c | 37 +++++++++++++++++--------------------
dlls/wined3d/glsl_shader.c | 9 ++-------
2 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 9203905..80a9ba7 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -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 j = context->tex_unit_map[stage];
+ TRACE("Mapping stage %u to unit %u.\n", stage, unit);
context->tex_unit_map[stage] = unit;
if (i != WINED3D_UNMAPPED_STAGE && i != 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,
- const struct wined3d_shader_resource_info *ps_resource_info,
- const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
+ const struct wined3d_shader_resource_info *ps_resource_info, DWORD 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;
}
- /* Used by a vertex sampler */
- return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
+ return TRUE;
}
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;
if (vs_resource_info[i].type)
{
- if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
- {
- /* Already mapped somewhere */
- continue;
- }
-
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))
{
- context_map_stage(context, vsampler_idx, start);
- context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
+ if (context->tex_unit_map[vsampler_idx] != start)
+ {
+ context_map_stage(context, vsampler_idx, start);
+ context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
+ }
--start;
break;
@@ -2757,6 +2753,8 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
--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 ps = use_ps(state);
- /*
- * Rules are:
- * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but
- * that would be really messy and require shader recompilation
- * -> When the mapping of a stage is changed, sampler and ALL texture stage states have
- * to be reset. Because of that try to work with a 1:1 mapping as much as possible
- */
+
+ /* Try to go for a 1:1 mapping of the samplers when possible. Pixel shaders
+ * need a 1:1 map at the moment.
+ * When the mapping of a stage is changed, sampler and ALL texture stage
+ * states have to be reset. */
+
if (ps)
context_map_psamplers(context, state);
else
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 44e7090..abfaef8 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -7095,13 +7095,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
GL_EXTCALL(glUseProgram(program_id));
checkGLcall("glUseProgram");
- /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure
- * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If
- * 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. */
+ /* Texture unit mapping is set up to be the same each time the shader
+ * program is used so we can hardcode the sampler uniform values. */
shader_glsl_load_samplers(gl_info, priv, context->tex_unit_map, program_id);
entry->constant_update_mask = 0;