wined3d: Store shader input signatures as a wined3d_shader_signature structure.
This commit is contained in:
parent
2e5ad1b6e3
commit
002713de6d
|
@ -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 (!strcmp(ps_input_sig[j].semantic_name, output->semantic_name)
|
||||
&& ps_input_sig[j].semantic_idx == output->semantic_idx)
|
||||
if (!input->semantic_name)
|
||||
continue;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
||||
in_idx = map[i];
|
||||
if (!(reg_maps_in->input_registers & (1 << input->register_idx)))
|
||||
continue;
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue