The state table, as may have been described elsewhere, is not very friendly to modern CPUs (due to its indirect calls). Additionally, interdependencies between states are often more obscure (or at least harder to account for) than they might be with a linear function.
Hence, we'd like to transform the table into a linear function, with "dirty" state guarding explicitly spelled out. For the FFP tables, the approach I've taken to achieve this is to gradually move states out of the table and into the existing vp_enable() and fp_enable() functions, eventually making those functions the aforementioned single linear functions.
-- v3: wined3d/arb: Move fragment program compilation from fragment_prog_arbfp() to arbfp_apply_draw_state(). wined3d: Pass a non-const wined3d_context pointer to the FFP *_apply_draw_state() methods. wined3d: Pass a wined3d_state pointer to the vp_enable() and fp_enable() methods. wined3d: Introduce a separate fp_disable() method. wined3d: Introduce a separate vp_disable() method. wined3d: Merge shader_load_constants() into shader_select().
From: Zebediah Figura zfigura@codeweavers.com
Arguably there is a benefit here in that it reduces shader backend state application down to a single method, although whether that is an improvement may be up for debate.
More saliently, we would like to move FFP state application out of the state table and into a linear state function. In practice that function will probably be vp_enable / fp_enable. In that case we will need those functions, and hence also shader_select(), to be called when more states are dirty.
This does not in itself mean that shader_load_constants() needs to be merged with shader_select(), but it does remove the primary impetus for keeping them separate.
Rename to shader_apply_draw_state() to reflect the adjusted purpose, as suggested by Henri Verbeet. --- dlls/wined3d/arb_program_shader.c | 40 +++++++++++++++---------------- dlls/wined3d/context_gl.c | 16 ++++--------- dlls/wined3d/context_vk.c | 2 +- dlls/wined3d/glsl_shader.c | 38 +++++++++++++++++------------ dlls/wined3d/shader.c | 7 ++---- dlls/wined3d/shader_spirv.c | 11 ++------- dlls/wined3d/wined3d_private.h | 4 +--- 7 files changed, 54 insertions(+), 64 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index eecbe1c22b1..4e856c6a616 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -622,7 +622,7 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g checkGLcall("Load vs int consts"); }
-static void shader_arb_select(void *shader_priv, struct wined3d_context *context, +static void shader_arb_apply_draw_state(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state);
/** @@ -650,7 +650,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str && (vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts)))) { TRACE("bool/integer vertex shader constants potentially modified, forcing shader reselection.\n"); - shader_arb_select(priv, &context_gl->c, state); + shader_arb_apply_draw_state(priv, &context_gl->c, state); } else if (pshader && (pshader->reg_maps.boolean_constants @@ -658,7 +658,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str && (pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts)))) { TRACE("bool/integer pixel shader constants potentially modified, forcing shader reselection.\n"); - shader_arb_select(priv, &context_gl->c, state); + shader_arb_apply_draw_state(priv, &context_gl->c, state); } }
@@ -714,13 +714,6 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str } }
-static void shader_arb_load_constants(void *shader_priv, struct wined3d_context *context, - const struct wined3d_state *state) -{ - shader_arb_load_constants_internal(shader_priv, wined3d_context_gl(context), - state, use_ps(state), use_vs(state), FALSE); -} - static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) { struct wined3d_context_gl *context_gl = wined3d_context_gl_get_current(); @@ -4614,12 +4607,11 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, }
/* Context activation is done by the caller. */ -static void shader_arb_select(void *shader_priv, struct wined3d_context *context, - const struct wined3d_state *state) +static void shader_arb_update_graphics_shaders(struct shader_arb_priv *priv, + struct wined3d_context *context, const struct wined3d_state *state) { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct shader_arb_priv *priv = shader_priv; int i;
/* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */ @@ -4659,7 +4651,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context priv->pshader_const_dirty[i] = 1; } /* Also takes care of loading local constants */ - shader_arb_load_constants_internal(shader_priv, context_gl, state, TRUE, FALSE, TRUE); + shader_arb_load_constants_internal(priv, context_gl, state, TRUE, FALSE, TRUE); } else { @@ -4748,6 +4740,19 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context } }
+static void shader_arb_apply_draw_state(void *shader_priv, struct wined3d_context *context, + const struct wined3d_state *state) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct shader_arb_priv *priv = shader_priv; + + if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) + shader_arb_update_graphics_shaders(priv, context, state); + + if (context->constant_update_mask) + shader_arb_load_constants_internal(priv, context_gl, state, use_ps(state), use_vs(state), FALSE); +} + static void shader_arb_select_compute(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { @@ -5703,12 +5708,11 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend = { shader_arb_handle_instruction, shader_arb_precompile, - shader_arb_select, + shader_arb_apply_draw_state, shader_arb_select_compute, shader_arb_disable, shader_arb_update_float_vertex_constants, shader_arb_update_float_pixel_constants, - shader_arb_load_constants, shader_arb_destroy, shader_arb_alloc, shader_arb_free, @@ -6638,10 +6642,6 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi desc = new_desc; }
- /* Now activate the replacement program. GL_FRAGMENT_PROGRAM_ARB is already active (however, note the - * comment above the shader_select call below). If e.g. GLSL is active, the shader_select call will - * deactivate it. - */ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)); checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)");
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 2c319132164..ffd56f5f770 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -4386,12 +4386,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
memset(context->dirty_graphics_states, 0, sizeof(context->dirty_graphics_states));
- if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) - { - device->shader_backend->shader_select(device->shader_priv, context, state); - context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE; - } - if (context->update_shader_resource_bindings) { for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) @@ -4413,11 +4407,11 @@ 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; - } + /* WINED3D_SHADER_CONST_PS_NP2_FIXUP may be set when binding shader + * resources, so constant loading needs to be done after that. */ + device->shader_backend->shader_apply_draw_state(device->shader_priv, context, state); + context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE; + context->constant_update_mask = 0;
context->last_was_blit = FALSE; context->last_was_ffp_blit = FALSE; diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 29a4a4998d4..c73db4f20cd 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -3667,7 +3667,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c context_vk->sample_count = VK_SAMPLE_COUNT_1_BIT; if (context_vk->c.shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) { - device_vk->d.shader_backend->shader_select(device_vk->d.shader_priv, &context_vk->c, state); + device_vk->d.shader_backend->shader_apply_draw_state(device_vk->d.shader_priv, &context_vk->c, state); if (!context_vk->graphics.vk_pipeline_layout) { ERR("No pipeline layout set.\n"); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index bc4053e21de..4e9a3b3467b 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1513,9 +1513,8 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r)); }
-/* Context activation is done by the caller (state handler). */ -static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context, - const struct wined3d_state *state) +static void shader_glsl_load_constants(struct shader_glsl_priv *priv, + struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; @@ -1525,7 +1524,6 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context const struct wined3d_gl_info *gl_info = context_gl->gl_info; float position_fixup[4 * WINED3D_MAX_VIEWPORTS]; struct wined3d_device *device = context->device; - struct shader_glsl_priv *priv = shader_priv; unsigned int constant_version; DWORD update_mask; int i; @@ -10697,19 +10695,17 @@ static void shader_glsl_precompile(void *shader_priv, struct wined3d_shader *sha }
/* Context activation is done by the caller. */ -static void shader_glsl_select(void *shader_priv, struct wined3d_context *context, - const struct wined3d_state *state) +static void shader_glsl_update_graphics_program(struct shader_glsl_priv *priv, + struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { - struct wined3d_context_gl *context_gl = wined3d_context_gl(context); - struct glsl_context_data *ctx_data = context->shader_backend_data; + struct glsl_context_data *ctx_data = context_gl->c.shader_backend_data; const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct shader_glsl_priv *priv = shader_priv; struct glsl_shader_prog_link *glsl_program; GLenum current_vertex_color_clamp; GLuint program_id, prev_id;
- priv->vertex_pipe->vp_enable(context, !use_vs(state)); - priv->fragment_pipe->fp_enable(context, !use_ps(state)); + priv->vertex_pipe->vp_enable(&context_gl->c, !use_vs(state)); + priv->fragment_pipe->fp_enable(&context_gl->c, !use_ps(state));
prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; set_glsl_shader_program(context_gl, state, priv, ctx_data); @@ -10750,10 +10746,23 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex checkGLcall("glUseProgram");
if (glsl_program) - context->constant_update_mask |= glsl_program->constant_update_mask; + context_gl->c.constant_update_mask |= glsl_program->constant_update_mask; }
- context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE); + context_gl->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE); +} + +static void shader_glsl_apply_draw_state(void *shader_priv, struct wined3d_context *context, + const struct wined3d_state *state) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct shader_glsl_priv *priv = shader_priv; + + if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) + shader_glsl_update_graphics_program(priv, context_gl, state); + + if (context->constant_update_mask) + shader_glsl_load_constants(priv, context, state); }
/* Context activation is done by the caller. */ @@ -11538,12 +11547,11 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = { shader_glsl_handle_instruction, shader_glsl_precompile, - shader_glsl_select, + shader_glsl_apply_draw_state, shader_glsl_select_compute, shader_glsl_disable, shader_glsl_update_float_vertex_constants, shader_glsl_update_float_pixel_constants, - shader_glsl_load_constants, shader_glsl_destroy, shader_glsl_alloc, shader_glsl_free, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 91105a43a91..b72a3df8737 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1933,14 +1933,12 @@ static void shader_none_select_compute(void *shader_priv, struct wined3d_context const struct wined3d_state *state) {} static void shader_none_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) {} 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_destroy(struct wined3d_shader *shader) {} static void shader_none_free_context_data(struct wined3d_context *context) {} static void shader_none_init_context_state(struct wined3d_context *context) {}
/* Context activation is done by the caller. */ -static void shader_none_select(void *shader_priv, struct wined3d_context *context, +static void shader_none_apply_draw_state(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { struct shader_none_priv *priv = shader_priv; @@ -2036,12 +2034,11 @@ const struct wined3d_shader_backend_ops none_shader_backend = { shader_none_handle_instruction, shader_none_precompile, - shader_none_select, + shader_none_apply_draw_state, shader_none_select_compute, shader_none_disable, shader_none_update_float_vertex_constants, shader_none_update_float_pixel_constants, - shader_none_load_constants, shader_none_destroy, shader_none_alloc, shader_none_free, diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index ad34856ab5d..1eac7373ee3 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -814,7 +814,7 @@ static void shader_spirv_precompile(void *shader_priv, struct wined3d_shader *sh shader_spirv_scan_shader(shader, &program_vk->descriptor_info, &program_vk->signature_info); }
-static void shader_spirv_select(void *shader_priv, struct wined3d_context *context, +static void shader_spirv_apply_draw_state(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { struct wined3d_context_vk *context_vk = wined3d_context_vk(context); @@ -926,12 +926,6 @@ static void shader_spirv_update_float_pixel_constants(struct wined3d_device *dev WARN("Not implemented.\n"); }
-static void shader_spirv_load_constants(void *shader_priv, struct wined3d_context *context, - const struct wined3d_state *state) -{ - WARN("Not implemented.\n"); -} - static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk *context_vk, const struct shader_spirv_compute_program_vk *program) { @@ -1119,12 +1113,11 @@ static const struct wined3d_shader_backend_ops spirv_shader_backend_vk = { .shader_handle_instruction = shader_spirv_handle_instruction, .shader_precompile = shader_spirv_precompile, - .shader_select = shader_spirv_select, + .shader_apply_draw_state = shader_spirv_apply_draw_state, .shader_select_compute = shader_spirv_select_compute, .shader_disable = shader_spirv_disable, .shader_update_float_vertex_constants = shader_spirv_update_float_vertex_constants, .shader_update_float_pixel_constants = shader_spirv_update_float_pixel_constants, - .shader_load_constants = shader_spirv_load_constants, .shader_destroy = shader_spirv_destroy, .shader_alloc_private = shader_spirv_alloc, .shader_free_private = shader_spirv_free, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 474a31a9206..033e0d6b9dc 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1542,15 +1542,13 @@ struct wined3d_shader_backend_ops { void (*shader_handle_instruction)(const struct wined3d_shader_instruction *); void (*shader_precompile)(void *shader_priv, struct wined3d_shader *shader); - void (*shader_select)(void *shader_priv, struct wined3d_context *context, + void (*shader_apply_draw_state)(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state); void (*shader_select_compute)(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state); void (*shader_disable)(void *shader_priv, struct wined3d_context *context); void (*shader_update_float_vertex_constants)(struct wined3d_device *device, UINT start, UINT count); 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_destroy)(struct wined3d_shader *shader); HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct wined3d_fragment_pipe_ops *fragment_pipe);
From: Zebediah Figura zfigura@codeweavers.com
Analogous to shader_disable().
We'd like to pass a wined3d_state pointer to vp_enable() to let it handle actually compiling the vertex pipeline, which doesn't mesh well conceptually with its use in shader_disable(). --- dlls/wined3d/arb_program_shader.c | 2 +- dlls/wined3d/ffp_gl.c | 29 +++++++++++++++++------------ dlls/wined3d/glsl_shader.c | 17 ++++++++++------- dlls/wined3d/shader.c | 2 +- dlls/wined3d/shader_spirv.c | 8 +++++++- dlls/wined3d/wined3d_private.h | 1 + 6 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 4e856c6a616..a1f56406a0a 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4778,7 +4778,7 @@ static void shader_arb_disable(void *shader_priv, struct wined3d_context *contex gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB); checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)"); } - priv->vertex_pipe->vp_enable(context, FALSE); + priv->vertex_pipe->vp_disable(context);
if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT] && priv->last_vs_color_unclamp) { diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index d52d198e545..8d8a14107eb 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -4842,6 +4842,8 @@ static const struct wined3d_state_entry_template ffp_fragmentstate_template[] = /* Context activation is done by the caller. */ static void ffp_pipe_enable(const struct wined3d_context *context, BOOL enable) {}
+static void ffp_pipe_disable(const struct wined3d_context *context) {} + static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { return shader_priv; @@ -4879,12 +4881,13 @@ static unsigned int vp_ffp_get_emul_mask(const struct wined3d_adapter *adapter)
const struct wined3d_vertex_pipe_ops ffp_vertex_pipe = { - ffp_pipe_enable, - vp_ffp_get_caps, - vp_ffp_get_emul_mask, - ffp_alloc, - ffp_free, - vp_ffp_states, + .vp_enable = ffp_pipe_enable, + .vp_disable = ffp_pipe_disable, + .vp_get_caps = vp_ffp_get_caps, + .vp_get_emul_mask = vp_ffp_get_emul_mask, + .vp_alloc = ffp_alloc, + .vp_free = ffp_free, + .vp_states = vp_ffp_states, };
static void ffp_fragment_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) @@ -4965,6 +4968,8 @@ const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline =
static void none_pipe_enable(const struct wined3d_context *context, BOOL enable) {}
+static void none_pipe_disable(const struct wined3d_context *context) {} + static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { return shader_priv; @@ -4984,12 +4989,12 @@ static unsigned int vp_none_get_emul_mask(const struct wined3d_adapter *adapter)
const struct wined3d_vertex_pipe_ops none_vertex_pipe = { - none_pipe_enable, - vp_none_get_caps, - vp_none_get_emul_mask, - none_alloc, - none_free, - NULL, + .vp_enable = none_pipe_enable, + .vp_disable = none_pipe_disable, + .vp_get_caps = vp_none_get_caps, + .vp_get_emul_mask = vp_none_get_emul_mask, + .vp_alloc = none_alloc, + .vp_free = none_free, };
static void fp_none_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 4e9a3b3467b..07b3d002c67 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -10820,7 +10820,7 @@ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *conte GL_EXTCALL(glUseProgram(0)); checkGLcall("glUseProgram");
- priv->vertex_pipe->vp_enable(context, FALSE); + priv->vertex_pipe->vp_disable(context); priv->fragment_pipe->fp_enable(context, FALSE);
if (needs_legacy_glsl_syntax(gl_info) && gl_info->supported[ARB_COLOR_BUFFER_FLOAT]) @@ -11565,6 +11565,8 @@ const struct wined3d_shader_backend_ops glsl_shader_backend =
static void glsl_vertex_pipe_vp_enable(const struct wined3d_context *context, BOOL enable) {}
+static void glsl_vertex_pipe_vp_disable(const struct wined3d_context *context) {} + static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps) { const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl_const(adapter)->gl_info; @@ -12049,12 +12051,13 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = * - Implement vertex tweening. */ const struct wined3d_vertex_pipe_ops glsl_vertex_pipe = { - glsl_vertex_pipe_vp_enable, - glsl_vertex_pipe_vp_get_caps, - glsl_vertex_pipe_vp_get_emul_mask, - glsl_vertex_pipe_vp_alloc, - glsl_vertex_pipe_vp_free, - glsl_vertex_pipe_vp_states, + .vp_enable = glsl_vertex_pipe_vp_enable, + .vp_disable = glsl_vertex_pipe_vp_disable, + .vp_get_caps = glsl_vertex_pipe_vp_get_caps, + .vp_get_emul_mask = glsl_vertex_pipe_vp_get_emul_mask, + .vp_alloc = glsl_vertex_pipe_vp_alloc, + .vp_free = glsl_vertex_pipe_vp_free, + .vp_states = glsl_vertex_pipe_vp_states, };
static void glsl_fragment_pipe_enable(const struct wined3d_context *context, BOOL enable) diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index b72a3df8737..e047e3da03d 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1952,7 +1952,7 @@ static void shader_none_disable(void *shader_priv, struct wined3d_context *conte { struct shader_none_priv *priv = shader_priv;
- priv->vertex_pipe->vp_enable(context, FALSE); + priv->vertex_pipe->vp_disable(context); priv->fragment_pipe->fp_enable(context, FALSE);
context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 1eac7373ee3..ca14564d7d6 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -904,7 +904,7 @@ static void shader_spirv_disable(void *shader_priv, struct wined3d_context *cont struct wined3d_context_vk *context_vk = wined3d_context_vk(context); struct shader_spirv_priv *priv = shader_priv;
- priv->vertex_pipe->vp_enable(context, false); + priv->vertex_pipe->vp_disable(context); priv->fragment_pipe->fp_enable(context, false);
context_vk->compute.vk_pipeline = VK_NULL_HANDLE; @@ -1141,6 +1141,11 @@ static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context *context /* Nothing to do. */ }
+static void spirv_vertex_pipe_vk_vp_disable(const struct wined3d_context *context) +{ + /* Nothing to do. */ +} + static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps) { memset(caps, 0, sizeof(*caps)); @@ -1200,6 +1205,7 @@ static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states[ static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk = { .vp_enable = spirv_vertex_pipe_vk_vp_enable, + .vp_disable = spirv_vertex_pipe_vk_vp_disable, .vp_get_caps = spirv_vertex_pipe_vk_vp_get_caps, .vp_get_emul_mask = spirv_vertex_pipe_vk_vp_get_emul_mask, .vp_alloc = spirv_vertex_pipe_vk_vp_alloc, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 033e0d6b9dc..8c562ba5daf 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2029,6 +2029,7 @@ struct wined3d_vertex_caps struct wined3d_vertex_pipe_ops { void (*vp_enable)(const struct wined3d_context *context, BOOL enable); + void (*vp_disable)(const struct wined3d_context *context); void (*vp_get_caps)(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps); unsigned int (*vp_get_emul_mask)(const struct wined3d_adapter *adapter); void *(*vp_alloc)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
From: Zebediah Figura zfigura@codeweavers.com
Analogous to shader_disable().
We'd like to pass a wined3d_state pointer to fp_enable() to let it handle actually compiling the fragment pipeline, which doesn't mesh well conceptually with its use in shader_disable(). --- dlls/wined3d/arb_program_shader.c | 29 ++++++++++----- dlls/wined3d/ati_fragment_shader.c | 27 +++++++++----- dlls/wined3d/ffp_gl.c | 37 ++++++++++--------- dlls/wined3d/glsl_shader.c | 25 ++++++++----- dlls/wined3d/nvidia_texture_shader.c | 55 +++++++++++++++++++--------- dlls/wined3d/shader.c | 2 +- dlls/wined3d/shader_spirv.c | 8 +++- dlls/wined3d/wined3d_private.h | 1 + 8 files changed, 117 insertions(+), 67 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index a1f56406a0a..ec2a578802a 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4771,7 +4771,7 @@ static void shader_arb_disable(void *shader_priv, struct wined3d_context *contex gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); } - priv->fragment_pipe->fp_enable(context, FALSE); + priv->fragment_pipe->fp_disable(context);
if (gl_info->supported[ARB_VERTEX_PROGRAM]) { @@ -5756,6 +5756,14 @@ static void arbfp_enable(const struct wined3d_context *context, BOOL enable) } }
+static void arbfp_disable(const struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + + gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); + checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); +} + static void *arbfp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { struct shader_arb_priv *priv; @@ -6894,15 +6902,16 @@ static void arbfp_free_context_data(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops arbfp_fragment_pipeline = { - arbfp_enable, - arbfp_get_caps, - arbfp_get_emul_mask, - arbfp_alloc, - arbfp_free, - arbfp_alloc_context_data, - arbfp_free_context_data, - shader_arb_color_fixup_supported, - arbfp_fragmentstate_template, + .fp_enable = arbfp_enable, + .fp_disable = arbfp_disable, + .get_caps = arbfp_get_caps, + .get_emul_mask = arbfp_get_emul_mask, + .alloc_private = arbfp_alloc, + .free_private = arbfp_free, + .allocate_context_data = arbfp_alloc_context_data, + .free_context_data = arbfp_free_context_data, + .color_fixup_supported = shader_arb_color_fixup_supported, + .states = arbfp_fragmentstate_template, };
struct arbfp_blit_type diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 605d050ff7d..058fd1680a9 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1267,6 +1267,14 @@ static void atifs_enable(const struct wined3d_context *context, BOOL enable) } }
+static void atifs_disable(const struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + + gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_SHADER_ATI); + checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)"); +} + static void atifs_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { memset(caps, 0, sizeof(*caps)); @@ -1382,13 +1390,14 @@ static void atifs_free_context_data(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops atifs_fragment_pipeline = { - atifs_enable, - atifs_get_caps, - atifs_get_emul_mask, - atifs_alloc, - atifs_free, - atifs_alloc_context_data, - atifs_free_context_data, - atifs_color_fixup_supported, - atifs_fragmentstate_template, + .fp_enable = atifs_enable, + .fp_disable = atifs_disable, + .get_caps = atifs_get_caps, + .get_emul_mask = atifs_get_emul_mask, + .alloc_private = atifs_alloc, + .free_private = atifs_free, + .allocate_context_data = atifs_alloc_context_data, + .free_context_data = atifs_free_context_data, + .color_fixup_supported = atifs_color_fixup_supported, + .states = atifs_fragmentstate_template, }; diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index 8d8a14107eb..a9c6bd9fbb2 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -4955,15 +4955,16 @@ static void ffp_none_context_free(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline = { - ffp_pipe_enable, - ffp_fragment_get_caps, - ffp_fragment_get_emul_mask, - ffp_alloc, - ffp_free, - ffp_none_context_alloc, - ffp_none_context_free, - ffp_color_fixup_supported, - ffp_fragmentstate_template, + .fp_enable = ffp_pipe_enable, + .fp_disable = ffp_pipe_disable, + .get_caps = ffp_fragment_get_caps, + .get_emul_mask = ffp_fragment_get_emul_mask, + .alloc_private = ffp_alloc, + .free_private = ffp_free, + .allocate_context_data = ffp_none_context_alloc, + .free_context_data = ffp_none_context_free, + .color_fixup_supported = ffp_color_fixup_supported, + .states = ffp_fragmentstate_template, };
static void none_pipe_enable(const struct wined3d_context *context, BOOL enable) {} @@ -5014,15 +5015,15 @@ static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
const struct wined3d_fragment_pipe_ops none_fragment_pipe = { - none_pipe_enable, - fp_none_get_caps, - fp_none_get_emul_mask, - none_alloc, - none_free, - ffp_none_context_alloc, - ffp_none_context_free, - fp_none_color_fixup_supported, - NULL, + .fp_enable = none_pipe_enable, + .fp_disable = none_pipe_disable, + .get_caps = fp_none_get_caps, + .get_emul_mask = fp_none_get_emul_mask, + .alloc_private = none_alloc, + .free_private = none_free, + .allocate_context_data = ffp_none_context_alloc, + .free_context_data = ffp_none_context_free, + .color_fixup_supported = fp_none_color_fixup_supported, };
static unsigned int num_handlers(const APPLYSTATEFUNC *funcs) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 07b3d002c67..afea97e1c5f 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -10821,7 +10821,7 @@ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *conte checkGLcall("glUseProgram");
priv->vertex_pipe->vp_disable(context); - priv->fragment_pipe->fp_enable(context, FALSE); + priv->fragment_pipe->fp_disable(context);
if (needs_legacy_glsl_syntax(gl_info) && gl_info->supported[ARB_COLOR_BUFFER_FLOAT]) { @@ -12065,6 +12065,10 @@ static void glsl_fragment_pipe_enable(const struct wined3d_context *context, BOO /* Nothing to do. */ }
+static void glsl_fragment_pipe_disable(const struct wined3d_context *context) +{ +} + static void glsl_fragment_pipe_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl_const(adapter)->gl_info; @@ -12424,15 +12428,16 @@ static void glsl_fragment_pipe_free_context_data(struct wined3d_context *context
const struct wined3d_fragment_pipe_ops glsl_fragment_pipe = { - glsl_fragment_pipe_enable, - glsl_fragment_pipe_get_caps, - glsl_fragment_pipe_get_emul_mask, - glsl_fragment_pipe_alloc, - glsl_fragment_pipe_free, - glsl_fragment_pipe_alloc_context_data, - glsl_fragment_pipe_free_context_data, - shader_glsl_color_fixup_supported, - glsl_fragment_pipe_state_template, + .fp_enable = glsl_fragment_pipe_enable, + .fp_disable = glsl_fragment_pipe_disable, + .get_caps = glsl_fragment_pipe_get_caps, + .get_emul_mask = glsl_fragment_pipe_get_emul_mask, + .alloc_private = glsl_fragment_pipe_alloc, + .free_private = glsl_fragment_pipe_free, + .allocate_context_data = glsl_fragment_pipe_alloc_context_data, + .free_context_data = glsl_fragment_pipe_free_context_data, + .color_fixup_supported = shader_glsl_color_fixup_supported, + .states = glsl_fragment_pipe_state_template, };
struct glsl_blitter_args diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 0e56f5f58e0..14510b25f0e 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -676,6 +676,14 @@ static void nvrc_enable(const struct wined3d_context *context, BOOL enable) } }
+static void nvrc_disable(const struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + + gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV); + checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)"); +} + /* Context activation is done by the caller. */ static void nvts_enable(const struct wined3d_context *context, BOOL enable) { @@ -694,6 +702,15 @@ static void nvts_enable(const struct wined3d_context *context, BOOL enable) } }
+static void nvts_disable(const struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + + nvrc_disable(context); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_SHADER_NV); + checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)"); +} + static void nvrc_fragment_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl_const(adapter)->gl_info; @@ -931,26 +948,28 @@ static void nvrc_context_free(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops nvts_fragment_pipeline = { - nvts_enable, - nvrc_fragment_get_caps, - nvrc_fragment_get_emul_mask, - nvrc_fragment_alloc, - nvrc_fragment_free, - nvrc_context_alloc, - nvrc_context_free, - nvts_color_fixup_supported, - nvrc_fragmentstate_template, + .fp_enable = nvts_enable, + .fp_disable = nvts_disable, + .get_caps = nvrc_fragment_get_caps, + .get_emul_mask = nvrc_fragment_get_emul_mask, + .alloc_private = nvrc_fragment_alloc, + .free_private = nvrc_fragment_free, + .allocate_context_data = nvrc_context_alloc, + .free_context_data = nvrc_context_free, + .color_fixup_supported = nvts_color_fixup_supported, + .states = nvrc_fragmentstate_template, };
const struct wined3d_fragment_pipe_ops nvrc_fragment_pipeline = { - nvrc_enable, - nvrc_fragment_get_caps, - nvrc_fragment_get_emul_mask, - nvrc_fragment_alloc, - nvrc_fragment_free, - nvrc_context_alloc, - nvrc_context_free, - nvts_color_fixup_supported, - nvrc_fragmentstate_template, + .fp_enable = nvrc_enable, + .fp_disable = nvrc_disable, + .get_caps = nvrc_fragment_get_caps, + .get_emul_mask = nvrc_fragment_get_emul_mask, + .alloc_private = nvrc_fragment_alloc, + .free_private = nvrc_fragment_free, + .allocate_context_data = nvrc_context_alloc, + .free_context_data = nvrc_context_free, + .color_fixup_supported = nvts_color_fixup_supported, + .states = nvrc_fragmentstate_template, }; diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index e047e3da03d..72c1158f5ba 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1953,7 +1953,7 @@ static void shader_none_disable(void *shader_priv, struct wined3d_context *conte struct shader_none_priv *priv = shader_priv;
priv->vertex_pipe->vp_disable(context); - priv->fragment_pipe->fp_enable(context, FALSE); + priv->fragment_pipe->fp_disable(context);
context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index ca14564d7d6..40c1a9f80ae 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -905,7 +905,7 @@ static void shader_spirv_disable(void *shader_priv, struct wined3d_context *cont struct shader_spirv_priv *priv = shader_priv;
priv->vertex_pipe->vp_disable(context); - priv->fragment_pipe->fp_enable(context, false); + priv->fragment_pipe->fp_disable(context);
context_vk->compute.vk_pipeline = VK_NULL_HANDLE; context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) @@ -1223,6 +1223,11 @@ static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context *conte /* Nothing to do. */ }
+static void spirv_fragment_pipe_vk_fp_disable(const struct wined3d_context *context) +{ + /* Nothing to do. */ +} + static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { memset(caps, 0, sizeof(*caps)); @@ -1285,6 +1290,7 @@ static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_state static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk = { .fp_enable = spirv_fragment_pipe_vk_fp_enable, + .fp_disable = spirv_fragment_pipe_vk_fp_disable, .get_caps = spirv_fragment_pipe_vk_fp_get_caps, .get_emul_mask = spirv_fragment_pipe_vk_fp_get_emul_mask, .alloc_private = spirv_fragment_pipe_vk_fp_alloc, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8c562ba5daf..04e86004f28 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2002,6 +2002,7 @@ struct wined3d_state_entry_template struct wined3d_fragment_pipe_ops { void (*fp_enable)(const struct wined3d_context *context, BOOL enable); + void (*fp_disable)(const struct wined3d_context *context); void (*get_caps)(const struct wined3d_adapter *adapter, struct fragment_caps *caps); unsigned int (*get_emul_mask)(const struct wined3d_adapter *adapter); void *(*alloc_private)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
From: Zebediah Figura zfigura@codeweavers.com
Rename to *_apply_draw_state() per Henri's suggestion. --- dlls/wined3d/arb_program_shader.c | 14 +++++++------- dlls/wined3d/ati_fragment_shader.c | 6 +++--- dlls/wined3d/ffp_gl.c | 12 ++++++------ dlls/wined3d/glsl_shader.c | 13 +++++++------ dlls/wined3d/nvidia_texture_shader.c | 14 +++++++------- dlls/wined3d/shader.c | 4 ++-- dlls/wined3d/shader_spirv.c | 13 +++++++------ dlls/wined3d/wined3d_private.h | 4 ++-- 8 files changed, 41 insertions(+), 39 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index ec2a578802a..8a31d67662d 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4630,7 +4630,7 @@ static void shader_arb_update_graphics_shaders(struct shader_arb_priv *priv, GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, compiled->prgId)); checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, compiled->prgId);");
- priv->fragment_pipe->fp_enable(context, FALSE); + priv->fragment_pipe->fp_apply_draw_state(context, state);
/* Enable OpenGL fragment programs. Note that we may have already * disabled them when disabling the fragment pipeline. */ @@ -4677,7 +4677,7 @@ static void shader_arb_update_graphics_shaders(struct shader_arb_priv *priv, gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); } - priv->fragment_pipe->fp_enable(context, TRUE); + priv->fragment_pipe->fp_apply_draw_state(context, state); }
if (use_vs(state)) @@ -4706,7 +4706,7 @@ static void shader_arb_update_graphics_shaders(struct shader_arb_priv *priv, GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, compiled->prgId)); checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, compiled->prgId);");
- priv->vertex_pipe->vp_enable(context, FALSE); + priv->vertex_pipe->vp_apply_draw_state(context, state);
/* Enable OpenGL vertex programs */ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_ARB); @@ -4736,7 +4736,7 @@ static void shader_arb_update_graphics_shaders(struct shader_arb_priv *priv, gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB); checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)"); } - priv->vertex_pipe->vp_enable(context, TRUE); + priv->vertex_pipe->vp_apply_draw_state(context, state); } }
@@ -5740,11 +5740,11 @@ struct arbfp_ffp_desc };
/* Context activation is done by the caller. */ -static void arbfp_enable(const struct wined3d_context *context, BOOL enable) +static void arbfp_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
- if (enable) + if (!use_ps(state)) { gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)"); @@ -6902,7 +6902,7 @@ static void arbfp_free_context_data(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops arbfp_fragment_pipeline = { - .fp_enable = arbfp_enable, + .fp_apply_draw_state = arbfp_apply_draw_state, .fp_disable = arbfp_disable, .get_caps = arbfp_get_caps, .get_emul_mask = arbfp_get_emul_mask, diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 058fd1680a9..45e6c081ba0 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1251,11 +1251,11 @@ static const struct wined3d_state_entry_template atifs_fragmentstate_template[] };
/* Context activation is done by the caller. */ -static void atifs_enable(const struct wined3d_context *context, BOOL enable) +static void atifs_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
- if (enable) + if (!use_ps(state)) { gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_SHADER_ATI); checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)"); @@ -1390,7 +1390,7 @@ static void atifs_free_context_data(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops atifs_fragment_pipeline = { - .fp_enable = atifs_enable, + .fp_apply_draw_state = atifs_apply_draw_state, .fp_disable = atifs_disable, .get_caps = atifs_get_caps, .get_emul_mask = atifs_get_emul_mask, diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index a9c6bd9fbb2..0b5f1fab653 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -4840,7 +4840,7 @@ static const struct wined3d_state_entry_template ffp_fragmentstate_template[] = };
/* Context activation is done by the caller. */ -static void ffp_pipe_enable(const struct wined3d_context *context, BOOL enable) {} +static void ffp_pipe_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) {}
static void ffp_pipe_disable(const struct wined3d_context *context) {}
@@ -4881,7 +4881,7 @@ static unsigned int vp_ffp_get_emul_mask(const struct wined3d_adapter *adapter)
const struct wined3d_vertex_pipe_ops ffp_vertex_pipe = { - .vp_enable = ffp_pipe_enable, + .vp_apply_draw_state = ffp_pipe_apply_draw_state, .vp_disable = ffp_pipe_disable, .vp_get_caps = vp_ffp_get_caps, .vp_get_emul_mask = vp_ffp_get_emul_mask, @@ -4955,7 +4955,7 @@ static void ffp_none_context_free(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline = { - .fp_enable = ffp_pipe_enable, + .fp_apply_draw_state = ffp_pipe_apply_draw_state, .fp_disable = ffp_pipe_disable, .get_caps = ffp_fragment_get_caps, .get_emul_mask = ffp_fragment_get_emul_mask, @@ -4967,7 +4967,7 @@ const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline = .states = ffp_fragmentstate_template, };
-static void none_pipe_enable(const struct wined3d_context *context, BOOL enable) {} +static void none_pipe_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) {}
static void none_pipe_disable(const struct wined3d_context *context) {}
@@ -4990,7 +4990,7 @@ static unsigned int vp_none_get_emul_mask(const struct wined3d_adapter *adapter)
const struct wined3d_vertex_pipe_ops none_vertex_pipe = { - .vp_enable = none_pipe_enable, + .vp_apply_draw_state = none_pipe_apply_draw_state, .vp_disable = none_pipe_disable, .vp_get_caps = vp_none_get_caps, .vp_get_emul_mask = vp_none_get_emul_mask, @@ -5015,7 +5015,7 @@ static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
const struct wined3d_fragment_pipe_ops none_fragment_pipe = { - .fp_enable = none_pipe_enable, + .fp_apply_draw_state = none_pipe_apply_draw_state, .fp_disable = none_pipe_disable, .get_caps = fp_none_get_caps, .get_emul_mask = fp_none_get_emul_mask, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index afea97e1c5f..4cff60b1775 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -10704,8 +10704,8 @@ static void shader_glsl_update_graphics_program(struct shader_glsl_priv *priv, GLenum current_vertex_color_clamp; GLuint program_id, prev_id;
- priv->vertex_pipe->vp_enable(&context_gl->c, !use_vs(state)); - priv->fragment_pipe->fp_enable(&context_gl->c, !use_ps(state)); + priv->vertex_pipe->vp_apply_draw_state(&context_gl->c, state); + priv->fragment_pipe->fp_apply_draw_state(&context_gl->c, state);
prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; set_glsl_shader_program(context_gl, state, priv, ctx_data); @@ -11563,7 +11563,7 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = shader_glsl_shader_compile, };
-static void glsl_vertex_pipe_vp_enable(const struct wined3d_context *context, BOOL enable) {} +static void glsl_vertex_pipe_vp_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) {}
static void glsl_vertex_pipe_vp_disable(const struct wined3d_context *context) {}
@@ -12051,7 +12051,7 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = * - Implement vertex tweening. */ const struct wined3d_vertex_pipe_ops glsl_vertex_pipe = { - .vp_enable = glsl_vertex_pipe_vp_enable, + .vp_apply_draw_state = glsl_vertex_pipe_vp_apply_draw_state, .vp_disable = glsl_vertex_pipe_vp_disable, .vp_get_caps = glsl_vertex_pipe_vp_get_caps, .vp_get_emul_mask = glsl_vertex_pipe_vp_get_emul_mask, @@ -12060,7 +12060,8 @@ const struct wined3d_vertex_pipe_ops glsl_vertex_pipe = .vp_states = glsl_vertex_pipe_vp_states, };
-static void glsl_fragment_pipe_enable(const struct wined3d_context *context, BOOL enable) +static void glsl_fragment_pipe_apply_draw_state( + const struct wined3d_context *context, const struct wined3d_state *state) { /* Nothing to do. */ } @@ -12428,7 +12429,7 @@ static void glsl_fragment_pipe_free_context_data(struct wined3d_context *context
const struct wined3d_fragment_pipe_ops glsl_fragment_pipe = { - .fp_enable = glsl_fragment_pipe_enable, + .fp_apply_draw_state = glsl_fragment_pipe_apply_draw_state, .fp_disable = glsl_fragment_pipe_disable, .get_caps = glsl_fragment_pipe_get_caps, .get_emul_mask = glsl_fragment_pipe_get_emul_mask, diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 14510b25f0e..c68dc42b690 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -660,11 +660,11 @@ static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d }
/* Context activation is done by the caller. */ -static void nvrc_enable(const struct wined3d_context *context, BOOL enable) +static void nvrc_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
- if (enable) + if (!use_ps(state)) { gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV); checkGLcall("glEnable(GL_REGISTER_COMBINERS_NV)"); @@ -685,12 +685,12 @@ static void nvrc_disable(const struct wined3d_context *context) }
/* Context activation is done by the caller. */ -static void nvts_enable(const struct wined3d_context *context, BOOL enable) +static void nvts_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
- nvrc_enable(context, enable); - if (enable) + nvrc_apply_draw_state(context, state); + if (!use_ps(state)) { gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_SHADER_NV); checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)"); @@ -948,7 +948,7 @@ static void nvrc_context_free(struct wined3d_context *context)
const struct wined3d_fragment_pipe_ops nvts_fragment_pipeline = { - .fp_enable = nvts_enable, + .fp_apply_draw_state = nvts_apply_draw_state, .fp_disable = nvts_disable, .get_caps = nvrc_fragment_get_caps, .get_emul_mask = nvrc_fragment_get_emul_mask, @@ -962,7 +962,7 @@ const struct wined3d_fragment_pipe_ops nvts_fragment_pipeline =
const struct wined3d_fragment_pipe_ops nvrc_fragment_pipeline = { - .fp_enable = nvrc_enable, + .fp_apply_draw_state = nvrc_apply_draw_state, .fp_disable = nvrc_disable, .get_caps = nvrc_fragment_get_caps, .get_emul_mask = nvrc_fragment_get_emul_mask, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 72c1158f5ba..6b41bf5ebc5 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1943,8 +1943,8 @@ static void shader_none_apply_draw_state(void *shader_priv, struct wined3d_conte { struct shader_none_priv *priv = shader_priv;
- priv->vertex_pipe->vp_enable(context, !use_vs(state)); - priv->fragment_pipe->fp_enable(context, !use_ps(state)); + priv->vertex_pipe->vp_apply_draw_state(context, state); + priv->fragment_pipe->fp_apply_draw_state(context, state); }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 40c1a9f80ae..70affa1558e 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -826,8 +826,8 @@ static void shader_spirv_apply_draw_state(void *shader_priv, struct wined3d_cont enum wined3d_shader_type shader_type; struct wined3d_shader *shader;
- priv->vertex_pipe->vp_enable(context, !use_vs(state)); - priv->fragment_pipe->fp_enable(context, !use_ps(state)); + priv->vertex_pipe->vp_apply_draw_state(context, state); + priv->fragment_pipe->fp_apply_draw_state(context, state);
bindings = &priv->bindings; memcpy(binding_base, bindings->binding_base, sizeof(bindings->binding_base)); @@ -1136,7 +1136,7 @@ const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(vo return &spirv_shader_backend_vk; }
-static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context *context, BOOL enable) +static void spirv_vertex_pipe_vk_vp_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) { /* Nothing to do. */ } @@ -1204,7 +1204,7 @@ static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states[
static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk = { - .vp_enable = spirv_vertex_pipe_vk_vp_enable, + .vp_apply_draw_state = spirv_vertex_pipe_vk_vp_apply_draw_state, .vp_disable = spirv_vertex_pipe_vk_vp_disable, .vp_get_caps = spirv_vertex_pipe_vk_vp_get_caps, .vp_get_emul_mask = spirv_vertex_pipe_vk_vp_get_emul_mask, @@ -1218,7 +1218,8 @@ const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void) return &spirv_vertex_pipe_vk; }
-static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context *context, BOOL enable) +static void spirv_fragment_pipe_vk_fp_apply_draw_state( + const struct wined3d_context *context, const struct wined3d_state *state) { /* Nothing to do. */ } @@ -1289,7 +1290,7 @@ static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_state
static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk = { - .fp_enable = spirv_fragment_pipe_vk_fp_enable, + .fp_apply_draw_state = spirv_fragment_pipe_vk_fp_apply_draw_state, .fp_disable = spirv_fragment_pipe_vk_fp_disable, .get_caps = spirv_fragment_pipe_vk_fp_get_caps, .get_emul_mask = spirv_fragment_pipe_vk_fp_get_emul_mask, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 04e86004f28..74c0ea52f3a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2001,7 +2001,7 @@ struct wined3d_state_entry_template
struct wined3d_fragment_pipe_ops { - void (*fp_enable)(const struct wined3d_context *context, BOOL enable); + void (*fp_apply_draw_state)(const struct wined3d_context *context, const struct wined3d_state *state); void (*fp_disable)(const struct wined3d_context *context); void (*get_caps)(const struct wined3d_adapter *adapter, struct fragment_caps *caps); unsigned int (*get_emul_mask)(const struct wined3d_adapter *adapter); @@ -2029,7 +2029,7 @@ struct wined3d_vertex_caps
struct wined3d_vertex_pipe_ops { - void (*vp_enable)(const struct wined3d_context *context, BOOL enable); + void (*vp_apply_draw_state)(const struct wined3d_context *context, const struct wined3d_state *state); void (*vp_disable)(const struct wined3d_context *context); void (*vp_get_caps)(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps); unsigned int (*vp_get_emul_mask)(const struct wined3d_adapter *adapter);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/arb_program_shader.c | 2 +- dlls/wined3d/ati_fragment_shader.c | 2 +- dlls/wined3d/ffp_gl.c | 4 ++-- dlls/wined3d/glsl_shader.c | 5 ++--- dlls/wined3d/nvidia_texture_shader.c | 4 ++-- dlls/wined3d/shader_spirv.c | 4 ++-- dlls/wined3d/wined3d_private.h | 4 ++-- 7 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 8a31d67662d..9ca6dd8ff46 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -5740,7 +5740,7 @@ struct arbfp_ffp_desc };
/* Context activation is done by the caller. */ -static void arbfp_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) +static void arbfp_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 45e6c081ba0..925b712f372 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1251,7 +1251,7 @@ static const struct wined3d_state_entry_template atifs_fragmentstate_template[] };
/* Context activation is done by the caller. */ -static void atifs_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) +static void atifs_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index 0b5f1fab653..dbc82a1ba4d 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -4840,7 +4840,7 @@ static const struct wined3d_state_entry_template ffp_fragmentstate_template[] = };
/* Context activation is done by the caller. */ -static void ffp_pipe_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) {} +static void ffp_pipe_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) {}
static void ffp_pipe_disable(const struct wined3d_context *context) {}
@@ -4967,7 +4967,7 @@ const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline = .states = ffp_fragmentstate_template, };
-static void none_pipe_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) {} +static void none_pipe_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) {}
static void none_pipe_disable(const struct wined3d_context *context) {}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 4cff60b1775..5a2133bf5a0 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -11563,7 +11563,7 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = shader_glsl_shader_compile, };
-static void glsl_vertex_pipe_vp_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) {} +static void glsl_vertex_pipe_vp_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) {}
static void glsl_vertex_pipe_vp_disable(const struct wined3d_context *context) {}
@@ -12060,8 +12060,7 @@ const struct wined3d_vertex_pipe_ops glsl_vertex_pipe = .vp_states = glsl_vertex_pipe_vp_states, };
-static void glsl_fragment_pipe_apply_draw_state( - const struct wined3d_context *context, const struct wined3d_state *state) +static void glsl_fragment_pipe_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) { /* Nothing to do. */ } diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index c68dc42b690..0575e72ef43 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -660,7 +660,7 @@ static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d }
/* Context activation is done by the caller. */ -static void nvrc_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) +static void nvrc_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
@@ -685,7 +685,7 @@ static void nvrc_disable(const struct wined3d_context *context) }
/* Context activation is done by the caller. */ -static void nvts_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) +static void nvts_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info;
diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 70affa1558e..5be17815d3a 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -1136,7 +1136,7 @@ const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(vo return &spirv_shader_backend_vk; }
-static void spirv_vertex_pipe_vk_vp_apply_draw_state(const struct wined3d_context *context, const struct wined3d_state *state) +static void spirv_vertex_pipe_vk_vp_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) { /* Nothing to do. */ } @@ -1219,7 +1219,7 @@ const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void) }
static void spirv_fragment_pipe_vk_fp_apply_draw_state( - const struct wined3d_context *context, const struct wined3d_state *state) + struct wined3d_context *context, const struct wined3d_state *state) { /* Nothing to do. */ } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 74c0ea52f3a..ae9e049a054 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2001,7 +2001,7 @@ struct wined3d_state_entry_template
struct wined3d_fragment_pipe_ops { - void (*fp_apply_draw_state)(const struct wined3d_context *context, const struct wined3d_state *state); + void (*fp_apply_draw_state)(struct wined3d_context *context, const struct wined3d_state *state); void (*fp_disable)(const struct wined3d_context *context); void (*get_caps)(const struct wined3d_adapter *adapter, struct fragment_caps *caps); unsigned int (*get_emul_mask)(const struct wined3d_adapter *adapter); @@ -2029,7 +2029,7 @@ struct wined3d_vertex_caps
struct wined3d_vertex_pipe_ops { - void (*vp_apply_draw_state)(const struct wined3d_context *context, const struct wined3d_state *state); + void (*vp_apply_draw_state)(struct wined3d_context *context, const struct wined3d_state *state); void (*vp_disable)(const struct wined3d_context *context); void (*vp_get_caps)(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps); unsigned int (*vp_get_emul_mask)(const struct wined3d_adapter *adapter);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/arb_program_shader.c | 123 +++++++++++++++--------------- 1 file changed, 62 insertions(+), 61 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 9ca6dd8ff46..5025102f15f 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4665,6 +4665,8 @@ static void shader_arb_update_graphics_shaders(struct shader_arb_priv *priv,
if (ps->load_local_constsF) context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F; + + context->last_was_pshader = TRUE; } else { @@ -5739,23 +5741,6 @@ struct arbfp_ffp_desc GLuint shader; };
-/* Context activation is done by the caller. */ -static void arbfp_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) -{ - const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; - - if (!use_ps(state)) - { - gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); - checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)"); - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); - checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); - } -} - static void arbfp_disable(const struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; @@ -6615,67 +6600,65 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con }
static void fragment_prog_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + if (use_ps(state) && !context->last_was_pshader && context->device->shader_backend == &arb_program_shader_backend) + { + /* Reload pixel shader constants since they collide with the + * fixed function constants. */ + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F; + } + + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; +} + +static void arbfp_update_shader(struct wined3d_context *context, const struct wined3d_state *state) { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_device *device = context->device; struct shader_arb_priv *priv = device->fragment_priv; - BOOL use_pshader = use_ps(state); struct ffp_frag_settings settings; const struct arbfp_ffp_desc *desc; unsigned int i;
- TRACE("context %p, state %p, state_id %#lx.\n", context, state, state_id); - - if (!use_pshader) + /* Find or create a shader implementing the fixed function pipeline + * settings, then activate it. */ + wined3d_ffp_get_fs_settings(context, state, &settings, FALSE); + desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings); + if (!desc) { - /* Find or create a shader implementing the fixed function pipeline - * settings, then activate it. */ - wined3d_ffp_get_fs_settings(context, state, &settings, FALSE); - desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings); - if (!desc) - { - struct arbfp_ffp_desc *new_desc; - - if (!(new_desc = heap_alloc(sizeof(*new_desc)))) - { - ERR("Out of memory\n"); - return; - } + struct arbfp_ffp_desc *new_desc;
- new_desc->parent.settings = settings; - new_desc->shader = gen_arbfp_ffp_shader(&settings, gl_info); - add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent); - TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc); - desc = new_desc; + if (!(new_desc = heap_alloc(sizeof(*new_desc)))) + { + ERR("Out of memory\n"); + return; }
- GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)); - checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)"); + new_desc->parent.settings = settings; + new_desc->shader = gen_arbfp_ffp_shader(&settings, gl_info); + add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent); + TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc); + desc = new_desc; + } + + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)); + checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)");
- if (device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) + if (device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) + { + /* Reload fixed function constants since they collide with the + * pixel shader constants. */ + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) { - /* Reload fixed function constants since they collide with the - * pixel shader constants. */ - for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) - { - set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); - state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); - } - state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); - state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); - color_key_arbfp(context, state, STATE_COLOR_KEY); + set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); + state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); } - context->last_was_pshader = FALSE; + state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); + state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); + color_key_arbfp(context, state, STATE_COLOR_KEY); } - else if (!context->last_was_pshader) - { - if (device->shader_backend == &arb_program_shader_backend) - context->constant_update_mask |= WINED3D_SHADER_CONST_PS_F; - context->last_was_pshader = TRUE; - } - - context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; + context->last_was_pshader = FALSE; }
/* We can't link the fog states to the fragment state directly since the @@ -6900,6 +6883,24 @@ static void arbfp_free_context_data(struct wined3d_context *context) { }
+static void arbfp_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + + if (use_ps(state)) + { + gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); + checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); + return; + } + + gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); + checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)"); + + if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL)) + arbfp_update_shader(context, state); +} + const struct wined3d_fragment_pipe_ops arbfp_fragment_pipeline = { .fp_apply_draw_state = arbfp_apply_draw_state,
This merge request was approved by Jan Sikorski.