tgsi: add properties and system value register
authorZack Rusin <zackr@vmware.com>
Mon, 14 Dec 2009 21:34:07 +0000 (16:34 -0500)
committerZack Rusin <zackr@vmware.com>
Mon, 14 Dec 2009 21:35:09 +0000 (16:35 -0500)
adds support for properties to all parts of the tgsi framework, plus
introduces a new register which will be used for system generated
values.

18 files changed:
src/gallium/auxiliary/tgsi/tgsi_build.c
src/gallium/auxiliary/tgsi/tgsi_build.h
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_dump.h
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_iterate.c
src/gallium/auxiliary/tgsi/tgsi_iterate.h
src/gallium/auxiliary/tgsi/tgsi_parse.c
src/gallium/auxiliary/tgsi/tgsi_parse.h
src/gallium/auxiliary/tgsi/tgsi_ppc.c
src/gallium/auxiliary/tgsi/tgsi_sanity.c
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/auxiliary/tgsi/tgsi_scan.h
src/gallium/auxiliary/tgsi/tgsi_sse2.c
src/gallium/auxiliary/tgsi/tgsi_text.c
src/gallium/auxiliary/tgsi/tgsi_transform.c
src/gallium/auxiliary/tgsi/tgsi_transform.h
src/gallium/include/pipe/p_shader_tokens.h

index 4092f78f4a2abe5f3b42829b6e167223ddfb4943..92903fe57f38f8b6979e553ad2a9ed2be54d4ce9 100644 (file)
@@ -942,3 +942,107 @@ tgsi_default_full_dst_register( void )
    return full_dst_register;
 }
 
+struct tgsi_property
+tgsi_default_property( void )
+{
+   struct tgsi_property property;
+
+   property.Type = TGSI_TOKEN_TYPE_PROPERTY;
+   property.NrTokens = 1;
+   property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
+   property.Padding = 0;
+
+   return property;
+}
+
+struct tgsi_property
+tgsi_build_property(unsigned property_name,
+                    struct tgsi_header *header)
+{
+   struct tgsi_property property;
+
+   property = tgsi_default_property();
+   property.PropertyName = property_name;
+
+   header_bodysize_grow( header );
+
+   return property;
+}
+
+
+struct tgsi_full_property
+tgsi_default_full_property( void )
+{
+   struct tgsi_full_property  full_property;
+
+   full_property.Property  = tgsi_default_property();
+   memset(full_property.u, 0,
+          sizeof(struct tgsi_property_data) * 8);
+
+   return full_property;
+}
+
+static void
+property_grow(
+   struct tgsi_property *property,
+   struct tgsi_header *header )
+{
+   assert( property->NrTokens < 0xFF );
+
+   property->NrTokens++;
+
+   header_bodysize_grow( header );
+}
+
+struct tgsi_property_data
+tgsi_build_property_data(
+   unsigned value,
+   struct tgsi_property *property,
+   struct tgsi_header *header )
+{
+   struct tgsi_property_data property_data;
+
+   property_data.Data = value;
+
+   property_grow( property, header );
+
+   return property_data;
+}
+
+unsigned
+tgsi_build_full_property(
+   const struct tgsi_full_property *full_prop,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   unsigned maxsize )
+{
+   unsigned size = 0, i;
+   struct tgsi_property *property;
+
+   if( maxsize <= size )
+      return 0;
+   property = (struct tgsi_property *) &tokens[size];
+   size++;
+
+   *property = tgsi_build_property(
+      TGSI_PROPERTY_GS_INPUT_PRIM,
+      header );
+
+   assert( full_prop->Property.NrTokens <= 8 + 1 );
+
+   for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
+      struct tgsi_property_data *data;
+
+      if( maxsize <= size )
+         return  0;
+      data = (struct tgsi_property_data *) &tokens[size];
+      size++;
+
+      *data = tgsi_build_property_data(
+         full_prop->u[i].Data,
+         property,
+         header );
+   }
+
+   return size;
+}
index ffea786770c3986efced3ea5ffa14883b349216b..9de2757fe40b9ecc579784a37d3af0f6d2c43c73 100644 (file)
@@ -126,6 +126,34 @@ tgsi_build_full_immediate(
    struct tgsi_header *header,
    unsigned maxsize );
 
+/*
+ * properties
+ */
+
+struct tgsi_property
+tgsi_default_property( void );
+
+struct tgsi_property
+tgsi_build_property(
+   unsigned property_name,
+   struct tgsi_header *header );
+
+struct tgsi_full_property
+tgsi_default_full_property( void );
+
+struct tgsi_property_data
+tgsi_build_property_data(
+   unsigned value,
+   struct tgsi_property *property,
+   struct tgsi_header *header );
+
+unsigned
+tgsi_build_full_property(
+   const struct tgsi_full_property *full_prop,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   unsigned maxsize );
+
 /*
  * instruction
  */
index d09ab925656ce50b08872701bd708e41ed62a2c9..ba1357697d1041da2f4ce643804ef41b94caa59c 100644 (file)
@@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
    "ADDR",
    "IMM",
    "LOOP",
-   "PRED"
+   "PRED",
+   "SV"
 };
 
 static const char *interpolate_names[] =
@@ -149,6 +150,27 @@ static const char *texture_names[] =
    "SHADOWRECT"
 };
 
+static const char *property_names[] =
+{
+   "GS_INPUT_PRIMITIVE",
+   "GS_OUTPUT_PRIMITIVE",
+   "GS_MAX_OUTPUT_VERTICES"
+};
+
+static const char *primitive_names[] =
+{
+   "POINTS",
+   "LINES",
+   "LINE_LOOP",
+   "LINE_STRIP",
+   "TRIANGLES",
+   "TRIANGLE_STRIP",
+   "TRIANGLE_FAN",
+   "QUADS",
+   "QUAD_STRIP",
+   "POLYGON"
+};
+
 
 static void
 _dump_register(
@@ -272,6 +294,50 @@ tgsi_dump_declaration(
    iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl );
 }
 
+static boolean
+iter_property(
+   struct tgsi_iterate_context *iter,
+   struct tgsi_full_property *prop )
+{
+   int i;
+   struct dump_ctx *ctx = (struct dump_ctx *)iter;
+
+   assert(Elements(property_names) == TGSI_PROPERTY_COUNT);
+
+   TXT( "PROPERTY " );
+   ENM(prop->Property.PropertyName, property_names);
+
+   if (prop->Property.NrTokens > 1)
+      TXT(" ");
+
+   for (i = 0; i < prop->Property.NrTokens - 1; ++i) {
+      switch (prop->Property.PropertyName) {
+      case TGSI_PROPERTY_GS_INPUT_PRIM:
+      case TGSI_PROPERTY_GS_OUTPUT_PRIM:
+         ENM(prop->u[i].Data, primitive_names);
+         break;
+      default:
+         SID( prop->u[i].Data );
+         break;
+      }
+      if (i < prop->Property.NrTokens - 2)
+         TXT( ", " );
+   }
+   EOL();
+
+   return TRUE;
+}
+
+void tgsi_dump_property(
+   const struct tgsi_full_property *prop )
+{
+   struct dump_ctx ctx;
+
+   ctx.printf = dump_ctx_printf;
+
+   iter_property( &ctx.iter, (struct tgsi_full_property *)prop );
+}
+
 static boolean
 iter_immediate(
    struct tgsi_iterate_context *iter,
@@ -492,6 +558,7 @@ tgsi_dump(
    ctx.iter.iterate_instruction = iter_instruction;
    ctx.iter.iterate_declaration = iter_declaration;
    ctx.iter.iterate_immediate = iter_immediate;
+   ctx.iter.iterate_property = iter_property;
    ctx.iter.epilog = NULL;
 
    ctx.instno = 0;
@@ -546,6 +613,7 @@ tgsi_dump_str(
    ctx.base.iter.iterate_instruction = iter_instruction;
    ctx.base.iter.iterate_declaration = iter_declaration;
    ctx.base.iter.iterate_immediate = iter_immediate;
+   ctx.base.iter.iterate_property = iter_property;
    ctx.base.iter.epilog = NULL;
 
    ctx.base.instno = 0;
index ad1e647ec9000b0b2956627e4393d3c38c082a5c..4cd27317b36792b5d60e53c8efca3ee5dc51b054 100644 (file)
@@ -49,6 +49,7 @@ tgsi_dump(
 struct tgsi_full_immediate;
 struct tgsi_full_instruction;
 struct tgsi_full_declaration;
+struct tgsi_full_property;
 
 void
 tgsi_dump_immediate(
@@ -63,6 +64,10 @@ void
 tgsi_dump_declaration(
    const struct tgsi_full_declaration *decl );
 
+void
+tgsi_dump_property(
+   const struct tgsi_full_property *prop );
+
 #if defined __cplusplus
 }
 #endif
index 22984c32320e8531895d8a55cb437f28266b21b5..717358620c58ce6da45b05278eb1fbbc26b8c1e1 100644 (file)
@@ -336,6 +336,9 @@ tgsi_exec_machine_bind_shader(
          numInstructions++;
          break;
 
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         break;
+
       default:
          assert( 0 );
       }
@@ -1158,6 +1161,7 @@ fetch_src_file_channel(
          break;
 
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
          chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
          chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
@@ -1302,6 +1306,7 @@ fetch_source(
        */
       switch (reg->Register.File) {
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
          index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
          index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
@@ -1892,7 +1897,8 @@ exec_declaration(struct tgsi_exec_machine *mach,
                  const struct tgsi_full_declaration *decl)
 {
    if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
-      if (decl->Declaration.File == TGSI_FILE_INPUT) {
+      if (decl->Declaration.File == TGSI_FILE_INPUT ||
+          decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
          uint first, last, mask;
 
          first = decl->Range.First;
index 7b384f5e12a44810ba03f11f148def8d4c8f1328..0ba5fe48419bdcd0df467824ac4c996506e11535 100644 (file)
@@ -66,6 +66,12 @@ tgsi_iterate_shader(
                goto fail;
          break;
 
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         if (ctx->iterate_property)
+            if (!ctx->iterate_property( ctx,  &parse.FullToken.FullProperty ))
+               goto fail;
+         break;
+
       default:
          assert( 0 );
       }
index ef5a33ebce9f7464f529a483cc1685cf77c7c381..8d67f22c4295d16a660f55e692e0cb856a9147e2 100644 (file)
@@ -56,6 +56,11 @@ struct tgsi_iterate_context
       struct tgsi_iterate_context *ctx,
       struct tgsi_full_immediate *imm );
 
+   boolean
+   (* iterate_property)(
+      struct tgsi_iterate_context *ctx,
+      struct tgsi_full_property *prop );
+
    boolean
    (* epilog)(
       struct tgsi_iterate_context *ctx );
index 8f2b6a307d38b56829cdf6fcda2d48f5cd258771..fa65ecb99754722924fbaa6a3e22253f086ae8f8 100644 (file)
@@ -220,6 +220,22 @@ tgsi_parse_token(
       break;
    }
 
+   case TGSI_TOKEN_TYPE_PROPERTY:
+   {
+      struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;
+      uint prop_count;
+
+      memset(prop, 0, sizeof *prop);
+      copy_token(&prop->Property, &token);
+
+      prop_count = prop->Property.NrTokens - 1;
+      for (i = 0; i < prop_count; i++) {
+         next_token(ctx, &prop->u[i]);
+      }
+
+      break;
+   }
+
    default:
       assert( 0 );
    }
index 3aa1979a63a5e40a5ecb3706c1535acfd1c0b1ea..439a57269b7ef4e85565b08113d88b08cdb455b9 100644 (file)
@@ -67,6 +67,12 @@ struct tgsi_full_immediate
    union tgsi_immediate_data u[4];
 };
 
+struct tgsi_full_property
+{
+   struct tgsi_property   Property;
+   struct tgsi_property_data u[8];
+};
+
 #define TGSI_FULL_MAX_DST_REGISTERS 2
 #define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
 
@@ -86,6 +92,7 @@ union tgsi_full_token
    struct tgsi_full_declaration  FullDeclaration;
    struct tgsi_full_immediate    FullImmediate;
    struct tgsi_full_instruction  FullInstruction;
+   struct tgsi_full_property     FullProperty;
 };
 
 struct tgsi_parse_context
index da6ad6da04ce7176b5da9abc887aaf48e061921a..138d2d095bb037577148113ccc8a43ee958c5a10 100644 (file)
@@ -293,6 +293,7 @@ emit_fetch(struct gen_context *gen,
    case TGSI_SWIZZLE_W:
       switch (reg->Register.File) {
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          {
             int offset = (reg->Register.Index * 4 + swizzle) * 16;
             int offset_reg = emit_li_offset(gen, offset);
@@ -1173,7 +1174,8 @@ emit_declaration(
    struct ppc_function *func,
    struct tgsi_full_declaration *decl )
 {
-   if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+   if( decl->Declaration.File == TGSI_FILE_INPUT ||
+       decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
 #if 0
       unsigned first, last, mask;
       unsigned i, j;
@@ -1339,6 +1341,9 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
          }
          break;
 
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         break;
+
       default:
         ok = 0;
          assert( 0 );
index b5d1faa897a7297b1186ea2fa920031a2f881b04..c27579e79427270411c36238f6c06c70d34ee935 100644 (file)
@@ -324,6 +324,17 @@ iter_immediate(
    return TRUE;
 }
 
+
+static boolean
+iter_property(
+   struct tgsi_iterate_context *iter,
+   struct tgsi_full_property *prop )
+{
+   /*struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;*/
+
+   return TRUE;
+}
+
 static boolean
 epilog(
    struct tgsi_iterate_context *iter )
@@ -367,6 +378,7 @@ tgsi_sanity_check(
    ctx.iter.iterate_instruction = iter_instruction;
    ctx.iter.iterate_declaration = iter_declaration;
    ctx.iter.iterate_immediate = iter_immediate;
+   ctx.iter.iterate_property = iter_property;
    ctx.iter.epilog = epilog;
 
    memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
index a5d2db04ec1f8f8c2302c024848269ccf3b7115f..5f5c95bfbdb41c2a81f5bed85f0a9b2e9302f8bd 100644 (file)
@@ -97,7 +97,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
                   const struct tgsi_full_src_register *src =
                      &fullinst->Src[i];
-                  if (src->Register.File == TGSI_FILE_INPUT) {
+                  if (src->Register.File == TGSI_FILE_INPUT ||
+                      src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
                      const int ind = src->Register.Index;
                      if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
                         if (src->Register.SwizzleX == TGSI_SWIZZLE_X) {
@@ -128,7 +129,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                info->file_count[file]++;
                info->file_max[file] = MAX2(info->file_max[file], (int)reg);
 
-               if (file == TGSI_FILE_INPUT) {
+               if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) {
                   info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
                   info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
                   info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
@@ -160,6 +161,19 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
             info->file_max[file] = MAX2(info->file_max[file], (int)reg);
          }
          break;
+      case TGSI_TOKEN_TYPE_PROPERTY:
+      {
+         const struct tgsi_full_property *fullprop
+            = &parse.FullToken.FullProperty;
+
+         info->properties[info->num_properties].name =
+            fullprop->Property.PropertyName;
+         memcpy(info->properties[info->num_properties].data,
+                fullprop->u, 8 * sizeof(unsigned));;
+
+         ++info->num_properties;
+      }
+      break;
 
       default:
          assert( 0 );
@@ -212,6 +226,7 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
             /* Do a whole bunch of checks for a simple move */
             if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
                 src->Register.File != TGSI_FILE_INPUT ||
+                src->Register.File != TGSI_FILE_SYSTEM_VALUE ||
                 dst->Register.File != TGSI_FILE_OUTPUT ||
                 src->Register.Index != dst->Register.Index ||
 
@@ -235,6 +250,8 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
          /* fall-through */
       case TGSI_TOKEN_TYPE_IMMEDIATE:
          /* fall-through */
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         /* fall-through */
       default:
          ; /* no-op */
       }
index 8a7ee0c7e4f1f1e2e69f159586f45d0a8cd28018..a1e8a4f6bb7c7072c9f9fc636acd099f66177be6 100644 (file)
@@ -33,7 +33,6 @@
 #include "pipe/p_state.h"
 #include "pipe/p_shader_tokens.h"
 
-
 /**
  * Shader summary info
  */
@@ -61,8 +60,13 @@ struct tgsi_shader_info
    boolean uses_kill;  /**< KIL or KILP instruction used? */
    boolean uses_fogcoord; /**< fragment shader uses fog coord? */
    boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
-};
 
+   struct {
+      unsigned name;
+      unsigned data[8];
+   } properties[TGSI_PROPERTY_COUNT];
+   uint num_properties;
+};
 
 extern void
 tgsi_scan_shader(const struct tgsi_token *tokens,
index 76051ea0d8e0b81a1ff626f713c9b5565603fab4..d63c75dafb37aae87982a6ca48ccbc5805cdf84b 100644 (file)
@@ -1288,6 +1288,7 @@ emit_fetch(
          break;
 
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          emit_inputf(
             func,
             xmm,
@@ -2633,7 +2634,8 @@ emit_declaration(
    struct x86_function *func,
    struct tgsi_full_declaration *decl )
 {
-   if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+   if( decl->Declaration.File == TGSI_FILE_INPUT ||
+       decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
       unsigned first, last, mask;
       unsigned i, j;
 
@@ -2952,6 +2954,9 @@ tgsi_emit_sse2(
             num_immediates++;
          }
          break;
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         /* we just ignore them for now */
+         break;
 
       default:
         ok = 0;
index eb376fa9572c50144996dae3bcc96403307211ad..5a17b9d5d4e314ac4fb5cf9688c5676056b94a62 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "util/u_debug.h"
 #include "util/u_memory.h"
+#include "pipe/p_defines.h"
 #include "tgsi_text.h"
 #include "tgsi_build.h"
 #include "tgsi_info.h"
@@ -110,6 +111,20 @@ static boolean parse_uint( const char **pcur, uint *val )
    return FALSE;
 }
 
+static boolean parse_identifier( const char **pcur, char *ret )
+{
+   const char *cur = *pcur;
+   int i = 0;
+   if (is_alpha_underscore( cur )) {
+      ret[i++] = *cur++;
+      while (is_alpha_underscore( cur ))
+         ret[i++] = *cur++;
+      *pcur = cur;
+      return TRUE;
+   }
+   return FALSE;
+}
+
 /* Parse floating point.
  */
 static boolean parse_float( const char **pcur, float *val )
@@ -229,7 +244,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
    "ADDR",
    "IMM",
    "LOOP",
-   "PRED"
+   "PRED",
+   "SV"
 };
 
 static boolean
@@ -939,6 +955,107 @@ static boolean parse_immediate( struct translate_ctx *ctx )
    return TRUE;
 }
 
+static const char *property_names[] =
+{
+   "GS_INPUT_PRIMITIVE",
+   "GS_OUTPUT_PRIMITIVE",
+   "GS_MAX_OUTPUT_VERTICES"
+};
+
+static const char *primitive_names[] =
+{
+   "POINTS",
+   "LINES",
+   "LINE_LOOP",
+   "LINE_STRIP",
+   "TRIANGLES",
+   "TRIANGLE_STRIP",
+   "TRIANGLE_FAN",
+   "QUADS",
+   "QUAD_STRIP",
+   "POLYGON"
+};
+
+static boolean
+parse_primitive( const char **pcur, uint *primitive )
+{
+   uint i;
+
+   for (i = 0; i < PIPE_PRIM_MAX; i++) {
+      const char *cur = *pcur;
+
+      if (str_match_no_case( &cur, primitive_names[i])) {
+         *primitive = i;
+         *pcur = cur;
+         return TRUE;
+      }
+   }
+   return FALSE;
+}
+
+
+static boolean parse_property( struct translate_ctx *ctx )
+{
+   struct tgsi_full_property prop;
+   uint property_name;
+   uint values[8];
+   uint advance;
+   char id[64];
+
+   if (!eat_white( &ctx->cur )) {
+      report_error( ctx, "Syntax error" );
+      return FALSE;
+   }
+   if (!parse_identifier( &ctx->cur, id )) {
+      report_error( ctx, "Syntax error" );
+      return FALSE;
+   }
+   for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
+        ++property_name) {
+      if (strncasecmp(id, property_names[property_name],
+                      strlen(property_names[property_name]))) {
+         break;
+      }
+   }
+   if (property_name >= TGSI_PROPERTY_COUNT) {
+      debug_printf( "\nError: Unknown property : '%s'", id );
+      return FALSE;
+   }
+
+   eat_opt_white( &ctx->cur );
+   switch(property_name) {
+   case TGSI_PROPERTY_GS_INPUT_PRIM:
+   case TGSI_PROPERTY_GS_OUTPUT_PRIM:
+      if (!parse_primitive(&ctx->cur, &values[0] )) {
+         report_error( ctx, "Unknown primitive name as property!" );
+         return FALSE;
+      }
+      break;
+   default:
+      if (!parse_uint(&ctx->cur, &values[0] )) {
+         report_error( ctx, "Expected unsigned integer as property!" );
+         return FALSE;
+      }
+   }
+
+   prop = tgsi_default_full_property();
+   prop.Property.PropertyName = property_name;
+   prop.Property.NrTokens += 1;
+   prop.u[0].Data = values[0];
+
+   advance = tgsi_build_full_property(
+      &prop,
+      ctx->tokens_cur,
+      ctx->header,
+      (uint) (ctx->tokens_end - ctx->tokens_cur) );
+   if (advance == 0)
+      return FALSE;
+   ctx->tokens_cur += advance;
+
+   return TRUE;
+}
+
+
 static boolean translate( struct translate_ctx *ctx )
 {
    eat_opt_white( &ctx->cur );
@@ -947,7 +1064,6 @@ static boolean translate( struct translate_ctx *ctx )
 
    while (*ctx->cur != '\0') {
       uint label_val = 0;
-
       if (!eat_white( &ctx->cur )) {
          report_error( ctx, "Syntax error" );
          return FALSE;
@@ -955,7 +1071,6 @@ static boolean translate( struct translate_ctx *ctx )
 
       if (*ctx->cur == '\0')
          break;
-
       if (parse_label( ctx, &label_val )) {
          if (!parse_instruction( ctx, TRUE ))
             return FALSE;
@@ -968,6 +1083,10 @@ static boolean translate( struct translate_ctx *ctx )
          if (!parse_immediate( ctx ))
             return FALSE;
       }
+      else if (str_match_no_case( &ctx->cur, "PROPERTY" )) {
+         if (!parse_property( ctx ))
+            return FALSE;
+      }
       else if (!parse_instruction( ctx, FALSE )) {
          return FALSE;
       }
index 8b8f489b355b1b2e9d0d7cfb92c8f5cec491996a..ae875f29abfb23334a42fa5c55d42d6461909455 100644 (file)
@@ -79,6 +79,19 @@ emit_immediate(struct tgsi_transform_context *ctx,
 }
 
 
+static void
+emit_property(struct tgsi_transform_context *ctx,
+              const struct tgsi_full_property *prop)
+{
+   uint ti = ctx->ti;
+
+   ti += tgsi_build_full_property(prop,
+                                  ctx->tokens_out + ti,
+                                  ctx->header,
+                                  ctx->max_tokens_out - ti);
+   ctx->ti = ti;
+}
+
 
 /**
  * Apply user-defined transformations to the input shader to produce
@@ -110,6 +123,7 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
    ctx->emit_instruction = emit_instruction;
    ctx->emit_declaration = emit_declaration;
    ctx->emit_immediate = emit_immediate;
+   ctx->emit_property = emit_property;
    ctx->tokens_out = tokens_out;
    ctx->max_tokens_out = max_tokens_out;
 
@@ -182,6 +196,17 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
                ctx->emit_immediate(ctx, fullimm);
          }
          break;
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         {
+            struct tgsi_full_property *fullprop
+               = &parse.FullToken.FullProperty;
+
+            if (ctx->transform_property)
+               ctx->transform_property(ctx, fullprop);
+            else
+               ctx->emit_property(ctx, fullprop);
+         }
+         break;
 
       default:
          assert( 0 );
index a121adbaef4056fa296fc0f7591dadb72479a176..818478e277a91e8ed55105453578987550965e7f 100644 (file)
@@ -53,6 +53,8 @@ struct tgsi_transform_context
 
    void (*transform_immediate)(struct tgsi_transform_context *ctx,
                                struct tgsi_full_immediate *imm);
+   void (*transform_property)(struct tgsi_transform_context *ctx,
+                              struct tgsi_full_property *prop);
 
    /**
     * Called at end of input program to allow caller to append extra
@@ -73,6 +75,8 @@ struct tgsi_transform_context
                             const struct tgsi_full_declaration *decl);
    void (*emit_immediate)(struct tgsi_transform_context *ctx,
                           const struct tgsi_full_immediate *imm);
+   void (*emit_property)(struct tgsi_transform_context *ctx,
+                         const struct tgsi_full_property *prop);
 
    struct tgsi_header *header;
    uint max_tokens_out;
index 588ca5e026d482c784ee9c7e14890d0b96dfc761..79f3d3f056677e286c73ed9ea9762a49b3cd90d1 100644 (file)
@@ -55,6 +55,7 @@ struct tgsi_processor
 #define TGSI_TOKEN_TYPE_DECLARATION    0
 #define TGSI_TOKEN_TYPE_IMMEDIATE      1
 #define TGSI_TOKEN_TYPE_INSTRUCTION    2
+#define TGSI_TOKEN_TYPE_PROPERTY       3
 
 struct tgsi_token
 {
@@ -64,16 +65,17 @@ struct tgsi_token
 };
 
 enum tgsi_file_type {
-   TGSI_FILE_NULL        =0,
-   TGSI_FILE_CONSTANT    =1,
-   TGSI_FILE_INPUT       =2,
-   TGSI_FILE_OUTPUT      =3,
-   TGSI_FILE_TEMPORARY   =4,
-   TGSI_FILE_SAMPLER     =5,
-   TGSI_FILE_ADDRESS     =6,
-   TGSI_FILE_IMMEDIATE   =7,
-   TGSI_FILE_LOOP        =8,
-   TGSI_FILE_PREDICATE   =9,
+   TGSI_FILE_NULL         =0,
+   TGSI_FILE_CONSTANT     =1,
+   TGSI_FILE_INPUT        =2,
+   TGSI_FILE_OUTPUT       =3,
+   TGSI_FILE_TEMPORARY    =4,
+   TGSI_FILE_SAMPLER      =5,
+   TGSI_FILE_ADDRESS      =6,
+   TGSI_FILE_IMMEDIATE    =7,
+   TGSI_FILE_LOOP         =8,
+   TGSI_FILE_PREDICATE    =9,
+   TGSI_FILE_SYSTEM_VALUE =10,
    TGSI_FILE_COUNT      /**< how many TGSI_FILE_ types */
 };
 
@@ -151,6 +153,22 @@ union tgsi_immediate_data
    float Float;
 };
 
+#define TGSI_PROPERTY_GS_INPUT_PRIM          0
+#define TGSI_PROPERTY_GS_OUTPUT_PRIM         1
+#define TGSI_PROPERTY_GS_MAX_VERTICES        2
+#define TGSI_PROPERTY_COUNT                  3
+
+struct tgsi_property {
+   unsigned Type         : 4;  /**< TGSI_TOKEN_TYPE_PROPERTY */
+   unsigned NrTokens     : 8;  /**< UINT */
+   unsigned PropertyName : 8;  /**< one of TGSI_PROPERTY */
+   unsigned Padding      : 12;
+};
+
+struct tgsi_property_data {
+   unsigned Data;
+};
+
 /* TGSI opcodes.  
  * 
  * For more information on semantics of opcodes and