Commit 2e5ad1b6 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Store shader output signatures as a wined3d_shader_signature structure.

Instead of a fixed array of wined3d_shader_signature_element structures. Shader model 4 shaders can have different semantics in a single register, e.g. v1.xy TEXCOORD0 and v1.zw TEXCOORD1, so having a single wined3d_shader_signature_element structure per register isn't necessarily sufficient.
parent 47ab1759
......@@ -3986,7 +3986,6 @@ static void init_output_registers(const struct wined3d_shader *shader,
"result.texcoord[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
"result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]"
};
const char *semantic_name;
DWORD semantic_idx, reg_idx;
/* Write generic input varyings 0 to 7 to result.texcoord[], varying 8 to result.color.primary
......@@ -4012,47 +4011,57 @@ static void init_output_registers(const struct wined3d_shader *shader,
priv_ctx->fog_output = "TMP_FOGCOORD";
/* Map declared regs to builtins. Use "TA" to /dev/null unread output */
for (i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); ++i)
for (i = 0; i < shader->output_signature.element_count; ++i)
{
semantic_name = shader->output_signature[i].semantic_name;
if (!semantic_name) continue;
const struct wined3d_shader_signature_element *output = &shader->output_signature.elements[i];
if (!output->semantic_name)
continue;
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION))
if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_POSITION))
{
TRACE("o%u is TMP_OUT\n", i);
if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "TMP_OUT";
else priv_ctx->vs_output[i] = "TA";
TRACE("o%u is TMP_OUT\n", output->register_idx);
if (!output->semantic_idx)
priv_ctx->vs_output[output->register_idx] = "TMP_OUT";
else
priv_ctx->vs_output[output->register_idx] = "TA";
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE))
else if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_PSIZE))
{
TRACE("o%u is result.pointsize\n", i);
if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "result.pointsize";
else priv_ctx->vs_output[i] = "TA";
TRACE("o%u is result.pointsize\n", output->register_idx);
if (!output->semantic_idx)
priv_ctx->vs_output[output->register_idx] = "result.pointsize";
else
priv_ctx->vs_output[output->register_idx] = "TA";
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
else if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_COLOR))
{
TRACE("o%u is result.color.?, idx %u\n", i, shader->output_signature[i].semantic_idx);
if (!shader->output_signature[i].semantic_idx)
priv_ctx->vs_output[i] = "result.color.primary";
else if (shader->output_signature[i].semantic_idx == 1)
priv_ctx->vs_output[i] = "result.color.secondary";
else priv_ctx->vs_output[i] = "TA";
TRACE("o%u is result.color.?, idx %u\n", output->register_idx, output->semantic_idx);
if (!output->semantic_idx)
priv_ctx->vs_output[output->register_idx] = "result.color.primary";
else if (output->semantic_idx == 1)
priv_ctx->vs_output[output->register_idx] = "result.color.secondary";
else priv_ctx->vs_output[output->register_idx] = "TA";
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
else if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
TRACE("o%u is %s\n", i, texcoords[shader->output_signature[i].semantic_idx]);
if (shader->output_signature[i].semantic_idx >= 8) priv_ctx->vs_output[i] = "TA";
else priv_ctx->vs_output[i] = texcoords[shader->output_signature[i].semantic_idx];
TRACE("o%u is result.texcoord[%u]\n", output->register_idx, output->semantic_idx);
if (output->semantic_idx >= 8)
priv_ctx->vs_output[output->register_idx] = "TA";
else
priv_ctx->vs_output[output->register_idx] = texcoords[output->semantic_idx];
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
else if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_FOG))
{
TRACE("o%u is result.fogcoord\n", i);
if (shader->output_signature[i].semantic_idx > 0) priv_ctx->vs_output[i] = "TA";
else priv_ctx->vs_output[i] = "result.fogcoord";
TRACE("o%u is result.fogcoord\n", output->register_idx);
if (output->semantic_idx > 0)
priv_ctx->vs_output[output->register_idx] = "TA";
else
priv_ctx->vs_output[output->register_idx] = "result.fogcoord";
}
else
{
priv_ctx->vs_output[i] = "TA";
priv_ctx->vs_output[output->register_idx] = "TA";
}
}
return;
......@@ -4071,6 +4080,8 @@ static void init_output_registers(const struct wined3d_shader *shader,
for(i = 0; i < MAX_REG_INPUT; i++)
{
const char *semantic_name;
semantic_name = ps_input_sig[i].semantic_name;
semantic_idx = ps_input_sig[i].semantic_idx;
reg_idx = ps_input_sig[i].register_idx;
......@@ -4110,23 +4121,24 @@ static void init_output_registers(const struct wined3d_shader *shader,
}
/* Map declared to declared */
for (i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); ++i)
for (i = 0; i < shader->output_signature.element_count; ++i)
{
const struct wined3d_shader_signature_element *output = &shader->output_signature.elements[i];
/* Write unread output to TA to throw them away */
priv_ctx->vs_output[i] = "TA";
semantic_name = shader->output_signature[i].semantic_name;
if (!semantic_name) continue;
priv_ctx->vs_output[output->register_idx] = "TA";
if (!output->semantic_name)
continue;
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION)
&& !shader->output_signature[i].semantic_idx)
if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_POSITION) && !output->semantic_idx)
{
priv_ctx->vs_output[i] = "TMP_OUT";
priv_ctx->vs_output[output->register_idx] = "TMP_OUT";
continue;
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE)
&& !shader->output_signature[i].semantic_idx)
else if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_PSIZE) && !output->semantic_idx)
{
priv_ctx->vs_output[i] = "result.pointsize";
priv_ctx->vs_output[output->register_idx] = "result.pointsize";
continue;
}
......@@ -4134,13 +4146,13 @@ static void init_output_registers(const struct wined3d_shader *shader,
{
if (!ps_input_sig[j].semantic_name) continue;
if (!strcmp(ps_input_sig[j].semantic_name, semantic_name)
&& ps_input_sig[j].semantic_idx == shader->output_signature[i].semantic_idx)
if (!strcmp(ps_input_sig[j].semantic_name, output->semantic_name)
&& ps_input_sig[j].semantic_idx == output->semantic_idx)
{
priv_ctx->vs_output[i] = decl_idx_to_string[ps_input_sig[j].register_idx];
priv_ctx->vs_output[output->register_idx] = decl_idx_to_string[ps_input_sig[j].register_idx];
if (!strcmp(priv_ctx->vs_output[i], "result.color.primary")
|| !strcmp(priv_ctx->vs_output[i], "result.color.secondary"))
if (!strcmp(priv_ctx->vs_output[output->register_idx], "result.color.primary")
|| !strcmp(priv_ctx->vs_output[output->register_idx], "result.color.secondary"))
{
compiled->need_color_unclamp = TRUE;
}
......
......@@ -4261,7 +4261,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
const struct wined3d_gl_info *gl_info, const DWORD *map,
const struct wined3d_shader_signature_element *input_signature,
const struct wined3d_shader_reg_maps *reg_maps_in,
const struct wined3d_shader_signature_element *output_signature,
const struct wined3d_shader_signature *output_signature,
const struct wined3d_shader_reg_maps *reg_maps_out)
{
unsigned int i, j;
......@@ -4272,7 +4272,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
unsigned int in_count = vec4_varyings(3, gl_info);
char reg_mask[6];
char destination[50];
WORD input_map, output_map;
WORD input_map;
set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2));
......@@ -4299,24 +4299,28 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
semantic_name_in = input_signature[i].semantic_name;
semantic_idx_in = input_signature[i].semantic_idx;
set[in_idx] = ~0U;
if (!set[in_idx])
set[in_idx] = ~0u;
output_map = reg_maps_out->output_registers;
for (j = 0; output_map; output_map >>= 1, ++j)
for (j = 0; j < output_signature->element_count; ++j)
{
const struct wined3d_shader_signature_element *output = &output_signature->elements[j];
DWORD mask;
if (!(output_map & 1)
|| semantic_idx_in != output_signature[j].semantic_idx
|| strcmp(semantic_name_in, output_signature[j].semantic_name)
|| !(mask = input_signature[i].mask & output_signature[j].mask))
if (!(reg_maps_out->output_registers & (1 << output->register_idx))
|| semantic_idx_in != output->semantic_idx
|| strcmp(semantic_name_in, output->semantic_name)
|| !(mask = input_signature[i].mask & output->mask))
continue;
set[in_idx] = mask;
if (set[in_idx] == ~0u)
set[in_idx] = mask;
else
set[in_idx] |= mask;
shader_glsl_write_mask_to_str(mask, reg_mask);
shader_addline(buffer, "%s%s = vs_out[%u]%s;\n",
destination, reg_mask, j, reg_mask);
destination, reg_mask, output->register_idx, reg_mask);
}
}
......@@ -4361,8 +4365,6 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
const char *semantic_name;
UINT semantic_idx;
char reg_mask[6];
const struct wined3d_shader_signature_element *output_signature = vs->output_signature;
WORD map = vs->reg_maps.output_registers;
shader_buffer_clear(buffer);
......@@ -4372,30 +4374,32 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
{
shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output);
for (i = 0; map; map >>= 1, ++i)
for (i = 0; i < vs->output_signature.element_count; ++i)
{
const struct wined3d_shader_signature_element *output = &vs->output_signature.elements[i];
DWORD write_mask;
if (!(map & 1)) continue;
if (!(vs->reg_maps.output_registers & (1 << output->register_idx)))
continue;
semantic_name = output_signature[i].semantic_name;
semantic_idx = output_signature[i].semantic_idx;
write_mask = output_signature[i].mask;
semantic_name = output->semantic_name;
semantic_idx = output->semantic_idx;
write_mask = output->mask;
shader_glsl_write_mask_to_str(write_mask, reg_mask);
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
{
if (!semantic_idx)
shader_addline(buffer, "gl_FrontColor%s = vs_out[%u]%s;\n",
reg_mask, i, reg_mask);
reg_mask, output->register_idx, reg_mask);
else if (semantic_idx == 1)
shader_addline(buffer, "gl_FrontSecondaryColor%s = vs_out[%u]%s;\n",
reg_mask, i, reg_mask);
reg_mask, output->register_idx, reg_mask);
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
{
shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n",
reg_mask, i, reg_mask);
reg_mask, output->register_idx, reg_mask);
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
......@@ -4405,18 +4409,19 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
write_mask |= WINED3DSP_WRITEMASK_3;
shader_addline(buffer, "gl_TexCoord[%u]%s = vs_out[%u]%s;\n",
semantic_idx, reg_mask, i, reg_mask);
semantic_idx, reg_mask, output->register_idx, reg_mask);
if (!(write_mask & WINED3DSP_WRITEMASK_3))
shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
}
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE))
{
shader_addline(buffer, "gl_PointSize = vs_out[%u].%c;\n", i, reg_mask[1]);
shader_addline(buffer, "gl_PointSize = vs_out[%u].%c;\n", output->register_idx, reg_mask[1]);
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
{
shader_addline(buffer, "gl_FogFragCoord = clamp(vs_out[%u].%c, 0.0, 1.0);\n", i, reg_mask[1]);
shader_addline(buffer, "gl_FogFragCoord = clamp(vs_out[%u].%c, 0.0, 1.0);\n",
output->register_idx, reg_mask[1]);
}
}
shader_addline(buffer, "}\n");
......@@ -4429,28 +4434,31 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output);
/* First, sort out position and point size. Those are not passed to the pixel shader */
for (i = 0; map; map >>= 1, ++i)
for (i = 0; i < vs->output_signature.element_count; ++i)
{
if (!(map & 1)) continue;
const struct wined3d_shader_signature_element *output = &vs->output_signature.elements[i];
if (!(vs->reg_maps.output_registers & (1 << output->register_idx)))
continue;
semantic_name = output_signature[i].semantic_name;
semantic_idx = output_signature[i].semantic_idx;
shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask);
semantic_name = output->semantic_name;
semantic_idx = output->semantic_idx;
shader_glsl_write_mask_to_str(output->mask, reg_mask);
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
{
shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n",
reg_mask, i, reg_mask);
reg_mask, output->register_idx, reg_mask);
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE))
{
shader_addline(buffer, "gl_PointSize = vs_out[%u].%c;\n", i, reg_mask[1]);
shader_addline(buffer, "gl_PointSize = vs_out[%u].%c;\n", output->register_idx, reg_mask[1]);
}
}
/* Then, fix the pixel shader input */
handle_ps3_input(buffer, gl_info, ps->u.ps.input_reg_map, ps->input_signature,
&ps->reg_maps, output_signature, &vs->reg_maps);
&ps->reg_maps, &vs->output_signature, &vs->reg_maps);
shader_addline(buffer, "}\n");
}
......
......@@ -2932,7 +2932,7 @@ struct wined3d_shader
BOOL lconst_inf_or_nan;
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
struct wined3d_shader_signature output_signature;
char *signature_strings;
/* Pointer to the parent device */
......
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