From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/arb_program_shader.c | 4 ++-- dlls/wined3d/ati_fragment_shader.c | 2 +- dlls/wined3d/context_gl.c | 2 +- dlls/wined3d/cs.c | 5 +++-- dlls/wined3d/glsl_shader.c | 6 +++--- dlls/wined3d/nvidia_texture_shader.c | 4 ++-- dlls/wined3d/shader.c | 7 +++---- dlls/wined3d/state.c | 14 ++++++++------ dlls/wined3d/stateblock.c | 2 +- dlls/wined3d/utils.c | 24 ++++++++++++------------ dlls/wined3d/wined3d_private.h | 6 ++++++ 11 files changed, 42 insertions(+), 34 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 0773c3e34d9..4941fd40057 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -490,7 +490,7 @@ static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info while (active) { i = wined3d_bit_scan(&active); - if (!(tex = state->textures[i])) + if (!(tex = wined3d_state_get_ffp_texture(state, i))) { ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n"); continue; @@ -6048,9 +6048,9 @@ static void alpha_test_arbfp(struct wined3d_context *context, const struct wined
static void color_key_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, 0); struct wined3d_context_gl *context_gl = wined3d_context_gl(context); const struct wined3d_gl_info *gl_info = context_gl->gl_info; - const struct wined3d_texture *texture = state->textures[0]; struct wined3d_device *device = context->device; struct wined3d_color float_key[2];
diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index dddf2d45c7d..605d050ff7d 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1057,7 +1057,7 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined if (mapped_stage != WINED3D_UNMAPPED_STAGE) { wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); - texture_activate_dimensions(state->textures[i], gl_info); + texture_activate_dimensions(wined3d_state_get_ffp_texture(state, i), gl_info); } }
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 0c440d12d84..57fd182d926 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -4906,7 +4906,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context_gl *context_gl, continue; }
- if (!ps && !state->textures[texture_idx]) + if (!ps && !wined3d_state_get_ffp_texture(state, texture_idx)) continue;
texture_unit = context_gl->tex_unit_map[texture_idx]; diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 00fc9aa0b45..84c025ff46c 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1912,7 +1912,7 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat break;
case WINED3D_CKEY_SRC_BLT: - if (texture == cs->state.textures[0]) + if (texture == wined3d_state_get_ffp_texture(&cs->state, 0)) { device_invalidate_state(cs->c.device, STATE_COLOR_KEY); if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) @@ -1942,7 +1942,8 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat break;
case WINED3D_CKEY_SRC_BLT: - if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) + if (texture == wined3d_state_get_ffp_texture(&cs->state, 0) + && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) device_invalidate_state(cs->c.device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 4a6338223c9..ba84131b9d8 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1299,7 +1299,7 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps
for (i = 0; fixup; fixup >>= 1, ++i) { - const struct wined3d_texture *tex = state->textures[i]; + const struct wined3d_texture *tex = wined3d_state_get_ffp_texture(state, i); unsigned char idx = ps->np2_fixup_info->idx[i];
if (!tex) @@ -1522,7 +1522,7 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) { struct wined3d_color float_key[2]; - const struct wined3d_texture *texture = state->textures[0]; + const struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, 0);
wined3d_format_get_float_color_key(texture->resource.format, &texture->async.src_blt_color_key, float_key); GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r)); @@ -11842,7 +11842,7 @@ static void glsl_vertex_pipe_texmatrix_np2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD sampler = state_id - STATE_SAMPLER(0); - const struct wined3d_texture *texture = state->textures[sampler]; + const struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, sampler); BOOL np2;
if (!texture) diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 55e2a596dd1..2793b6ff1df 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -48,7 +48,7 @@ static void nvts_activate_dimensions(const struct wined3d_state *state, context_gl->c.texShaderBumpMap &= ~(1u << stage); }
- if ((texture = state->textures[stage])) + if ((texture = wined3d_state_get_ffp_texture(state, stage))) { switch (wined3d_texture_gl(texture)->target) { @@ -552,7 +552,7 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s if (gl_info->supported[NV_TEXTURE_SHADER2]) nvts_activate_dimensions(state, stage, context_gl); else - texture_activate_dimensions(state->textures[stage], gl_info); + texture_activate_dimensions(wined3d_state_get_ffp_texture(state, stage), gl_info); } }
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 9a7919b437b..ee58559a96c 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2858,7 +2858,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 /* Treat unbound textures as 2D. The dummy texture will provide * the proper sample value. The tex_types bitmap defaults to * 2D because of the memset. */ - if (!(texture = state->textures[i])) + if (!(texture = wined3d_state_get_ffp_texture(state, i))) continue;
switch (wined3d_texture_gl(texture)->target) @@ -2900,7 +2900,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 break; }
- if ((texture = state->textures[i])) + if ((texture = wined3d_state_get_ffp_texture(state, i))) { /* Star Wars: The Old Republic uses mismatched samplers for rendering water. */ if (texture->resource.type == WINED3D_RTYPE_TEXTURE_2D @@ -2930,8 +2930,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 if (!shader->reg_maps.resource_info[i].type) continue;
- texture = state->textures[i]; - if (!texture) + if (!(texture = wined3d_state_get_ffp_texture(state, i))) { args->color_fixup[i] = COLOR_FIXUP_IDENTITY; continue; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 28daf5dacbb..87fa7c454fe 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -808,6 +808,7 @@ static void blend_dbb(struct wined3d_context *context, const struct wined3d_stat
void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, 0); const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; int glParm = 0; float ref; @@ -822,7 +823,7 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat * WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture * function will call alpha in case it finds some texture + colorkeyenable * combination which needs extra care. */ - if (state->textures[0] && (state->textures[0]->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) + if (texture && (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) enable_ckey = TRUE;
if (enable_ckey || context->last_was_ckey) @@ -2062,7 +2063,7 @@ static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined op = WINED3D_TOP_SELECT_ARG1; }
- if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE) + if (isAlpha && !wined3d_state_get_ffp_texture(state, Stage) && arg1 == WINED3DTA_TEXTURE) { get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1); } else { @@ -3109,7 +3110,7 @@ static void tex_colorop(struct wined3d_context *context, const struct wined3d_st /* The sampler will also activate the correct texture dimensions, so no * need to do it here if the sampler for this stage is dirty. */ if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used) - texture_activate_dimensions(state->textures[stage], gl_info); + texture_activate_dimensions(wined3d_state_get_ffp_texture(state, stage), gl_info);
set_tex_op(gl_info, state, FALSE, stage, state->texture_states[stage][WINED3D_TSS_COLOR_OP], @@ -3121,6 +3122,7 @@ 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) { unsigned int stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, 0); struct wined3d_context_gl *context_gl = wined3d_context_gl(context); BOOL tex_used = context->fixed_function_usage_map & (1u << stage); const struct wined3d_gl_info *gl_info = context_gl->gl_info; @@ -3144,9 +3146,9 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2]; arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
- if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0]) + if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && texture) { - struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[0]); + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture); GLenum texture_dimensions = texture_gl->target;
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) @@ -3424,7 +3426,7 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const DWORD sampler = state_id - STATE_SAMPLER(0); - const struct wined3d_texture *texture = state->textures[sampler]; + const struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, sampler);
TRACE("context %p, state %p, state_id %#lx.\n", context, state, state_id);
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 6d440f94a94..6361de4909b 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -2478,7 +2478,7 @@ static void resolve_depth_buffer(struct wined3d_device *device) struct wined3d_resource *dst_resource; struct wined3d_texture *dst_texture;
- if (!(dst_texture = state->textures[0])) + if (!(dst_texture = wined3d_state_get_ffp_texture(state, 0))) return; dst_resource = &dst_texture->resource; if (!dst_resource->format->depth_size) diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index bc03938e90a..d9a051065ef 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5611,7 +5611,7 @@ BOOL is_invalid_op(const struct wined3d_state *state, int stage, { if (op == WINED3D_TOP_DISABLE) return FALSE; - if (state->textures[stage]) + if (wined3d_state_get_ffp_texture(state, stage)) return FALSE;
if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE @@ -5847,13 +5847,14 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t }
void get_texture_matrix(const struct wined3d_context *context, const struct wined3d_state *state, - unsigned int tex, struct wined3d_matrix *mat) + const unsigned int tex, struct wined3d_matrix *mat) { const struct wined3d_device *device = context->device; BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], WINED3D_MAX_FFP_TEXTURES - 1); + struct wined3d_texture *texture = wined3d_state_get_ffp_texture(state, tex);
compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex], state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS], @@ -5863,7 +5864,7 @@ void get_texture_matrix(const struct wined3d_context *context, const struct wine : WINED3DFMT_UNKNOWN, device->shader_backend->shader_has_ffp_proj_control(device->shader_priv), mat);
- if ((context->lastWasPow2Texture & (1u << tex)) && state->textures[tex]) + if ((context->lastWasPow2Texture & (1u << tex)) && texture) { if (generated) FIXME("Non-power-of-two texture being used with generated texture coords.\n"); @@ -5872,7 +5873,7 @@ void get_texture_matrix(const struct wined3d_context *context, const struct wine if (!use_ps(state)) { TRACE("Non-power-of-two texture matrix multiply fixup.\n"); - multiply_matrix(mat, mat, (struct wined3d_matrix *)state->textures[tex]->pow2_matrix); + multiply_matrix(mat, mat, (struct wined3d_matrix *)texture->pow2_matrix); } } } @@ -6408,13 +6409,12 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_context *context, const st DWORD ttff; DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; const struct wined3d_d3d_info *d3d_info = context->d3d_info; + struct wined3d_texture *texture;
settings->padding = 0;
for (i = 0; i < d3d_info->ffp_fragment_caps.max_blend_stages; ++i) { - struct wined3d_texture *texture; - settings->op[i].padding = 0; if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE) { @@ -6430,7 +6430,7 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_context *context, const st break; }
- if ((texture = state->textures[i])) + if ((texture = wined3d_state_get_ffp_texture(state, i))) { if (can_use_texture_swizzle(d3d_info, texture->resource.format)) settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; @@ -6498,11 +6498,10 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_context *context, const st aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED; }
- if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE]) + if (!i && texture && state->render_states[WINED3D_RS_COLORKEYENABLE]) { GLenum texture_dimensions;
- texture = state->textures[0]; texture_dimensions = wined3d_texture_gl(texture)->target;
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) @@ -6630,8 +6629,9 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_context *context, const st settings->emul_clipplanes = 1; }
- if (state->render_states[WINED3D_RS_COLORKEYENABLE] && state->textures[0] - && state->textures[0]->async.color_key_flags & WINED3D_CKEY_SRC_BLT + texture = wined3d_state_get_ffp_texture(state, 0); + if (state->render_states[WINED3D_RS_COLORKEYENABLE] + && texture && (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) && settings->op[0].cop != WINED3D_TOP_DISABLE) settings->color_key_enabled = 1; else @@ -6811,7 +6811,7 @@ void sampler_texdim(struct wined3d_context *context, const struct wined3d_state if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) return;
- texture_activate_dimensions(state->textures[sampler], context_gl->gl_info); + texture_activate_dimensions(wined3d_state_get_ffp_texture(state, sampler), context_gl->gl_info); }
int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4f7cacda858..bb955873467 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3936,6 +3936,12 @@ struct wined3d_shader_resource_view
void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN;
+static inline struct wined3d_texture *wined3d_state_get_ffp_texture(const struct wined3d_state *state, unsigned int idx) +{ + assert(idx <= WINED3D_MAX_FFP_TEXTURES); + return state->textures[idx]; +} + struct wined3d_unordered_access_view { LONG refcount;
From: Zebediah Figura zfigura@codeweavers.com
Ported from state_sampler().
This is currently relevant to the case where a d3d11 device is created with a 9.x feature level—this will have resources bound via SRVs [and will therefore go through wined3d_context_gl_bind_shader_resources() rather than state_sampler()] but need not support ARB_texture_non_power_of_two.
The NPOT non-requirement is explicitly called out in the d3d11 documentation, and because we need some degree of emulation for conditional NPOT textures, we need to hook that up for feature level 9.x d3d11 devices as well.
Looking forward, d3d 1-9 will be normalized to creating internal SRVs and binding those through the d3d10+ path, so this will also be necessary for that reason. --- dlls/wined3d/context_gl.c | 12 ++++++------ dlls/wined3d/view.c | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 57fd182d926..bdea2879a51 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -4290,12 +4290,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE; }
- if (context->constant_update_mask) - { - device->shader_backend->shader_load_constants(device->shader_priv, context, state); - context->constant_update_mask = 0; - } - if (context->update_shader_resource_bindings) { for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) @@ -4317,6 +4311,12 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) wined3d_context_gl_check_fbo_status(context_gl, GL_FRAMEBUFFER);
+ if (context->constant_update_mask) + { + device->shader_backend->shader_load_constants(device->shader_priv, context, state); + context->constant_update_mask = 0; + } + context->last_was_blit = FALSE; context->last_was_ffp_blit = FALSE;
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 5729d5909e6..4b0ccea7bb2 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -1266,6 +1266,10 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl texture_gl = wined3d_texture_gl(wined3d_texture_from_resource(view_gl->v.resource)); wined3d_texture_gl_bind(texture_gl, context_gl, FALSE); wined3d_sampler_gl_bind(sampler_gl, unit, texture_gl, context_gl); + + /* Trigger shader constant reloading (for NP2 texcoord fixup) */ + if (!(texture_gl->t.flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) + context_gl->c.constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; }
/* Context activation is done by the caller. */
From: Elizabeth Figura zfigura@codeweavers.com
This was probably accidentally omitted in 51e64b3fe95afb3246c8690d9ea1e7b4c38ce2b4.
In practice, this is guaranteed to work anyway, since due to the state table construction the equivalent misc handler, i.e. sampler(), is always guaranteed to be called right before the fragment pipeline handler for each stage. However, this is a subtle detail and best not to be depended on. --- dlls/wined3d/utils.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index d9a051065ef..05a0ab36af8 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6811,6 +6811,7 @@ void sampler_texdim(struct wined3d_context *context, const struct wined3d_state if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) return;
+ wined3d_context_gl_active_texture(context_gl, context_gl->gl_info, sampler); texture_activate_dimensions(wined3d_state_get_ffp_texture(state, sampler), context_gl->gl_info); }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/nvidia_texture_shader.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 2793b6ff1df..0e56f5f58e0 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -616,6 +616,7 @@ static void nvts_texdim(struct wined3d_context *context, const struct wined3d_st if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) return;
+ wined3d_context_gl_active_texture(context_gl, context_gl->gl_info, sampler); nvts_activate_dimensions(state, sampler, context_gl); }