wined3d: Get rid of the "reorder shaders" for SM4+.
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cf52d1635c
commit
0f062f5108
|
@ -1949,7 +1949,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
|
|||
}
|
||||
|
||||
shader_addline(buffer, "uniform vec4 posFixup;\n");
|
||||
shader_addline(buffer, "void setup_vs_output(in vec4[%u]);\n", shader->limits->packed_output);
|
||||
if (version->major < 4)
|
||||
shader_addline(buffer, "void setup_vs_output(in vec4[%u]);\n", shader->limits->packed_output);
|
||||
}
|
||||
else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY)
|
||||
{
|
||||
|
@ -2072,35 +2073,6 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
|
|||
shader_addline(buffer, ";\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Start the main program. */
|
||||
shader_addline(buffer, "void main()\n{\n");
|
||||
|
||||
/* Direct3D applications expect integer vPos values, while OpenGL drivers
|
||||
* add approximately 0.5. This causes off-by-one problems as spotted by
|
||||
* the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
|
||||
* 0.5, but rather something like 0.49999999 or 0.50000001, which still
|
||||
* causes precision troubles when we just subtract 0.5.
|
||||
*
|
||||
* To deal with that, just floor() the position. This will eliminate the
|
||||
* fraction on all cards.
|
||||
*
|
||||
* TODO: Test how this behaves with multisampling.
|
||||
*
|
||||
* An advantage of floor is that it works even if the driver doesn't add
|
||||
* 0.5. It is somewhat questionable if 1.5, 2.5, ... are the proper values
|
||||
* to return in gl_FragCoord, even though coordinates specify the pixel
|
||||
* centers instead of the pixel corners. This code will behave correctly
|
||||
* on drivers that returns integer values. */
|
||||
if (version->type == WINED3D_SHADER_TYPE_PIXEL && reg_maps->vpos)
|
||||
{
|
||||
if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER)
|
||||
shader_addline(buffer,
|
||||
"vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n");
|
||||
else
|
||||
shader_addline(buffer,
|
||||
"vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -5257,7 +5229,7 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
|
|||
}
|
||||
|
||||
static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv,
|
||||
const struct wined3d_shader_signature *output_signature,
|
||||
unsigned int input_count, const struct wined3d_shader_signature *output_signature,
|
||||
const struct wined3d_shader_reg_maps *reg_maps_out, const char *out_array_name)
|
||||
{
|
||||
struct wined3d_string_buffer *destination = string_buffer_get(&priv->string_buffers);
|
||||
|
@ -5272,6 +5244,9 @@ static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv,
|
|||
if (!(reg_maps_out->output_registers & (1u << output->register_idx)))
|
||||
continue;
|
||||
|
||||
if (output->register_idx >= input_count)
|
||||
continue;
|
||||
|
||||
string_buffer_sprintf(destination, "%s[%u]", out_array_name, output->register_idx);
|
||||
|
||||
shader_glsl_write_mask_to_str(output->mask, reg_mask);
|
||||
|
@ -5286,7 +5261,7 @@ static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv,
|
|||
static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv,
|
||||
const struct wined3d_gl_info *gl_info, const DWORD *map,
|
||||
const struct wined3d_shader_signature *input_signature,
|
||||
const struct wined3d_shader_reg_maps *reg_maps_in,
|
||||
const struct wined3d_shader_reg_maps *reg_maps_in, unsigned int input_count,
|
||||
const struct wined3d_shader_signature *output_signature,
|
||||
const struct wined3d_shader_reg_maps *reg_maps_out, BOOL per_vertex_point_size)
|
||||
{
|
||||
|
@ -5325,11 +5300,11 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv
|
|||
shader_glsl_setup_vs3_output(priv, gl_info, map, input_signature, reg_maps_in,
|
||||
output_signature, reg_maps_out, "ps_link");
|
||||
else
|
||||
shader_glsl_setup_sm4_shader_output(priv, output_signature, reg_maps_out, "ps_link");
|
||||
shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature, reg_maps_out, "ps_link");
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static GLuint shader_glsl_generate_vs_rasterizer_input_setup(struct shader_glsl_priv *priv,
|
||||
static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl_priv *priv,
|
||||
const struct wined3d_shader *vs, const struct wined3d_shader *ps,
|
||||
BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
|
@ -5460,7 +5435,7 @@ static GLuint shader_glsl_generate_vs_rasterizer_input_setup(struct shader_glsl_
|
|||
declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", in_count);
|
||||
shader_addline(buffer, "void setup_vs_output(in vec4 shader_out[%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, &vs->output_signature, &vs->reg_maps, per_vertex_point_size);
|
||||
&ps->reg_maps, 0, &vs->output_signature, &vs->reg_maps, per_vertex_point_size);
|
||||
}
|
||||
|
||||
shader_addline(buffer, "}\n");
|
||||
|
@ -5472,6 +5447,23 @@ static GLuint shader_glsl_generate_vs_rasterizer_input_setup(struct shader_glsl_
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void shader_glsl_generate_vs4_rasterizer_input_setup(struct shader_glsl_priv *priv,
|
||||
const struct wined3d_shader *vs, unsigned int input_count,
|
||||
const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
|
||||
|
||||
if (input_count)
|
||||
declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", min(vec4_varyings(4, gl_info), input_count));
|
||||
|
||||
shader_addline(buffer, "void setup_vs_output(in vec4 shader_out[%u])\n{\n", vs->limits->packed_output);
|
||||
|
||||
shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, NULL, NULL,
|
||||
NULL, input_count, &vs->output_signature, &vs->reg_maps, FALSE);
|
||||
|
||||
shader_addline(buffer, "}\n");
|
||||
}
|
||||
|
||||
static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer,
|
||||
const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
|
@ -5585,6 +5577,34 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
|
|||
/* Base Declarations */
|
||||
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
|
||||
|
||||
shader_addline(buffer, "void main()\n{\n");
|
||||
|
||||
/* Direct3D applications expect integer vPos values, while OpenGL drivers
|
||||
* add approximately 0.5. This causes off-by-one problems as spotted by
|
||||
* the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
|
||||
* 0.5, but rather something like 0.49999999 or 0.50000001, which still
|
||||
* causes precision troubles when we just subtract 0.5.
|
||||
*
|
||||
* To deal with that, just floor() the position. This will eliminate the
|
||||
* fraction on all cards.
|
||||
*
|
||||
* TODO: Test how this behaves with multisampling.
|
||||
*
|
||||
* An advantage of floor is that it works even if the driver doesn't add
|
||||
* 0.5. It is somewhat questionable if 1.5, 2.5, ... are the proper values
|
||||
* to return in gl_FragCoord, even though coordinates specify the pixel
|
||||
* centers instead of the pixel corners. This code will behave correctly
|
||||
* on drivers that returns integer values. */
|
||||
if (reg_maps->vpos)
|
||||
{
|
||||
if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER)
|
||||
shader_addline(buffer,
|
||||
"vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n");
|
||||
else
|
||||
shader_addline(buffer,
|
||||
"vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n");
|
||||
}
|
||||
|
||||
if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -5647,11 +5667,11 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
|
|||
|
||||
/* Context activation is done by the caller. */
|
||||
static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context,
|
||||
struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers,
|
||||
const struct wined3d_shader *shader,
|
||||
const struct vs_compile_args *args)
|
||||
struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct vs_compile_args *args)
|
||||
{
|
||||
struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers;
|
||||
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
|
||||
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
const DWORD *function = shader->function;
|
||||
struct shader_glsl_ctx_priv priv_ctx;
|
||||
|
@ -5682,6 +5702,11 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
|
|||
/* Base Declarations */
|
||||
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
|
||||
|
||||
if (reg_maps->shader_version.major >= 4)
|
||||
shader_glsl_generate_vs4_rasterizer_input_setup(priv, shader, args->next_shader_input_count, gl_info);
|
||||
|
||||
shader_addline(buffer, "void main()\n{\n");
|
||||
|
||||
/* Base Shader Body */
|
||||
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
|
||||
|
||||
|
@ -5767,6 +5792,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
|
|||
memset(&priv_ctx, 0, sizeof(priv_ctx));
|
||||
priv_ctx.string_buffers = string_buffers;
|
||||
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
|
||||
shader_addline(buffer, "void main()\n{\n");
|
||||
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
|
||||
shader_addline(buffer, "}\n");
|
||||
|
||||
|
@ -5863,13 +5889,13 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str
|
|||
return FALSE;
|
||||
if (stored->flatshading != new->flatshading)
|
||||
return FALSE;
|
||||
if (stored->next_shader_input_count != new->next_shader_input_count)
|
||||
return FALSE;
|
||||
return stored->fog_src == new->fog_src;
|
||||
}
|
||||
|
||||
static GLuint find_glsl_vshader(const struct wined3d_context *context,
|
||||
struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers,
|
||||
struct wined3d_shader *shader,
|
||||
const struct vs_compile_args *args)
|
||||
static GLuint find_glsl_vshader(const struct wined3d_context *context, struct shader_glsl_priv *priv,
|
||||
struct wined3d_shader *shader, const struct vs_compile_args *args)
|
||||
{
|
||||
UINT i;
|
||||
DWORD new_size;
|
||||
|
@ -5926,8 +5952,8 @@ static GLuint find_glsl_vshader(const struct wined3d_context *context,
|
|||
|
||||
gl_shaders[shader_data->num_gl_shaders].args = *args;
|
||||
|
||||
string_buffer_clear(buffer);
|
||||
ret = shader_glsl_generate_vshader(context, buffer, string_buffers, shader, args);
|
||||
string_buffer_clear(&priv->shader_buffer);
|
||||
ret = shader_glsl_generate_vshader(context, priv, shader, args);
|
||||
gl_shaders[shader_data->num_gl_shaders++].id = ret;
|
||||
|
||||
return ret;
|
||||
|
@ -7314,7 +7340,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);
|
||||
vs_id = find_glsl_vshader(context, &priv->shader_buffer, &priv->string_buffers, vshader, &vs_compile_args);
|
||||
vs_id = find_glsl_vshader(context, priv, vshader, &vs_compile_args);
|
||||
vs_list = &vshader->linked_programs;
|
||||
|
||||
if ((gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]))
|
||||
|
@ -7396,17 +7422,19 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
|
|||
if (vshader)
|
||||
{
|
||||
attribs_map = vshader->reg_maps.input_registers;
|
||||
reorder_shader_id = shader_glsl_generate_vs_rasterizer_input_setup(priv, vshader, pshader,
|
||||
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");
|
||||
/* Flag the reorder function for deletion, then it will be freed automatically when the program
|
||||
* is destroyed
|
||||
*/
|
||||
GL_EXTCALL(glDeleteShader(reorder_shader_id));
|
||||
if (vshader->reg_maps.shader_version.major < 4)
|
||||
{
|
||||
reorder_shader_id = shader_glsl_generate_vs3_rasterizer_input_setup(priv, vshader, pshader,
|
||||
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");
|
||||
/* Flag the reorder function for deletion, it will be freed
|
||||
* automatically when the program is destroyed. */
|
||||
GL_EXTCALL(glDeleteShader(reorder_shader_id));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8598,6 +8626,14 @@ static void glsl_vertex_pipe_vs(struct wined3d_context *context,
|
|||
context_apply_state(context, state, STATE_VDECL);
|
||||
}
|
||||
|
||||
static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context,
|
||||
const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
if (state->shader[WINED3D_SHADER_TYPE_VERTEX]
|
||||
&& state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.shader_version.major >= 4)
|
||||
context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
|
||||
}
|
||||
|
||||
static void glsl_vertex_pipe_world(struct wined3d_context *context,
|
||||
const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
|
@ -8722,6 +8758,7 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
|
|||
{
|
||||
{STATE_VDECL, {STATE_VDECL, glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE },
|
||||
{STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), glsl_vertex_pipe_vs }, WINED3D_GL_EXT_NONE },
|
||||
{STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), glsl_vertex_pipe_pixel_shader}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_MATERIAL, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
|
||||
{STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_vertex_pipe_material}, WINED3D_GL_EXT_NONE },
|
||||
/* Clip planes */
|
||||
|
|
|
@ -2678,6 +2678,15 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3
|
|||
&& 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;
|
||||
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;
|
||||
else
|
||||
args->next_shader_input_count = 0;
|
||||
args->swizzle_map = swizzle_map;
|
||||
if (d3d_info->emulated_flatshading)
|
||||
args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
|
||||
|
|
|
@ -1046,6 +1046,7 @@ struct vs_compile_args
|
|||
BYTE flatshading : 1;
|
||||
BYTE padding : 4;
|
||||
WORD swizzle_map; /* MAX_ATTRIBS, 16 */
|
||||
unsigned int next_shader_input_count;
|
||||
};
|
||||
|
||||
struct wined3d_context;
|
||||
|
|
Loading…
Reference in New Issue