wined3d: Implement SM4+ interpolation modifiers for GLSL < 4.40.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
46b3a03a97
commit
5189a4f135
|
@ -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;
|
||||
}
|
||||
|
||||
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)
|
||||
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_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
|
||||
|
|
Loading…
Reference in New Issue