From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/ffp_gl.c | 4 +-- dlls/wined3d/glsl_shader.c | 65 +++++----------------------------- dlls/wined3d/shader_spirv.c | 4 --- dlls/wined3d/stateblock.c | 62 ++++++++++++++++++++++++++++++-- dlls/wined3d/utils.c | 40 --------------------- dlls/wined3d/wined3d_private.h | 17 ++++----- 6 files changed, 77 insertions(+), 115 deletions(-)
diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index 61b4244c15f..b75c5b1aef7 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -1570,8 +1570,8 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 11, 14}, { 16, 24}, { 27, 27}, - { 30, 33}, - { 39, 40}, + { 30, 34}, + { 36, 40}, { 42, 47}, { 49, 135}, {138, 139}, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b2e89704933..fe7042c9c3c 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1682,26 +1682,17 @@ static void shader_glsl_pointsize_uniform(struct wined3d_context_gl *context_gl, checkGLcall("glUniform1f"); }
-static void shader_glsl_load_fog_uniform(const struct wined3d_context_gl *context_gl, +static void shader_glsl_load_fog_uniform(struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { + const struct wined3d_ffp_ps_constants *constants = wined3d_buffer_load_sysmem( + context_gl->c.device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], &context_gl->c); const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct wined3d_color color; - float start, end, scale; - union - { - DWORD d; - float f; - } tmpvalue; - - wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_FOGCOLOR]); - GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &color.r)); - tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY]; - GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, tmpvalue.f)); - get_fog_start_end(&context_gl->c, state, &start, &end); - scale = 1.0f / (end - start); - GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, end)); - GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, scale)); + + GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &constants->fog.colour.r)); + GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, constants->fog.density)); + GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, constants->fog.end)); + GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, constants->fog.scale)); checkGLcall("fog emulation uniforms"); }
@@ -12083,43 +12074,10 @@ static void glsl_fragment_pipe_shader(struct wined3d_context *context, context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; }
-static void glsl_fragment_pipe_fogparams(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG; -} - static void glsl_fragment_pipe_fog(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - 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]; - context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; - - if (!state->render_states[WINED3D_RS_FOGENABLE]) - return; - - if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE) - { - if (use_vshader || state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE - || context->stream_info.position_transformed) - new_source = FOGSOURCE_VS; - else - new_source = FOGSOURCE_FFP; - } - else - { - new_source = FOGSOURCE_FFP; - } - - if (new_source != context->fog_source || fogstart == fogend) - { - context->fog_source = new_source; - context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG; - } }
static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, @@ -12130,9 +12088,6 @@ static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, /* Because of settings->texcoords_initialized and args->texcoords_initialized. */ if (!shader_glsl_full_ffp_varyings(gl_info)) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; - - if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE))) - glsl_fragment_pipe_fog(context, state, state_id); }
static void glsl_fragment_pipe_vs(struct wined3d_context *context, @@ -12211,12 +12166,8 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, ARB_POINT_SPRITE }, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, WINED3D_GL_VERSION_2_0}, {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 51cfe58e255..cc67760d1dc 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -1287,11 +1287,7 @@ static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_state {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}}, - {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}}, - {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_nop}}, - {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}}, - {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}}, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}}, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 1407565aed5..ed9c8ec19b3 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -69,6 +69,7 @@ struct wined3d_saved_states uint32_t rasterizer_state : 1; uint32_t position_transformed : 1; uint32_t bumpenv_constants : 1; + uint32_t fog_constants : 1; };
struct stage_state @@ -327,6 +328,7 @@ void CDECL wined3d_stateblock_primary_dirtify_all_states(struct wined3d_device * states->rasterizer_state = 1; states->position_transformed = 1; states->bumpenv_constants = 1; + states->fog_constants = 1;
list_init(&stateblock->changed.changed_lights); RB_FOR_EACH_ENTRY(light, lights_tree, struct wined3d_light_info, entry) @@ -1667,8 +1669,6 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb case WINED3D_RS_DIFFUSEMATERIALSOURCE: case WINED3D_RS_EMISSIVEMATERIALSOURCE: case WINED3D_RS_FOGENABLE: - case WINED3D_RS_FOGTABLEMODE: - case WINED3D_RS_FOGVERTEXMODE: case WINED3D_RS_LIGHTING: case WINED3D_RS_LOCALVIEWER: case WINED3D_RS_NORMALIZENORMALS: @@ -1695,6 +1695,19 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb stateblock->changed.rasterizer_state = 1; break;
+ case WINED3D_RS_FOGCOLOR: + case WINED3D_RS_FOGDENSITY: + case WINED3D_RS_FOGEND: + case WINED3D_RS_FOGSTART: + stateblock->changed.fog_constants = 1; + break; + + case WINED3D_RS_FOGTABLEMODE: + case WINED3D_RS_FOGVERTEXMODE: + stateblock->changed.ffp_vs_settings = 1; + stateblock->changed.fog_constants = 1; + break; + default: break; } @@ -2446,6 +2459,7 @@ static void wined3d_stateblock_invalidate_initial_states(struct wined3d_stateblo stateblock->changed.ffp_vs_settings = 1; stateblock->changed.ffp_ps_settings = 1; stateblock->changed.bumpenv_constants = 1; + stateblock->changed.fog_constants = 1; }
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const struct wined3d_stateblock *device_state, @@ -3182,6 +3196,10 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_POINTSCALE_C: case WINED3D_RS_TEXTUREFACTOR: case WINED3D_RS_ALPHAREF: + case WINED3D_RS_FOGCOLOR: + case WINED3D_RS_FOGDENSITY: + case WINED3D_RS_FOGEND: + case WINED3D_RS_FOGSTART: break;
case WINED3D_RS_ANTIALIAS: @@ -3931,6 +3949,46 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, offsetof(struct wined3d_ffp_ps_constants, alpha_test_ref), sizeof(f), &f); }
+ if (changed->fog_constants || changed->ffp_vs_settings || changed->position_transformed) + { + bool rhw = state->vertex_declaration && state->vertex_declaration->position_transformed; + struct wined3d_ffp_fog_constants fog; + + wined3d_color_from_d3dcolor(&fog.colour, state->rs[WINED3D_RS_FOGCOLOR]); + fog.density = int_to_float(state->rs[WINED3D_RS_FOGDENSITY]); + + if (state->rs[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE + || (state->rs[WINED3D_RS_FOGVERTEXMODE] != WINED3D_FOG_NONE && !state->vs && !rhw)) + { + float start = int_to_float(state->rs[WINED3D_RS_FOGSTART]); + float end = int_to_float(state->rs[WINED3D_RS_FOGEND]); + + if (start == end) + { + /* With vertex fog, everything is fogged. + * With pixel fog, coordinates < start are unfogged, + * and coordinates > start are fogged. + * Windows drivers disagree when coord == start. */ + fog.end = 0.0f; + fog.scale = 0.0f; + } + else + { + fog.end = end; + fog.scale = 1.0f / (end - start); + } + } + else + { + fog.end = 0.0f; + fog.scale = -1.0f; + } + + wined3d_device_context_push_constants(context, + WINED3D_PUSH_CONSTANTS_PS_FFP, WINED3D_SHADER_CONST_PS_FOG, + offsetof(struct wined3d_ffp_ps_constants, fog), sizeof(fog), &fog); + } + if (changed->vertexShader) { wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, state->vs); diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index f176e09fa3c..f35c11ebbd6 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5786,46 +5786,6 @@ void get_pointsize_minmax(const struct wined3d_context *context, const struct wi *out_max = max.f; }
-void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state, - float *start, float *end) -{ - union - { - DWORD d; - float f; - } tmpvalue; - - switch (context->fog_source) - { - case FOGSOURCE_VS: - *start = 1.0f; - *end = 0.0f; - break; - - case FOGSOURCE_FFP: - tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART]; - *start = tmpvalue.f; - tmpvalue.d = state->render_states[WINED3D_RS_FOGEND]; - *end = tmpvalue.f; - /* Special handling for fog_start == fog_end. In d3d with vertex - * fog, everything is fogged. With table fog, everything with - * fog_coord < fog_start is unfogged, and fog_coord > fog_start - * is fogged. Windows drivers disagree when fog_coord == fog_start. */ - if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE && *start == *end) - { - *start = -INFINITY; - *end = 0.0f; - } - break; - - default: - /* This should not happen, context->fog_source is set in wined3d, not the app. */ - ERR("Unexpected fog coordinate source.\n"); - *start = 0.0f; - *end = 0.0f; - } -} - static BOOL wined3d_get_primary_display(WCHAR *display) { DISPLAY_DEVICEW display_device; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e73ba018929..2a7746a8762 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1811,11 +1811,6 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state #define STATE_UNORDERED_ACCESS_VIEW_BINDING(a) ((a) == WINED3D_PIPELINE_GRAPHICS ? \ STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING : STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING)
-enum fogsource { - FOGSOURCE_FFP, - FOGSOURCE_VS, -}; - /* Direct3D terminology with little modifications. We do not have an issued * state because only the driver knows about it, but we have a created state * because D3D allows GetData() on a created query, but OpenGL doesn't. */ @@ -1915,8 +1910,6 @@ struct wined3d_context
DWORD constant_update_mask; DWORD numbered_array_mask; - enum fogsource fog_source; -
void *shader_backend_data;
@@ -2848,7 +2841,13 @@ struct wined3d_ffp_ps_constants
/* States not used by the HLSL pipeline. */ float alpha_test_ref; - float padding[3]; /* to align to 16 bytes */ + struct wined3d_ffp_fog_constants + { + float scale; + float end; + float density; + struct wined3d_color colour; + } fog; };
/* Float/int/bool constants are bound to VKD3D_SHADER_D3DBC_*_CONSTANT_REGISTER @@ -4465,8 +4464,6 @@ void get_texture_matrix(const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat); void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state, float *out_min, float *out_max); -void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state, - float *start, float *end);
struct wined3d_palette {
From: Elizabeth Figura zfigura@codeweavers.com
This contians pixel shader states part of the Direct3D 1-9 FFP, which are also used when using shaders, which are not implemented as uniforms but rather will eventually affect ps_compile_args. We don't use ps_compile_args directly, because it contains states other than those controlled by the stateblock.
Simply put, the point here is to provide a more directed alternative to the render states array, which should itself go away, and at the same time to invalidate STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL) immediately rather than through the state table. --- dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ dlls/wined3d/ffp_gl.c | 2 +- dlls/wined3d/glsl_shader.c | 2 -- dlls/wined3d/shader.c | 2 +- dlls/wined3d/shader_spirv.c | 1 - dlls/wined3d/stateblock.c | 15 +++++++++++++++ dlls/wined3d/utils.c | 2 +- dlls/wined3d/wined3d_private.h | 12 ++++++++++++ 8 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 9bac7afdba2..0404674fa9d 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -123,6 +123,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_COLOR_KEY, WINED3D_CS_OP_SET_LIGHT, WINED3D_CS_OP_SET_LIGHT_ENABLE, + WINED3D_CS_OP_SET_EXTRA_PS_ARGS, WINED3D_CS_OP_SET_FEATURE_LEVEL, WINED3D_CS_OP_PUSH_CONSTANTS, WINED3D_CS_OP_RESET_STATE, @@ -405,6 +406,12 @@ struct wined3d_cs_set_light_enable BOOL enable; };
+struct wined3d_cs_set_extra_ps_args +{ + enum wined3d_cs_op opcode; + struct wined3d_extra_ps_args args; +}; + struct wined3d_cs_set_feature_level { enum wined3d_cs_op opcode; @@ -609,6 +616,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_COLOR_KEY); WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT); WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT_ENABLE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_EXTRA_PS_ARGS); WINED3D_TO_STR(WINED3D_CS_OP_SET_FEATURE_LEVEL); WINED3D_TO_STR(WINED3D_CS_OP_PUSH_CONSTANTS); WINED3D_TO_STR(WINED3D_CS_OP_RESET_STATE); @@ -2119,6 +2127,26 @@ void wined3d_device_context_emit_set_light_enable(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
+static void wined3d_cs_exec_set_extra_ps_args(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_extra_ps_args *op = data; + + cs->state.extra_ps_args = op->args; + device_invalidate_state(cs->c.device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); +} + +void wined3d_device_context_emit_set_extra_ps_args(struct wined3d_device_context *context, + const struct wined3d_extra_ps_args *args) +{ + struct wined3d_cs_set_extra_ps_args *op; + + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_EXTRA_PS_ARGS; + op->args = *args; + + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_exec_set_feature_level(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_feature_level *op = data; @@ -2992,6 +3020,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, + /* WINED3D_CS_OP_SET_EXTRA_PS_ARGS */ wined3d_cs_exec_set_extra_ps_args, /* WINED3D_CS_OP_SET_FEATURE_LEVEL */ wined3d_cs_exec_set_feature_level, /* WINED3D_CS_OP_PUSH_CONSTANTS */ wined3d_cs_exec_push_constants, /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index b75c5b1aef7..4c587f2edc4 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -1578,7 +1578,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) {144, 144}, {149, 150}, {153, 153}, - {157, 160}, + {156, 160}, {162, 165}, {167, 193}, {195, 209}, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index fe7042c9c3c..df43a5d1025 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -12168,8 +12168,6 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, ARB_POINT_SPRITE }, - {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, WINED3D_GL_VERSION_2_0}, {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index bbf873954b8..4c9ea349bc9 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3109,7 +3109,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->texcoords_initialized = wined3d_mask_from_size(WINED3D_MAX_FFP_TEXTURES); }
- args->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] + args->pointsprite = state->extra_ps_args.point_sprite && state->primitive_type == WINED3D_PT_POINTLIST;
if (d3d_info->ffp_alpha_test) diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index cc67760d1dc..062929f9265 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -1289,7 +1289,6 @@ static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_state {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}}, - {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}}, {0}, /* Terminate */ }; diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index ed9c8ec19b3..390694ca852 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -70,6 +70,7 @@ struct wined3d_saved_states uint32_t position_transformed : 1; uint32_t bumpenv_constants : 1; uint32_t fog_constants : 1; + uint32_t extra_ps_args : 1; };
struct stage_state @@ -329,6 +330,7 @@ void CDECL wined3d_stateblock_primary_dirtify_all_states(struct wined3d_device * states->position_transformed = 1; states->bumpenv_constants = 1; states->fog_constants = 1; + states->extra_ps_args = 1;
list_init(&stateblock->changed.changed_lights); RB_FOR_EACH_ENTRY(light, lights_tree, struct wined3d_light_info, entry) @@ -1708,6 +1710,10 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb stateblock->changed.fog_constants = 1; break;
+ case WINED3D_RS_POINTSPRITEENABLE: + stateblock->changed.extra_ps_args = 1; + break; + default: break; } @@ -3200,6 +3206,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_FOGDENSITY: case WINED3D_RS_FOGEND: case WINED3D_RS_FOGSTART: + case WINED3D_RS_POINTSPRITEENABLE: break;
case WINED3D_RS_ANTIALIAS: @@ -3940,6 +3947,14 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, WINED3D_SHADER_CONST_FFP_PS, 0, offsetof(struct wined3d_ffp_ps_constants, color_key), &constants); }
+ if (changed->extra_ps_args) + { + struct wined3d_extra_ps_args args; + + args.point_sprite = state->rs[WINED3D_RS_POINTSPRITEENABLE]; + wined3d_device_context_emit_set_extra_ps_args(context, &args); + } + if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_ALPHAREF)) { float f = (state->rs[WINED3D_RS_ALPHAREF] & 0xff) / 255.0f; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index f35c11ebbd6..11b72e6ebc6 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6446,7 +6446,7 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_state *state, settings->texcoords_initialized = wined3d_mask_from_size(WINED3D_MAX_FFP_TEXTURES); }
- settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] + settings->pointsprite = state->extra_ps_args.point_sprite && state->primitive_type == WINED3D_PT_POINTLIST;
if (d3d_info->ffp_alpha_test) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2a7746a8762..6dca6452201 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2869,6 +2869,15 @@ enum wined3d_push_constants WINED3D_PUSH_CONSTANTS_COUNT, };
+/* Pixel shader states part of the Direct3D 1-9 FFP, which are also used when + * using shaders, which are not implemented as uniforms. + * These eventually make their way into vs_compile_args / ps_compile_args, but + * those structs also include states other than the FFP states. */ +struct wined3d_extra_ps_args +{ + bool point_sprite; +}; + struct wined3d_blend_state { LONG refcount; @@ -2969,6 +2978,7 @@ struct wined3d_state uint32_t sample_mask; struct wined3d_depth_stencil_state *depth_stencil_state; unsigned int stencil_ref; + struct wined3d_extra_ps_args extra_ps_args; bool depth_bounds_enable; float depth_bounds_min, depth_bounds_max; struct wined3d_rasterizer_state *rasterizer_state; @@ -3756,6 +3766,8 @@ void wined3d_device_context_emit_set_depth_stencil_state(struct wined3d_device_c struct wined3d_depth_stencil_state *state, unsigned int stencil_ref); void wined3d_device_context_emit_set_depth_stencil_view(struct wined3d_device_context *context, struct wined3d_rendertarget_view *view); +void wined3d_device_context_emit_set_extra_ps_args(struct wined3d_device_context *context, + const struct wined3d_extra_ps_args *args); void wined3d_device_context_emit_set_feature_level(struct wined3d_device_context *context, enum wined3d_feature_level level); void wined3d_device_context_emit_set_index_buffer(struct wined3d_device_context *context, struct wined3d_buffer *buffer,
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/glsl_shader.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index df43a5d1025..390e371d4d7 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -12248,8 +12248,7 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GLSL_130 }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE }, };
@@ -12278,6 +12277,10 @@ const struct wined3d_fragment_pipe_ops glsl_fragment_pipe =
static void shader_glsl_update_legacy_states(struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { + if (!context_gl->gl_info->supported[WINED3D_GLSL_130] + && (context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL))) + state_shademode(&context_gl->c, state, STATE_RENDER(WINED3D_RS_SHADEMODE)); + if (!context_gl->gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) return;
From: Elizabeth Figura zfigura@codeweavers.com
We still need to pass it through the CS, for the sake of the vertex side. --- dlls/wined3d/ffp_gl.c | 23 ++++++++--------------- dlls/wined3d/glsl_shader.c | 7 ------- dlls/wined3d/shader.c | 2 +- dlls/wined3d/shader_spirv.c | 1 - dlls/wined3d/stateblock.c | 2 ++ dlls/wined3d/utils.c | 2 +- dlls/wined3d/wined3d_private.h | 1 + 7 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index 4c587f2edc4..a0411214733 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -100,22 +100,15 @@ void state_shademode(struct wined3d_context *context, const struct wined3d_state { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
- switch (state->render_states[WINED3D_RS_SHADEMODE]) + if (state->extra_ps_args.flat_shading) { - case WINED3D_SHADE_FLAT: - gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT); - checkGLcall("glShadeModel(GL_FLAT)"); - break; - case WINED3D_SHADE_GOURAUD: - /* WINED3D_SHADE_PHONG in practice is the same as WINED3D_SHADE_GOURAUD - * in D3D. */ - case WINED3D_SHADE_PHONG: - gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH); - checkGLcall("glShadeModel(GL_SMOOTH)"); - break; - default: - FIXME("Unrecognized shade mode %#x.\n", - state->render_states[WINED3D_RS_SHADEMODE]); + gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT); + checkGLcall("glShadeModel(GL_FLAT)"); + } + else + { + gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH); + checkGLcall("glShadeModel(GL_SMOOTH)"); } }
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 390e371d4d7..48943dbbe2a 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -12150,12 +12150,6 @@ static void glsl_fragment_pipe_alpha_test(struct wined3d_context_gl *context_gl, } }
-static void glsl_fragment_pipe_shademode(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; -} - static const struct wined3d_state_entry_template glsl_fragment_pipe_state_template[] = { {STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE }, @@ -12248,7 +12242,6 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE }, };
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 4c9ea349bc9..1c0aada0681 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3120,7 +3120,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 : WINED3D_CMP_ALWAYS) - 1;
if (d3d_info->emulated_flatshading) - args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + args->flatshading = state->extra_ps_args.flat_shading;
for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i) { diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 062929f9265..a033c69feec 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -1283,7 +1283,6 @@ static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context *
static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states[] = { - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_nop}}, {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}}, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 390694ca852..cb26f01a0b9 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1711,6 +1711,7 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb break;
case WINED3D_RS_POINTSPRITEENABLE: + case WINED3D_RS_SHADEMODE: stateblock->changed.extra_ps_args = 1; break;
@@ -3952,6 +3953,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_extra_ps_args args;
args.point_sprite = state->rs[WINED3D_RS_POINTSPRITEENABLE]; + args.flat_shading = state->rs[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; wined3d_device_context_emit_set_extra_ps_args(context, &args); }
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 11b72e6ebc6..f068c6ebf77 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6457,7 +6457,7 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_state *state, : WINED3D_CMP_ALWAYS) - 1;
if (d3d_info->emulated_flatshading) - settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + settings->flatshading = state->extra_ps_args.flat_shading; else settings->flatshading = FALSE; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 6dca6452201..9a391475ba8 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2876,6 +2876,7 @@ enum wined3d_push_constants struct wined3d_extra_ps_args { bool point_sprite; + bool flat_shading; };
struct wined3d_blend_state
This merge request was approved by Jan Sikorski.