Commit 5189a4f1 authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

wined3d: Implement SM4+ interpolation modifiers for GLSL < 4.40.

parent 46b3a03a
......@@ -4494,7 +4494,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, d3d_info);
find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super, context);
args->clip.boolclip_compare = 0;
if (use_ps(state))
......
......@@ -2154,12 +2154,8 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i
shader_addline(buffer, "in shader_in_out {\n");
for (i = 0; i < element_count; ++i)
{
const char *interpolation_qualifiers = "";
if (shader_glsl_get_version(gl_info) >= 440)
interpolation_qualifiers = shader_glsl_interpolation_qualifiers(interpolation_mode[i]);
else if (interpolation_mode[i] && interpolation_mode[i] != WINED3DSIM_LINEAR)
FIXME("Unhandled interpolation mode %#x.\n", interpolation_mode[i]);
shader_addline(buffer, "%s vec4 reg%u;\n", interpolation_qualifiers, i);
shader_addline(buffer, "%s vec4 reg%u;\n",
shader_glsl_interpolation_qualifiers(interpolation_mode[i]), i);
}
shader_addline(buffer, "} shader_in;\n");
}
......@@ -2175,7 +2171,8 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i
}
static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info,
struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL rasterizer_setup)
struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL rasterizer_setup,
const enum wined3d_shader_interpolation_mode *interpolation_mode)
{
unsigned int i;
......@@ -2185,7 +2182,12 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_
{
shader_addline(buffer, "out shader_in_out {\n");
for (i = 0; i < element_count; ++i)
shader_addline(buffer, " vec4 reg%u;\n", i);
{
const char *interpolation_qualifiers = "";
if (needs_interpolation_qualifiers_for_shader_outputs(gl_info))
interpolation_qualifiers = shader_glsl_interpolation_qualifiers(interpolation_mode[i]);
shader_addline(buffer, "%s vec4 reg%u;\n", interpolation_qualifiers, i);
}
shader_addline(buffer, "} shader_out;\n");
}
else
......@@ -7044,7 +7046,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
{
unsigned int in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input);
shader_glsl_declare_shader_outputs(gl_info, buffer, in_count, FALSE);
shader_glsl_declare_shader_outputs(gl_info, buffer, in_count, FALSE, NULL);
shader_addline(buffer, "void setup_vs_output(in vec4 outputs[%u])\n{\n", vs->limits->packed_output);
shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature,
&ps->reg_maps, 0, &vs->output_signature, &vs->reg_maps, per_vertex_point_size);
......@@ -7061,7 +7063,8 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
static void shader_glsl_generate_sm4_output_setup(struct shader_glsl_priv *priv,
const struct wined3d_shader *shader, unsigned int input_count,
const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup)
const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup,
const enum wined3d_shader_interpolation_mode *interpolation_mode)
{
const char *prefix = shader_glsl_get_prefix(shader->reg_maps.shader_version.type);
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
......@@ -7070,7 +7073,7 @@ static void shader_glsl_generate_sm4_output_setup(struct shader_glsl_priv *priv,
input_count = min(vec4_varyings(4, gl_info), input_count);
if (input_count)
shader_glsl_declare_shader_outputs(gl_info, buffer, input_count, rasterizer_setup);
shader_glsl_declare_shader_outputs(gl_info, buffer, input_count, rasterizer_setup, interpolation_mode);
shader_addline(buffer, "void setup_%s_output(in vec4 outputs[%u])\n{\n",
prefix, shader->limits->packed_output);
......@@ -7660,7 +7663,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
if (reg_maps->shader_version.major >= 4)
shader_glsl_generate_sm4_output_setup(priv, shader, args->next_shader_input_count,
gl_info, args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL);
gl_info, args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL, args->interpolation_mode);
shader_addline(buffer, "void main()\n{\n");
......@@ -7901,7 +7904,7 @@ static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *c
shader_addline(buffer, "uniform vec4 pos_fixup;\n");
shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info,
args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL);
args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL, args->interpolation_mode);
shader_glsl_generate_patch_constant_setup(buffer, &shader->patch_constant_signature, TRUE);
shader_addline(buffer, "void main()\n{\n");
......@@ -7950,7 +7953,8 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
if (!gl_info->supported[ARB_CLIP_CONTROL])
shader_addline(buffer, "uniform vec4 pos_fixup;\n");
shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info, TRUE);
shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count,
gl_info, TRUE, args->interpolation_mode);
shader_addline(buffer, "void main()\n{\n");
if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
return 0;
......@@ -9818,7 +9822,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, d3d_info);
find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, context);
vs_id = find_glsl_vshader(context, priv, vshader, &vs_compile_args);
vs_list = &vshader->linked_programs;
}
......@@ -9861,7 +9865,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
{
struct gs_compile_args args;
find_gs_compile_args(state, gshader, &args);
find_gs_compile_args(state, gshader, &args, context);
gs_id = find_glsl_geometry_shader(context, priv, gshader, &args);
}
......
......@@ -3400,25 +3400,41 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
return WINED3D_OK;
}
static void init_interpolation_compile_args(enum wined3d_shader_interpolation_mode *interpolation_args,
const struct wined3d_shader *pixel_shader, const struct wined3d_gl_info *gl_info)
{
if (!needs_interpolation_qualifiers_for_shader_outputs(gl_info)
|| !pixel_shader || pixel_shader->reg_maps.shader_version.major < 4)
{
memset(interpolation_args, 0, MAX_REG_INPUT * sizeof(*interpolation_args));
return;
}
memcpy(interpolation_args, pixel_shader->u.ps.interpolation_mode,
sizeof(pixel_shader->u.ps.interpolation_mode));
}
void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
WORD swizzle_map, struct vs_compile_args *args, const struct wined3d_d3d_info *d3d_info)
WORD swizzle_map, struct vs_compile_args *args, const struct wined3d_context *context)
{
const struct wined3d_shader *geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
const struct wined3d_shader *pixel_shader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
const struct wined3d_shader *hull_shader = state->shader[WINED3D_SHADER_TYPE_HULL];
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
const struct wined3d_gl_info *gl_info = context->gl_info;
args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE]
== 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->next_shader_type = state->shader[WINED3D_SHADER_TYPE_HULL] ? WINED3D_SHADER_TYPE_HULL
: state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? WINED3D_SHADER_TYPE_GEOMETRY
: WINED3D_SHADER_TYPE_PIXEL;
args->next_shader_type = hull_shader? WINED3D_SHADER_TYPE_HULL
: geometry_shader ? WINED3D_SHADER_TYPE_GEOMETRY : WINED3D_SHADER_TYPE_PIXEL;
if (shader->reg_maps.shader_version.major >= 4)
args->next_shader_input_count = state->shader[WINED3D_SHADER_TYPE_HULL]
? state->shader[WINED3D_SHADER_TYPE_HULL]->limits->packed_input
: state->shader[WINED3D_SHADER_TYPE_GEOMETRY]
? state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->limits->packed_input
: state->shader[WINED3D_SHADER_TYPE_PIXEL]
? state->shader[WINED3D_SHADER_TYPE_PIXEL]->limits->packed_input : 0;
args->next_shader_input_count = hull_shader ? hull_shader->limits->packed_input
: geometry_shader ? geometry_shader->limits->packed_input
: pixel_shader ? pixel_shader->limits->packed_input : 0;
else
args->next_shader_input_count = 0;
args->swizzle_map = swizzle_map;
......@@ -3426,6 +3442,9 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3
args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
else
args->flatshading = 0;
init_interpolation_compile_args(args->interpolation_mode,
args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL ? pixel_shader : NULL, gl_info);
}
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
......@@ -3695,28 +3714,35 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3
void find_ds_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
struct ds_compile_args *args, const struct wined3d_context *context)
{
const struct wined3d_shader *geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
const struct wined3d_shader *pixel_shader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
const struct wined3d_shader *hull_shader = state->shader[WINED3D_SHADER_TYPE_HULL];
const struct wined3d_gl_info *gl_info = context->gl_info;
args->tessellator_output_primitive = hull_shader->u.hs.tessellator_output_primitive;
args->tessellator_partitioning = hull_shader->u.hs.tessellator_partitioning;
args->output_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ?
state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->limits->packed_input :
state->shader[WINED3D_SHADER_TYPE_PIXEL] ? state->shader[WINED3D_SHADER_TYPE_PIXEL]->limits->packed_input
: shader->limits->packed_output;
args->next_shader_type = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? WINED3D_SHADER_TYPE_GEOMETRY
: WINED3D_SHADER_TYPE_PIXEL;
args->output_count = geometry_shader ? geometry_shader->limits->packed_input
: pixel_shader ? pixel_shader->limits->packed_input : shader->limits->packed_output;
args->next_shader_type = geometry_shader ? WINED3D_SHADER_TYPE_GEOMETRY : WINED3D_SHADER_TYPE_PIXEL;
args->render_offscreen = context->render_offscreen;
init_interpolation_compile_args(args->interpolation_mode,
args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL ? pixel_shader : NULL, gl_info);
args->padding = 0;
}
void find_gs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
struct gs_compile_args *args)
struct gs_compile_args *args, const struct wined3d_context *context)
{
args->output_count = state->shader[WINED3D_SHADER_TYPE_PIXEL]
? state->shader[WINED3D_SHADER_TYPE_PIXEL]->limits->packed_input : shader->limits->packed_output;
const struct wined3d_shader *pixel_shader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
const struct wined3d_gl_info *gl_info = context->gl_info;
args->output_count = pixel_shader ? pixel_shader->limits->packed_input : shader->limits->packed_output;
init_interpolation_compile_args(args->interpolation_mode, pixel_shader, gl_info);
}
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
......
......@@ -61,6 +61,8 @@
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
#endif
#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffffu) << 16) | (min & 0xffffu))
/* Driver quirks */
#define WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT 0x00000001
#define WINED3D_QUIRK_SET_TEXCOORD_W 0x00000002
......@@ -1323,7 +1325,8 @@ enum wined3d_shader_tex_types
WINED3D_SHADER_TEX_CUBE = 2,
};
struct ps_compile_args {
struct ps_compile_args
{
struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];
enum vertexprocessing_mode vp_mode;
enum wined3d_ffp_ps_fog_mode fog;
......@@ -1343,7 +1346,8 @@ struct ps_compile_args {
DWORD padding : 26;
};
enum fog_src_type {
enum fog_src_type
{
VS_FOG_Z = 0,
VS_FOG_COORD = 1
};
......@@ -1359,6 +1363,7 @@ struct vs_compile_args
BYTE padding : 1;
WORD swizzle_map; /* MAX_ATTRIBS, 16 */
unsigned int next_shader_input_count;
enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
};
struct ds_compile_args
......@@ -1369,11 +1374,13 @@ struct ds_compile_args
unsigned int next_shader_type : 3;
unsigned int render_offscreen : 1;
unsigned int padding : 12;
enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
};
struct gs_compile_args
{
unsigned int output_count;
enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
};
struct wined3d_context;
......@@ -3970,13 +3977,13 @@ BOOL vshader_get_input(const struct wined3d_shader *shader,
BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) 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,
const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN;
const struct wined3d_context *context) DECLSPEC_HIDDEN;
void find_ds_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
struct ds_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN;
void find_gs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
struct gs_compile_args *args) DECLSPEC_HIDDEN;
struct gs_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN;
void string_buffer_clear(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
BOOL string_buffer_init(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
......@@ -4277,6 +4284,15 @@ static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info
&& !is_scaling_fixup(format->color_fixup);
}
static inline BOOL needs_interpolation_qualifiers_for_shader_outputs(const struct wined3d_gl_info *gl_info)
{
/* In GLSL 4.40+ it is fine to specify interpolation qualifiers only in
* fragment shaders. In older GLSL versions interpolation qualifiers must
* match between shader stages.
*/
return gl_info->glsl_version < MAKEDWORD_VERSION(4, 40);
}
static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context)
{
struct wined3d_texture *texture = context->current_rt.texture;
......@@ -4300,6 +4316,4 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs)
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffffu) << 16) | (min & 0xffffu))
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment