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, ...@@ -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[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
"result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]" "result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]"
}; };
const char *semantic_name;
DWORD semantic_idx, reg_idx; DWORD semantic_idx, reg_idx;
/* Write generic input varyings 0 to 7 to result.texcoord[], varying 8 to result.color.primary /* 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, ...@@ -4012,47 +4011,57 @@ static void init_output_registers(const struct wined3d_shader *shader,
priv_ctx->fog_output = "TMP_FOGCOORD"; priv_ctx->fog_output = "TMP_FOGCOORD";
/* Map declared regs to builtins. Use "TA" to /dev/null unread output */ /* 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; const struct wined3d_shader_signature_element *output = &shader->output_signature.elements[i];
if (!semantic_name) continue;
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); TRACE("o%u is TMP_OUT\n", output->register_idx);
if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "TMP_OUT"; if (!output->semantic_idx)
else priv_ctx->vs_output[i] = "TA"; 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); TRACE("o%u is result.pointsize\n", output->register_idx);
if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "result.pointsize"; if (!output->semantic_idx)
else priv_ctx->vs_output[i] = "TA"; 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); TRACE("o%u is result.color.?, idx %u\n", output->register_idx, output->semantic_idx);
if (!shader->output_signature[i].semantic_idx) if (!output->semantic_idx)
priv_ctx->vs_output[i] = "result.color.primary"; priv_ctx->vs_output[output->register_idx] = "result.color.primary";
else if (shader->output_signature[i].semantic_idx == 1) else if (output->semantic_idx == 1)
priv_ctx->vs_output[i] = "result.color.secondary"; priv_ctx->vs_output[output->register_idx] = "result.color.secondary";
else priv_ctx->vs_output[i] = "TA"; 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]); TRACE("o%u is result.texcoord[%u]\n", output->register_idx, output->semantic_idx);
if (shader->output_signature[i].semantic_idx >= 8) priv_ctx->vs_output[i] = "TA"; if (output->semantic_idx >= 8)
else priv_ctx->vs_output[i] = texcoords[shader->output_signature[i].semantic_idx]; 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); TRACE("o%u is result.fogcoord\n", output->register_idx);
if (shader->output_signature[i].semantic_idx > 0) priv_ctx->vs_output[i] = "TA"; if (output->semantic_idx > 0)
else priv_ctx->vs_output[i] = "result.fogcoord"; priv_ctx->vs_output[output->register_idx] = "TA";
else
priv_ctx->vs_output[output->register_idx] = "result.fogcoord";
} }
else else
{ {
priv_ctx->vs_output[i] = "TA"; priv_ctx->vs_output[output->register_idx] = "TA";
} }
} }
return; return;
...@@ -4071,6 +4080,8 @@ static void init_output_registers(const struct wined3d_shader *shader, ...@@ -4071,6 +4080,8 @@ static void init_output_registers(const struct wined3d_shader *shader,
for(i = 0; i < MAX_REG_INPUT; i++) for(i = 0; i < MAX_REG_INPUT; i++)
{ {
const char *semantic_name;
semantic_name = ps_input_sig[i].semantic_name; semantic_name = ps_input_sig[i].semantic_name;
semantic_idx = ps_input_sig[i].semantic_idx; semantic_idx = ps_input_sig[i].semantic_idx;
reg_idx = ps_input_sig[i].register_idx; reg_idx = ps_input_sig[i].register_idx;
...@@ -4110,23 +4121,24 @@ static void init_output_registers(const struct wined3d_shader *shader, ...@@ -4110,23 +4121,24 @@ static void init_output_registers(const struct wined3d_shader *shader,
} }
/* Map declared to declared */ /* 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 */ /* Write unread output to TA to throw them away */
priv_ctx->vs_output[i] = "TA"; priv_ctx->vs_output[output->register_idx] = "TA";
semantic_name = shader->output_signature[i].semantic_name;
if (!semantic_name) continue; 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) && !output->semantic_idx)
&& !shader->output_signature[i].semantic_idx)
{ {
priv_ctx->vs_output[i] = "TMP_OUT"; priv_ctx->vs_output[output->register_idx] = "TMP_OUT";
continue; continue;
} }
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) else if (shader_match_semantic(output->semantic_name, WINED3D_DECL_USAGE_PSIZE) && !output->semantic_idx)
&& !shader->output_signature[i].semantic_idx)
{ {
priv_ctx->vs_output[i] = "result.pointsize"; priv_ctx->vs_output[output->register_idx] = "result.pointsize";
continue; continue;
} }
...@@ -4134,13 +4146,13 @@ static void init_output_registers(const struct wined3d_shader *shader, ...@@ -4134,13 +4146,13 @@ static void init_output_registers(const struct wined3d_shader *shader,
{ {
if (!ps_input_sig[j].semantic_name) continue; if (!ps_input_sig[j].semantic_name) continue;
if (!strcmp(ps_input_sig[j].semantic_name, semantic_name) if (!strcmp(ps_input_sig[j].semantic_name, output->semantic_name)
&& ps_input_sig[j].semantic_idx == shader->output_signature[i].semantic_idx) && 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") if (!strcmp(priv_ctx->vs_output[output->register_idx], "result.color.primary")
|| !strcmp(priv_ctx->vs_output[i], "result.color.secondary")) || !strcmp(priv_ctx->vs_output[output->register_idx], "result.color.secondary"))
{ {
compiled->need_color_unclamp = TRUE; compiled->need_color_unclamp = TRUE;
} }
......
...@@ -4261,7 +4261,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, ...@@ -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_gl_info *gl_info, const DWORD *map,
const struct wined3d_shader_signature_element *input_signature, const struct wined3d_shader_signature_element *input_signature,
const struct wined3d_shader_reg_maps *reg_maps_in, 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) const struct wined3d_shader_reg_maps *reg_maps_out)
{ {
unsigned int i, j; unsigned int i, j;
...@@ -4272,7 +4272,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, ...@@ -4272,7 +4272,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
unsigned int in_count = vec4_varyings(3, gl_info); unsigned int in_count = vec4_varyings(3, gl_info);
char reg_mask[6]; char reg_mask[6];
char destination[50]; char destination[50];
WORD input_map, output_map; WORD input_map;
set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2)); 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, ...@@ -4299,24 +4299,28 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
semantic_name_in = input_signature[i].semantic_name; semantic_name_in = input_signature[i].semantic_name;
semantic_idx_in = input_signature[i].semantic_idx; 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; j < output_signature->element_count; ++j)
for (j = 0; output_map; output_map >>= 1, ++j)
{ {
const struct wined3d_shader_signature_element *output = &output_signature->elements[j];
DWORD mask; DWORD mask;
if (!(output_map & 1) if (!(reg_maps_out->output_registers & (1 << output->register_idx))
|| semantic_idx_in != output_signature[j].semantic_idx || semantic_idx_in != output->semantic_idx
|| strcmp(semantic_name_in, output_signature[j].semantic_name) || strcmp(semantic_name_in, output->semantic_name)
|| !(mask = input_signature[i].mask & output_signature[j].mask)) || !(mask = input_signature[i].mask & output->mask))
continue; 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_glsl_write_mask_to_str(mask, reg_mask);
shader_addline(buffer, "%s%s = vs_out[%u]%s;\n", 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 ...@@ -4361,8 +4365,6 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
const char *semantic_name; const char *semantic_name;
UINT semantic_idx; UINT semantic_idx;
char reg_mask[6]; 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); shader_buffer_clear(buffer);
...@@ -4372,30 +4374,32 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff ...@@ -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); 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; 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_name = output->semantic_name;
semantic_idx = output_signature[i].semantic_idx; semantic_idx = output->semantic_idx;
write_mask = output_signature[i].mask; write_mask = output->mask;
shader_glsl_write_mask_to_str(write_mask, reg_mask); shader_glsl_write_mask_to_str(write_mask, reg_mask);
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR)) if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
{ {
if (!semantic_idx) if (!semantic_idx)
shader_addline(buffer, "gl_FrontColor%s = vs_out[%u]%s;\n", 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) else if (semantic_idx == 1)
shader_addline(buffer, "gl_FrontSecondaryColor%s = vs_out[%u]%s;\n", 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) else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
{ {
shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n", 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)) 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 ...@@ -4405,18 +4409,19 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
write_mask |= WINED3DSP_WRITEMASK_3; write_mask |= WINED3DSP_WRITEMASK_3;
shader_addline(buffer, "gl_TexCoord[%u]%s = vs_out[%u]%s;\n", 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)) if (!(write_mask & WINED3DSP_WRITEMASK_3))
shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx); shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
} }
} }
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE)) 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)) 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"); shader_addline(buffer, "}\n");
...@@ -4429,28 +4434,31 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff ...@@ -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); 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 */ /* 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_name = output->semantic_name;
semantic_idx = output_signature[i].semantic_idx; semantic_idx = output->semantic_idx;
shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask); shader_glsl_write_mask_to_str(output->mask, reg_mask);
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx) if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
{ {
shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n", 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)) 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 */ /* Then, fix the pixel shader input */
handle_ps3_input(buffer, gl_info, ps->u.ps.input_reg_map, ps->input_signature, 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"); shader_addline(buffer, "}\n");
} }
......
...@@ -2932,7 +2932,7 @@ struct wined3d_shader ...@@ -2932,7 +2932,7 @@ struct wined3d_shader
BOOL lconst_inf_or_nan; BOOL lconst_inf_or_nan;
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)]; 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; char *signature_strings;
/* Pointer to the parent device */ /* 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