[PATCH 2/5] wined3d: Store shader input signatures as a wined3d_shader_signature structure.
Henri Verbeet
hverbeet at codeweavers.com
Mon Mar 23 03:17:13 CDT 2015
---
dlls/wined3d/arb_program_shader.c | 182 +++++++++++++++++++++----------------
dlls/wined3d/glsl_shader.c | 62 ++++++-------
dlls/wined3d/shader.c | 144 ++++++++++++++++++-----------
dlls/wined3d/wined3d_private.h | 2 +-
4 files changed, 226 insertions(+), 164 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 212ccba..aa9dc76 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -288,7 +288,7 @@ struct shader_arb_ctx_priv
struct ps_signature
{
- struct wined3d_shader_signature_element *sig;
+ struct wined3d_shader_signature sig;
DWORD idx;
struct wine_rb_entry entry;
};
@@ -3489,7 +3489,7 @@ static void init_ps_input(const struct wined3d_shader *shader,
"fragment.texcoord[4]", "fragment.texcoord[5]", "fragment.texcoord[6]", "fragment.texcoord[7]"
};
unsigned int i;
- const struct wined3d_shader_signature_element *sig = shader->input_signature;
+ const struct wined3d_shader_signature_element *input;
const char *semantic_name;
DWORD semantic_idx;
@@ -3505,38 +3505,47 @@ static void init_ps_input(const struct wined3d_shader *shader,
* we'd either need a replacement shader that can load other attribs like BINORMAL, or
* load the texcoord attrib pointers to match the pixel shader signature
*/
- for(i = 0; i < MAX_REG_INPUT; i++)
+ for (i = 0; i < shader->input_signature.element_count; ++i)
{
- semantic_name = sig[i].semantic_name;
- semantic_idx = sig[i].semantic_idx;
- if (!semantic_name) continue;
+ input = &shader->input_signature.elements[i];
+ if (!(semantic_name = input->semantic_name))
+ continue;
+ semantic_idx = input->semantic_idx;
if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
{
- if (!semantic_idx) priv->ps_input[i] = "fragment.color.primary";
- else if(semantic_idx == 1) priv->ps_input[i] = "fragment.color.secondary";
- else priv->ps_input[i] = "0.0";
+ if (!semantic_idx)
+ priv->ps_input[input->register_idx] = "fragment.color.primary";
+ else if (semantic_idx == 1)
+ priv->ps_input[input->register_idx] = "fragment.color.secondary";
+ else
+ priv->ps_input[input->register_idx] = "0.0";
}
- else if(args->super.vp_mode == fixedfunction)
+ else if (args->super.vp_mode == fixedfunction)
{
- priv->ps_input[i] = "0.0";
+ priv->ps_input[input->register_idx] = "0.0";
}
- else if(shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
- if(semantic_idx < 8) priv->ps_input[i] = texcoords[semantic_idx];
- else priv->ps_input[i] = "0.0";
+ if (semantic_idx < 8)
+ priv->ps_input[input->register_idx] = texcoords[semantic_idx];
+ else
+ priv->ps_input[input->register_idx] = "0.0";
}
- else if(shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
{
- if (!semantic_idx) priv->ps_input[i] = "fragment.fogcoord";
- else priv->ps_input[i] = "0.0";
+ if (!semantic_idx)
+ priv->ps_input[input->register_idx] = "fragment.fogcoord";
+ else
+ priv->ps_input[input->register_idx] = "0.0";
}
else
{
- priv->ps_input[i] = "0.0";
+ priv->ps_input[input->register_idx] = "0.0";
}
- TRACE("v%u, semantic %s%u is %s\n", i, semantic_name, semantic_idx, priv->ps_input[i]);
+ TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
+ semantic_name, semantic_idx, priv->ps_input[input->register_idx]);
}
break;
@@ -3910,51 +3919,68 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
return retval;
}
-static int compare_sig(const struct wined3d_shader_signature_element *sig1, const struct wined3d_shader_signature_element *sig2)
+static int compare_sig(const struct wined3d_shader_signature *sig1, const struct wined3d_shader_signature *sig2)
{
unsigned int i;
int ret;
- for(i = 0; i < MAX_REG_INPUT; i++)
+ if (sig1->element_count != sig2->element_count)
+ return sig1->element_count < sig2->element_count ? -1 : 1;
+
+ for (i = 0; i < sig1->element_count; ++i)
{
- if (!sig1[i].semantic_name || !sig2[i].semantic_name)
+ const struct wined3d_shader_signature_element *e1, *e2;
+
+ e1 = &sig1->elements[i];
+ e2 = &sig2->elements[i];
+
+ if (!e1->semantic_name || !e2->semantic_name)
{
- /* Compare pointers, not contents. One string is NULL(element does not exist), the other one is not NULL */
- if(sig1[i].semantic_name != sig2[i].semantic_name) return sig1[i].semantic_name < sig2[i].semantic_name ? -1 : 1;
+ /* Compare pointers, not contents. One string is NULL (element
+ * does not exist), the other one is not NULL. */
+ if (e1->semantic_name != e2->semantic_name)
+ return e1->semantic_name < e2->semantic_name ? -1 : 1;
continue;
}
- if ((ret = strcmp(sig1[i].semantic_name, sig2[i].semantic_name))) return ret;
- if(sig1[i].semantic_idx != sig2[i].semantic_idx) return sig1[i].semantic_idx < sig2[i].semantic_idx ? -1 : 1;
- if(sig1[i].sysval_semantic != sig2[i].sysval_semantic) return sig1[i].sysval_semantic < sig2[i].sysval_semantic ? -1 : 1;
- if(sig1[i].component_type != sig2[i].component_type) return sig1[i].component_type < sig2[i].component_type ? -1 : 1;
- if(sig1[i].register_idx != sig2[i].register_idx) return sig1[i].register_idx < sig2[i].register_idx ? -1 : 1;
- if(sig1[i].mask != sig2[i].mask) return sig1[i].mask < sig2[i].mask ? -1 : 1;
+ if ((ret = strcmp(e1->semantic_name, e2->semantic_name)))
+ return ret;
+ if (e1->semantic_idx != e2->semantic_idx)
+ return e1->semantic_idx < e2->semantic_idx ? -1 : 1;
+ if (e1->sysval_semantic != e2->sysval_semantic)
+ return e1->sysval_semantic < e2->sysval_semantic ? -1 : 1;
+ if (e1->component_type != e2->component_type)
+ return e1->component_type < e2->component_type ? -1 : 1;
+ if (e1->register_idx != e2->register_idx)
+ return e1->register_idx < e2->register_idx ? -1 : 1;
+ if (e1->mask != e2->mask)
+ return e1->mask < e2->mask ? -1 : 1;
}
return 0;
}
-static struct wined3d_shader_signature_element *clone_sig(const struct wined3d_shader_signature_element *sig)
+static void clone_sig(struct wined3d_shader_signature *new, const struct wined3d_shader_signature *sig)
{
- struct wined3d_shader_signature_element *new;
- int i;
+ unsigned int i;
char *name;
- new = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*new) * MAX_REG_INPUT);
- for(i = 0; i < MAX_REG_INPUT; i++)
+ new->element_count = sig->element_count;
+ new->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*new->elements) * new->element_count);
+ for (i = 0; i < sig->element_count; ++i)
{
- if (!sig[i].semantic_name) continue;
+ new->elements[i] = sig->elements[i];
+
+ if (!new->elements[i].semantic_name)
+ continue;
- new[i] = sig[i];
/* Clone the semantic string */
- name = HeapAlloc(GetProcessHeap(), 0, strlen(sig[i].semantic_name) + 1);
- strcpy(name, sig[i].semantic_name);
- new[i].semantic_name = name;
+ name = HeapAlloc(GetProcessHeap(), 0, strlen(sig->elements[i].semantic_name) + 1);
+ strcpy(name, sig->elements[i].semantic_name);
+ new->elements[i].semantic_name = name;
}
- return new;
}
-static DWORD find_input_signature(struct shader_arb_priv *priv, const struct wined3d_shader_signature_element *sig)
+static DWORD find_input_signature(struct shader_arb_priv *priv, const struct wined3d_shader_signature *sig)
{
struct wine_rb_entry *entry = wine_rb_get(&priv->signature_tree, sig);
struct ps_signature *found_sig;
@@ -3966,7 +3992,7 @@ static DWORD find_input_signature(struct shader_arb_priv *priv, const struct win
return found_sig->idx;
}
found_sig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*found_sig));
- found_sig->sig = clone_sig(sig);
+ clone_sig(&found_sig->sig, sig);
found_sig->idx = priv->ps_sig_number++;
TRACE("New signature stored and assigned number %u\n", found_sig->idx);
if(wine_rb_put(&priv->signature_tree, sig, &found_sig->entry) == -1)
@@ -3977,7 +4003,7 @@ static DWORD find_input_signature(struct shader_arb_priv *priv, const struct win
}
static void init_output_registers(const struct wined3d_shader *shader,
- const struct wined3d_shader_signature_element *ps_input_sig,
+ const struct wined3d_shader_signature *ps_input_sig,
struct shader_arb_ctx_priv *priv_ctx, struct arb_vs_compiled_shader *compiled)
{
unsigned int i, j;
@@ -3986,8 +4012,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]"
};
- DWORD semantic_idx, reg_idx;
-
/* Write generic input varyings 0 to 7 to result.texcoord[], varying 8 to result.color.primary
* and varying 9 to result.color.secondary
*/
@@ -4078,14 +4102,12 @@ static void init_output_registers(const struct wined3d_shader *shader,
priv_ctx->color_output[1] = "TA";
priv_ctx->fog_output = "TA";
- for(i = 0; i < MAX_REG_INPUT; i++)
+ for (i = 0; i < ps_input_sig->element_count; ++i)
{
- const char *semantic_name;
+ const struct wined3d_shader_signature_element *input = &ps_input_sig->elements[i];
- semantic_name = ps_input_sig[i].semantic_name;
- semantic_idx = ps_input_sig[i].semantic_idx;
- reg_idx = ps_input_sig[i].register_idx;
- if (!semantic_name) continue;
+ if (!input->semantic_name)
+ continue;
/* If a declared input register is not written by builtin arguments, don't write to it.
* GL_NV_vertex_program makes sure the input defaults to 0.0, which is correct with D3D
@@ -4093,28 +4115,28 @@ static void init_output_registers(const struct wined3d_shader *shader,
* Don't care about POSITION and PSIZE here - this is a builtin vertex shader, position goes
* to TMP_OUT in any case
*/
- if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ if (shader_match_semantic(input->semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
- if (semantic_idx < 8)
- priv_ctx->texcrd_output[semantic_idx] = decl_idx_to_string[reg_idx];
+ if (input->semantic_idx < 8)
+ priv_ctx->texcrd_output[input->semantic_idx] = decl_idx_to_string[input->register_idx];
}
- else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ else if (shader_match_semantic(input->semantic_name, WINED3D_DECL_USAGE_COLOR))
{
- if (semantic_idx < 2)
- priv_ctx->color_output[semantic_idx] = decl_idx_to_string[reg_idx];
+ if (input->semantic_idx < 2)
+ priv_ctx->color_output[input->semantic_idx] = decl_idx_to_string[input->register_idx];
}
- else if(shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ else if (shader_match_semantic(input->semantic_name, WINED3D_DECL_USAGE_FOG))
{
- if (!semantic_idx)
- priv_ctx->fog_output = decl_idx_to_string[reg_idx];
+ if (!input->semantic_idx)
+ priv_ctx->fog_output = decl_idx_to_string[input->register_idx];
}
else
{
continue;
}
- if (!strcmp(decl_idx_to_string[reg_idx], "result.color.primary")
- || !strcmp(decl_idx_to_string[reg_idx], "result.color.secondary"))
+ if (!strcmp(decl_idx_to_string[input->register_idx], "result.color.primary")
+ || !strcmp(decl_idx_to_string[input->register_idx], "result.color.secondary"))
{
compiled->need_color_unclamp = TRUE;
}
@@ -4142,14 +4164,17 @@ static void init_output_registers(const struct wined3d_shader *shader,
continue;
}
- for(j = 0; j < MAX_REG_INPUT; j++)
+ for (j = 0; j < ps_input_sig->element_count; ++j)
{
- if (!ps_input_sig[j].semantic_name) continue;
+ const struct wined3d_shader_signature_element *input = &ps_input_sig->elements[i];
+
+ if (!input->semantic_name)
+ continue;
- if (!strcmp(ps_input_sig[j].semantic_name, output->semantic_name)
- && ps_input_sig[j].semantic_idx == output->semantic_idx)
+ if (!strcmp(input->semantic_name, output->semantic_name)
+ && input->semantic_idx == output->semantic_idx)
{
- priv_ctx->vs_output[output->register_idx] = decl_idx_to_string[ps_input_sig[j].register_idx];
+ priv_ctx->vs_output[output->register_idx] = decl_idx_to_string[input->register_idx];
if (!strcmp(priv_ctx->vs_output[output->register_idx], "result.color.primary")
|| !strcmp(priv_ctx->vs_output[output->register_idx], "result.color.secondary"))
@@ -4165,7 +4190,7 @@ static void init_output_registers(const struct wined3d_shader *shader,
static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
const struct arb_vs_compile_args *args, struct arb_vs_compiled_shader *compiled,
- const struct wined3d_shader_signature_element *ps_input_sig)
+ const struct wined3d_shader_signature *ps_input_sig)
{
const struct arb_vshader_private *shader_data = shader->backend_data;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
@@ -4345,7 +4370,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
if (shader->reg_maps.shader_version.major < 3)
shader_data->input_signature_idx = ~0U;
else
- shader_data->input_signature_idx = find_input_signature(priv, shader->input_signature);
+ shader_data->input_signature_idx = find_input_signature(priv, &shader->input_signature);
TRACE("Shader got assigned input signature index %u\n", shader_data->input_signature_idx);
@@ -4420,7 +4445,7 @@ static inline BOOL vs_args_equal(const struct arb_vs_compile_args *stored, const
static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *shader,
const struct wined3d_gl_info *gl_info, DWORD use_map, const struct arb_vs_compile_args *args,
- const struct wined3d_shader_signature_element *ps_input_sig)
+ const struct wined3d_shader_signature *ps_input_sig)
{
UINT i;
DWORD new_size;
@@ -4717,7 +4742,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context
struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
struct arb_vs_compile_args compile_args;
struct arb_vs_compiled_shader *compiled;
- const struct wined3d_shader_signature_element *ps_input_sig;
+ const struct wined3d_shader_signature *ps_input_sig;
TRACE("Using vertex shader %p\n", vs);
find_arb_vs_compile_args(state, context, vs, &compile_args);
@@ -4728,7 +4753,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context
if (compile_args.ps_signature == ~0U)
ps_input_sig = NULL;
else
- ps_input_sig = state->shader[WINED3D_SHADER_TYPE_PIXEL]->input_signature;
+ ps_input_sig = &state->shader[WINED3D_SHADER_TYPE_PIXEL]->input_signature;
compiled = find_arb_vshader(vs, context->gl_info, context->stream_info.use_map,
&compile_args, ps_input_sig);
@@ -4917,7 +4942,7 @@ static void shader_arb_destroy(struct wined3d_shader *shader)
static int sig_tree_compare(const void *key, const struct wine_rb_entry *entry)
{
struct ps_signature *e = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
- return compare_sig(key, e->sig);
+ return compare_sig(key, &e->sig);
}
static const struct wine_rb_functions sig_tree_functions =
@@ -4994,12 +5019,13 @@ fail:
static void release_signature(struct wine_rb_entry *entry, void *context)
{
struct ps_signature *sig = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
- int i;
- for(i = 0; i < MAX_REG_INPUT; i++)
+ unsigned int i;
+
+ for (i = 0; i < sig->sig.element_count; ++i)
{
- HeapFree(GetProcessHeap(), 0, (char *) sig->sig[i].semantic_name);
+ HeapFree(GetProcessHeap(), 0, (char *)sig->sig.elements[i].semantic_name);
}
- HeapFree(GetProcessHeap(), 0, sig->sig);
+ HeapFree(GetProcessHeap(), 0, sig->sig.elements);
HeapFree(GetProcessHeap(), 0, sig);
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index c784af0..4240b08 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -4144,60 +4144,62 @@ static void shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
}
static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct wined3d_shader_buffer *buffer,
- const struct wined3d_shader_signature_element *input_signature,
+ const struct wined3d_shader_signature *input_signature,
const struct wined3d_shader_reg_maps *reg_maps,
enum vertexprocessing_mode vertexprocessing)
{
- WORD map = reg_maps->input_registers;
unsigned int i;
- for (i = 0; map; map >>= 1, ++i)
+ for (i = 0; i < input_signature->element_count; ++i)
{
+ const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
const char *semantic_name;
UINT semantic_idx;
char reg_mask[6];
/* Unused */
- if (!(map & 1)) continue;
+ if (!(reg_maps->input_registers & (1 << input->register_idx)))
+ continue;
- semantic_name = input_signature[i].semantic_name;
- semantic_idx = input_signature[i].semantic_idx;
- shader_glsl_write_mask_to_str(input_signature[i].mask, reg_mask);
+ semantic_name = input->semantic_name;
+ semantic_idx = input->semantic_idx;
+ shader_glsl_write_mask_to_str(input->mask, reg_mask);
if (vertexprocessing == vertexshader)
{
if (!strcmp(semantic_name, "SV_POSITION") && !semantic_idx)
shader_addline(buffer, "ps_in[%u]%s = vpos%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
else
shader_addline(buffer, "ps_in[%u]%s = ps_link[%u]%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, shader->u.ps.input_reg_map[i], reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask,
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask);
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
if (semantic_idx < 8 && vertexprocessing == pretransformed)
shader_addline(buffer, "ps_in[%u]%s = gl_TexCoord[%u]%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, semantic_idx, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, semantic_idx, reg_mask);
else
shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
{
if (!semantic_idx)
shader_addline(buffer, "ps_in[%u]%s = vec4(gl_Color)%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
else if (semantic_idx == 1)
shader_addline(buffer, "ps_in[%u]%s = vec4(gl_SecondaryColor)%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
else
shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
}
else
{
shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
- shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
}
}
}
@@ -4259,31 +4261,31 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struc
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_signature *input_signature,
const struct wined3d_shader_reg_maps *reg_maps_in,
const struct wined3d_shader_signature *output_signature,
const struct wined3d_shader_reg_maps *reg_maps_out)
{
unsigned int i, j;
- const char *semantic_name_in;
- UINT semantic_idx_in;
DWORD *set;
DWORD in_idx;
unsigned int in_count = vec4_varyings(3, gl_info);
char reg_mask[6];
char destination[50];
- WORD input_map;
set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2));
- input_map = reg_maps_in->input_registers;
- for (i = 0; input_map; input_map >>= 1, ++i)
+ for (i = 0; i < input_signature->element_count; ++i)
{
- if (!(input_map & 1)) continue;
+ const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
+
+ if (!(reg_maps_in->input_registers & (1 << input->register_idx)))
+ continue;
- in_idx = map[i];
+ in_idx = map[input->register_idx];
/* Declared, but not read register */
- if (in_idx == ~0U) continue;
+ if (in_idx == ~0u)
+ continue;
if (in_idx >= (in_count + 2))
{
FIXME("More input varyings declared than supported, expect issues.\n");
@@ -4297,8 +4299,6 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
else
sprintf(destination, "ps_link[%u]", in_idx);
- semantic_name_in = input_signature[i].semantic_name;
- semantic_idx_in = input_signature[i].semantic_idx;
if (!set[in_idx])
set[in_idx] = ~0u;
@@ -4308,9 +4308,9 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
DWORD 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))
+ || input->semantic_idx != output->semantic_idx
+ || strcmp(input->semantic_name, output->semantic_name)
+ || !(mask = input->mask & output->mask))
continue;
if (set[in_idx] == ~0u)
@@ -4457,7 +4457,7 @@ static GLuint generate_param_reorder_function(struct wined3d_shader_buffer *buff
}
/* 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, &vs->output_signature, &vs->reg_maps);
shader_addline(buffer, "}\n");
@@ -4546,7 +4546,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
/* Pack 3.0 inputs */
if (reg_maps->shader_version.major >= 3)
- shader_glsl_input_pack(shader, buffer, shader->input_signature, reg_maps, args->vp_mode);
+ shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps, args->vp_mode);
/* Base Shader Body */
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index f912ed1..9425ac4 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -639,9 +639,10 @@ static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HAN
/* Note that this does not count the loop register as an address register. */
static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe,
- struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature_element *input_signature,
+ struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature,
struct wined3d_shader_signature *output_signature, const DWORD *byte_code, DWORD constf_size)
{
+ struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT];
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
void *fe_data = shader->frontend_data;
@@ -650,6 +651,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
unsigned int i;
memset(reg_maps, 0, sizeof(*reg_maps));
+ memset(input_signature_elements, 0, sizeof(input_signature_elements));
memset(output_signature_elements, 0, sizeof(output_signature_elements));
reg_maps->min_rel_offset = ~0U;
@@ -699,7 +701,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
&& semantic->usage == WINED3D_DECL_USAGE_POSITION && !semantic->usage_idx)
return WINED3DERR_INVALIDCALL;
reg_maps->input_registers |= 1 << reg_idx;
- shader_signature_from_semantic(&input_signature[reg_idx], semantic);
+ shader_signature_from_semantic(&input_signature_elements[reg_idx], semantic);
break;
/* Vertex shader: mark 3.0 output registers used, save token. */
@@ -1048,6 +1050,36 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
shader->functionLength = ((const char *)ptr - (const char *)byte_code);
+ if (input_signature->elements)
+ {
+ for (i = 0; i < input_signature->element_count; ++i)
+ {
+ reg_maps->input_registers |= 1 << input_signature->elements[i].register_idx;
+ if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL
+ && !strcmp(input_signature->elements[i].semantic_name, "SV_POSITION"))
+ reg_maps->vpos = 1;
+ }
+ }
+ else if (!input_signature->elements && reg_maps->input_registers)
+ {
+ unsigned int count = count_bits(reg_maps->input_registers);
+ struct wined3d_shader_signature_element *e;
+ unsigned int i;
+
+ if (!(input_signature->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*input_signature->elements) * count)))
+ return E_OUTOFMEMORY;
+ input_signature->element_count = count;
+
+ e = input_signature->elements;
+ for (i = 0; i < ARRAY_SIZE(input_signature_elements); ++i)
+ {
+ if (!(reg_maps->input_registers & (1 << i)))
+ continue;
+ input_signature_elements[i].register_idx = i;
+ *e++ = input_signature_elements[i];
+ }
+ }
+
if (output_signature->elements)
{
for (i = 0; i < output_signature->element_count; ++i)
@@ -1059,7 +1091,6 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
{
unsigned int count = count_bits(reg_maps->output_registers);
struct wined3d_shader_signature_element *e;
- unsigned int i;
if (!(output_signature->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*output_signature->elements) * count)))
return E_OUTOFMEMORY;
@@ -1986,7 +2017,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b
shader->lconst_inf_or_nan = FALSE;
/* Second pass: figure out which registers are used, what the semantics are, etc. */
- if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, shader->input_signature,
+ if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, &shader->input_signature,
&shader->output_signature, byte_code, float_const_count)))
return hr;
@@ -2174,7 +2205,6 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
unsigned int i;
HRESULT hr;
- WORD map;
const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
if (!desc->byte_code)
@@ -2237,15 +2267,16 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
return hr;
}
- map = reg_maps->input_registers;
- for (i = 0; map; map >>= 1, ++i)
+ for (i = 0; i < shader->input_signature.element_count; ++i)
{
- if (!(map & 1) || !shader->input_signature[i].semantic_name)
+ const struct wined3d_shader_signature_element *input = &shader->input_signature.elements[i];
+
+ if (!(reg_maps->input_registers & (1 << input->register_idx)) || !input->semantic_name)
continue;
- shader->u.vs.attributes[i].usage =
- shader_usage_from_semantic_name(shader->input_signature[i].semantic_name);
- shader->u.vs.attributes[i].usage_idx = shader->input_signature[i].semantic_idx;
+ shader->u.vs.attributes[input->register_idx].usage =
+ shader_usage_from_semantic_name(input->semantic_name);
+ shader->u.vs.attributes[i].usage_idx = input->semantic_idx;
}
shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
@@ -2461,6 +2492,54 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
return WINED3DERR_INVALIDCALL;
shader_init(shader, device, parent, parent_ops);
+
+ if (desc->input_signature)
+ {
+ struct wined3d_shader_signature_element *e;
+ SIZE_T total, len;
+ char *ptr;
+
+ total = 0;
+ for (i = 0; i < desc->input_signature->element_count; ++i)
+ {
+ e = &desc->input_signature->elements[i];
+ len = strlen(e->semantic_name);
+ if (len >= ~(SIZE_T)0 - total)
+ {
+ shader_cleanup(shader);
+ return E_OUTOFMEMORY;
+ }
+
+ total += len + 1;
+ }
+
+ if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
+ {
+ shader_cleanup(shader);
+ return E_OUTOFMEMORY;
+ }
+ ptr = shader->signature_strings;
+
+ shader->input_signature.element_count = desc->input_signature->element_count;
+ if (!(shader->input_signature.elements = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*shader->input_signature.elements) * shader->input_signature.element_count)))
+ {
+ shader_cleanup(shader);
+ return E_OUTOFMEMORY;
+ }
+
+ for (i = 0; i < desc->input_signature->element_count; ++i)
+ {
+ e = &desc->input_signature->elements[i];
+ shader->input_signature.elements[i] = *e;
+
+ len = strlen(e->semantic_name);
+ memcpy(ptr, e->semantic_name, len + 1);
+ shader->input_signature.elements[i].semantic_name = ptr;
+ ptr += len + 1;
+ }
+ }
+
if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
ps_uniform_count, WINED3D_SHADER_TYPE_PIXEL, desc->max_version)))
{
@@ -2511,49 +2590,6 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
shader->load_local_constsF = shader->lconst_inf_or_nan;
- if (desc->input_signature)
- {
- struct wined3d_shader_signature_element *e;
- SIZE_T total, len;
- char *ptr;
-
- total = 0;
- for (i = 0; i < desc->input_signature->element_count; ++i)
- {
- e = &desc->input_signature->elements[i];
- len = strlen(e->semantic_name);
- if (len >= ~(SIZE_T)0 - total)
- {
- shader_cleanup(shader);
- return E_OUTOFMEMORY;
- }
-
- total += len + 1;
- }
-
- if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
- {
- shader_cleanup(shader);
- return E_OUTOFMEMORY;
- }
- ptr = shader->signature_strings;
-
- for (i = 0; i < desc->input_signature->element_count; ++i)
- {
- e = &desc->input_signature->elements[i];
- shader->reg_maps.input_registers |= 1 << e->register_idx;
- shader->input_signature[e->register_idx] = *e;
-
- len = strlen(e->semantic_name);
- memcpy(ptr, e->semantic_name, len + 1);
- shader->input_signature[e->register_idx].semantic_name = ptr;
- ptr += len + 1;
-
- if (!strcmp(e->semantic_name, "SV_POSITION"))
- shader->reg_maps.vpos = 1;
- }
- }
-
return WINED3D_OK;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 519ef98..70f07a1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2931,7 +2931,7 @@ struct wined3d_shader
struct wined3d_shader_reg_maps reg_maps;
BOOL lconst_inf_or_nan;
- struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
+ struct wined3d_shader_signature input_signature;
struct wined3d_shader_signature output_signature;
char *signature_strings;
--
1.7.10.4
More information about the wine-patches
mailing list