diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 1ba41b0ac16..6ef18d6bd4d 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -505,52 +505,49 @@ static unsigned int shader_arb_load_constantsF(const struct wined3d_shader *shad } } -/** - * Loads the texture dimensions for NP2 fixup into the currently set ARB_[vertex/fragment]_programs. - */ -static void shader_arb_load_np2fixup_constants(void *shader_priv, +/* Loads the texture dimensions for NP2 fixup into the currently set + * ARB_[vertex/fragment]_programs. */ +static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info *fixup, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) { - const struct shader_arb_priv * priv = shader_priv; + GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS]; + WORD active = fixup->super.active; + UINT i; - /* NP2 texcoord fixup is (currently) only done for pixelshaders. */ - if (!use_ps(state)) return; + if (!active) + return; - if (priv->compiled_fprog && priv->compiled_fprog->np2fixup_info.super.active) { - const struct arb_ps_np2fixup_info* const fixup = &priv->compiled_fprog->np2fixup_info; - UINT i; - WORD active = fixup->super.active; - GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS]; + for (i = 0; active; active >>= 1, ++i) + { + const struct wined3d_texture *tex = state->textures[i]; + unsigned char idx = fixup->super.idx[i]; + GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4]; - for (i = 0; active; active >>= 1, ++i) + if (!(active & 1)) + continue; + + if (!tex) { - const struct wined3d_texture *tex = state->textures[i]; - const unsigned char idx = fixup->super.idx[i]; - GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4]; - - if (!(active & 1)) continue; - - if (!tex) { - FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n"); - continue; - } - - if (idx % 2) - { - tex_dim[2] = tex->pow2_matrix[0]; - tex_dim[3] = tex->pow2_matrix[5]; - } - else - { - tex_dim[0] = tex->pow2_matrix[0]; - tex_dim[1] = tex->pow2_matrix[5]; - } + ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n"); + continue; } - for (i = 0; i < fixup->super.num_consts; ++i) { - GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, - fixup->offset + i, &np2fixup_constants[i * 4])); + if (idx % 2) + { + tex_dim[2] = tex->pow2_matrix[0]; + tex_dim[3] = tex->pow2_matrix[5]; } + else + { + tex_dim[0] = tex->pow2_matrix[0]; + tex_dim[1] = tex->pow2_matrix[5]; + } + } + + for (i = 0; i < fixup->super.num_consts; ++i) + { + GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, + fixup->offset + i, &np2fixup_constants[i * 4])); } } @@ -720,6 +717,9 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty); shader_arb_ps_local_constants(gl_shader, context, state, rt_height); + + if (context->constant_update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) + shader_arb_load_np2fixup_constants(&gl_shader->np2fixup_info, gl_info, state); } } @@ -4696,7 +4696,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context /* Force constant reloading for the NP2 fixup (see comment in shader_glsl_select for more info) */ if (compiled->np2fixup_info.super.active) - shader_arb_load_np2fixup_constants(priv, gl_info, state); + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; if (ps->load_local_constsF) context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F; @@ -5709,7 +5709,6 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend = shader_arb_update_float_vertex_constants, shader_arb_update_float_pixel_constants, shader_arb_load_constants, - shader_arb_load_np2fixup_constants, shader_arb_destroy, shader_arb_alloc, shader_arb_free, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 4faf8598308..bd2b140c74e 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -767,51 +767,38 @@ static void reset_program_constant_version(struct wine_rb_entry *entry, void *co } /* Context activation is done by the caller (state handler). */ -static void shader_glsl_load_np2fixup_constants(void *shader_priv, +static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) { - struct shader_glsl_priv *glsl_priv = shader_priv; - const struct glsl_shader_prog_link *prog = glsl_priv->glsl_program; + GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS]; + UINT fixup = ps->np2_fixup_info->active; + UINT i; - /* No GLSL program set - nothing to do. */ - if (!prog) return; - - /* NP2 texcoord fixup is (currently) only done for pixelshaders. */ - if (!use_ps(state)) return; - - if (prog->ps.np2_fixup_info && prog->ps.np2_fixup_location != -1) + for (i = 0; fixup; fixup >>= 1, ++i) { - UINT i; - UINT fixup = prog->ps.np2_fixup_info->active; - GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS]; + const struct wined3d_texture *tex = state->textures[i]; + unsigned char idx = ps->np2_fixup_info->idx[i]; + GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4]; - for (i = 0; fixup; fixup >>= 1, ++i) + if (!tex) { - const struct wined3d_texture *tex = state->textures[i]; - const unsigned char idx = prog->ps.np2_fixup_info->idx[i]; - GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4]; - - if (!tex) - { - ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n"); - continue; - } - - if (idx % 2) - { - tex_dim[2] = tex->pow2_matrix[0]; - tex_dim[3] = tex->pow2_matrix[5]; - } - else - { - tex_dim[0] = tex->pow2_matrix[0]; - tex_dim[1] = tex->pow2_matrix[5]; - } + ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n"); + continue; } - GL_EXTCALL(glUniform4fvARB(prog->ps.np2_fixup_location, - prog->ps.np2_fixup_info->num_consts, np2fixup_constants)); + if (idx % 2) + { + tex_dim[2] = tex->pow2_matrix[0]; + tex_dim[3] = tex->pow2_matrix[5]; + } + else + { + tex_dim[0] = tex->pow2_matrix[0]; + tex_dim[1] = tex->pow2_matrix[5]; + } } + + GL_EXTCALL(glUniform4fvARB(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants)); } /* Context activation is done by the caller (state handler). */ @@ -907,6 +894,9 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context GL_EXTCALL(glUniform4fvARB(prog->ps.ycorrection_location, 1, correction_params)); } + if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) + shader_glsl_load_np2fixup_constants(&prog->ps, gl_info, state); + if (update_mask & WINED3D_SHADER_CONST_FFP_PS) { float col[4]; @@ -6086,6 +6076,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const break; } } + + if (entry->ps.np2_fixup_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; } } @@ -6258,14 +6251,6 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex if (program_id) context->constant_update_mask |= priv->glsl_program->constant_update_mask; } - - /* In case that NP2 texcoord fixup data is found for the selected program, trigger a reload of the - * constants. This has to be done because it can't be guaranteed that sampler() (from state.c) is - * called between selecting the shader and using it, which results in wrong fixup for some frames. */ - if (priv->glsl_program && priv->glsl_program->ps.np2_fixup_info) - { - shader_glsl_load_np2fixup_constants(priv, gl_info, state); - } } /* Context activation is done by the caller. */ @@ -6822,7 +6807,6 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = shader_glsl_update_float_vertex_constants, shader_glsl_update_float_pixel_constants, shader_glsl_load_constants, - shader_glsl_load_np2fixup_constants, shader_glsl_destroy, shader_glsl_alloc, shader_glsl_free, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 25f56601c96..01dbac6b426 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1511,8 +1511,6 @@ static void shader_none_update_float_vertex_constants(struct wined3d_device *dev static void shader_none_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) {} static void shader_none_load_constants(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) {} -static void shader_none_load_np2fixup_constants(void *shader_priv, - const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) {} static void shader_none_destroy(struct wined3d_shader *shader) {} static void shader_none_context_destroyed(void *shader_priv, const struct wined3d_context *context) {} @@ -1619,7 +1617,6 @@ const struct wined3d_shader_backend_ops none_shader_backend = shader_none_update_float_vertex_constants, shader_none_update_float_pixel_constants, shader_none_load_constants, - shader_none_load_np2fixup_constants, shader_none_destroy, shader_none_alloc, shader_none_free, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index b43fda8f2cd..59debd5e1fa 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3676,7 +3676,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state /* Trigger shader constant reloading (for NP2 texcoord fixup) */ if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) - device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state); + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; } else { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 12dd2c64294..17722346c20 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -292,7 +292,8 @@ enum wined3d_sampler_texture_type #define WINED3D_SHADER_CONST_PS_B 0x00000040 #define WINED3D_SHADER_CONST_PS_BUMP_ENV 0x00000080 #define WINED3D_SHADER_CONST_PS_Y_CORR 0x00000100 -#define WINED3D_SHADER_CONST_FFP_PS 0x00000200 +#define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00000200 +#define WINED3D_SHADER_CONST_FFP_PS 0x00000400 enum wined3d_shader_register_type { @@ -817,8 +818,6 @@ struct wined3d_shader_backend_ops void (*shader_update_float_pixel_constants)(struct wined3d_device *device, UINT start, UINT count); void (*shader_load_constants)(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state); - void (*shader_load_np2fixup_constants)(void *shader_priv, const struct wined3d_gl_info *gl_info, - const struct wined3d_state *state); void (*shader_destroy)(struct wined3d_shader *shader); HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct fragment_pipeline *fragment_pipe);