wined3d: Move tex_unit_map and friends into the context.

This commit is contained in:
Stefan Dösinger 2013-09-16 12:43:18 +02:00 committed by Alexandre Julliard
parent f29c24f2de
commit 112617f00b
12 changed files with 279 additions and 286 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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)
{
@ -883,7 +883,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
struct wined3d_context *context;
DWORD clear_flags = 0;
HRESULT hr;
DWORD state;
TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc);
@ -895,21 +894,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)))
{
@ -2442,217 +2426,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;
@ -4442,7 +4215,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");

View File

@ -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);
}

View File

@ -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)

View File

@ -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];

View File

@ -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;

View File

@ -654,7 +654,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
@ -666,10 +665,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);
}
@ -2247,7 +2246,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);

View File

@ -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

View File

@ -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);
}

View File

@ -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));
}