From 1fe2f01aace4b69008e43c4824621402fe280c64 Mon Sep 17 00:00:00 2001 From: Elizabeth Figura Date: Sun, 9 Jun 2024 12:50:29 -0500 Subject: [PATCH] wined3d: Allow using the HLSL FFP replacement with GL. This will allow us to replace the GLSL FFP pipes, and is useful for testing the FFP HLSL backend before the Vulkan backend is mature enough in other respects. This patch introduces the d3d setting "ffp_hlsl", set to a DWORD value. It is disabled by default, and only has an effect on the GL renderer. --- dlls/wined3d/adapter_gl.c | 1 + dlls/wined3d/cs.c | 8 ++++ dlls/wined3d/glsl_shader.c | 72 +++++++++++++++++++++++++--------- dlls/wined3d/wined3d_main.c | 5 +++ dlls/wined3d/wined3d_private.h | 5 ++- 5 files changed, 70 insertions(+), 21 deletions(-) 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;