[PATCH 3/5] wined3d: Move tex_unit_map and friends into the context
Stefan Dösinger
stefan at codeweavers.com
Fri Sep 13 05:40:34 CDT 2013
---
dlls/wined3d/arb_program_shader.c | 8 +-
dlls/wined3d/ati_fragment_shader.c | 2 +-
dlls/wined3d/context.c | 236 ++++++++++++++++++++++++++++++++++-
dlls/wined3d/device.c | 231 +---------------------------------
dlls/wined3d/drawprim.c | 4 +-
dlls/wined3d/glsl_shader.c | 5 +-
dlls/wined3d/nvidia_texture_shader.c | 9 +-
dlls/wined3d/state.c | 25 ++--
dlls/wined3d/surface.c | 7 +-
dlls/wined3d/utils.c | 2 +-
dlls/wined3d/volume.c | 4 +-
dlls/wined3d/wined3d_private.h | 32 ++---
12 files changed, 279 insertions(+), 286 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index ec4cb89..631c2ea 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -4574,7 +4574,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
const struct wined3d_context *context, const struct wined3d_shader *shader,
struct arb_vs_compile_args *args)
{
- struct wined3d_device *device = shader->device;
+ const struct wined3d_device *device = shader->device;
const struct wined3d_adapter *adapter = device->adapter;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
@@ -4618,9 +4618,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
args->clip.boolclip.bools |= ( 1 << i);
}
- args->vertex.samplers[0] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 0];
- args->vertex.samplers[1] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 1];
- args->vertex.samplers[2] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 2];
+ args->vertex.samplers[0] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 0];
+ args->vertex.samplers[1] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 1];
+ args->vertex.samplers[2] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 2];
args->vertex.samplers[3] = 0;
/* Skip if unused or local */
diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c
index cf35f64..8fc7909 100644
--- a/dlls/wined3d/ati_fragment_shader.c
+++ b/dlls/wined3d/ati_fragment_shader.c
@@ -874,7 +874,7 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined
*/
for (i = 0; i < desc->num_textures_used; ++i)
{
- mapped_stage = device->texUnitMap[i];
+ mapped_stage = context->tex_unit_map[i];
if (mapped_stage != WINED3D_UNMAPPED_STAGE)
{
context_active_texture(context, gl_info, mapped_stage);
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index b69a520..a6f27dc 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1350,6 +1350,21 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
goto out;
}
+ /* Initialize the texture unit mapping to a 1:1 mapping */
+ for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s)
+ {
+ if (s < gl_info->limits.fragment_samplers)
+ {
+ ret->tex_unit_map[s] = s;
+ ret->rev_tex_unit_map[s] = s;
+ }
+ else
+ {
+ ret->tex_unit_map[s] = WINED3D_UNMAPPED_STAGE;
+ ret->rev_tex_unit_map[s] = WINED3D_UNMAPPED_STAGE;
+ }
+ }
+
if (!(hdc = GetDC(swapchain->win_handle)))
{
WARN("Failed to retireve device context, trying swapchain backup.\n");
@@ -1772,7 +1787,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
*/
for (i = gl_info->limits.textures - 1; i > 0 ; --i)
{
- sampler = device->rev_tex_unit_map[i];
+ sampler = context->rev_tex_unit_map[i];
context_active_texture(context, gl_info, i);
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
@@ -1802,7 +1817,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
}
context_active_texture(context, gl_info, 0);
- sampler = device->rev_tex_unit_map[0];
+ sampler = context->rev_tex_unit_map[0];
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
{
@@ -2328,6 +2343,221 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
}
}
+static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit)
+{
+ DWORD i = context->rev_tex_unit_map[unit];
+ DWORD j = context->tex_unit_map[stage];
+
+ context->tex_unit_map[stage] = unit;
+ if (i != WINED3D_UNMAPPED_STAGE && i != stage)
+ context->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE;
+
+ context->rev_tex_unit_map[unit] = stage;
+ if (j != WINED3D_UNMAPPED_STAGE && j != unit)
+ context->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE;
+}
+
+static void context_invalidate_texture_stage(struct wined3d_context *context, DWORD stage)
+{
+ DWORD i;
+
+ for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
+ context_invalidate_state(context, STATE_TEXTURESTAGE(stage, i));
+}
+
+static void context_update_fixed_function_usage_map(struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ UINT i;
+
+ context->fixed_function_usage_map = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP];
+ enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
+ DWORD color_arg1 = state->texture_states[i][WINED3D_TSS_COLOR_ARG1] & WINED3DTA_SELECTMASK;
+ DWORD color_arg2 = state->texture_states[i][WINED3D_TSS_COLOR_ARG2] & WINED3DTA_SELECTMASK;
+ DWORD color_arg3 = state->texture_states[i][WINED3D_TSS_COLOR_ARG0] & WINED3DTA_SELECTMASK;
+ DWORD alpha_arg1 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] & WINED3DTA_SELECTMASK;
+ DWORD alpha_arg2 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] & WINED3DTA_SELECTMASK;
+ DWORD alpha_arg3 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] & WINED3DTA_SELECTMASK;
+
+ /* Not used, and disable higher stages. */
+ if (color_op == WINED3D_TOP_DISABLE)
+ break;
+
+ if (((color_arg1 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG2)
+ || ((color_arg2 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG1)
+ || ((color_arg3 == WINED3DTA_TEXTURE)
+ && (color_op == WINED3D_TOP_MULTIPLY_ADD || color_op == WINED3D_TOP_LERP))
+ || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG2)
+ || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG1)
+ || ((alpha_arg3 == WINED3DTA_TEXTURE)
+ && (alpha_op == WINED3D_TOP_MULTIPLY_ADD || alpha_op == WINED3D_TOP_LERP)))
+ context->fixed_function_usage_map |= (1 << i);
+
+ if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ && i < MAX_TEXTURES - 1)
+ context->fixed_function_usage_map |= (1 << (i + 1));
+ }
+}
+
+static void context_map_fixed_function_samplers(struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ unsigned int i, tex;
+ WORD ffu_map;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+
+ context_update_fixed_function_usage_map(context, state);
+ ffu_map = context->fixed_function_usage_map;
+
+ if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages
+ || state->lowest_disabled_stage <= d3d_info->limits.ffp_textures)
+ {
+ for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+ {
+ if (!(ffu_map & 1))
+ continue;
+
+ if (context->tex_unit_map[i] != i)
+ {
+ context_map_stage(context, i, i);
+ context_invalidate_state(context, STATE_SAMPLER(i));
+ context_invalidate_texture_stage(context, i);
+ }
+ }
+ return;
+ }
+
+ /* Now work out the mapping */
+ tex = 0;
+ for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+ {
+ if (!(ffu_map & 1))
+ continue;
+
+ if (context->tex_unit_map[i] != tex)
+ {
+ context_map_stage(context, i, tex);
+ context_invalidate_state(context, STATE_SAMPLER(i));
+ context_invalidate_texture_stage(context, i);
+ }
+
+ ++tex;
+ }
+}
+
+static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state)
+{
+ const enum wined3d_sampler_texture_type *sampler_type =
+ state->pixel_shader->reg_maps.sampler_type;
+ unsigned int i;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (sampler_type[i] && context->tex_unit_map[i] != i)
+ {
+ context_map_stage(context, i, i);
+ context_invalidate_state(context, STATE_SAMPLER(i));
+ if (i < d3d_info->limits.ffp_blend_stages)
+ context_invalidate_texture_stage(context, i);
+ }
+ }
+}
+
+static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
+ const enum wined3d_sampler_texture_type *pshader_sampler_tokens,
+ const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit)
+{
+ DWORD current_mapping = context->rev_tex_unit_map[unit];
+
+ /* Not currently used */
+ if (current_mapping == WINED3D_UNMAPPED_STAGE)
+ return TRUE;
+
+ if (current_mapping < MAX_FRAGMENT_SAMPLERS)
+ {
+ /* Used by a fragment sampler */
+
+ if (!pshader_sampler_tokens)
+ {
+ /* No pixel shader, check fixed function */
+ return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping));
+ }
+
+ /* Pixel shader, check the shader's sampler map */
+ return !pshader_sampler_tokens[current_mapping];
+ }
+
+ /* Used by a vertex sampler */
+ return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
+}
+
+static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
+{
+ const enum wined3d_sampler_texture_type *vshader_sampler_type =
+ state->vertex_shader->reg_maps.sampler_type;
+ const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
+ int i;
+
+ if (ps)
+ {
+ /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
+ * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
+ pshader_sampler_type = state->pixel_shader->reg_maps.sampler_type;
+ }
+
+ for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
+ DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
+ if (vshader_sampler_type[i])
+ {
+ if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
+ {
+ /* Already mapped somewhere */
+ continue;
+ }
+
+ while (start >= 0)
+ {
+ if (context_unit_free_for_vs(context, pshader_sampler_type, vshader_sampler_type, start))
+ {
+ context_map_stage(context, vsampler_idx, start);
+ context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
+
+ --start;
+ break;
+ }
+
+ --start;
+ }
+ }
+ }
+}
+
+static void context_update_tex_unit_map(struct wined3d_context *context, const struct wined3d_state *state)
+{
+ 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
+ */
+ if (ps)
+ context_map_psamplers(context, state);
+ else
+ context_map_fixed_function_samplers(context, state);
+
+ if (vs)
+ context_map_vsamplers(context, ps, state);
+}
+
/* Context activation is done by the caller. */
void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
@@ -2576,7 +2806,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
/* Preload resources before FBO setup. Texture preload in particular may
* result in changes to the current FBO, due to using e.g. FBO blits for
* updating a resource location. */
- device_update_tex_unit_map(device);
+ context_update_tex_unit_map(context, state);
device_preload_textures(device, context);
if (isStateDirty(context, STATE_VDECL) || isStateDirty(context, STATE_STREAMSRC))
context_update_stream_info(context, state);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 13e62c7..97e499c 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -171,7 +171,7 @@ void device_preload_textures(const struct wined3d_device *device, struct wined3d
}
else
{
- WORD ffu_map = device->fixed_function_usage_map;
+ WORD ffu_map = context->fixed_function_usage_map;
for (i = 0; ffu_map; ffu_map >>= 1, ++i)
{
@@ -882,7 +882,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
struct wined3d_swapchain *swapchain = NULL;
struct wined3d_context *context;
HRESULT hr;
- DWORD state;
TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc);
@@ -894,21 +893,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(*device->fb.render_targets) * gl_info->limits.buffers);
- /* Initialize the texture unit mapping to a 1:1 mapping */
- for (state = 0; state < MAX_COMBINED_SAMPLERS; ++state)
- {
- if (state < gl_info->limits.fragment_samplers)
- {
- device->texUnitMap[state] = state;
- device->rev_tex_unit_map[state] = state;
- }
- else
- {
- device->texUnitMap[state] = WINED3D_UNMAPPED_STAGE;
- device->rev_tex_unit_map[state] = WINED3D_UNMAPPED_STAGE;
- }
- }
-
if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
{
@@ -2451,217 +2435,6 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device
return WINED3D_OK;
}
-static void device_invalidate_texture_stage(const struct wined3d_device *device, DWORD stage)
-{
- DWORD i;
-
- for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
- {
- device_invalidate_state(device, STATE_TEXTURESTAGE(stage, i));
- }
-}
-
-static void device_map_stage(struct wined3d_device *device, DWORD stage, DWORD unit)
-{
- DWORD i = device->rev_tex_unit_map[unit];
- DWORD j = device->texUnitMap[stage];
-
- device->texUnitMap[stage] = unit;
- if (i != WINED3D_UNMAPPED_STAGE && i != stage)
- device->texUnitMap[i] = WINED3D_UNMAPPED_STAGE;
-
- device->rev_tex_unit_map[unit] = stage;
- if (j != WINED3D_UNMAPPED_STAGE && j != unit)
- device->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE;
-}
-
-static void device_update_fixed_function_usage_map(struct wined3d_device *device)
-{
- UINT i;
-
- device->fixed_function_usage_map = 0;
- for (i = 0; i < MAX_TEXTURES; ++i)
- {
- const struct wined3d_state *state = &device->state;
- enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP];
- enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
- DWORD color_arg1 = state->texture_states[i][WINED3D_TSS_COLOR_ARG1] & WINED3DTA_SELECTMASK;
- DWORD color_arg2 = state->texture_states[i][WINED3D_TSS_COLOR_ARG2] & WINED3DTA_SELECTMASK;
- DWORD color_arg3 = state->texture_states[i][WINED3D_TSS_COLOR_ARG0] & WINED3DTA_SELECTMASK;
- DWORD alpha_arg1 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] & WINED3DTA_SELECTMASK;
- DWORD alpha_arg2 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] & WINED3DTA_SELECTMASK;
- DWORD alpha_arg3 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] & WINED3DTA_SELECTMASK;
-
- /* Not used, and disable higher stages. */
- if (color_op == WINED3D_TOP_DISABLE)
- break;
-
- if (((color_arg1 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG2)
- || ((color_arg2 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG1)
- || ((color_arg3 == WINED3DTA_TEXTURE)
- && (color_op == WINED3D_TOP_MULTIPLY_ADD || color_op == WINED3D_TOP_LERP))
- || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG2)
- || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG1)
- || ((alpha_arg3 == WINED3DTA_TEXTURE)
- && (alpha_op == WINED3D_TOP_MULTIPLY_ADD || alpha_op == WINED3D_TOP_LERP)))
- device->fixed_function_usage_map |= (1 << i);
-
- if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
- && i < MAX_TEXTURES - 1)
- device->fixed_function_usage_map |= (1 << (i + 1));
- }
-}
-
-static void device_map_fixed_function_samplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info)
-{
- unsigned int i, tex;
- WORD ffu_map;
-
- device_update_fixed_function_usage_map(device);
- ffu_map = device->fixed_function_usage_map;
-
- if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages
- || device->state.lowest_disabled_stage <= d3d_info->limits.ffp_textures)
- {
- for (i = 0; ffu_map; ffu_map >>= 1, ++i)
- {
- if (!(ffu_map & 1)) continue;
-
- if (device->texUnitMap[i] != i)
- {
- device_map_stage(device, i, i);
- device_invalidate_state(device, STATE_SAMPLER(i));
- device_invalidate_texture_stage(device, i);
- }
- }
- return;
- }
-
- /* Now work out the mapping */
- tex = 0;
- for (i = 0; ffu_map; ffu_map >>= 1, ++i)
- {
- if (!(ffu_map & 1)) continue;
-
- if (device->texUnitMap[i] != tex)
- {
- device_map_stage(device, i, tex);
- device_invalidate_state(device, STATE_SAMPLER(i));
- device_invalidate_texture_stage(device, i);
- }
-
- ++tex;
- }
-}
-
-static void device_map_psamplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info)
-{
- const enum wined3d_sampler_texture_type *sampler_type =
- device->state.pixel_shader->reg_maps.sampler_type;
- unsigned int i;
-
- for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
- {
- if (sampler_type[i] && device->texUnitMap[i] != i)
- {
- device_map_stage(device, i, i);
- device_invalidate_state(device, STATE_SAMPLER(i));
- if (i < d3d_info->limits.ffp_blend_stages)
- device_invalidate_texture_stage(device, i);
- }
- }
-}
-
-static BOOL device_unit_free_for_vs(const struct wined3d_device *device,
- const enum wined3d_sampler_texture_type *pshader_sampler_tokens,
- const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit)
-{
- DWORD current_mapping = device->rev_tex_unit_map[unit];
-
- /* Not currently used */
- if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE;
-
- if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
- /* Used by a fragment sampler */
-
- if (!pshader_sampler_tokens) {
- /* No pixel shader, check fixed function */
- return current_mapping >= MAX_TEXTURES || !(device->fixed_function_usage_map & (1 << current_mapping));
- }
-
- /* Pixel shader, check the shader's sampler map */
- return !pshader_sampler_tokens[current_mapping];
- }
-
- /* Used by a vertex sampler */
- return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
-}
-
-static void device_map_vsamplers(struct wined3d_device *device, BOOL ps, const struct wined3d_gl_info *gl_info)
-{
- const enum wined3d_sampler_texture_type *vshader_sampler_type =
- device->state.vertex_shader->reg_maps.sampler_type;
- const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL;
- int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
- int i;
-
- if (ps)
- {
- /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
- * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
- pshader_sampler_type = device->state.pixel_shader->reg_maps.sampler_type;
- }
-
- for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
- DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
- if (vshader_sampler_type[i])
- {
- if (device->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
- {
- /* Already mapped somewhere */
- continue;
- }
-
- while (start >= 0)
- {
- if (device_unit_free_for_vs(device, pshader_sampler_type, vshader_sampler_type, start))
- {
- device_map_stage(device, vsampler_idx, start);
- device_invalidate_state(device, STATE_SAMPLER(vsampler_idx));
-
- --start;
- break;
- }
-
- --start;
- }
- }
- }
-}
-
-void device_update_tex_unit_map(struct wined3d_device *device)
-{
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
- const struct wined3d_state *state = &device->state;
- 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
- */
- if (ps)
- device_map_psamplers(device, d3d_info);
- else
- device_map_fixed_function_samplers(device, d3d_info);
-
- if (vs)
- device_map_vsamplers(device, ps, gl_info);
-}
-
void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader)
{
struct wined3d_shader *prev = device->update_state->pixel_shader;
@@ -4451,7 +4224,7 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device
context = context_acquire(device, NULL);
- invalidate_active_texture(device, context);
+ context_invalidate_active_texture(context);
/* Create a new cursor texture */
gl_info->gl_ops.gl.p_glGenTextures(1, &device->cursorTexture);
checkGLcall("glGenTextures");
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 0b4b3f7..81d2aba 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -194,7 +194,7 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_
for (textureNo = 0; textureNo < texture_stages; ++textureNo)
{
int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
- DWORD texture_idx = device->texUnitMap[textureNo];
+ DWORD texture_idx = context->tex_unit_map[textureNo];
if (!gl_info->supported[ARB_MULTITEXTURE] && textureNo > 0)
{
@@ -266,7 +266,7 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_
coord_idx = state->texture_states[texture][WINED3D_TSS_TEXCOORD_INDEX];
ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
- texture_idx = device->texUnitMap[texture];
+ texture_idx = context->tex_unit_map[texture];
ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
GL_TEXTURE0_ARB + texture_idx, ptr);
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 67de5ea..f30cd47 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -5783,7 +5783,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
GLhandleARB gs_id = 0;
GLhandleARB ps_id = 0;
struct list *ps_list, *vs_list;
- struct wined3d_device *device = context->swapchain->device;
if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX)))
{
@@ -5985,8 +5984,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
* fixed function fragment processing setups. So once the program is linked these samplers
* won't change.
*/
- shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId);
- shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId);
+ shader_glsl_load_vsamplers(gl_info, context->tex_unit_map, programId);
+ shader_glsl_load_psamplers(gl_info, context->tex_unit_map, programId);
entry->constant_update_mask = 0;
if (vshader)
diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c
index 7d4817e..285952a 100644
--- a/dlls/wined3d/nvidia_texture_shader.c
+++ b/dlls/wined3d/nvidia_texture_shader.c
@@ -477,9 +477,8 @@ void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d
static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
- const struct wined3d_device *device = context->swapchain->device;
- BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
- DWORD mapped_stage = device->texUnitMap[stage];
+ BOOL tex_used = context->fixed_function_usage_map & (1 << stage);
+ DWORD mapped_stage = context->tex_unit_map[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Setting color op for stage %u.\n", stage);
@@ -584,7 +583,7 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s
static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD sampler = state_id - STATE_SAMPLER(0);
- DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
+ DWORD mapped_stage = context->tex_unit_map[sampler];
/* No need to enable / disable anything here for unused samplers. The tex_colorop
* handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
@@ -602,7 +601,7 @@ static void nvts_texdim(struct wined3d_context *context, const struct wined3d_st
static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
- DWORD mapped_stage = context->swapchain->device->texUnitMap[stage + 1];
+ DWORD mapped_stage = context->tex_unit_map[stage + 1];
const struct wined3d_gl_info *gl_info = context->gl_info;
float mat[2][2];
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 36d9108..59c03a2 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3130,9 +3130,8 @@ static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined
static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
- const struct wined3d_device *device = context->swapchain->device;
- BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
- DWORD mapped_stage = device->texUnitMap[stage];
+ BOOL tex_used = context->fixed_function_usage_map & (1 << stage);
+ DWORD mapped_stage = context->tex_unit_map[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Setting color op for stage %d\n", stage);
@@ -3192,9 +3191,8 @@ static void tex_colorop(struct wined3d_context *context, const struct wined3d_st
void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
- const struct wined3d_device *device = context->swapchain->device;
- BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
- DWORD mapped_stage = device->texUnitMap[stage];
+ BOOL tex_used = context->fixed_function_usage_map & (1 << stage);
+ DWORD mapped_stage = context->tex_unit_map[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
DWORD op, arg1, arg2, arg0;
@@ -3295,7 +3293,7 @@ void transform_texture(struct wined3d_context *context, const struct wined3d_sta
DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
const struct wined3d_device *device = context->swapchain->device;
const struct wined3d_gl_info *gl_info = context->gl_info;
- DWORD mapped_stage = device->texUnitMap[texUnit];
+ DWORD mapped_stage = context->tex_unit_map[texUnit];
BOOL generated;
int coordIdx;
@@ -3351,7 +3349,6 @@ static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
GLuint *curVBO, const struct wined3d_state *state)
{
- const struct wined3d_device *device = context->swapchain->device;
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int mapped_stage = 0;
unsigned int textureNo = 0;
@@ -3360,7 +3357,7 @@ static void load_tex_coords(const struct wined3d_context *context, const struct
{
int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
- mapped_stage = device->texUnitMap[textureNo];
+ mapped_stage = context->tex_unit_map[textureNo];
if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
if (mapped_stage >= gl_info->limits.texture_coords)
@@ -3411,13 +3408,12 @@ static void load_tex_coords(const struct wined3d_context *context, const struct
static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
- const struct wined3d_device *device = context->swapchain->device;
static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const struct wined3d_gl_info *gl_info = context->gl_info;
- DWORD mapped_stage = device->texUnitMap[stage];
+ DWORD mapped_stage = context->tex_unit_map[stage];
if (mapped_stage == WINED3D_UNMAPPED_STAGE)
{
@@ -3605,24 +3601,21 @@ void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_sta
if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
{
- const struct wined3d_device *device = context->swapchain->device;
-
if (texIsPow2)
context->lastWasPow2Texture |= 1 << sampler;
else
context->lastWasPow2Texture &= ~(1 << sampler);
transform_texture(context, state,
- STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
+ STATE_TEXTURESTAGE(context->tex_unit_map[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
}
}
}
static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
- const struct wined3d_device *device = context->swapchain->device;
DWORD sampler = state_id - STATE_SAMPLER(0);
- DWORD mapped_stage = device->texUnitMap[sampler];
+ DWORD mapped_stage = context->tex_unit_map[sampler];
const struct wined3d_gl_info *gl_info = context->gl_info;
union {
float f;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index ab15870..22a2976 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -659,7 +659,6 @@ static void surface_bind(struct wined3d_surface *surface, struct wined3d_context
static void surface_bind_and_dirtify(struct wined3d_surface *surface,
struct wined3d_context *context, BOOL srgb)
{
- struct wined3d_device *device = surface->resource.device;
DWORD active_sampler;
/* We don't need a specific texture unit, but after binding the texture
@@ -671,10 +670,10 @@ static void surface_bind_and_dirtify(struct wined3d_surface *surface,
* called from sampler() in state.c. This means we can't touch anything
* other than whatever happens to be the currently active texture, or we
* would risk marking already applied sampler states dirty again. */
- active_sampler = device->rev_tex_unit_map[context->active_texture];
+ active_sampler = context->rev_tex_unit_map[context->active_texture];
if (active_sampler != WINED3D_UNMAPPED_STAGE)
- device_invalidate_state(device, STATE_SAMPLER(active_sampler));
+ context_invalidate_state(context, STATE_SAMPLER(active_sampler));
surface_bind(surface, context, srgb);
}
@@ -2254,7 +2253,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data);
- invalidate_active_texture(dst_surface->resource.device, context);
+ context_invalidate_active_texture(context);
context_release(context);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 9a56031..6eafb85 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3497,7 +3497,7 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st
void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD sampler = state_id - STATE_SAMPLER(0);
- DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
+ DWORD mapped_stage = context->tex_unit_map[sampler];
/* No need to enable / disable anything here for unused samplers. The
* tex_colorop handler takes care. Also no action is needed with pixel
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 7f2dbf9..e9408f0 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -42,10 +42,10 @@ static void volume_bind_and_dirtify(const struct wined3d_volume *volume,
* from sampler() in state.c. This means we can't touch anything other than
* whatever happens to be the currently active texture, or we would risk
* marking already applied sampler states dirty again. */
- active_sampler = volume->resource.device->rev_tex_unit_map[context->active_texture];
+ active_sampler = context->rev_tex_unit_map[context->active_texture];
if (active_sampler != WINED3D_UNMAPPED_STAGE)
- device_invalidate_state(volume->resource.device, STATE_SAMPLER(active_sampler));
+ context_invalidate_state(context, STATE_SAMPLER(active_sampler));
container->texture_ops->texture_bind(container, context, srgb);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e98499c..686b97f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1086,6 +1086,8 @@ struct wined3d_context
DWORD use_immediate_mode_draw : 1;
DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */
DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */
+ DWORD fixed_function_usage_map : 8; /* MAX_TEXTURES, 8 */
+ DWORD padding : 24;
DWORD shader_update_mask;
DWORD constant_update_mask;
DWORD numbered_array_mask;
@@ -1138,6 +1140,9 @@ struct wined3d_context
struct wined3d_event_query *buffer_queries[MAX_ATTRIBS];
unsigned int num_buffer_queries;
+ DWORD tex_unit_map[MAX_COMBINED_SAMPLERS];
+ DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
+
/* Extension emulation */
GLint gl_fog_source;
GLfloat fog_coord_value;
@@ -1882,18 +1887,18 @@ struct wined3d_device
UINT instance_count;
- WORD vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
- WORD bCursorVisible : 1;
- WORD d3d_initialized : 1;
- WORD inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */
- WORD softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */
- WORD filter_messages : 1;
- WORD padding : 10;
-
- BYTE fixed_function_usage_map; /* MAX_TEXTURES, 8 */
+ BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
+ BYTE bCursorVisible : 1;
+ BYTE d3d_initialized : 1;
+ BYTE inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */
+ BYTE softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */
+ BYTE filter_messages : 1;
+ BYTE padding : 2;
unsigned char surface_alignment; /* Line Alignment of surfaces */
+ WORD padding2 : 16;
+
struct wined3d_state state;
struct wined3d_state *update_state;
struct wined3d_stateblock *recording;
@@ -1934,10 +1939,6 @@ struct wined3d_device
UINT dummy_texture_3d[MAX_COMBINED_SAMPLERS];
UINT dummy_texture_cube[MAX_COMBINED_SAMPLERS];
- /* With register combiners we can skip junk texture stages */
- DWORD texUnitMap[MAX_COMBINED_SAMPLERS];
- DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
-
/* Context management */
struct wined3d_context **contexts;
UINT context_count;
@@ -1958,7 +1959,6 @@ void device_resource_add(struct wined3d_device *device, struct wined3d_resource
void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context,
struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN;
-void device_update_tex_unit_map(struct wined3d_device *device) DECLSPEC_HIDDEN;
void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
@@ -1968,9 +1968,9 @@ static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD sta
return context->isStateDirty[idx] & (1 << shift);
}
-static inline void invalidate_active_texture(const struct wined3d_device *device, struct wined3d_context *context)
+static inline void context_invalidate_active_texture(struct wined3d_context *context)
{
- DWORD sampler = device->rev_tex_unit_map[context->active_texture];
+ DWORD sampler = context->rev_tex_unit_map[context->active_texture];
if (sampler != WINED3D_UNMAPPED_STAGE)
context_invalidate_state(context, STATE_SAMPLER(sampler));
}
--
1.8.1.5
More information about the wine-patches
mailing list