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 {