[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