[PATCH 1/5] wined3d: Store shader output signatures as a wined3d_shader_signature structure.
Henri Verbeet
hverbeet at codeweavers.com
Mon Mar 23 03:17:12 CDT 2015
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.
---
dlls/wined3d/arb_program_shader.c | 98 +++++++++++++++++++---------------
dlls/wined3d/glsl_shader.c | 72 ++++++++++++++-----------
dlls/wined3d/shader.c | 105 +++++++++++++++++++++++++------------
dlls/wined3d/wined3d_private.h | 2 +-
4 files changed, 167 insertions(+), 110 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 69cf687..212ccba 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -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;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index e38cd18..c784af0 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -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");
}
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 28f3b17..f912ed1 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -640,14 +640,17 @@ 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_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size)
+ struct wined3d_shader_signature *output_signature, const DWORD *byte_code, DWORD constf_size)
{
+ 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;
struct wined3d_shader_version shader_version;
const DWORD *ptr = byte_code;
+ unsigned int i;
memset(reg_maps, 0, sizeof(*reg_maps));
+ memset(output_signature_elements, 0, sizeof(output_signature_elements));
reg_maps->min_rel_offset = ~0U;
fe->shader_read_header(fe_data, &ptr, &shader_version);
@@ -707,7 +710,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
break;
}
reg_maps->output_registers |= 1 << reg_idx;
- shader_signature_from_semantic(&output_signature[reg_idx], semantic);
+ shader_signature_from_semantic(&output_signature_elements[reg_idx], semantic);
if (semantic->usage == WINED3D_DECL_USAGE_FOG)
reg_maps->fog = 1;
break;
@@ -851,19 +854,19 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
{
case 0: /* oPos */
reg_maps->output_registers |= 1 << 10;
- shader_signature_from_usage(&output_signature[10],
+ shader_signature_from_usage(&output_signature_elements[10],
WINED3D_DECL_USAGE_POSITION, 0, 10, WINED3DSP_WRITEMASK_ALL);
break;
case 1: /* oFog */
reg_maps->output_registers |= 1 << 11;
- shader_signature_from_usage(&output_signature[11],
+ shader_signature_from_usage(&output_signature_elements[11],
WINED3D_DECL_USAGE_FOG, 0, 11, WINED3DSP_WRITEMASK_0);
break;
case 2: /* oPts */
reg_maps->output_registers |= 1 << 11;
- shader_signature_from_usage(&output_signature[11],
+ shader_signature_from_usage(&output_signature_elements[11],
WINED3D_DECL_USAGE_PSIZE, 0, 11, WINED3DSP_WRITEMASK_1);
break;
}
@@ -875,12 +878,12 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
idx += 8;
if (reg_maps->output_registers & (1 << idx))
{
- output_signature[idx].mask |= ins.dst[i].write_mask;
+ output_signature_elements[idx].mask |= ins.dst[i].write_mask;
}
else
{
reg_maps->output_registers |= 1 << idx;
- shader_signature_from_usage(&output_signature[idx],
+ shader_signature_from_usage(&output_signature_elements[idx],
WINED3D_DECL_USAGE_COLOR, idx - 8, idx, ins.dst[i].write_mask);
}
}
@@ -891,12 +894,12 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
reg_maps->texcoord_mask[idx] |= ins.dst[i].write_mask;
if (reg_maps->output_registers & (1 << idx))
{
- output_signature[idx].mask |= ins.dst[i].write_mask;
+ output_signature_elements[idx].mask |= ins.dst[i].write_mask;
}
else
{
reg_maps->output_registers |= 1 << idx;
- shader_signature_from_usage(&output_signature[idx],
+ shader_signature_from_usage(&output_signature_elements[idx],
WINED3D_DECL_USAGE_TEXCOORD, idx, idx, ins.dst[i].write_mask);
}
break;
@@ -1045,6 +1048,32 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
shader->functionLength = ((const char *)ptr - (const char *)byte_code);
+ if (output_signature->elements)
+ {
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ reg_maps->output_registers |= 1 << output_signature->elements[i].register_idx;
+ }
+ }
+ else if (reg_maps->output_registers)
+ {
+ 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;
+ output_signature->element_count = count;
+
+ e = output_signature->elements;
+ for (i = 0; i < ARRAY_SIZE(output_signature_elements); ++i)
+ {
+ if (!(reg_maps->output_registers & (1 << i)))
+ continue;
+ *e++ = output_signature_elements[i];
+ }
+ }
+
return WINED3D_OK;
}
@@ -1765,6 +1794,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
static void shader_cleanup(struct wined3d_shader *shader)
{
+ HeapFree(GetProcessHeap(), 0, shader->output_signature.elements);
HeapFree(GetProcessHeap(), 0, shader->signature_strings);
shader->device->shader_backend->shader_destroy(shader);
HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf);
@@ -1956,10 +1986,9 @@ 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. */
- hr = shader_get_registers_used(shader, fe,
- reg_maps, shader->input_signature, shader->output_signature,
- byte_code, float_const_count);
- if (FAILED(hr)) return hr;
+ if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, shader->input_signature,
+ &shader->output_signature, byte_code, float_const_count)))
+ return hr;
if (reg_maps->shader_version.type != type)
{
@@ -2152,24 +2181,6 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
return WINED3DERR_INVALIDCALL;
shader_init(shader, device, parent, parent_ops);
- if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
- vs_uniform_count, WINED3D_SHADER_TYPE_VERTEX, desc->max_version)))
- {
- WARN("Failed to set function, hr %#x.\n", hr);
- shader_cleanup(shader);
- return hr;
- }
-
- map = reg_maps->input_registers;
- for (i = 0; map; map >>= 1, ++i)
- {
- if (!(map & 1) || !shader->input_signature[i].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;
- }
if (desc->output_signature)
{
@@ -2198,19 +2209,45 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
}
ptr = shader->signature_strings;
+ shader->output_signature.element_count = desc->output_signature->element_count;
+ if (!(shader->output_signature.elements = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*shader->output_signature.elements) * shader->output_signature.element_count)))
+ {
+ shader_cleanup(shader);
+ return E_OUTOFMEMORY;
+ }
+
for (i = 0; i < desc->output_signature->element_count; ++i)
{
e = &desc->output_signature->elements[i];
- reg_maps->output_registers |= 1 << e->register_idx;
- shader->output_signature[e->register_idx] = *e;
+ shader->output_signature.elements[i] = *e;
len = strlen(e->semantic_name);
memcpy(ptr, e->semantic_name, len + 1);
- shader->output_signature[e->register_idx].semantic_name = ptr;
+ shader->output_signature.elements[i].semantic_name = ptr;
ptr += len + 1;
}
}
+ if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature,
+ vs_uniform_count, WINED3D_SHADER_TYPE_VERTEX, desc->max_version)))
+ {
+ WARN("Failed to set function, hr %#x.\n", hr);
+ shader_cleanup(shader);
+ return hr;
+ }
+
+ map = reg_maps->input_registers;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1) || !shader->input_signature[i].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->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
shader->lconst_inf_or_nan;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2d62846..519ef98 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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 */
--
1.7.10.4
More information about the wine-patches
mailing list