[PATCH 4/5] wined3d: Introduce a structure for shader register indices.

Henri Verbeet hverbeet at codeweavers.com
Sun Oct 14 11:40:36 CDT 2012


---
 dlls/wined3d/arb_program_shader.c |  258 ++++++++++++++++++-------------------
 dlls/wined3d/glsl_shader.c        |  140 +++++++++++---------
 dlls/wined3d/shader.c             |  118 +++++++++--------
 dlls/wined3d/shader_sm1.c         |   21 ++--
 dlls/wined3d/shader_sm4.c         |   25 +---
 dlls/wined3d/wined3d_private.h    |   16 ++-
 6 files changed, 295 insertions(+), 283 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 4f5efe0..5201998 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1006,7 +1006,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
     switch (reg->type)
     {
         case WINED3DSPR_TEMP:
-            sprintf(register_name, "R%u", reg->idx);
+            sprintf(register_name, "R%u", reg->idx[0].offset);
             break;
 
         case WINED3DSPR_INPUT:
@@ -1014,19 +1014,21 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
             {
                 if (reg_maps->shader_version.major < 3)
                 {
-                    if (!reg->idx) strcpy(register_name, "fragment.color.primary");
-                    else strcpy(register_name, "fragment.color.secondary");
+                    if (!reg->idx[0].offset)
+                        strcpy(register_name, "fragment.color.primary");
+                    else
+                        strcpy(register_name, "fragment.color.secondary");
                 }
                 else
                 {
-                    if(reg->rel_addr)
+                    if (reg->idx[0].rel_addr)
                     {
                         char rel_reg[50];
-                        shader_arb_get_src_param(ins, reg->rel_addr, 0, rel_reg);
+                        shader_arb_get_src_param(ins, reg->idx[0].rel_addr, 0, rel_reg);
 
                         if (!strcmp(rel_reg, "**aL_emul**"))
                         {
-                            DWORD idx = ctx->aL + reg->idx;
+                            DWORD idx = ctx->aL + reg->idx[0].offset;
                             if(idx < MAX_REG_INPUT)
                             {
                                 strcpy(register_name, ctx->ps_input[idx]);
@@ -1052,7 +1054,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
                             FIXME("Relative input register addressing with more than 8 registers\n");
 
                             /* This is better than nothing for now */
-                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx);
+                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
                         }
                         else if(ctx->cur_ps_args->super.vp_mode != vertexshader)
                         {
@@ -1064,39 +1066,40 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
                              * For now use the texcoords and hope for the best
                              */
                             FIXME("Non-vertex shader varying input with indirect addressing\n");
-                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx);
+                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
                         }
                         else
                         {
                             /* D3D supports indirect addressing only with aL in loop registers. The loop instruction
                              * pulls GL_NV_fragment_program2 in
                              */
-                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx);
+                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
                         }
                     }
                     else
                     {
-                        if(reg->idx < MAX_REG_INPUT)
+                        if (reg->idx[0].offset < MAX_REG_INPUT)
                         {
-                            strcpy(register_name, ctx->ps_input[reg->idx]);
+                            strcpy(register_name, ctx->ps_input[reg->idx[0].offset]);
                         }
                         else
                         {
-                            ERR("Pixel shader input register out of bounds: %u\n", reg->idx);
-                            sprintf(register_name, "out_of_bounds_%u", reg->idx);
+                            ERR("Pixel shader input register out of bounds: %u\n", reg->idx[0].offset);
+                            sprintf(register_name, "out_of_bounds_%u", reg->idx[0].offset);
                         }
                     }
                 }
             }
             else
             {
-                if (ctx->cur_vs_args->super.swizzle_map & (1 << reg->idx)) *is_color = TRUE;
-                sprintf(register_name, "vertex.attrib[%u]", reg->idx);
+                if (ctx->cur_vs_args->super.swizzle_map & (1 << reg->idx[0].offset))
+                    *is_color = TRUE;
+                sprintf(register_name, "vertex.attrib[%u]", reg->idx[0].offset);
             }
             break;
 
         case WINED3DSPR_CONST:
-            if (!pshader && reg->rel_addr)
+            if (!pshader && reg->idx[0].rel_addr)
             {
                 const struct arb_vshader_private *shader_data = shader->backend_data;
                 UINT rel_offset = shader_data->rel_offset;
@@ -1105,9 +1108,12 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
                 if (reg_maps->shader_version.major < 2)
                 {
                     sprintf(rel_reg, "A0.x");
-                } else {
-                    shader_arb_get_src_param(ins, reg->rel_addr, 0, rel_reg);
-                    if(ctx->target_version == ARB) {
+                }
+                else
+                {
+                    shader_arb_get_src_param(ins, reg->idx[0].rel_addr, 0, rel_reg);
+                    if (ctx->target_version == ARB)
+                    {
                         if (!strcmp(rel_reg, "**aL_emul**"))
                         {
                             aL = TRUE;
@@ -1117,19 +1123,19 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
                         }
                     }
                 }
-                if(aL)
-                    sprintf(register_name, "C[%u]", ctx->aL + reg->idx);
-                else if (reg->idx >= rel_offset)
-                    sprintf(register_name, "C[%s + %u]", rel_reg, reg->idx - rel_offset);
+                if (aL)
+                    sprintf(register_name, "C[%u]", ctx->aL + reg->idx[0].offset);
+                else if (reg->idx[0].offset >= rel_offset)
+                    sprintf(register_name, "C[%s + %u]", rel_reg, reg->idx[0].offset - rel_offset);
                 else
-                    sprintf(register_name, "C[%s - %u]", rel_reg, rel_offset - reg->idx);
+                    sprintf(register_name, "C[%s - %u]", rel_reg, rel_offset - reg->idx[0].offset);
             }
             else
             {
                 if (reg_maps->usesrelconstF)
-                    sprintf(register_name, "C[%u]", reg->idx);
+                    sprintf(register_name, "C[%u]", reg->idx[0].offset);
                 else
-                    sprintf(register_name, "C%u", reg->idx);
+                    sprintf(register_name, "C%u", reg->idx[0].offset);
             }
             break;
 
@@ -1138,52 +1144,45 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
             {
                 if (reg_maps->shader_version.major == 1
                         && reg_maps->shader_version.minor <= 3)
-                {
-                    /* In ps <= 1.3, Tx is a temporary register as destination to all instructions,
-                     * and as source to most instructions. For some instructions it is the texcoord
-                     * input. Those instructions know about the special use
-                     */
-                    sprintf(register_name, "T%u", reg->idx);
-                } else {
-                    /* in ps 1.4 and 2.x Tx is always a (read-only) varying */
-                    sprintf(register_name, "fragment.texcoord[%u]", reg->idx);
-                }
+                    /* In ps <= 1.3, Tx is a temporary register as destination
+                     * to all instructions, and as source to most instructions.
+                     * For some instructions it is the texcoord input. Those
+                     * instructions know about the special use. */
+                    sprintf(register_name, "T%u", reg->idx[0].offset);
+                else
+                    /* In ps 1.4 and 2.x Tx is always a (read-only) varying. */
+                    sprintf(register_name, "fragment.texcoord[%u]", reg->idx[0].offset);
             }
             else
             {
                 if (reg_maps->shader_version.major == 1 || ctx->target_version >= NV2)
-                {
-                    sprintf(register_name, "A%u", reg->idx);
-                }
+                    sprintf(register_name, "A%u", reg->idx[0].offset);
                 else
-                {
-                    sprintf(register_name, "A%u_SHADOW", reg->idx);
-                }
+                    sprintf(register_name, "A%u_SHADOW", reg->idx[0].offset);
             }
             break;
 
         case WINED3DSPR_COLOROUT:
-            if (ctx->cur_ps_args->super.srgb_correction && !reg->idx)
+            if (ctx->cur_ps_args->super.srgb_correction && !reg->idx[0].offset)
             {
                 strcpy(register_name, "TMP_COLOR");
             }
             else
             {
-                if(ctx->cur_ps_args->super.srgb_correction) FIXME("sRGB correction on higher render targets\n");
+                if (ctx->cur_ps_args->super.srgb_correction)
+                    FIXME("sRGB correction on higher render targets.\n");
                 if (reg_maps->rt_mask > 1)
-                {
-                    sprintf(register_name, "result.color[%u]", reg->idx);
-                }
+                    sprintf(register_name, "result.color[%u]", reg->idx[0].offset);
                 else
-                {
                     strcpy(register_name, "result.color");
-                }
             }
             break;
 
         case WINED3DSPR_RASTOUT:
-            if(reg->idx == 1) sprintf(register_name, "%s", ctx->fog_output);
-            else sprintf(register_name, "%s", rastout_reg_names[reg->idx]);
+            if (reg->idx[0].offset == 1)
+                sprintf(register_name, "%s", ctx->fog_output);
+            else
+                sprintf(register_name, "%s", rastout_reg_names[reg->idx[0].offset]);
             break;
 
         case WINED3DSPR_DEPTHOUT:
@@ -1192,26 +1191,19 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
 
         case WINED3DSPR_ATTROUT:
         /* case WINED3DSPR_OUTPUT: */
-            if (pshader) sprintf(register_name, "oD[%u]", reg->idx);
-            else strcpy(register_name, ctx->color_output[reg->idx]);
+            if (pshader)
+                sprintf(register_name, "oD[%u]", reg->idx[0].offset);
+            else
+                strcpy(register_name, ctx->color_output[reg->idx[0].offset]);
             break;
 
         case WINED3DSPR_TEXCRDOUT:
             if (pshader)
-            {
-                sprintf(register_name, "oT[%u]", reg->idx);
-            }
+                sprintf(register_name, "oT[%u]", reg->idx[0].offset);
+            else if (reg_maps->shader_version.major < 3)
+                strcpy(register_name, ctx->texcrd_output[reg->idx[0].offset]);
             else
-            {
-                if (reg_maps->shader_version.major < 3)
-                {
-                    strcpy(register_name, ctx->texcrd_output[reg->idx]);
-                }
-                else
-                {
-                    strcpy(register_name, ctx->vs_output[reg->idx]);
-                }
-            }
+                strcpy(register_name, ctx->vs_output[reg->idx[0].offset]);
             break;
 
         case WINED3DSPR_LOOP:
@@ -1235,27 +1227,21 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
             break;
 
         case WINED3DSPR_CONSTINT:
-            sprintf(register_name, "I%u", reg->idx);
+            sprintf(register_name, "I%u", reg->idx[0].offset);
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (!reg->idx)
-            {
+            if (!reg->idx[0].offset)
                 sprintf(register_name, "vpos");
-            }
-            else if(reg->idx == 1)
-            {
+            else if (reg->idx[0].offset == 1)
                 sprintf(register_name, "fragment.facing.x");
-            }
             else
-            {
-                FIXME("Unknown MISCTYPE register index %u\n", reg->idx);
-            }
+                FIXME("Unknown MISCTYPE register index %u.\n", reg->idx[0].offset);
             break;
 
         default:
-            FIXME("Unhandled register type %#x[%u]\n", reg->type, reg->idx);
-            sprintf(register_name, "unrecognized_register[%u]", reg->idx);
+            FIXME("Unhandled register type %#x[%u].\n", reg->type, reg->idx[0].offset);
+            sprintf(register_name, "unrecognized_register[%u]", reg->idx[0].offset);
             break;
     }
 }
@@ -1587,9 +1573,9 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    DWORD sampler_code = dst->reg.idx[0].offset;
     char dst_name[50];
     char src_name[2][50];
-    DWORD sampler_code = dst->reg.idx;
 
     shader_arb_get_dst_param(ins, dst, dst_name);
 
@@ -1863,7 +1849,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
             shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
         }
     }
-    else if (ins->dst[0].reg.type == WINED3DSPR_COLOROUT && !ins->dst[0].reg.idx && pshader)
+    else if (ins->dst[0].reg.type == WINED3DSPR_COLOROUT && !ins->dst[0].reg.idx[0].offset && pshader)
     {
         if (ctx->cur_ps_args->super.srgb_correction && shader->u.ps.color0_mov)
         {
@@ -1913,18 +1899,19 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
             shader_addline(buffer, "SWZ TA, %s, %c, %c, %c, %c;\n", reg_dest, x, y, z, w);
         }
         shader_addline(buffer, "KIL %s;\n", kilsrc);
-    } else {
+    }
+    else
+    {
         /* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component,
          * copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL
          *
          * ps_1_3 shaders use the texcoord incarnation of the Tx register. ps_1_4 shaders can use the same,
          * or pass in any temporary register(in shader phase 2)
          */
-        if(ins->ctx->reg_maps->shader_version.minor <= 3) {
-            sprintf(reg_dest, "fragment.texcoord[%u]", dst->reg.idx);
-        } else {
+        if (ins->ctx->reg_maps->shader_version.minor <= 3)
+            sprintf(reg_dest, "fragment.texcoord[%u]", dst->reg.idx[0].offset);
+        else
             shader_arb_get_dst_param(ins, dst, reg_dest);
-        }
         shader_addline(buffer, "SWZ TA, %s, x, y, z, 1;\n", reg_dest);
         shader_addline(buffer, "KIL TA;\n");
     }
@@ -1950,9 +1937,9 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
     /* 1.0-1.4: Use destination register number as texture code.
        2.0+: Use provided sampler number as texure code. */
     if (shader_version < WINED3D_SHADER_VERSION(2,0))
-        reg_sampler_code = dst->reg.idx;
+        reg_sampler_code = dst->reg.idx[0].offset;
     else
-        reg_sampler_code = ins->src[1].reg.idx;
+        reg_sampler_code = ins->src[1].reg.idx[0].offset;
 
     /* 1.0-1.3: Use the texcoord varying.
        1.4+: Use provided coordinate source register. */
@@ -2019,7 +2006,7 @@ static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 
     if (shader_version < WINED3D_SHADER_VERSION(1,4))
     {
-        DWORD reg = dst->reg.idx;
+        DWORD reg = dst->reg.idx[0].offset;
 
         shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
         shader_addline(buffer, "MOV_SAT %s, fragment.texcoord[%u];\n", dst_str, reg);
@@ -2037,7 +2024,7 @@ static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
      struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
      DWORD flags = 0;
 
-     DWORD reg1 = ins->dst[0].reg.idx;
+     DWORD reg1 = ins->dst[0].reg.idx[0].offset;
      char dst_str[50];
      char src_str[50];
 
@@ -2059,7 +2046,7 @@ static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
      struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
 
-     DWORD reg1 = ins->dst[0].reg.idx;
+     DWORD reg1 = ins->dst[0].reg.idx[0].offset;
      char dst_str[50];
      char src_str[50];
 
@@ -2073,7 +2060,7 @@ static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
-    DWORD reg1 = ins->dst[0].reg.idx;
+    DWORD reg1 = ins->dst[0].reg.idx[0].offset;
     char dst_str[50];
     char src_str[50];
 
@@ -2094,7 +2081,7 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
     /* All versions have a destination register. The Tx where the texture coordinates come
      * from is the varying incarnation of the texture register
      */
-    reg_dest_code = dst->reg.idx;
+    reg_dest_code = dst->reg.idx[0].offset;
     shader_arb_get_dst_param(ins, &ins->dst[0], dst_reg);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_reg);
     sprintf(reg_coord, "fragment.texcoord[%u]", reg_dest_code);
@@ -2140,7 +2127,7 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char src0_name[50], dst_name[50];
     BOOL is_color;
@@ -2150,7 +2137,7 @@ static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
     /* The next instruction will be a texm3x2tex or texm3x2depth that writes to the uninitialized
      * T<reg+1> register. Use this register to store the calculated vector
      */
-    tmp_reg.idx = reg + 1;
+    tmp_reg.idx[0].offset = reg + 1;
     shader_arb_get_register_name(ins, &tmp_reg, dst_name, &is_color);
     shader_addline(buffer, "DP3 %s.x, fragment.texcoord[%u], %s;\n", dst_name, reg, src0_name);
 }
@@ -2159,7 +2146,7 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
 {
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     DWORD flags;
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_str[50];
     char src0_name[50];
@@ -2179,7 +2166,7 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char src0_name[50], dst_name[50];
     struct wined3d_shader_register tmp_reg = ins->dst[0].reg;
@@ -2189,7 +2176,7 @@ static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
      * incrementing ins->dst[0].register_idx numbers. So the pad instruction already knows the final destination
      * register, and this register is uninitialized(otherwise the assembler complains that it is 'redeclared')
      */
-    tmp_reg.idx = reg + 2 - tex_mx->current_row;
+    tmp_reg.idx[0].offset = reg + 2 - tex_mx->current_row;
     shader_arb_get_register_name(ins, &tmp_reg, dst_name, &is_color);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
@@ -2203,7 +2190,7 @@ static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
     DWORD flags;
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_str[50];
     char src0_name[50], dst_name[50];
@@ -2225,7 +2212,7 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
     DWORD flags;
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_str[50];
     char src0_name[50];
@@ -2266,7 +2253,7 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
     DWORD flags;
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_str[50];
     char src0_name[50];
@@ -2338,7 +2325,7 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    DWORD sampler_idx = ins->dst[0].reg.idx;
+    DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
     char src0[50];
     char dst_str[50];
 
@@ -2362,7 +2349,7 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
     /* Handle output register */
     shader_arb_get_dst_param(ins, dst, dst_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 %s, fragment.texcoord[%u], %s;\n", dst_str, dst->reg.idx, src0);
+    shader_addline(buffer, "DP3 %s, fragment.texcoord[%u], %s;\n", dst_str, dst->reg.idx[0].offset, src0);
 }
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in ARB
@@ -2378,7 +2365,7 @@ static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
     shader_arb_get_dst_param(ins, dst, dst_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
     shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
-    shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx, src0);
+    shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx[0].offset, src0);
     shader_addline(buffer, "MOV %s, %s;\n", dst_str, dst_name);
 }
 
@@ -2398,7 +2385,7 @@ static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
     shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
-    shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx, src0);
+    shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx[0].offset, src0);
 
     /* How to deal with the special case dst_name.g == 0? if r != 0, then
      * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
@@ -2459,10 +2446,11 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
     tmp_dst = ins->dst[0];
     tmp_src[0] = ins->src[0];
     tmp_src[1] = ins->src[1];
-    for (i = 0; i < nComponents; i++) {
+    for (i = 0; i < nComponents; ++i)
+    {
         tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
         shader_hw_map2gl(&tmp_ins);
-        ++tmp_src[1].reg.idx;
+        ++tmp_src[1].reg.idx[0].offset;
     }
 }
 
@@ -3119,7 +3107,7 @@ static void shader_hw_endif(const struct wined3d_shader_instruction *ins)
 
 static void shader_hw_texldd(const struct wined3d_shader_instruction *ins)
 {
-    DWORD sampler_idx = ins->src[1].reg.idx;
+    DWORD sampler_idx = ins->src[1].reg.idx[0].offset;
     char reg_dest[40];
     char reg_src[3][40];
     WORD flags = TEX_DERIV;
@@ -3137,7 +3125,7 @@ static void shader_hw_texldd(const struct wined3d_shader_instruction *ins)
 
 static void shader_hw_texldl(const struct wined3d_shader_instruction *ins)
 {
-    DWORD sampler_idx = ins->src[1].reg.idx;
+    DWORD sampler_idx = ins->src[1].reg.idx[0].offset;
     char reg_dest[40];
     char reg_coord[40];
     WORD flags = TEX_LOD;
@@ -3162,7 +3150,7 @@ static void shader_hw_label(const struct wined3d_shader_instruction *ins)
      */
     if(priv->target_version == ARB) return;
 
-    shader_addline(buffer, "l%u:\n", ins->src[0].reg.idx);
+    shader_addline(buffer, "l%u:\n", ins->src[0].reg.idx[0].offset);
 }
 
 static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx,
@@ -3294,7 +3282,7 @@ static void shader_hw_ret(const struct wined3d_shader_instruction *ins)
 static void shader_hw_call(const struct wined3d_shader_instruction *ins)
 {
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    shader_addline(buffer, "CAL l%u;\n", ins->src[0].reg.idx);
+    shader_addline(buffer, "CAL l%u;\n", ins->src[0].reg.idx[0].offset);
 }
 
 /* GL locking is done by the caller */
@@ -5300,26 +5288,29 @@ static void record_instruction(struct list *list, const struct wined3d_shader_in
     dst_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_param));
     if(!dst_param) goto free;
     *dst_param = *ins->dst;
-    if(ins->dst->reg.rel_addr)
+    if (ins->dst->reg.idx[0].rel_addr)
     {
-        rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_param->reg.rel_addr));
-        if(!rel_addr) goto free;
-        *rel_addr = *ins->dst->reg.rel_addr;
-        dst_param->reg.rel_addr = rel_addr;
+        rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
+        if (!rel_addr)
+            goto free;
+        *rel_addr = *ins->dst->reg.idx[0].rel_addr;
+        dst_param->reg.idx[0].rel_addr = rel_addr;
     }
     rec->ins.dst = dst_param;
 
     src_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*src_param) * ins->src_count);
-    if(!src_param) goto free;
-    for(i = 0; i < ins->src_count; i++)
+    if (!src_param)
+        goto free;
+    for (i = 0; i < ins->src_count; ++i)
     {
         src_param[i] = ins->src[i];
-        if(ins->src[i].reg.rel_addr)
+        if (ins->src[i].reg.idx[0].rel_addr)
         {
             rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
-            if(!rel_addr) goto free;
-            *rel_addr = *ins->src[i].reg.rel_addr;
-            src_param[i].reg.rel_addr = rel_addr;
+            if (!rel_addr)
+                goto free;
+            *rel_addr = *ins->src[i].reg.idx[0].rel_addr;
+            src_param[i].reg.idx[0].rel_addr = rel_addr;
         }
     }
     rec->ins.src = src_param;
@@ -5330,14 +5321,14 @@ free:
     ERR("Out of memory\n");
     if(dst_param)
     {
-        HeapFree(GetProcessHeap(), 0, (void *) dst_param->reg.rel_addr);
+        HeapFree(GetProcessHeap(), 0, (void *)dst_param->reg.idx[0].rel_addr);
         HeapFree(GetProcessHeap(), 0, dst_param);
     }
     if(src_param)
     {
         for(i = 0; i < ins->src_count; i++)
         {
-            HeapFree(GetProcessHeap(), 0, (void *) src_param[i].reg.rel_addr);
+            HeapFree(GetProcessHeap(), 0, (void *)src_param[i].reg.idx[0].rel_addr);
         }
         HeapFree(GetProcessHeap(), 0, src_param);
     }
@@ -5352,18 +5343,18 @@ static void free_recorded_instruction(struct list *list)
     LIST_FOR_EACH_ENTRY_SAFE(rec_ins, entry2, list, struct recorded_instruction, entry)
     {
         list_remove(&rec_ins->entry);
-        if(rec_ins->ins.dst)
+        if (rec_ins->ins.dst)
         {
-            HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.dst->reg.rel_addr);
-            HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.dst);
+            HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.dst->reg.idx[0].rel_addr);
+            HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.dst);
         }
-        if(rec_ins->ins.src)
+        if (rec_ins->ins.src)
         {
-            for(i = 0; i < rec_ins->ins.src_count; i++)
+            for (i = 0; i < rec_ins->ins.src_count; ++i)
             {
-                HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.src[i].reg.rel_addr);
+                HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.src[i].reg.idx[0].rel_addr);
             }
-            HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.src);
+            HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.src);
         }
         HeapFree(GetProcessHeap(), 0, rec_ins);
     }
@@ -5403,7 +5394,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
                 list_init(&priv->record);
                 priv->recording = TRUE;
                 control_frame->outer_loop = TRUE;
-                get_loop_control_const(ins, shader, ins->src[0].reg.idx, &control_frame->loop_control);
+                get_loop_control_const(ins, shader, ins->src[0].reg.idx[0].offset, &control_frame->loop_control);
                 return; /* Instruction is handled */
             }
             /* Record this loop in the outer loop's recording */
@@ -5500,8 +5491,9 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
         list_add_head(&priv->control_frames, &control_frame->entry);
         control_frame->type = IF;
 
-        bool_const = get_bool_const(ins, shader, ins->src[0].reg.idx);
-        if(ins->src[0].modifiers == WINED3DSPSM_NOT) bool_const = !bool_const;
+        bool_const = get_bool_const(ins, shader, ins->src[0].reg.idx[0].offset);
+        if (ins->src[0].modifiers == WINED3DSPSM_NOT)
+            bool_const = !bool_const;
         if (!priv->muted && !bool_const)
         {
             shader_addline(buffer, "#if(FALSE){\n");
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 046ee43..f6e3d8d 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1328,7 +1328,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
     switch (reg->type)
     {
         case WINED3DSPR_TEMP:
-            sprintf(register_name, "R%u", reg->idx);
+            sprintf(register_name, "R%u", reg->idx[0].offset);
             break;
 
         case WINED3DSPR_INPUT:
@@ -1336,22 +1336,23 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             if (!pshader)
             {
                 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
-                if (priv->cur_vs_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE;
-                sprintf(register_name, "%s_in%u", prefix, reg->idx);
+                if (priv->cur_vs_args->swizzle_map & (1 << reg->idx[0].offset))
+                    *is_color = TRUE;
+                sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset);
                 break;
             }
 
             /* pixel shaders >= 3.0 */
             if (reg_maps->shader_version.major >= 3)
             {
-                DWORD idx = shader->u.ps.input_reg_map[reg->idx];
+                DWORD idx = shader->u.ps.input_reg_map[reg->idx[0].offset];
                 unsigned int in_count = vec4_varyings(reg_maps->shader_version.major, gl_info);
 
-                if (reg->rel_addr)
+                if (reg->idx[0].rel_addr)
                 {
                     struct glsl_src_param rel_param;
 
-                    shader_glsl_add_src_param(ins, reg->rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
+                    shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
 
                     /* Removing a + 0 would be an obvious optimization, but macos doesn't see the NOP
                      * operation there */
@@ -1392,8 +1393,10 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             }
             else
             {
-                if (!reg->idx) strcpy(register_name, "gl_Color");
-                else strcpy(register_name, "gl_SecondaryColor");
+                if (!reg->idx[0].offset)
+                    strcpy(register_name, "gl_Color");
+                else
+                    strcpy(register_name, "gl_SecondaryColor");
                 break;
             }
             break;
@@ -1401,36 +1404,38 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
         case WINED3DSPR_CONST:
             {
                 /* Relative addressing */
-                if (reg->rel_addr)
+                if (reg->idx[0].rel_addr)
                 {
                     struct glsl_src_param rel_param;
-                    shader_glsl_add_src_param(ins, reg->rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
-                    if (reg->idx)
-                        sprintf(register_name, "%s_c[%s + %u]", prefix, rel_param.param_str, reg->idx);
+                    shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
+                    if (reg->idx[0].offset)
+                        sprintf(register_name, "%s_c[%s + %u]", prefix, rel_param.param_str, reg->idx[0].offset);
                     else
                         sprintf(register_name, "%s_c[%s]", prefix, rel_param.param_str);
                 }
                 else
                 {
-                    if (shader_constant_is_local(shader, reg->idx))
-                        sprintf(register_name, "%s_lc%u", prefix, reg->idx);
+                    if (shader_constant_is_local(shader, reg->idx[0].offset))
+                        sprintf(register_name, "%s_lc%u", prefix, reg->idx[0].offset);
                     else
-                        sprintf(register_name, "%s_c[%u]", prefix, reg->idx);
+                        sprintf(register_name, "%s_c[%u]", prefix, reg->idx[0].offset);
                 }
             }
             break;
 
         case WINED3DSPR_CONSTINT:
-            sprintf(register_name, "%s_i[%u]", prefix, reg->idx);
+            sprintf(register_name, "%s_i[%u]", prefix, reg->idx[0].offset);
             break;
 
         case WINED3DSPR_CONSTBOOL:
-            sprintf(register_name, "%s_b[%u]", prefix, reg->idx);
+            sprintf(register_name, "%s_b[%u]", prefix, reg->idx[0].offset);
             break;
 
         case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
-            if (pshader) sprintf(register_name, "T%u", reg->idx);
-            else sprintf(register_name, "A%u", reg->idx);
+            if (pshader)
+                sprintf(register_name, "T%u", reg->idx[0].offset);
+            else
+                sprintf(register_name, "A%u", reg->idx[0].offset);
             break;
 
         case WINED3DSPR_LOOP:
@@ -1438,18 +1443,19 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             break;
 
         case WINED3DSPR_SAMPLER:
-            sprintf(register_name, "%s_sampler%u", prefix, reg->idx);
+            sprintf(register_name, "%s_sampler%u", prefix, reg->idx[0].offset);
             break;
 
         case WINED3DSPR_COLOROUT:
-            if (reg->idx >= gl_info->limits.buffers)
-                WARN("Write to render target %u, only %d supported.\n", reg->idx, gl_info->limits.buffers);
+            if (reg->idx[0].offset >= gl_info->limits.buffers)
+                WARN("Write to render target %u, only %d supported.\n",
+                        reg->idx[0].offset, gl_info->limits.buffers);
 
-            sprintf(register_name, "gl_FragData[%u]", reg->idx);
+            sprintf(register_name, "gl_FragData[%u]", reg->idx[0].offset);
             break;
 
         case WINED3DSPR_RASTOUT:
-            sprintf(register_name, "%s", hwrastout_reg_names[reg->idx]);
+            sprintf(register_name, "%s", hwrastout_reg_names[reg->idx[0].offset]);
             break;
 
         case WINED3DSPR_DEPTHOUT:
@@ -1457,22 +1463,24 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             break;
 
         case WINED3DSPR_ATTROUT:
-            if (!reg->idx) sprintf(register_name, "%s_out[8]", prefix);
-            else sprintf(register_name, "%s_out[9]", prefix);
+            if (!reg->idx[0].offset)
+                sprintf(register_name, "%s_out[8]", prefix);
+            else
+                sprintf(register_name, "%s_out[9]", prefix);
             break;
 
         case WINED3DSPR_TEXCRDOUT:
             /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
-            sprintf(register_name, "%s_out[%u]", prefix, reg->idx);
+            sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset);
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (!reg->idx)
+            if (!reg->idx[0].offset)
             {
                 /* vPos */
                 sprintf(register_name, "vpos");
             }
-            else if (reg->idx == 1)
+            else if (reg->idx[0].offset == 1)
             {
                 /* Note that gl_FrontFacing is a bool, while vFace is
                  * a float for which the sign determines front/back */
@@ -1480,7 +1488,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             }
             else
             {
-                FIXME("Unhandled misctype register %d\n", reg->idx);
+                FIXME("Unhandled misctype register %u.\n", reg->idx[0].offset);
                 sprintf(register_name, "unrecognized_register");
             }
             break;
@@ -1541,15 +1549,16 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             break;
 
         case WINED3DSPR_CONSTBUFFER:
-            if (reg->array_rel_addr)
+            if (reg->idx[1].rel_addr)
             {
                 struct glsl_src_param rel_param;
-                shader_glsl_add_src_param(ins, reg->array_rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
-                sprintf(register_name, "%s_cb%u[%s + %u]", prefix, reg->idx, rel_param.param_str, reg->array_idx);
+                shader_glsl_add_src_param(ins, reg->idx[1].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
+                sprintf(register_name, "%s_cb%u[%s + %u]",
+                        prefix, reg->idx[0].offset, rel_param.param_str, reg->idx[1].offset);
             }
             else
             {
-                sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx, reg->array_idx);
+                sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx[0].offset, reg->idx[1].offset);
             }
             break;
 
@@ -2740,11 +2749,11 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
             * The first lines may overwrite source parameters of the following lines.
             * Deal with that by using a temporary destination register if needed
             */
-            if ((ins->src[0].reg.idx == ins->dst[0].reg.idx
+            if ((ins->src[0].reg.idx[0].offset == ins->dst[0].reg.idx[0].offset
                     && ins->src[0].reg.type == ins->dst[0].reg.type)
-                    || (ins->src[1].reg.idx == ins->dst[0].reg.idx
+                    || (ins->src[1].reg.idx[0].offset == ins->dst[0].reg.idx[0].offset
                     && ins->src[1].reg.type == ins->dst[0].reg.type)
-                    || (ins->src[2].reg.idx == ins->dst[0].reg.idx
+                    || (ins->src[2].reg.idx[0].offset == ins->dst[0].reg.idx[0].offset
                     && ins->src[2].reg.type == ins->dst[0].reg.type))
             {
                 write_mask = shader_glsl_get_write_mask(&dst, mask_char);
@@ -2900,7 +2909,7 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
     {
         tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
         shader_glsl_dot(&tmp_ins);
-        ++tmp_src[1].reg.idx;
+        ++tmp_src[1].reg.idx[0].offset;
     }
 }
 
@@ -3125,7 +3134,7 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
         {
             LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
             {
-                if (constant->idx == ins->src[1].reg.idx)
+                if (constant->idx == ins->src[1].reg.idx[0].offset)
                 {
                     control_values = constant->value;
                     break;
@@ -3211,7 +3220,7 @@ static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
     {
         LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
         {
-            if (constant->idx == ins->src[0].reg.idx)
+            if (constant->idx == ins->src[0].reg.idx[0].offset)
             {
                 control_values = constant->value;
                 break;
@@ -3295,12 +3304,12 @@ static void shader_glsl_breakp(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
 {
     shader_addline(ins->ctx->buffer, "}\n");
-    shader_addline(ins->ctx->buffer, "void subroutine%u () {\n",  ins->src[0].reg.idx);
+    shader_addline(ins->ctx->buffer, "void subroutine%u()\n{\n", ins->src[0].reg.idx[0].offset);
 }
 
 static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
 {
-    shader_addline(ins->ctx->buffer, "subroutine%u();\n", ins->src[0].reg.idx);
+    shader_addline(ins->ctx->buffer, "subroutine%u();\n", ins->src[0].reg.idx[0].offset);
 }
 
 static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
@@ -3308,7 +3317,8 @@ static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
     struct glsl_src_param src1_param;
 
     shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
-    shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, ins->src[0].reg.idx);
+    shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n",
+            src1_param.param_str, ins->src[0].reg.idx[0].offset);
 }
 
 static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
@@ -3335,8 +3345,10 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
 
     /* 1.0-1.4: Use destination register as sampler source.
      * 2.0+: Use provided sampler source. */
-    if (shader_version < WINED3D_SHADER_VERSION(2,0)) sampler_idx = ins->dst[0].reg.idx;
-    else sampler_idx = ins->src[1].reg.idx;
+    if (shader_version < WINED3D_SHADER_VERSION(2,0))
+        sampler_idx = ins->dst[0].reg.idx[0].offset;
+    else
+        sampler_idx = ins->src[1].reg.idx[0].offset;
     texture = device->stateBlock->state.textures[sampler_idx];
 
     if (shader_version < WINED3D_SHADER_VERSION(1,4))
@@ -3442,7 +3454,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
         return;
     }
 
-    sampler_idx = ins->src[1].reg.idx;
+    sampler_idx = ins->src[1].reg.idx[0].offset;
     texture = device->stateBlock->state.textures[sampler_idx];
     if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
@@ -3468,7 +3480,7 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
     DWORD swizzle = ins->src[1].swizzle;
     const struct wined3d_texture *texture;
 
-    sampler_idx = ins->src[1].reg.idx;
+    sampler_idx = ins->src[1].reg.idx[0].offset;
     texture = device->stateBlock->state.textures[sampler_idx];
     if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
@@ -3502,12 +3514,12 @@ static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 
         shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
         shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
-                ins->dst[0].reg.idx, dst_mask);
+                ins->dst[0].reg.idx[0].offset, dst_mask);
     }
     else
     {
         enum wined3d_shader_src_modifier src_mod = ins->src[0].modifiers;
-        DWORD reg = ins->src[0].reg.idx;
+        DWORD reg = ins->src[0].reg.idx[0].offset;
         char dst_swizzle[6];
 
         shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
@@ -3548,8 +3560,8 @@ static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
-    DWORD sampler_idx = ins->dst[0].reg.idx;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+    DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
     struct glsl_sample_function sample_function;
     struct glsl_src_param src0_param;
     UINT mask_size;
@@ -3591,8 +3603,8 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
 static void shader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
 {
-    DWORD dstreg = ins->dst[0].reg.idx;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+    DWORD dstreg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
     DWORD dst_mask;
     unsigned int mask_size;
@@ -3634,7 +3646,7 @@ static void shader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
-    DWORD dstreg = ins->dst[0].reg.idx;
+    DWORD dstreg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
@@ -3648,7 +3660,7 @@ static void shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *in
 static void shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
-    DWORD reg = ins->dst[0].reg.idx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     struct glsl_src_param src0_param;
 
@@ -3661,9 +3673,9 @@ static void shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
-    DWORD reg = ins->dst[0].reg.idx;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
@@ -3674,9 +3686,9 @@ static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
-    DWORD reg = ins->dst[0].reg.idx;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     struct glsl_sample_function sample_function;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
@@ -3695,8 +3707,8 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
     struct glsl_sample_function sample_function;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
-    DWORD reg = ins->dst[0].reg.idx;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
     shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
@@ -3716,9 +3728,9 @@ static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
     char dst_mask[6];
-    DWORD reg = ins->dst[0].reg.idx;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
 
@@ -3735,11 +3747,11 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
 {
     struct glsl_src_param src0_param;
     struct glsl_src_param src1_param;
-    DWORD reg = ins->dst[0].reg.idx;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     struct glsl_sample_function sample_function;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     char coord_mask[6];
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
@@ -3765,11 +3777,11 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
 static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
-    DWORD reg = ins->dst[0].reg.idx;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     struct glsl_sample_function sample_function;
+    DWORD reg = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param;
     char coord_mask[6];
 
@@ -3808,7 +3820,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
     DWORD flags;
     char coord_mask[6];
 
-    sampler_idx = ins->dst[0].reg.idx;
+    sampler_idx = ins->dst[0].reg.idx[0].offset;
     flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
             & WINED3D_PSARGS_TEXTRANSFORM_MASK;
 
@@ -3866,8 +3878,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 
 static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
 {
+    DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
     struct glsl_src_param src0_param, src1_param;
-    DWORD sampler_idx = ins->dst[0].reg.idx;
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
     shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
@@ -3881,9 +3893,9 @@ static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
  * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
 static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
+    DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
     struct glsl_sample_function sample_function;
     struct glsl_src_param src0_param;
-    DWORD sampler_idx = ins->dst[0].reg.idx;
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
 
@@ -3896,9 +3908,9 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
  * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
 static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
+    DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
     struct glsl_sample_function sample_function;
     struct glsl_src_param src0_param;
-    DWORD sampler_idx = ins->dst[0].reg.idx;
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
 
@@ -3911,9 +3923,9 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
  * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
 static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
+    DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
     struct glsl_sample_function sample_function;
     struct glsl_src_param src0_param;
-    DWORD sampler_idx = ins->dst[0].reg.idx;
 
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index d7e9058..12d5f98 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -202,7 +202,7 @@ static void shader_signature_from_semantic(struct wined3d_shader_signature_eleme
     e->semantic_idx = s->usage_idx;
     e->sysval_semantic = 0;
     e->component_type = 0;
-    e->register_idx = s->reg.reg.idx;
+    e->register_idx = s->reg.reg.idx[0].offset;
     e->mask = s->reg.write_mask;
 }
 
@@ -365,18 +365,20 @@ static void shader_record_register_usage(struct wined3d_shader *shader, struct w
     switch (reg->type)
     {
         case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
-            if (shader_type == WINED3D_SHADER_TYPE_PIXEL) reg_maps->texcoord |= 1 << reg->idx;
-            else reg_maps->address |= 1 << reg->idx;
+            if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
+                reg_maps->texcoord |= 1 << reg->idx[0].offset;
+            else
+                reg_maps->address |= 1 << reg->idx[0].offset;
             break;
 
         case WINED3DSPR_TEMP:
-            reg_maps->temporary |= 1 << reg->idx;
+            reg_maps->temporary |= 1 << reg->idx[0].offset;
             break;
 
         case WINED3DSPR_INPUT:
             if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
             {
-                if (reg->rel_addr)
+                if (reg->idx[0].rel_addr)
                 {
                     /* If relative addressing is used, we must assume that all registers
                      * are used. Even if it is a construct like v3[aL], we can't assume
@@ -389,51 +391,58 @@ static void shader_record_register_usage(struct wined3d_shader *shader, struct w
                 }
                 else
                 {
-                    shader->u.ps.input_reg_used[reg->idx] = TRUE;
+                    shader->u.ps.input_reg_used[reg->idx[0].offset] = TRUE;
                 }
             }
-            else reg_maps->input_registers |= 1 << reg->idx;
+            else
+                reg_maps->input_registers |= 1 << reg->idx[0].offset;
             break;
 
         case WINED3DSPR_RASTOUT:
-            if (reg->idx == 1) reg_maps->fog = 1;
+            if (reg->idx[0].offset == 1)
+                reg_maps->fog = 1;
             break;
 
         case WINED3DSPR_MISCTYPE:
             if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
             {
-                if (!reg->idx) reg_maps->vpos = 1;
-                else if (reg->idx == 1) reg_maps->usesfacing = 1;
+                if (!reg->idx[0].offset)
+                    reg_maps->vpos = 1;
+                else if (reg->idx[0].offset == 1)
+                    reg_maps->usesfacing = 1;
             }
             break;
 
         case WINED3DSPR_CONST:
-            if (reg->rel_addr)
+            if (reg->idx[0].rel_addr)
             {
-                if (reg->idx < reg_maps->min_rel_offset) reg_maps->min_rel_offset = reg->idx;
-                if (reg->idx > reg_maps->max_rel_offset) reg_maps->max_rel_offset = reg->idx;
+                if (reg->idx[0].offset < reg_maps->min_rel_offset)
+                    reg_maps->min_rel_offset = reg->idx[0].offset;
+                if (reg->idx[0].offset > reg_maps->max_rel_offset)
+                    reg_maps->max_rel_offset = reg->idx[0].offset;
                 reg_maps->usesrelconstF = TRUE;
             }
             else
             {
-                set_bitmap_bit(reg_maps->constf, reg->idx);
+                set_bitmap_bit(reg_maps->constf, reg->idx[0].offset);
             }
             break;
 
         case WINED3DSPR_CONSTINT:
-            reg_maps->integer_constants |= (1 << reg->idx);
+            reg_maps->integer_constants |= (1 << reg->idx[0].offset);
             break;
 
         case WINED3DSPR_CONSTBOOL:
-            reg_maps->boolean_constants |= (1 << reg->idx);
+            reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
             break;
 
         case WINED3DSPR_COLOROUT:
-            reg_maps->rt_mask |= (1 << reg->idx);
+            reg_maps->rt_mask |= (1 << reg->idx[0].offset);
             break;
 
         default:
-            TRACE("Not recording register of type %#x and idx %u\n", reg->type, reg->idx);
+            TRACE("Not recording register of type %#x and [%#x][%#x].\n",
+                    reg->type, reg->idx[0].offset, reg->idx[1].offset);
             break;
     }
 }
@@ -511,21 +520,21 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             {
                 /* Mark input registers used. */
                 case WINED3DSPR_INPUT:
-                    reg_maps->input_registers |= 1 << semantic->reg.reg.idx;
-                    shader_signature_from_semantic(&input_signature[semantic->reg.reg.idx], semantic);
+                    reg_maps->input_registers |= 1 << semantic->reg.reg.idx[0].offset;
+                    shader_signature_from_semantic(&input_signature[semantic->reg.reg.idx[0].offset], semantic);
                     break;
 
                 /* Vertex shader: mark 3.0 output registers used, save token. */
                 case WINED3DSPR_OUTPUT:
-                    reg_maps->output_registers |= 1 << semantic->reg.reg.idx;
-                    shader_signature_from_semantic(&output_signature[semantic->reg.reg.idx], semantic);
+                    reg_maps->output_registers |= 1 << semantic->reg.reg.idx[0].offset;
+                    shader_signature_from_semantic(&output_signature[semantic->reg.reg.idx[0].offset], semantic);
                     if (semantic->usage == WINED3D_DECL_USAGE_FOG)
                         reg_maps->fog = 1;
                     break;
 
                 /* Save sampler usage token. */
                 case WINED3DSPR_SAMPLER:
-                    reg_maps->sampler_type[semantic->reg.reg.idx] = semantic->sampler_type;
+                    reg_maps->sampler_type[semantic->reg.reg.idx[0].offset] = semantic->sampler_type;
                     break;
 
                 default:
@@ -536,17 +545,17 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         else if (ins.handler_idx == WINED3DSIH_DCL_CONSTANT_BUFFER)
         {
             struct wined3d_shader_register *reg = &ins.declaration.src.reg;
-            if (reg->idx >= WINED3D_MAX_CBS)
-                ERR("Invalid CB index %u.\n", reg->idx);
+            if (reg->idx[0].offset >= WINED3D_MAX_CBS)
+                ERR("Invalid CB index %u.\n", reg->idx[0].offset);
             else
-                reg_maps->cb_sizes[reg->idx] = reg->array_idx;
+                reg_maps->cb_sizes[reg->idx[0].offset] = reg->idx[1].offset;
         }
         else if (ins.handler_idx == WINED3DSIH_DEF)
         {
             struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
             if (!lconst) return E_OUTOFMEMORY;
 
-            lconst->idx = ins.dst[0].reg.idx;
+            lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
@@ -570,7 +579,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
             if (!lconst) return E_OUTOFMEMORY;
 
-            lconst->idx = ins.dst[0].reg.idx;
+            lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
 
             list_add_head(&shader->constantsI, &lconst->entry);
@@ -581,7 +590,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
             if (!lconst) return E_OUTOFMEMORY;
 
-            lconst->idx = ins.dst[0].reg.idx;
+            lconst->idx = ins.dst[0].reg.idx[0].offset;
             memcpy(lconst->value, ins.src[0].reg.immconst_data, sizeof(DWORD));
 
             list_add_head(&shader->constantsB, &lconst->entry);
@@ -590,7 +599,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         /* For subroutine prototypes. */
         else if (ins.handler_idx == WINED3DSIH_LABEL)
         {
-            reg_maps->labels |= 1 << ins.src[0].reg.idx;
+            reg_maps->labels |= 1 << ins.src[0].reg.idx[0].offset;
         }
         /* Set texture, address, temporary registers. */
         else
@@ -613,7 +622,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                  * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
                 if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX && shader_version.major < 3)
                 {
-                    UINT idx = ins.dst[i].reg.idx;
+                    UINT idx = ins.dst[i].reg.idx[0].offset;
 
                     switch (ins.dst[i].reg.type)
                     {
@@ -679,7 +688,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
 
                 if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
                 {
-                    if (ins.dst[i].reg.type == WINED3DSPR_COLOROUT && !ins.dst[i].reg.idx)
+                    if (ins.dst[i].reg.type == WINED3DSPR_COLOROUT && !ins.dst[i].reg.idx[0].offset)
                     {
                         /* Many 2.0 and 3.0 pixel shaders end with a MOV from a temp register to
                          * COLOROUT 0. If we know this in advance, the ARB shader backend can skip
@@ -700,7 +709,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                      * end
                      */
                     else if (ins.dst[i].reg.type == WINED3DSPR_TEMP
-                            && ins.dst[i].reg.idx == shader->u.ps.color0_reg)
+                            && ins.dst[i].reg.idx[0].offset == shader->u.ps.color0_reg)
                     {
                         shader->u.ps.color0_mov = FALSE;
                     }
@@ -721,7 +730,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                             || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
                 {
                     /* Fake sampler usage, only set reserved bit and type. */
-                    DWORD sampler_code = ins.dst[i].reg.idx;
+                    DWORD sampler_code = ins.dst[i].reg.idx[0].offset;
 
                     TRACE("Setting fake 2D sampler for 1.x pixelshader.\n");
                     reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
@@ -730,16 +739,16 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                     if (ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML)
                     {
-                        reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx;
+                        reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
-                            reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx;
+                            reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx[0].offset;
                         }
                     }
                 }
                 else if (ins.handler_idx == WINED3DSIH_BEM)
                 {
-                    reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx;
+                    reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
                 }
             }
 
@@ -774,7 +783,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                 shader_record_register_usage(shader, reg_maps, &ins.src[i].reg, shader_version.type);
                 while (count)
                 {
-                    ++reg.idx;
+                    ++reg.idx[0].offset;
                     shader_record_register_usage(shader, reg_maps, &reg, shader_version.type);
                     --count;
                 }
@@ -785,7 +794,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                             && ins.src[i].swizzle == WINED3DSP_NOSWIZZLE)
                     {
                         shader->u.ps.color0_mov = TRUE;
-                        shader->u.ps.color0_reg = ins.src[i].reg.idx;
+                        shader->u.ps.color0_reg = ins.src[i].reg.idx[0].offset;
                     }
                 }
             }
@@ -903,7 +912,7 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
 {
     static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
     static const char * const misctype_reg_names[] = {"vPos", "vFace"};
-    UINT offset = reg->idx;
+    UINT offset = reg->idx[0].offset;
 
     switch (reg->type)
     {
@@ -920,7 +929,7 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
-            offset = shader_get_float_offset(reg->type, reg->idx);
+            offset = shader_get_float_offset(reg->type, offset);
             break;
 
         case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
@@ -928,7 +937,7 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
             break;
 
         case WINED3DSPR_RASTOUT:
-            TRACE("%s", rastout_reg_names[reg->idx]);
+            TRACE("%s", rastout_reg_names[offset]);
             break;
 
         case WINED3DSPR_COLOROUT:
@@ -971,8 +980,10 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (reg->idx > 1) FIXME("Unhandled misctype register %u.\n", reg->idx);
-            else TRACE("%s", misctype_reg_names[reg->idx]);
+            if (offset > 1)
+                FIXME("Unhandled misctype register %u.\n", offset);
+            else
+                TRACE("%s", misctype_reg_names[offset]);
             break;
 
         case WINED3DSPR_PREDICATE:
@@ -1064,22 +1075,22 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
         if (offset != ~0U)
         {
             TRACE("[");
-            if (reg->rel_addr)
+            if (reg->idx[0].rel_addr)
             {
-                shader_dump_src_param(reg->rel_addr, shader_version);
+                shader_dump_src_param(reg->idx[0].rel_addr, shader_version);
                 TRACE(" + ");
             }
             TRACE("%u]", offset);
 
-            if (reg->array_idx != ~0U)
+            if (reg->idx[1].offset != ~0U)
             {
                 TRACE("[");
-                if (reg->array_rel_addr)
+                if (reg->idx[1].rel_addr)
                 {
-                    shader_dump_src_param(reg->array_rel_addr, shader_version);
+                    shader_dump_src_param(reg->idx[1].rel_addr, shader_version);
                     TRACE(" + ");
                 }
-                TRACE("%u]", reg->array_idx);
+                TRACE("%u]", reg->idx[1].offset);
             }
         }
     }
@@ -1394,7 +1405,8 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
         }
         else if (ins.handler_idx == WINED3DSIH_DEF)
         {
-            TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(ins.dst[0].reg.type, ins.dst[0].reg.idx),
+            TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(ins.dst[0].reg.type,
+                    ins.dst[0].reg.idx[0].offset),
                     *(const float *)&ins.src[0].reg.immconst_data[0],
                     *(const float *)&ins.src[0].reg.immconst_data[1],
                     *(const float *)&ins.src[0].reg.immconst_data[2],
@@ -1402,7 +1414,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
         }
         else if (ins.handler_idx == WINED3DSIH_DEFI)
         {
-            TRACE("defi i%u = %d, %d, %d, %d", ins.dst[0].reg.idx,
+            TRACE("defi i%u = %d, %d, %d, %d", ins.dst[0].reg.idx[0].offset,
                     ins.src[0].reg.immconst_data[0],
                     ins.src[0].reg.immconst_data[1],
                     ins.src[0].reg.immconst_data[2],
@@ -1410,7 +1422,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
         }
         else if (ins.handler_idx == WINED3DSIH_DEFB)
         {
-            TRACE("defb b%u = %s", ins.dst[0].reg.idx, ins.src[0].reg.immconst_data[0] ? "true" : "false");
+            TRACE("defb b%u = %s", ins.dst[0].reg.idx[0].offset, ins.src[0].reg.immconst_data[0] ? "true" : "false");
         }
         else
         {
diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c
index b8b96dd..ae7e3a9 100644
--- a/dlls/wined3d/shader_sm1.c
+++ b/dlls/wined3d/shader_sm1.c
@@ -448,11 +448,12 @@ static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_
     src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
             | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
     src->reg.data_type = WINED3D_DATA_FLOAT;
-    src->reg.idx = param & WINED3DSP_REGNUM_MASK;
-    src->reg.array_idx = ~0U;
+    src->reg.idx[0].offset = param & WINED3DSP_REGNUM_MASK;
+    src->reg.idx[0].rel_addr = rel_addr;
+    src->reg.idx[1].offset = ~0U;
+    src->reg.idx[1].rel_addr = NULL;
     src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
     src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT;
-    src->reg.rel_addr = rel_addr;
 }
 
 static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
@@ -461,12 +462,13 @@ static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_
     dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
             | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
     dst->reg.data_type = WINED3D_DATA_FLOAT;
-    dst->reg.idx = param & WINED3DSP_REGNUM_MASK;
-    dst->reg.array_idx = ~0U;
+    dst->reg.idx[0].offset = param & WINED3DSP_REGNUM_MASK;
+    dst->reg.idx[0].rel_addr = rel_addr;
+    dst->reg.idx[1].offset = ~0U;
+    dst->reg.idx[1].rel_addr = NULL;
     dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT;
     dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT;
     dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    dst->reg.rel_addr = rel_addr;
 }
 
 /* Read the parameters of an unrecognized opcode from the input stream
@@ -628,9 +630,10 @@ static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_sr
     UINT count = type == WINED3D_IMMCONST_VEC4 ? 4 : 1;
     src_param->reg.type = WINED3DSPR_IMMCONST;
     src_param->reg.data_type = data_type;
-    src_param->reg.idx = ~0U;
-    src_param->reg.array_idx = ~0U;
-    src_param->reg.rel_addr = NULL;
+    src_param->reg.idx[0].offset = ~0U;
+    src_param->reg.idx[0].rel_addr = NULL;
+    src_param->reg.idx[1].offset = ~0U;
+    src_param->reg.idx[1].rel_addr = NULL;
     src_param->reg.immconst_type = type;
     memcpy(src_param->reg.immconst_data, *ptr, count * sizeof(DWORD));
     src_param->swizzle = WINED3DSP_NOSWIZZLE;
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index dceb120..f7a73fe 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -195,12 +195,6 @@ struct sysval_map
     UINT register_idx;
 };
 
-struct wined3d_sm4_reg_idx
-{
-    struct wined3d_shader_src_param *rel_addr;
-    unsigned int offset;
-};
-
 /*
  * F -> WINED3D_DATA_FLOAT
  * I -> WINED3D_DATA_INT
@@ -339,7 +333,7 @@ static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shade
         if (sysval == sysval_map[i].sysval)
         {
             reg->type = sysval_map[i].register_type;
-            reg->idx = sysval_map[i].register_idx;
+            reg->idx[0].offset = sysval_map[i].register_idx;
         }
     }
 }
@@ -362,7 +356,7 @@ static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_sha
 
                 for (i = 0; i < s->element_count; ++i)
                 {
-                    if (s->elements[i].register_idx == reg->idx)
+                    if (s->elements[i].register_idx == reg->idx[0].offset)
                     {
                         map_sysval(s->elements[i].sysval_semantic, reg);
                         break;
@@ -484,7 +478,7 @@ static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d
 }
 
 static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD **ptr,
-        DWORD addressing, struct wined3d_sm4_reg_idx *reg_idx)
+        DWORD addressing, struct wined3d_shader_register_index *reg_idx)
 {
     if (addressing & WINED3D_SM4_ADDRESSING_RELATIVE)
     {
@@ -516,7 +510,6 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
         enum wined3d_shader_src_modifier *modifier)
 {
     enum wined3d_sm4_register_type register_type;
-    struct wined3d_sm4_reg_idx reg_idx;
     DWORD token = *(*ptr)++;
     DWORD order;
 
@@ -563,31 +556,27 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
     order = (token & WINED3D_SM4_REGISTER_ORDER_MASK) >> WINED3D_SM4_REGISTER_ORDER_SHIFT;
 
     if (order < 1)
-        param->idx = ~0U;
+        param->idx[0].offset = ~0U;
     else
     {
         DWORD addressing = (token & WINED3D_SM4_ADDRESSING_MASK0) >> WINED3D_SM4_ADDRESSING_SHIFT0;
-        if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &reg_idx)))
+        if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &param->idx[0])))
         {
             ERR("Failed to read register index.\n");
             return FALSE;
         }
-        param->rel_addr = reg_idx.rel_addr;
-        param->idx = reg_idx.offset;
     }
 
     if (order < 2)
-        param->array_idx = ~0U;
+        param->idx[1].offset = ~0U;
     else
     {
         DWORD addressing = (token & WINED3D_SM4_ADDRESSING_MASK1) >> WINED3D_SM4_ADDRESSING_SHIFT1;
-        if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &reg_idx)))
+        if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &param->idx[1])))
         {
             ERR("Failed to read register index.\n");
             return FALSE;
         }
-        param->array_rel_addr = reg_idx.rel_addr;
-        param->array_idx = reg_idx.offset;
     }
 
     if (order > 2)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1afd890..41dd737 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -625,14 +625,17 @@ struct wined3d_shader_context
     void *backend_data;
 };
 
+struct wined3d_shader_register_index
+{
+    const struct wined3d_shader_src_param *rel_addr;
+    unsigned int offset;
+};
+
 struct wined3d_shader_register
 {
     enum wined3d_shader_register_type type;
     enum wined3d_data_type data_type;
-    UINT idx;
-    UINT array_idx;
-    const struct wined3d_shader_src_param *rel_addr;
-    const struct wined3d_shader_src_param *array_rel_addr;
+    struct wined3d_shader_register_index idx[2];
     enum wined3d_immconst_type immconst_type;
     DWORD immconst_data[4];
 };
@@ -2667,7 +2670,8 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
     {
         case WINED3DSPR_RASTOUT:
             /* oFog & oPts */
-            if (reg->idx) return TRUE;
+            if (reg->idx[0].offset)
+                return TRUE;
             /* oPos */
             return FALSE;
 
@@ -2678,7 +2682,7 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
             return TRUE;
 
         case WINED3DSPR_MISCTYPE:
-            switch(reg->idx)
+            switch (reg->idx[0].offset)
             {
                 case 0: /* vPos */
                     return FALSE;
-- 
1.7.8.6




More information about the wine-patches mailing list