tgsi/ureg: add ureg_UARL shortcut (v2)
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_text.c
index 68d1478d0d1497ad8bd8201aa4ce32dd961e2eca..f965b0130e0533f27fb346a5f932040d454098ad 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -242,6 +242,7 @@ struct translate_ctx
    struct tgsi_header *header;
    unsigned processor : 4;
    int implied_array_size : 5;
+   unsigned num_immediates;
 };
 
 static void report_error( struct translate_ctx *ctx, const char *msg )
@@ -321,7 +322,7 @@ parse_file( const char **pcur, uint *file )
    for (i = 0; i < TGSI_FILE_COUNT; i++) {
       const char *cur = *pcur;
 
-      if (str_match_nocase_whole( &cur, tgsi_file_names[i] )) {
+      if (str_match_nocase_whole( &cur, tgsi_file_name(i) )) {
          *pcur = cur;
          *file = i;
          return TRUE;
@@ -440,6 +441,7 @@ struct parsed_bracket {
    uint ind_file;
    int ind_index;
    uint ind_comp;
+   uint ind_array;
 };
 
 
@@ -507,6 +509,20 @@ parse_register_bracket(
       return FALSE;
    }
    ctx->cur++;
+   if (*ctx->cur == '(') {
+      ctx->cur++;
+      eat_opt_white( &ctx->cur );
+      if (!parse_uint( &ctx->cur, &brackets->ind_array )) {
+         report_error( ctx, "Expected literal unsigned integer" );
+         return FALSE;
+      }
+      eat_opt_white( &ctx->cur );
+      if (*ctx->cur != ')') {
+         report_error( ctx, "Expected `)'" );
+         return FALSE;
+      }
+      ctx->cur++;
+   }
    return TRUE;
 }
 
@@ -710,10 +726,8 @@ parse_dst_operand(
       dst->Register.Indirect = 1;
       dst->Indirect.File = bracket[0].ind_file;
       dst->Indirect.Index = bracket[0].ind_index;
-      dst->Indirect.SwizzleX = bracket[0].ind_comp;
-      dst->Indirect.SwizzleY = bracket[0].ind_comp;
-      dst->Indirect.SwizzleZ = bracket[0].ind_comp;
-      dst->Indirect.SwizzleW = bracket[0].ind_comp;
+      dst->Indirect.Swizzle = bracket[0].ind_comp;
+      dst->Indirect.ArrayID = bracket[0].ind_array;
    }
    return TRUE;
 }
@@ -721,8 +735,9 @@ parse_dst_operand(
 static boolean
 parse_optional_swizzle(
    struct translate_ctx *ctx,
-   uint swizzle[4],
-   boolean *parsed_swizzle )
+   uint *swizzle,
+   boolean *parsed_swizzle,
+   int components)
 {
    const char *cur = ctx->cur;
 
@@ -734,7 +749,7 @@ parse_optional_swizzle(
 
       cur++;
       eat_opt_white( &cur );
-      for (i = 0; i < 4; i++) {
+      for (i = 0; i < components; i++) {
          if (uprcase( *cur ) == 'X')
             swizzle[i] = TGSI_SWIZZLE_X;
          else if (uprcase( *cur ) == 'Y')
@@ -789,6 +804,13 @@ parse_src_operand(
       src->Dimension.Indirect = 0;
       src->Dimension.Dimension = 0;
       src->Dimension.Index = bracket[0].index;
+      if (bracket[0].ind_file != TGSI_FILE_NULL) {
+         src->Dimension.Indirect = 1;
+         src->DimIndirect.File = bracket[0].ind_file;
+         src->DimIndirect.Index = bracket[0].ind_index;
+         src->DimIndirect.Swizzle = bracket[0].ind_comp;
+         src->DimIndirect.ArrayID = bracket[0].ind_array;
+      }
       bracket[0] = bracket[1];
    }
    src->Register.Index = bracket[0].index;
@@ -796,15 +818,13 @@ parse_src_operand(
       src->Register.Indirect = 1;
       src->Indirect.File = bracket[0].ind_file;
       src->Indirect.Index = bracket[0].ind_index;
-      src->Indirect.SwizzleX = bracket[0].ind_comp;
-      src->Indirect.SwizzleY = bracket[0].ind_comp;
-      src->Indirect.SwizzleZ = bracket[0].ind_comp;
-      src->Indirect.SwizzleW = bracket[0].ind_comp;
+      src->Indirect.Swizzle = bracket[0].ind_comp;
+      src->Indirect.ArrayID = bracket[0].ind_array;
    }
 
    /* Parse optional swizzle.
     */
-   if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
+   if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 4 )) {
       if (parsed_swizzle) {
          src->Register.SwizzleX = swizzle[0];
          src->Register.SwizzleY = swizzle[1];
@@ -826,6 +846,35 @@ parse_src_operand(
    return TRUE;
 }
 
+static boolean
+parse_texoffset_operand(
+   struct translate_ctx *ctx,
+   struct tgsi_texture_offset *src )
+{
+   uint file;
+   uint swizzle[3];
+   boolean parsed_swizzle;
+   struct parsed_bracket bracket;
+
+   if (!parse_register_src(ctx, &file, &bracket))
+      return FALSE;
+
+   src->File = file;
+   src->Index = bracket.index;
+
+   /* Parse optional swizzle.
+    */
+   if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 3 )) {
+      if (parsed_swizzle) {
+         src->SwizzleX = swizzle[0];
+         src->SwizzleY = swizzle[1];
+         src->SwizzleZ = swizzle[2];
+      }
+   }
+
+   return TRUE;
+}
+
 static boolean
 match_inst(const char **pcur,
            unsigned *saturate,
@@ -892,7 +941,7 @@ parse_instruction(
       if (!parse_register_1d( ctx, &file, &index ))
          return FALSE;
 
-      if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
+      if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 4 )) {
          if (parsed_swizzle) {
             inst.Predicate.SwizzleX = swizzle[0];
             inst.Predicate.SwizzleY = swizzle[1];
@@ -940,6 +989,16 @@ parse_instruction(
    inst.Instruction.NumDstRegs = info->num_dst;
    inst.Instruction.NumSrcRegs = info->num_src;
 
+   if (i >= TGSI_OPCODE_SAMPLE && i <= TGSI_OPCODE_GATHER4) {
+      /*
+       * These are not considered tex opcodes here (no additional
+       * target argument) however we're required to set the Texture
+       * bit so we can set the number of tex offsets.
+       */
+      inst.Instruction.Texture = 1;
+      inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
+   }
+
    /* Parse instruction operands.
     */
    for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
@@ -978,6 +1037,19 @@ parse_instruction(
       }
    }
 
+   cur = ctx->cur;
+   eat_opt_white( &cur );
+   for (i = 0; inst.Instruction.Texture && *cur == ','; i++) {
+         cur++;
+         eat_opt_white( &cur );
+         ctx->cur = cur;
+         if (!parse_texoffset_operand( ctx, &inst.TexOffsets[i] ))
+            return FALSE;
+         cur = ctx->cur;
+         eat_opt_white( &cur );
+   }
+   inst.Texture.NumOffsets = i;
+
    cur = ctx->cur;
    eat_opt_white( &cur );
    if (info->is_branch && *cur == ':') {
@@ -1072,7 +1144,6 @@ static boolean parse_declaration( struct translate_ctx *ctx )
    const char *cur, *cur2;
    uint advance;
    boolean is_vs_input;
-   boolean is_imm_array;
 
    if (!eat_white( &ctx->cur )) {
       report_error( ctx, "Syntax error" );
@@ -1100,10 +1171,37 @@ static boolean parse_declaration( struct translate_ctx *ctx )
 
    is_vs_input = (file == TGSI_FILE_INPUT &&
                   ctx->processor == TGSI_PROCESSOR_VERTEX);
-   is_imm_array = (file == TGSI_FILE_IMMEDIATE_ARRAY);
 
    cur = ctx->cur;
    eat_opt_white( &cur );
+   if (*cur == ',') {
+      cur2 = cur;
+      cur2++;
+      eat_opt_white( &cur2 );
+      if (str_match_nocase_whole( &cur2, "ARRAY" )) {
+         int arrayid;
+         if (*cur2 != '(') {
+            report_error( ctx, "Expected `('" );
+            return FALSE;
+         }
+         cur2++;
+         eat_opt_white( &cur2 );
+         if (!parse_int( &cur2, &arrayid )) {
+            report_error( ctx, "Expected `,'" );
+            return FALSE;
+         }
+         eat_opt_white( &cur2 );
+         if (*cur2 != ')') {
+            report_error( ctx, "Expected `)'" );
+            return FALSE;
+         }
+         cur2++;
+         decl.Declaration.Array = 1;
+         decl.Array.ArrayID = arrayid;
+         ctx->cur = cur = cur2;
+      }
+   }
+
    if (*cur == ',' && !is_vs_input) {
       uint i, j;
 
@@ -1160,8 +1258,8 @@ static boolean parse_declaration( struct translate_ctx *ctx )
          ++cur;
          eat_opt_white( &cur );
          for (j = 0; j < 4; ++j) {
-            for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
-               if (str_match_nocase_whole(&cur, tgsi_type_names[i])) {
+            for (i = 0; i < TGSI_RETURN_TYPE_COUNT; ++i) {
+               if (str_match_nocase_whole(&cur, tgsi_return_type_names[i])) {
                   switch (j) {
                   case 0:
                      decl.SamplerView.ReturnTypeX = i;
@@ -1181,7 +1279,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
                   break;
                }
             }
-            if (i == PIPE_TYPE_COUNT) {
+            if (i == TGSI_RETURN_TYPE_COUNT) {
                if (j == 0 || j >  2) {
                   report_error(ctx, "Expected type name");
                   return FALSE;
@@ -1252,44 +1350,6 @@ static boolean parse_declaration( struct translate_ctx *ctx )
             }
          }
       }
-   } else if (is_imm_array) {
-      unsigned i;
-      union tgsi_immediate_data *vals_itr;
-      /* we have our immediate data */
-      if (*cur != '{') {
-         report_error( ctx, "Immediate array without data" );
-         return FALSE;
-      }
-      ++cur;
-      ctx->cur = cur;
-
-      decl.ImmediateData.u =
-         MALLOC(sizeof(union tgsi_immediate_data) * 4 *
-                (decl.Range.Last + 1));
-      vals_itr = decl.ImmediateData.u;
-      for (i = 0; i <= decl.Range.Last; ++i) {
-         if (!parse_immediate_data(ctx, TGSI_IMM_FLOAT32, vals_itr)) {
-            FREE(decl.ImmediateData.u);
-            return FALSE;
-         }
-         vals_itr += 4;
-         eat_opt_white( &ctx->cur );
-         if (*ctx->cur != ',') {
-            if (i !=  decl.Range.Last) {
-               report_error( ctx, "Not enough data in immediate array!" );
-               FREE(decl.ImmediateData.u);
-               return FALSE;
-            }
-         } else
-            ++ctx->cur;
-      }
-      eat_opt_white( &ctx->cur );
-      if (*ctx->cur != '}') {
-         FREE(decl.ImmediateData.u);
-         report_error( ctx, "Immediate array data missing closing '}'" );
-         return FALSE;
-      }
-      ++ctx->cur;
    }
 
    cur = ctx->cur;
@@ -1314,15 +1374,29 @@ static boolean parse_declaration( struct translate_ctx *ctx )
       }
    }
 
+   cur = ctx->cur;
+   eat_opt_white( &cur );
+   if (*cur == ',' && !is_vs_input) {
+      uint i;
+
+      cur++;
+      eat_opt_white( &cur );
+      for (i = 0; i < TGSI_INTERPOLATE_LOC_COUNT; i++) {
+         if (str_match_nocase_whole( &cur, tgsi_interpolate_locations[i] )) {
+            decl.Interp.Location = i;
+
+            ctx->cur = cur;
+            break;
+         }
+      }
+   }
+
    advance = tgsi_build_full_declaration(
       &decl,
       ctx->tokens_cur,
       ctx->header,
       (uint) (ctx->tokens_end - ctx->tokens_cur) );
 
-   if (is_imm_array)
-      FREE(decl.ImmediateData.u);
-
    if (advance == 0)
       return FALSE;
    ctx->tokens_cur += advance;
@@ -1336,6 +1410,31 @@ static boolean parse_immediate( struct translate_ctx *ctx )
    uint advance;
    int type;
 
+   if (*ctx->cur == '[') {
+      uint uindex;
+
+      ++ctx->cur;
+
+      eat_opt_white( &ctx->cur );
+      if (!parse_uint( &ctx->cur, &uindex )) {
+         report_error( ctx, "Expected literal unsigned integer" );
+         return FALSE;
+      }
+
+      if (uindex != ctx->num_immediates) {
+         report_error( ctx, "Immediates must be sorted" );
+         return FALSE;
+      }
+
+      eat_opt_white( &ctx->cur );
+      if (*ctx->cur != ']') {
+         report_error( ctx, "Expected `]'" );
+         return FALSE;
+      }
+
+      ctx->cur++;
+   }
+
    if (!eat_white( &ctx->cur )) {
       report_error( ctx, "Syntax error" );
       return FALSE;
@@ -1363,6 +1462,8 @@ static boolean parse_immediate( struct translate_ctx *ctx )
       return FALSE;
    ctx->tokens_cur += advance;
 
+   ctx->num_immediates++;
+
    return TRUE;
 }
 
@@ -1541,7 +1642,7 @@ tgsi_text_translate(
    struct tgsi_token *tokens,
    uint num_tokens )
 {
-   struct translate_ctx ctx;
+   struct translate_ctx ctx = {0};
 
    ctx.text = text;
    ctx.cur = text;