diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 1e8784e45a2..e7fa69f61ec 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -5059,6 +5059,8 @@ static void shader_arb_free_context_data(struct wined3d_context *context) priv->last_context = NULL; } +static void shader_arb_init_context_state(struct wined3d_context *context) {} + static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) { if (gl_info->supported[ARB_VERTEX_PROGRAM]) @@ -5738,6 +5740,7 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend = shader_arb_free, shader_arb_allocate_context_data, shader_arb_free_context_data, + shader_arb_init_context_state, shader_arb_get_caps, shader_arb_color_fixup_supported, shader_arb_has_ffp_proj_control, diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index a68d5d5707b..059503b23e1 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1762,6 +1762,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, { GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT)); } + device->shader_backend->shader_init_context_state(ret); ret->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL) | (1 << WINED3D_SHADER_TYPE_VERTEX) | (1 << WINED3D_SHADER_TYPE_GEOMETRY); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 93863d02220..e4bef5b6336 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1498,6 +1498,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont { const struct wined3d_shader_version *version = ®_maps->shader_version; const struct wined3d_state *state = &shader->device->state; + const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_fb_state *fb = &shader->device->fb; @@ -1728,6 +1729,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont shader_addline(buffer, "attribute vec4 %s_in%u;\n", prefix, e->register_idx); } + if (vs_args->point_size && !vs_args->per_vertex_point_size) + { + shader_addline(buffer, "uniform struct\n{\n"); + shader_addline(buffer, " float size;\n"); + shader_addline(buffer, " float size_min;\n"); + shader_addline(buffer, " float size_max;\n"); + shader_addline(buffer, "} ffp_point;\n"); + } + shader_addline(buffer, "uniform vec4 posFixup;\n"); shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits->packed_output); } @@ -5182,6 +5192,9 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context if (args->clip_enabled) shader_addline(buffer, "gl_ClipVertex = gl_Position;\n"); + if (args->point_size && !args->per_vertex_point_size) + shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n"); + /* Write the final position. * * OpenGL coordinates specify the center of the pixel while d3d coords specify @@ -5318,9 +5331,14 @@ static GLuint find_glsl_pshader(const struct wined3d_context *context, } static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new, - const DWORD use_map) { + const DWORD use_map) +{ if((stored->swizzle_map & use_map) != new->swizzle_map) return FALSE; if((stored->clip_enabled) != new->clip_enabled) return FALSE; + if (stored->point_size != new->point_size) + return FALSE; + if (stored->per_vertex_point_size != new->per_vertex_point_size) + return FALSE; return stored->fog_src == new->fog_src; } @@ -7414,6 +7432,14 @@ static void shader_glsl_free_context_data(struct wined3d_context *context) HeapFree(GetProcessHeap(), 0, context->shader_backend_data); } +static void shader_glsl_init_context_state(struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + gl_info->gl_ops.gl.p_glEnable(GL_PROGRAM_POINT_SIZE); + checkGLcall("GL_PROGRAM_POINT_SIZE"); +} + static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) { UINT shader_model; @@ -7640,19 +7666,13 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = shader_glsl_free, shader_glsl_allocate_context_data, shader_glsl_free_context_data, + shader_glsl_init_context_state, shader_glsl_get_caps, shader_glsl_color_fixup_supported, shader_glsl_has_ffp_proj_control, }; -static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) -{ - if (enable) - gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - else - gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - checkGLcall("GL_VERTEX_PROGRAM_POINT_SIZE_ARB"); -} +static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {} static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps) { @@ -7835,10 +7855,7 @@ static void glsl_vertex_pipe_viewport(struct wined3d_context *context, glsl_vertex_pipe_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)) && state->render_states[WINED3D_RS_POINTSCALEENABLE]) - { - state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)); context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - } context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; } @@ -7860,25 +7877,10 @@ static void glsl_vertex_pipe_light(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_LIGHTS; } -static void glsl_vertex_pipe_pointsize_arb(struct wined3d_context *context, +static void glsl_vertex_pipe_pointsize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - state_psizemin_arb(context, state, state_id); -} - -static void glsl_vertex_pipe_pointsize_ext(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - state_psizemin_ext(context, state, state_id); -} - -static void glsl_vertex_pipe_pointsize_w(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - state_psizemin_w(context, state, state_id); } static void glsl_vertex_pipe_pointscale(struct wined3d_context *context, @@ -7886,7 +7888,6 @@ static void glsl_vertex_pipe_pointscale(struct wined3d_context *context, { if (!use_vs(state)) context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - state_pscale(context, state, state_id); } static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = @@ -7985,18 +7986,14 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), glsl_vertex_pipe_pointsize_arb}, ARB_POINT_PARAMETERS }, - {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), glsl_vertex_pipe_pointsize_ext}, EXT_POINT_PARAMETERS }, - {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), glsl_vertex_pipe_pointsize_w}, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), glsl_vertex_pipe_pointsize}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE }, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), glsl_vertex_pipe_pointscale}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS }, - {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS }, {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 9bc3bac5862..02b0aff3249 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -550,6 +550,8 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w case WINED3DSPR_RASTOUT: if (reg->idx[0].offset == 1) reg_maps->fog = 1; + if (reg->idx[0].offset == 2) + reg_maps->point_size = 1; break; case WINED3DSPR_MISCTYPE: @@ -764,6 +766,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st shader_signature_from_semantic(&output_signature_elements[reg_idx], semantic); if (semantic->usage == WINED3D_DECL_USAGE_FOG) reg_maps->fog = 1; + if (semantic->usage == WINED3D_DECL_USAGE_PSIZE) + reg_maps->point_size = 1; break; case WINED3DSPR_SAMPLER: @@ -1904,6 +1908,7 @@ static void shader_none_load_constants(void *shader_priv, struct wined3d_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, @@ -2022,6 +2027,7 @@ const struct wined3d_shader_backend_ops none_shader_backend = shader_none_free, shader_none_allocate_context_data, shader_none_free_context_data, + shader_none_init_context_state, shader_none_get_caps, shader_none_color_fixup_supported, shader_none_has_ffp_proj_control, @@ -2210,6 +2216,8 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3 == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z; args->clip_enabled = state->render_states[WINED3D_RS_CLIPPING] && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; + args->point_size = state->gl_primitive_type == GL_POINTS; + args->per_vertex_point_size = shader->reg_maps.point_size; args->swizzle_map = swizzle_map; } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 37f4498ff72..e042add0b8c 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1417,7 +1417,7 @@ static void state_normalize(struct wined3d_context *context, const struct wined3 } } -void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { float min, max; @@ -1429,7 +1429,7 @@ void state_psizemin_w(struct wined3d_context *context, const struct wined3d_stat FIXME("WINED3D_RS_POINTSIZE_MAX value %.8e not supported on this OpenGL implementation.\n", max); } -void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; float min, max; @@ -1442,7 +1442,7 @@ void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_st checkGLcall("glPointParameterfEXT(...)"); } -void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; float min, max; @@ -1455,7 +1455,7 @@ void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_st checkGLcall("glPointParameterfARB(...)"); } -void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; float att[3]; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 75fc2beee2c..b1e2a3f16be 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -640,7 +640,8 @@ struct wined3d_shader_reg_maps WORD usesifc : 1; WORD usescall : 1; WORD usespow : 1; - WORD padding : 3; + WORD point_size : 1; + WORD padding : 2; DWORD rt_mask; /* Used render targets, 32 max. */ @@ -841,10 +842,14 @@ enum fog_src_type { VS_FOG_COORD = 1 }; -struct vs_compile_args { - BYTE fog_src; - BYTE clip_enabled; - WORD swizzle_map; /* MAX_ATTRIBS, 16 */ +struct vs_compile_args +{ + BYTE fog_src; + BYTE clip_enabled : 1; + BYTE point_size : 1; + BYTE per_vertex_point_size : 1; + BYTE padding : 5; + WORD swizzle_map; /* MAX_ATTRIBS, 16 */ }; struct wined3d_context; @@ -871,6 +876,7 @@ struct wined3d_shader_backend_ops void (*shader_free_private)(struct wined3d_device *device); BOOL (*shader_allocate_context_data)(struct wined3d_context *context); void (*shader_free_context_data)(struct wined3d_context *context); + void (*shader_init_context_state)(struct wined3d_context *context); void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps); BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup); BOOL (*shader_has_ffp_proj_control)(void *shader_priv); @@ -2836,18 +2842,10 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void state_psizemin_w(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void state_psizemin_ext(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void state_psizemin_arb(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; 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_pscale(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; BOOL getColorBits(const struct wined3d_format *format, BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;