[Mesa-dev] [PATCH v2 2/6] gallium/tgsi: add support for 64-bit integer immediates.

Nicolai Hähnle nhaehnle at gmail.com
Mon Sep 19 13:08:31 UTC 2016


From: Dave Airlie <airlied at redhat.com>

This adds support to TGSI for 64-bit integer immediates.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/auxiliary/tgsi/tgsi_dump.c     | 14 ++++++++++
 src/gallium/auxiliary/tgsi/tgsi_exec.c     |  2 ++
 src/gallium/auxiliary/tgsi/tgsi_parse.c    |  2 ++
 src/gallium/auxiliary/tgsi/tgsi_text.c     | 44 +++++++++++++++++++++++++++++
 src/gallium/auxiliary/tgsi/tgsi_ureg.c     | 45 ++++++++++++++++++++++++++++--
 src/gallium/auxiliary/tgsi/tgsi_ureg.h     | 10 +++++++
 src/gallium/include/pipe/p_shader_tokens.h |  2 ++
 7 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index d59b7ff..614bcb2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -247,20 +247,34 @@ dump_imm_data(struct tgsi_iterate_context *iter,
    assert( num_tokens <= 4 );
    for (i = 0; i < num_tokens; i++) {
       switch (data_type) {
       case TGSI_IMM_FLOAT64: {
          union di d;
          d.ui = data[i].Uint | (uint64_t)data[i+1].Uint << 32;
          DBL( d.d );
          i++;
          break;
       }
+      case TGSI_IMM_INT64: {
+         union di d;
+         d.i = data[i].Uint | (uint64_t)data[i+1].Uint << 32;
+         UID( d.i );
+         i++;
+         break;
+      }
+      case TGSI_IMM_UINT64: {
+         union di d;
+         d.ui = data[i].Uint | (uint64_t)data[i+1].Uint << 32;
+         UID( d.ui );
+         i++;
+         break;
+      }
       case TGSI_IMM_FLOAT32:
          if (ctx->dump_float_as_hex)
             HFLT( data[i].Float );
          else
             FLT( data[i].Float );
          break;
       case TGSI_IMM_UINT32:
          UID(data[i].Uint);
          break;
       case TGSI_IMM_INT32:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index aff35e6..37f3fc7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -70,20 +70,22 @@
 #define FAST_MATH 0
 
 #define TILE_TOP_LEFT     0
 #define TILE_TOP_RIGHT    1
 #define TILE_BOTTOM_LEFT  2
 #define TILE_BOTTOM_RIGHT 3
 
 union tgsi_double_channel {
    double d[TGSI_QUAD_SIZE];
    unsigned u[TGSI_QUAD_SIZE][2];
+   uint64_t u64[TGSI_QUAD_SIZE];
+   int64_t i64[TGSI_QUAD_SIZE];
 };
 
 struct tgsi_double_vector {
    union tgsi_double_channel xy;
    union tgsi_double_channel zw;
 };
 
 static void
 micro_abs(union tgsi_exec_channel *dst,
           const union tgsi_exec_channel *src)
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 16564dd..940af7d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -148,26 +148,28 @@ tgsi_parse_token(
 
       switch (imm->Immediate.DataType) {
       case TGSI_IMM_FLOAT32:
       case TGSI_IMM_FLOAT64:
          for (i = 0; i < imm_count; i++) {
             next_token(ctx, &imm->u[i].Float);
          }
          break;
 
       case TGSI_IMM_UINT32:
+      case TGSI_IMM_UINT64:
          for (i = 0; i < imm_count; i++) {
             next_token(ctx, &imm->u[i].Uint);
          }
          break;
 
       case TGSI_IMM_INT32:
+      case TGSI_IMM_INT64:
          for (i = 0; i < imm_count; i++) {
             next_token(ctx, &imm->u[i].Int);
          }
          break;
 
       default:
          assert( 0 );
       }
 
       break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 8bdec06..be80842 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -288,20 +288,56 @@ static boolean parse_double( const char **pcur, uint32_t *val0, uint32_t *val1)
    v.dval = strtod(cur, (char**)pcur);
    if (*pcur == cur)
       return FALSE;
 
    *val0 = v.uval[0];
    *val1 = v.uval[1];
 
    return TRUE;
 }
 
+static boolean parse_int64( const char **pcur, uint32_t *val0, uint32_t *val1)
+{
+   const char *cur = *pcur;
+   union {
+      int64_t i64val;
+      uint32_t uval[2];
+   } v;
+
+   v.i64val = strtoll(cur, (char**)pcur, 0);
+   if (*pcur == cur)
+      return FALSE;
+
+   *val0 = v.uval[0];
+   *val1 = v.uval[1];
+
+   return TRUE;
+}
+
+static boolean parse_uint64( const char **pcur, uint32_t *val0, uint32_t *val1)
+{
+   const char *cur = *pcur;
+   union {
+      uint64_t u64val;
+      uint32_t uval[2];
+   } v;
+
+   v.u64val = strtoull(cur, (char**)pcur, 0);
+   if (*pcur == cur)
+      return FALSE;
+
+   *val0 = v.uval[0];
+   *val1 = v.uval[1];
+
+   return TRUE;
+}
+
 struct translate_ctx
 {
    const char *text;
    const char *cur;
    struct tgsi_token *tokens;
    struct tgsi_token *tokens_cur;
    struct tgsi_token *tokens_end;
    struct tgsi_header *header;
    unsigned processor : 4;
    unsigned implied_array_size : 6;
@@ -1221,20 +1257,28 @@ static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type,
          }
          ctx->cur++;
          eat_opt_white( &ctx->cur );
       }
 
       switch (type) {
       case TGSI_IMM_FLOAT64:
          ret = parse_double(&ctx->cur, &values[i].Uint, &values[i+1].Uint);
          i++;
          break;
+      case TGSI_IMM_INT64:
+         ret = parse_int64(&ctx->cur, &values[i].Uint, &values[i+1].Uint);
+         i++;
+         break;
+      case TGSI_IMM_UINT64:
+         ret = parse_uint64(&ctx->cur, &values[i].Uint, &values[i+1].Uint);
+         i++;
+         break;
       case TGSI_IMM_FLOAT32:
          ret = parse_float(&ctx->cur, &values[i].Float);
          break;
       case TGSI_IMM_UINT32:
          ret = parse_uint(&ctx->cur, &values[i].Uint);
          break;
       case TGSI_IMM_INT32:
          ret = parse_int(&ctx->cur, &values[i].Int);
          break;
       default:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index b67c383..6ad514d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -785,21 +785,23 @@ static int
 match_or_expand_immediate( const unsigned *v,
                            int type,
                            unsigned nr,
                            unsigned *v2,
                            unsigned *pnr2,
                            unsigned *swizzle )
 {
    unsigned nr2 = *pnr2;
    unsigned i, j;
 
-   if (type == TGSI_IMM_FLOAT64)
+   if (type == TGSI_IMM_FLOAT64 ||
+       type == TGSI_IMM_UINT64 ||
+       type == TGSI_IMM_INT64)
       return match_or_expand_immediate64(v, type, nr, v2, pnr2, swizzle);
 
    *swizzle = 0;
 
    for (i = 0; i < nr; i++) {
       boolean found = FALSE;
 
       for (j = 0; j < nr2 && !found; j++) {
          if (v[i] == v2[j]) {
             *swizzle |= j << (i * 2);
@@ -864,21 +866,23 @@ decl_immediate( struct ureg_program *ureg,
          goto out;
       }
    }
 
    set_bad(ureg);
 
 out:
    /* Make sure that all referenced elements are from this immediate.
     * Has the effect of making size-one immediates into scalars.
     */
-   if (type == TGSI_IMM_FLOAT64) {
+   if (type == TGSI_IMM_FLOAT64 ||
+       type == TGSI_IMM_UINT64 ||
+       type == TGSI_IMM_INT64) {
       for (j = nr; j < 4; j+=2) {
          swizzle |= (swizzle & 0xf) << (j * 2);
       }
    } else {
       for (j = nr; j < 4; j++) {
          swizzle |= (swizzle & 0x3) << (j * 2);
       }
    }
    return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
                        (swizzle >> 0) & 0x3,
@@ -964,20 +968,57 @@ ureg_DECL_immediate_block_uint( struct ureg_program *ureg,
 
 
 struct ureg_src
 ureg_DECL_immediate_int( struct ureg_program *ureg,
                          const int *v,
                          unsigned nr )
 {
    return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);
 }
 
+struct ureg_src
+ureg_DECL_immediate_uint64( struct ureg_program *ureg,
+                            const uint64_t *v,
+                            unsigned nr )
+{
+   union {
+      unsigned u[4];
+      uint64_t u64[2];
+   } fu;
+   unsigned int i;
+
+   assert((nr / 2) < 3);
+   for (i = 0; i < nr / 2; i++) {
+      fu.u64[i] = v[i];
+   }
+
+   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_UINT64);
+}
+
+struct ureg_src
+ureg_DECL_immediate_int64( struct ureg_program *ureg,
+                           const int64_t *v,
+                           unsigned nr )
+{
+   union {
+      unsigned u[4];
+      int64_t i64[2];
+   } fu;
+   unsigned int i;
+
+   assert((nr / 2) < 3);
+   for (i = 0; i < nr / 2; i++) {
+      fu.i64[i] = v[i];
+   }
+
+   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_INT64);
+}
 
 void
 ureg_emit_src( struct ureg_program *ureg,
                struct ureg_src src )
 {
    unsigned size = 1 + (src.Indirect ? 1 : 0) +
                    (src.Dimension ? (src.DimIndirect ? 2 : 1) : 0);
 
    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
    unsigned n = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index b4258fd..c2c2f1a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -264,20 +264,30 @@ ureg_DECL_immediate_uint( struct ureg_program *,
 struct ureg_src
 ureg_DECL_immediate_block_uint( struct ureg_program *,
                                 const unsigned *v,
                                 unsigned nr );
 
 struct ureg_src
 ureg_DECL_immediate_int( struct ureg_program *,
                          const int *v,
                          unsigned nr );
 
+struct ureg_src
+ureg_DECL_immediate_uint64( struct ureg_program *,
+                            const uint64_t *v,
+                            unsigned nr );
+
+struct ureg_src
+ureg_DECL_immediate_int64( struct ureg_program *,
+                           const int64_t *v,
+                           unsigned nr );
+
 void
 ureg_DECL_constant2D(struct ureg_program *ureg,
                      unsigned first,
                      unsigned last,
                      unsigned index2D);
 
 struct ureg_src
 ureg_DECL_constant( struct ureg_program *,
                     unsigned index );
 
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index a8d323a..4a259db 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -238,20 +238,22 @@ struct tgsi_declaration_sampler_view {
 struct tgsi_declaration_array {
    unsigned ArrayID : 10;
    unsigned Padding : 22;
 };
 
 enum tgsi_imm_type {
    TGSI_IMM_FLOAT32,
    TGSI_IMM_UINT32,
    TGSI_IMM_INT32,
    TGSI_IMM_FLOAT64,
+   TGSI_IMM_UINT64,
+   TGSI_IMM_INT64,
 };
 
 struct tgsi_immediate
 {
    unsigned Type       : 4;  /**< TGSI_TOKEN_TYPE_IMMEDIATE */
    unsigned NrTokens   : 14; /**< UINT */
    unsigned DataType   : 4;  /**< one of TGSI_IMM_x */
    unsigned Padding    : 10;
 };
 
-- 
2.7.4



More information about the mesa-dev mailing list