From: Matteo Bruni Date: Thu, 12 Nov 2015 22:06:50 +0000 (+0100) Subject: wined3d: Flat shading emulation for core contexts. X-Git-Url: http://git.etersoft.ru/projects/?a=commitdiff_plain;h=0985606be4016280494b0ac5fb4becb576e60ab7;p=wine%2Feterwine.git wined3d: Flat shading emulation for core contexts. Signed-off-by: Matteo Bruni Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 9ac6666736..2af9845cad 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4596,7 +4596,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, int i; WORD int_skip; - find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super); + find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super, d3d_info); args->clip.boolclip_compare = 0; if (use_ps(state)) @@ -6879,6 +6879,7 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_arb_specularenable}, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 6558f27bee..78165da183 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1114,6 +1114,7 @@ static const struct StateEntryTemplate atifs_fragmentstate_template[] = { {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), atifs_srgbwriteenable }, WINED3D_GL_EXT_NONE }, {STATE_COLOR_KEY, { STATE_COLOR_KEY, state_nop }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index a7329e7775..1a7d837704 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3725,6 +3725,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw; adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes; adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; + adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading; adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index abfaef8742..6fe0ff6009 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1682,10 +1682,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont * Writing gl_ClipVertex requires one uniform for each * clipplane as well. */ max_constantsF = gl_info->limits.glsl_vs_float_constants - 3; - if(ctx_priv->cur_vs_args->clip_enabled) - { + if (vs_args->clip_enabled) max_constantsF -= gl_info->limits.clipplanes; - } max_constantsF -= count_bits(reg_maps->integer_constants); /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly, * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but @@ -1859,8 +1857,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] && version->major < 3) { - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_diffuse;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_specular;\n"); + declare_out_varying(gl_info, buffer, vs_args->flatshading, "vec4 ffp_varying_diffuse;\n"); + declare_out_varying(gl_info, buffer, vs_args->flatshading, "vec4 ffp_varying_specular;\n"); declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } @@ -1895,9 +1893,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont else { if (glsl_is_color_reg_read(shader, 0)) - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_diffuse;\n"); + declare_in_varying(gl_info, buffer, ps_args->flatshading, "vec4 ffp_varying_diffuse;\n"); if (glsl_is_color_reg_read(shader, 1)) - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_specular;\n"); + declare_in_varying(gl_info, buffer, ps_args->flatshading, "vec4 ffp_varying_specular;\n"); declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); @@ -4959,7 +4957,7 @@ static void handle_ps3_input(struct shader_glsl_priv *priv, /* Context activation is done by the caller. */ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, const struct wined3d_shader *vs, const struct wined3d_shader *ps, - BOOL per_vertex_point_size, const struct wined3d_gl_info *gl_info) + BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info) { struct wined3d_string_buffer *buffer = &priv->shader_buffer; GLuint ret = 0; @@ -4989,8 +4987,8 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, if (!legacy_context) { - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_diffuse;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_specular;\n"); + declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_diffuse;\n"); + declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_specular;\n"); declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } @@ -5472,6 +5470,8 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str return FALSE; if (stored->per_vertex_point_size != new->per_vertex_point_size) return FALSE; + if (stored->flatshading != new->flatshading) + return FALSE; return stored->fog_src == new->fog_src; } @@ -5844,8 +5844,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } else { - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_diffuse;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_specular;\n"); + declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n"); + declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n"); declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } @@ -6418,8 +6418,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * } else { - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_diffuse;\n"); - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_specular;\n"); + declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n"); + declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n"); declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); @@ -6882,6 +6882,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data) { const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; const struct ps_np2fixup_info *np2fixup_info = NULL; struct glsl_shader_prog_link *entry = NULL; struct wined3d_shader *vshader = NULL; @@ -6917,9 +6918,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const else if (use_vs(state)) { struct vs_compile_args vs_compile_args; + vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args); + find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, d3d_info); vs_id = find_glsl_vshader(context, &priv->shader_buffer, &priv->string_buffers, vshader, &vs_compile_args); vs_list = &vshader->linked_programs; @@ -7003,7 +7005,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const { attribs_map = vshader->reg_maps.input_registers; reorder_shader_id = generate_param_reorder_function(priv, vshader, pshader, - state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size, gl_info); + state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size, + d3d_info->emulated_flatshading + && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info); TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id); GL_EXTCALL(glAttachShader(program_id, reorder_shader_id)); checkGLcall("glAttachShader"); @@ -7988,6 +7992,7 @@ static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BO static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps) { caps->xyzrhw = TRUE; + caps->emulated_flatshading = !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; caps->ffp_generic_attributes = TRUE; caps->max_active_lights = MAX_ACTIVE_LIGHTS; caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; @@ -8060,6 +8065,9 @@ static void glsl_vertex_pipe_vp_free(struct wined3d_device *device) wine_rb_destroy(&priv->ffp_vertex_shaders, shader_glsl_free_ffp_vertex_shader, &ctx); } +static void glsl_vertex_pipe_nop(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) {} + static void glsl_vertex_pipe_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -8230,6 +8238,12 @@ static void glsl_vertex_pipe_pointscale(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; } +static void glsl_vertex_pipe_shademode(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX; +} + static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = { {STATE_VDECL, {STATE_VDECL, glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE }, @@ -8369,6 +8383,8 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, {STATE_SAMPLER(7), {STATE_SAMPLER(7), glsl_vertex_pipe_texmatrix_np2}, WINED3D_GL_EXT_NONE }, {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_nop }, WINED3D_GL_LEGACY_CONTEXT }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_shademode}, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE }, }; @@ -8597,6 +8613,12 @@ static void glsl_fragment_pipe_color_key(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_COLOR_KEY; } +static void glsl_fragment_pipe_shademode(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL; +} + static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = { {STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE }, @@ -8708,6 +8730,8 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_LEGACY_CONTEXT}, + {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/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 8c38fe2b51..8b4366f8ab 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -899,6 +899,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), nvts_texdim }, NV_TEXTURE_SHADER2 }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), nvts_texdim }, NV_TEXTURE_SHADER2 }, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index c3a842ee26..7e85988426 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2209,7 +2209,7 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh } void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, - WORD swizzle_map, struct vs_compile_args *args) + WORD swizzle_map, struct vs_compile_args *args, const struct wined3d_d3d_info *d3d_info) { args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z; @@ -2218,6 +2218,10 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3 args->point_size = state->gl_primitive_type == GL_POINTS; args->per_vertex_point_size = shader->reg_maps.point_size; args->swizzle_map = swizzle_map; + if (d3d_info->emulated_flatshading) + args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + else + args->flatshading = FALSE; } static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) @@ -2405,6 +2409,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; const struct wined3d_texture *texture; UINT i; @@ -2608,6 +2613,9 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->gl_primitive_type == GL_POINTS; + + if (d3d_info->emulated_flatshading) + args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; } static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 942023eb73..91d64171f0 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -165,7 +165,7 @@ static void state_cullmode(struct wined3d_context *context, const struct wined3d } } -static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -4941,7 +4941,6 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE }, @@ -5549,6 +5548,7 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 4ddfeada85..17ac29daf0 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4602,6 +4602,11 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->gl_primitive_type == GL_POINTS; + + if (d3d_info->emulated_flatshading) + settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + else + settings->flatshading = FALSE; } const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, @@ -4792,6 +4797,12 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, } if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info)) settings->texcoords = (1u << MAX_TEXTURES) - 1; + + if (d3d_info->emulated_flatshading) + settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + else + settings->flatshading = FALSE; + return; } @@ -4872,6 +4883,11 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, else settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; + if (d3d_info->emulated_flatshading) + settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + else + settings->flatshading = FALSE; + settings->padding = 0; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ac0b09a784..b6e663557f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -849,6 +849,7 @@ struct ps_compile_args { WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */ WORD texcoords_initialized; /* MAX_TEXTURES, 8 */ BOOL pointsprite; + BOOL flatshading; }; enum fog_src_type { @@ -862,7 +863,8 @@ struct vs_compile_args BYTE clip_enabled : 1; BYTE point_size : 1; BYTE per_vertex_point_size : 1; - BYTE padding : 5; + BYTE flatshading : 1; + BYTE padding : 4; WORD swizzle_map; /* MAX_ATTRIBS, 16 */ }; @@ -1317,6 +1319,7 @@ struct fragment_pipeline struct wined3d_vertex_caps { BOOL xyzrhw; + BOOL emulated_flatshading; BOOL ffp_generic_attributes; DWORD max_active_lights; DWORD max_vertex_blend_matrices; @@ -1785,6 +1788,7 @@ struct wined3d_d3d_info struct wined3d_d3d_limits limits; struct wined3d_ffp_attrib_ops ffp_attrib_ops; BOOL xyzrhw; + BOOL emulated_flatshading; BOOL ffp_generic_attributes; BOOL vs_clipping; BOOL shader_color_key; @@ -1880,7 +1884,8 @@ struct ffp_frag_settings unsigned char texcoords_initialized; unsigned char color_key_enabled : 1; unsigned char pointsprite : 1; - unsigned char padding : 6; + unsigned char flatshading : 1; + unsigned char padding : 5; }; struct ffp_frag_desc @@ -1939,7 +1944,8 @@ struct wined3d_ffp_vs_settings DWORD fog_mode : 2; DWORD texcoords : 8; /* MAX_TEXTURES */ DWORD ortho_fog : 1; - DWORD padding : 11; + DWORD flatshading : 1; + DWORD padding : 10; DWORD texgen[MAX_TEXTURES]; }; @@ -2902,6 +2908,8 @@ void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; +void state_shademode(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN; @@ -3024,7 +3032,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 const struct wined3d_context *context) DECLSPEC_HIDDEN; void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, - WORD swizzle_map, struct vs_compile_args *args) DECLSPEC_HIDDEN; + WORD swizzle_map, struct vs_compile_args *args, + const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; void string_buffer_clear(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN; BOOL string_buffer_init(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;