diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 56aa9b73269..c2803379347 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4928,6 +4928,7 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ d3d_info->feature_level = feature_level_from_caps(gl_info, &shader_caps, &d3d_info->ffp_fragment_caps); d3d_info->filling_convention_offset = gl_info->filling_convention_offset; d3d_info->persistent_map = !!gl_info->supported[ARB_BUFFER_STORAGE]; + d3d_info->ffp_hlsl = wined3d_settings.ffp_hlsl; if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) d3d_info->multisample_draw_location = WINED3D_LOCATION_TEXTURE_RGB; diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 711c031a028..1bd4e2b4242 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2123,15 +2123,23 @@ static void wined3d_cs_exec_push_constants(struct wined3d_cs *cs, const void *da { const struct wined3d_cs_push_constants *op = data; struct wined3d_device *device = cs->c.device; + unsigned int ffp_start_idx, ffp_end_idx; unsigned int context_count, i; /* The constant buffers were already updated; this op is just to mark the * constants as invalid in the device state. */ + ffp_start_idx = op->start_idx / sizeof(struct wined3d_vec4); + ffp_end_idx = (op->start_idx + op->count + sizeof(struct wined3d_vec4)) / sizeof(struct wined3d_vec4); + if (op->type == WINED3D_PUSH_CONSTANTS_VS_F) device->shader_backend->shader_update_float_vertex_constants(device, op->start_idx, op->count); else if (op->type == WINED3D_PUSH_CONSTANTS_PS_F) device->shader_backend->shader_update_float_pixel_constants(device, op->start_idx, op->count); + else if (op->type == WINED3D_PUSH_CONSTANTS_VS_FFP) + device->shader_backend->shader_update_float_vertex_constants(device, ffp_start_idx, ffp_end_idx - ffp_start_idx); + else if (op->type == WINED3D_PUSH_CONSTANTS_PS_FFP) + device->shader_backend->shader_update_float_pixel_constants(device, ffp_start_idx, ffp_end_idx - ffp_start_idx); for (i = 0, context_count = device->context_count; i < context_count; ++i) device->contexts[i]->constant_update_mask |= op->update_mask; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 7ff9ce0427b..785050e7631 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1735,17 +1735,38 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, constant_version = prog->constant_version; update_mask = context->constant_update_mask & prog->constant_update_mask; - if (update_mask & WINED3D_SHADER_CONST_VS_F) - shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F], - prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version); + if (vshader && vshader->is_ffp_vs) + { + /* The shader's constant update mask is WINED3D_SHADER_CONST_VS_F. + * This may be set from shader_glsl_update_graphics_program(). + * However, we also need to update constants when FFP flags change. */ + static const uint32_t vs_update_mask = WINED3D_SHADER_CONST_VS_F + | WINED3D_SHADER_CONST_FFP_LIGHTS + | WINED3D_SHADER_CONST_FFP_MATERIAL + | WINED3D_SHADER_CONST_FFP_MODELVIEW + | WINED3D_SHADER_CONST_FFP_PROJ + | WINED3D_SHADER_CONST_FFP_TEXMATRIX + | WINED3D_SHADER_CONST_FFP_VERTEXBLEND + | WINED3D_SHADER_CONST_VS_POINTSIZE; - if (update_mask & WINED3D_SHADER_CONST_VS_I) - shader_glsl_load_constants_i(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], - prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants); + if (context->constant_update_mask & vs_update_mask) + shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_FFP], + prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version); + } + else + { + if (update_mask & WINED3D_SHADER_CONST_VS_F) + shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F], + prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version); - if (update_mask & WINED3D_SHADER_CONST_VS_B) - shader_glsl_load_constants_b(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B], - prog->vs.uniform_b_locations, vshader->reg_maps.boolean_constants); + if (update_mask & WINED3D_SHADER_CONST_VS_I) + shader_glsl_load_constants_i(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], + prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants); + + if (update_mask & WINED3D_SHADER_CONST_VS_B) + shader_glsl_load_constants_b(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B], + prog->vs.uniform_b_locations, vshader->reg_maps.boolean_constants); + } if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES) { @@ -1890,17 +1911,30 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, WINED3D_LIGHT_PARALLELPOINT, &constants->light.lights[i], prog); } - if (update_mask & WINED3D_SHADER_CONST_PS_F) - shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F], - prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); + if (pshader && pshader->is_ffp_ps) + { + static const uint32_t ps_update_mask = WINED3D_SHADER_CONST_PS_F + | WINED3D_SHADER_CONST_FFP_COLOR_KEY + | WINED3D_SHADER_CONST_FFP_PS; - if (update_mask & WINED3D_SHADER_CONST_PS_I) - shader_glsl_load_constants_i(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], - prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants); + if (context->constant_update_mask & ps_update_mask) + shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], + prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); + } + else + { + if (update_mask & WINED3D_SHADER_CONST_PS_F) + shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F], + prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); - if (update_mask & WINED3D_SHADER_CONST_PS_B) - shader_glsl_load_constants_b(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B], - prog->ps.uniform_b_locations, pshader->reg_maps.boolean_constants); + if (update_mask & WINED3D_SHADER_CONST_PS_I) + shader_glsl_load_constants_i(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], + prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants); + + if (update_mask & WINED3D_SHADER_CONST_PS_B) + shader_glsl_load_constants_b(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B], + prog->ps.uniform_b_locations, pshader->reg_maps.boolean_constants); + } if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV) { @@ -12113,7 +12147,7 @@ static void glsl_fragment_pipe_fogparams(struct wined3d_context *context, static void glsl_fragment_pipe_fog(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - BOOL use_vshader = use_vs(state); + BOOL use_vshader = use_vs(state) && !state->shader[WINED3D_SHADER_TYPE_VERTEX]->is_ffp_vs; enum fogsource new_source; DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART]; DWORD fogend = state->render_states[WINED3D_RS_FOGEND]; diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 863428bb53a..3b436919559 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -463,6 +463,11 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) TRACE("Forcing all constant buffers to be write-mappable.\n"); wined3d_settings.cb_access_map_w = TRUE; } + if (!get_config_key_dword(hkey, appkey, env, "ffp_hlsl", &tmpvalue)) + { + ERR_(winediag)("Using the HLSL-based FFP backend.\n"); + wined3d_settings.ffp_hlsl = tmpvalue; + } } if (appkey) RegCloseKey( appkey ); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bb593a94fa2..12b61b68bbb 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -476,7 +476,6 @@ struct wined3d_settings char *logo; unsigned int multisample_textures; unsigned int sample_count; - BOOL check_float_constants; unsigned int strict_shader_math; unsigned int max_sm_vs; unsigned int max_sm_hs; @@ -486,7 +485,9 @@ struct wined3d_settings unsigned int max_sm_cs; enum wined3d_renderer renderer; enum wined3d_shader_backend shader_backend; - BOOL cb_access_map_w; + bool check_float_constants; + bool cb_access_map_w; + bool ffp_hlsl; }; extern struct wined3d_settings wined3d_settings;