Mesa (gallium-resource-sampling): gallium: initial implementation of resources and new texture opcodes

Zack Rusin zack at kemper.freedesktop.org
Tue Jun 8 09:19:11 PDT 2010


Module: Mesa
Branch: gallium-resource-sampling
Commit: f60db64f0424cdc5bc073b020a8527a94289d725
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f60db64f0424cdc5bc073b020a8527a94289d725

Author: Zack Rusin <zackr at vmware.com>
Date:   Tue Jun  8 12:12:14 2010 -0400

gallium: initial implementation of resources and new texture opcodes

the idea is to allow arbitrary binding of resources, the way opencl and
dx10+ require. i.e.
DCL RES[0], 2D, FLOAT

LOAD DST[0], SRC[0], RES[0]
SAMPLE DST[0], SRC[0], RES[0], SAMP[0]

the commit implements things interface wise, but the opcodes themselves
are not implemented in softpipe yet.

---

 src/gallium/auxiliary/tgsi/tgsi_build.c      |   57 +++++++++++
 src/gallium/auxiliary/tgsi/tgsi_build.h      |   13 +++
 src/gallium/auxiliary/tgsi/tgsi_dump.c       |   34 +++++++-
 src/gallium/auxiliary/tgsi/tgsi_exec.h       |    1 -
 src/gallium/auxiliary/tgsi/tgsi_info.c       |   15 +++-
 src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h |   17 ++++
 src/gallium/auxiliary/tgsi/tgsi_parse.c      |    4 +
 src/gallium/auxiliary/tgsi/tgsi_parse.h      |    3 +-
 src/gallium/auxiliary/tgsi/tgsi_sanity.c     |    3 +-
 src/gallium/auxiliary/tgsi/tgsi_text.c       |  133 ++++++++++++++++++++-----
 src/gallium/auxiliary/tgsi/tgsi_ureg.c       |   91 +++++++++++++++++-
 src/gallium/auxiliary/tgsi/tgsi_ureg.h       |   69 +++++++++++++
 src/gallium/include/pipe/p_format.h          |   10 ++
 src/gallium/include/pipe/p_shader_tokens.h   |   26 +++++-
 src/gallium/include/pipe/p_state.h           |    1 +
 15 files changed, 442 insertions(+), 35 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 0890078..59e4372 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 #include "util/u_debug.h"
+#include "pipe/p_format.h"
 #include "pipe/p_shader_tokens.h"
 #include "tgsi_build.h"
 #include "tgsi_parse.h"
@@ -164,6 +165,7 @@ tgsi_default_full_declaration( void )
    full_declaration.Declaration  = tgsi_default_declaration();
    full_declaration.Range = tgsi_default_declaration_range();
    full_declaration.Semantic = tgsi_default_declaration_semantic();
+   full_declaration.Resource = tgsi_default_declaration_resource();
 
    return full_declaration;
 }
@@ -235,6 +237,24 @@ tgsi_build_full_declaration(
          header );
    }
 
+   if (full_decl->Declaration.File == TGSI_FILE_RESOURCE) {
+      struct tgsi_declaration_resource *dr;
+
+      if (maxsize <= size) {
+         return  0;
+      }
+      dr = (struct tgsi_declaration_resource *)&tokens[size];
+      size++;
+
+      *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource,
+                                            full_decl->Resource.ReturnTypeX,
+                                            full_decl->Resource.ReturnTypeY,
+                                            full_decl->Resource.ReturnTypeZ,
+                                            full_decl->Resource.ReturnTypeW,
+                                            declaration,
+                                            header);
+   }
+
    return size;
 }
 
@@ -331,6 +351,43 @@ tgsi_build_declaration_semantic(
    return ds;
 }
 
+struct tgsi_declaration_resource
+tgsi_default_declaration_resource(void)
+{
+   struct tgsi_declaration_resource declaration_resource;
+
+   declaration_resource.Resource = TGSI_TEXTURE_UNKNOWN;
+   declaration_resource.ReturnTypeX = PIPE_TYPE_UNORM;
+   declaration_resource.ReturnTypeY = PIPE_TYPE_UNORM;
+   declaration_resource.ReturnTypeZ = PIPE_TYPE_UNORM;
+   declaration_resource.ReturnTypeW = PIPE_TYPE_UNORM;
+
+   return declaration_resource;
+}
+
+struct tgsi_declaration_resource
+tgsi_build_declaration_resource(unsigned texture,
+                                unsigned return_type_x,
+                                unsigned return_type_y,
+                                unsigned return_type_z,
+                                unsigned return_type_w,
+                                struct tgsi_declaration *declaration,
+                                struct tgsi_header *header)
+{
+   struct tgsi_declaration_resource declaration_resource;
+
+   declaration_resource = tgsi_default_declaration_resource();
+   declaration_resource.Resource = texture;
+   declaration_resource.ReturnTypeX = return_type_x;
+   declaration_resource.ReturnTypeY = return_type_y;
+   declaration_resource.ReturnTypeZ = return_type_z;
+   declaration_resource.ReturnTypeW = return_type_w;
+
+   declaration_grow(declaration, header);
+
+   return declaration_resource;
+}
+
 /*
  * immediate
  */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 13d7f52..82db347 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -109,6 +109,19 @@ tgsi_build_declaration_semantic(
    struct tgsi_declaration *declaration,
    struct tgsi_header *header );
 
+struct tgsi_declaration_resource
+tgsi_default_declaration_resource(void);
+
+struct tgsi_declaration_resource
+tgsi_build_declaration_resource(unsigned resource,
+                                unsigned return_type_x,
+                                unsigned return_type_y,
+                                unsigned return_type_z,
+                                unsigned return_type_w,
+                                struct tgsi_declaration *declaration,
+                                struct tgsi_header *header);
+
+
 /*
  * immediate
  */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 3548007..7032e0e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
    "ADDR",
    "IMM",
    "PRED",
-   "SV"
+   "SV",
+   "RES"
 };
 
 static const char *interpolate_names[] =
@@ -154,6 +155,15 @@ static const char *texture_names[] =
    "SHADOWRECT"
 };
 
+static const char *type_names[] =
+{
+   "UNORM",
+   "SNORM",
+   "SINT",
+   "UINT",
+   "FLOAT"
+};
+
 static const char *property_names[] =
 {
    "GS_INPUT_PRIMITIVE",
@@ -326,6 +336,28 @@ iter_declaration(
       }
    }
 
+   if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
+      TXT(", ");
+      ENM(decl->Resource.Resource, texture_names);
+      TXT(", ");
+      if (decl->Resource.ReturnTypeX ==
+          decl->Resource.ReturnTypeY ==
+          decl->Resource.ReturnTypeZ ==
+          decl->Resource.ReturnTypeW)
+         ENM(decl->Resource.ReturnTypeX, type_names);
+      else {
+         TXT(", ");
+         ENM(decl->Resource.ReturnTypeX, type_names);
+         TXT(", ");
+         ENM(decl->Resource.ReturnTypeY, type_names);
+         TXT(", ");
+         ENM(decl->Resource.ReturnTypeZ, type_names);
+         TXT(", ");
+         ENM(decl->Resource.ReturnTypeW, type_names);
+      }
+
+   }
+
    if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT &&
        decl->Declaration.File == TGSI_FILE_INPUT)
    {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 3caf820..d48c38f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -312,7 +312,6 @@ struct tgsi_exec_machine
 
    struct tgsi_full_declaration *Declarations;
    uint NumDeclarations;
-
 };
 
 struct tgsi_exec_machine *
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index e59e964..e420f5b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -175,7 +175,20 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
    { 0, 1, 0, 0, 0, 0, "SWITCH", TGSI_OPCODE_SWITCH },
    { 0, 1, 0, 0, 0, 0, "CASE", TGSI_OPCODE_CASE },
    { 0, 0, 0, 0, 0, 0, "DEFAULT", TGSI_OPCODE_DEFAULT },
-   { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH }
+   { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH },
+
+   { 1, 2, 1, 0, 0, 0, "LOAD",        TGSI_OPCODE_LOAD },
+   { 1, 2, 1, 0, 0, 0, "LOAD_MS",     TGSI_OPCODE_LOAD_MS },
+   { 1, 3, 1, 0, 0, 0, "SAMPLE",      TGSI_OPCODE_SAMPLE },
+   { 1, 4, 1, 0, 0, 0, "SAMPLE_B",    TGSI_OPCODE_SAMPLE_B },
+   { 1, 4, 1, 0, 0, 0, "SAMPLE_C",    TGSI_OPCODE_SAMPLE_C },
+   { 1, 4, 1, 0, 0, 0, "SAMPLE_C_LZ", TGSI_OPCODE_SAMPLE_C_LZ },
+   { 1, 5, 1, 0, 0, 0, "SAMPLE_D",    TGSI_OPCODE_SAMPLE_D },
+   { 1, 3, 1, 0, 0, 0, "SAMPLE_L",    TGSI_OPCODE_SAMPLE_L },
+   { 1, 3, 1, 0, 0, 0, "GATHER4",     TGSI_OPCODE_GATHER4 },
+   { 1, 2, 0, 0, 0, 0, "RESINFO",     TGSI_OPCODE_RESINFO },
+   { 1, 2, 0, 0, 0, 0, "SAMPLE_POS",  TGSI_OPCODE_SAMPLE_POS },
+   { 1, 2, 0, 0, 0, 0, "SAMPLE_INFO", TGSI_OPCODE_SAMPLE_INFO },
 };
 
 const struct tgsi_opcode_info *
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
index e472947..24c6bbd 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -164,6 +164,19 @@ OP12(USHR)
 OP12(USLT)
 OP12(USNE)
 
+OP12(LOAD)
+OP12(LOAD_MS)
+OP13(SAMPLE)
+OP14(SAMPLE_B)
+OP14(SAMPLE_C)
+OP14(SAMPLE_C_LZ)
+OP15(SAMPLE_D)
+OP13(SAMPLE_L)
+OP13(GATHER4)
+OP12(RESINFO)
+OP13(SAMPLE_POS)
+OP12(SAMPLE_INFO)
+
 
 #undef OP00
 #undef OP01
@@ -176,6 +189,10 @@ OP12(USNE)
 #undef OP14
 #endif
 
+#ifdef OP15
+#undef OP15
+#endif
+
 #undef OP00_LBL
 #undef OP01_LBL
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 7e19e1f..f17ea70 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -117,6 +117,10 @@ tgsi_parse_token(
          next_token( ctx, &decl->Semantic );
       }
 
+      if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
+         next_token(ctx, &decl->Resource);
+      }
+
       break;
    }
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index b45ccee..a51fdd4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -60,6 +60,7 @@ struct tgsi_full_declaration
    struct tgsi_declaration_range Range;
    struct tgsi_declaration_dimension Dim;
    struct tgsi_declaration_semantic Semantic;
+   struct tgsi_declaration_resource Resource;
 };
 
 struct tgsi_full_immediate
@@ -75,7 +76,7 @@ struct tgsi_full_property
 };
 
 #define TGSI_FULL_MAX_DST_REGISTERS 2
-#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
+#define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */
 
 struct tgsi_full_instruction
 {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index ce0a92f..aaafa81 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -236,7 +236,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
    "ADDR",
    "IMM",
    "PRED",
-   "SV"
+   "SV",
+   "RES"
 };
 
 static boolean
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 527b7d7..5a26eaa 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -280,7 +280,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
    "ADDR",
    "IMM",
    "PRED",
-   "SV"
+   "SV",
+   "RES"
 };
 
 static boolean
@@ -795,6 +796,15 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] =
    "SHADOWRECT"
 };
 
+static const char *type_names[] =
+{
+   "UNORM",
+   "SNORM",
+   "SINT",
+   "UINT",
+   "FLOAT"
+};
+
 static boolean
 match_inst_mnemonic(const char **pcur,
                     const struct tgsi_opcode_info *info)
@@ -1029,42 +1039,111 @@ static boolean parse_declaration( struct translate_ctx *ctx )
    cur = ctx->cur;
    eat_opt_white( &cur );
    if (*cur == ',' && !is_vs_input) {
-      uint i;
+      uint i, j;
 
       cur++;
       eat_opt_white( &cur );
-      for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
-         if (str_match_no_case( &cur, semantic_names[i] )) {
-            const char *cur2 = cur;
-            uint index;
-
-            if (is_digit_alpha_underscore( cur ))
-               continue;
-            eat_opt_white( &cur2 );
-            if (*cur2 == '[') {
-               cur2++;
-               eat_opt_white( &cur2 );
-               if (!parse_uint( &cur2, &index )) {
-                  report_error( ctx, "Expected literal integer" );
+      if (file == TGSI_FILE_RESOURCE) {
+         debug_printf("RESOURCE!!!!!!!!\n");
+         for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
+            if (str_match_no_case(&cur, texture_names[i])) {
+               if (!is_digit_alpha_underscore(cur)) {
+                  decl.Resource.Resource = i;
+                  break;
+               }
+            }
+         }
+         if (i == TGSI_TEXTURE_COUNT) {
+            report_error(ctx, "Expected texture target");
+            return FALSE;
+         }
+         eat_opt_white( &cur );
+         if (*ctx->cur != ',') {
+            report_error( ctx, "Expected `,'" );
+            return FALSE;
+         }
+         eat_opt_white( &cur );
+         for (j = 0; j < 4; ++j) {
+            for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
+               if (str_match_no_case(&cur, type_names[i])) {
+                  if (!is_digit_alpha_underscore(cur)) {
+                     switch (j) {
+                     case 0:
+                        decl.Resource.ReturnTypeX = i;
+                        break;
+                     case 1:
+                        decl.Resource.ReturnTypeY = i;
+                        break;
+                     case 2:
+                        decl.Resource.ReturnTypeZ = i;
+                        break;
+                     case 3:
+                        decl.Resource.ReturnTypeW = i;
+                        break;
+                     default:
+                        assert(0);
+                     }
+                     break;
+                  }
+               }
+            }
+            if (i == PIPE_TYPE_COUNT) {
+               if (j == 0 || j >  2) {
+                  report_error(ctx, "Expected type name");
                   return FALSE;
                }
-               eat_opt_white( &cur2 );
-               if (*cur2 != ']') {
-                  report_error( ctx, "Expected `]'" );
+               break;
+            } else {
+               eat_opt_white( &ctx->cur );
+               if (*ctx->cur != ',') {
+                  report_error( ctx, "Expected `,'" );
                   return FALSE;
                }
-               cur2++;
-
-               decl.Semantic.Index = index;
-
-               cur = cur2;
+               ctx->cur++;
+               eat_opt_white( &ctx->cur );
             }
+         }
+         if (j < 4) {
+            decl.Resource.ReturnTypeY =
+               decl.Resource.ReturnTypeZ =
+               decl.Resource.ReturnTypeW =
+               decl.Resource.ReturnTypeX;
+         }
+         ctx->cur = cur;
+      } else {
+         for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
+            if (str_match_no_case( &cur, semantic_names[i] )) {
+               const char *cur2 = cur;
+               uint index;
 
-            decl.Declaration.Semantic = 1;
-            decl.Semantic.Name = i;
+               if (is_digit_alpha_underscore( cur ))
+                  continue;
+               eat_opt_white( &cur2 );
+               if (*cur2 == '[') {
+                  cur2++;
+                  eat_opt_white( &cur2 );
+                  if (!parse_uint( &cur2, &index )) {
+                     report_error( ctx, "Expected literal integer" );
+                     return FALSE;
+                  }
+                  eat_opt_white( &cur2 );
+                  if (*cur2 != ']') {
+                     report_error( ctx, "Expected `]'" );
+                     return FALSE;
+                  }
+                  cur2++;
+
+                  decl.Semantic.Index = index;
+
+                  cur = cur2;
+               }
 
-            ctx->cur = cur;
-            break;
+               decl.Declaration.Semantic = 1;
+               decl.Semantic.Name = i;
+
+               ctx->cur = cur;
+               break;
+            }
          }
       }
    }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 5fda808..258ffde 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2009 VMware, Inc.
+ * Copyright 2009-2010 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -47,6 +47,7 @@ union tgsi_any_token {
    struct tgsi_declaration_range decl_range;
    struct tgsi_declaration_dimension decl_dim;
    struct tgsi_declaration_semantic decl_semantic;
+   struct tgsi_declaration_resource decl_resource;
    struct tgsi_immediate imm;
    union  tgsi_immediate_data imm_data;
    struct tgsi_instruction insn;
@@ -136,6 +137,16 @@ struct ureg_program
    struct ureg_src sampler[PIPE_MAX_SAMPLERS];
    unsigned nr_samplers;
 
+   struct {
+      unsigned index;
+      unsigned target;
+      unsigned return_type_x;
+      unsigned return_type_y;
+      unsigned return_type_z;
+      unsigned return_type_w;
+   } resource[PIPE_MAX_SHADER_RESOURCES];
+   unsigned nr_resources;
+
    unsigned temps_active[UREG_MAX_TEMP / 32];
    unsigned nr_temps;
 
@@ -569,6 +580,41 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
    return ureg->sampler[0];
 }
 
+/*
+ * Allocate a new shader resource.
+ */
+struct ureg_src
+ureg_DECL_resource(struct ureg_program *ureg,
+                   unsigned index,
+                   unsigned target,
+                   unsigned return_type_x,
+                   unsigned return_type_y,
+                   unsigned return_type_z,
+                   unsigned return_type_w)
+{
+   struct ureg_src reg = ureg_src_register(TGSI_FILE_RESOURCE, index);
+   uint i;
+
+   for (i = 0; i < ureg->nr_resources; i++) {
+      if (ureg->resource[i].index == index) {
+         return reg;
+      }
+   }
+
+   if (i < PIPE_MAX_SHADER_RESOURCES) {
+      ureg->resource[i].index = index;
+      ureg->resource[i].target = target;
+      ureg->resource[i].return_type_x = return_type_x;
+      ureg->resource[i].return_type_y = return_type_y;
+      ureg->resource[i].return_type_z = return_type_z;
+      ureg->resource[i].return_type_w = return_type_w;
+      ureg->nr_resources++;
+      return reg;
+   }
+
+   assert(0);
+   return reg;
+}
 
 static int
 match_or_expand_immediate( const unsigned *v,
@@ -795,9 +841,10 @@ ureg_emit_dst( struct ureg_program *ureg,
    assert(dst.File != TGSI_FILE_CONSTANT);
    assert(dst.File != TGSI_FILE_INPUT);
    assert(dst.File != TGSI_FILE_SAMPLER);
+   assert(dst.File != TGSI_FILE_RESOURCE);
    assert(dst.File != TGSI_FILE_IMMEDIATE);
    assert(dst.File < TGSI_FILE_COUNT);
-   
+
    out[n].value = 0;
    out[n].dst.File = dst.File;
    out[n].dst.WriteMask = dst.WriteMask;
@@ -1178,6 +1225,36 @@ emit_decl_range2D(struct ureg_program *ureg,
 }
 
 static void
+emit_decl_resource(struct ureg_program *ureg,
+                   unsigned index,
+                   unsigned target,
+                   unsigned return_type_x,
+                   unsigned return_type_y,
+                   unsigned return_type_z,
+                   unsigned return_type_w )
+{
+   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
+
+   out[0].value = 0;
+   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+   out[0].decl.NrTokens = 3;
+   out[0].decl.File = TGSI_FILE_RESOURCE;
+   out[0].decl.UsageMask = 0xf;
+   out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+
+   out[1].value = 0;
+   out[1].decl_range.First = index;
+   out[1].decl_range.Last = index;
+
+   out[2].value = 0;
+   out[2].decl_resource.Resource    = target;
+   out[2].decl_resource.ReturnTypeX = return_type_x;
+   out[2].decl_resource.ReturnTypeY = return_type_y;
+   out[2].decl_resource.ReturnTypeZ = return_type_z;
+   out[2].decl_resource.ReturnTypeW = return_type_w;
+}
+
+static void
 emit_immediate( struct ureg_program *ureg,
                 const unsigned *v,
                 unsigned type )
@@ -1304,6 +1381,16 @@ static void emit_decls( struct ureg_program *ureg )
                        ureg->sampler[i].Index, 1 );
    }
 
+   for (i = 0; i < ureg->nr_resources; i++) {
+      emit_decl_resource(ureg,
+                         ureg->resource[i].index,
+                         ureg->resource[i].target,
+                         ureg->resource[i].return_type_x,
+                         ureg->resource[i].return_type_y,
+                         ureg->resource[i].return_type_z,
+                         ureg->resource[i].return_type_w);
+   }
+
    if (ureg->const_decls.nr_constant_ranges) {
       for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) {
          emit_decl_range(ureg,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 055545f..87a715a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -246,6 +246,15 @@ struct ureg_src
 ureg_DECL_sampler( struct ureg_program *,
                    unsigned index );
 
+struct ureg_src
+ureg_DECL_resource(struct ureg_program *,
+                   unsigned index,
+                   unsigned target,
+                   unsigned return_type_x,
+                   unsigned return_type_y,
+                   unsigned return_type_z,
+                   unsigned return_type_w );
+
 
 static INLINE struct ureg_src
 ureg_imm4f( struct ureg_program *ureg,
@@ -709,6 +718,66 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
 }
 
 
+#define OP14( op )                                                      \
+static INLINE void ureg_##op( struct ureg_program *ureg,                \
+                              struct ureg_dst dst,                      \
+                              struct ureg_src src0,                     \
+                              struct ureg_src src1,                     \
+                              struct ureg_src src2,                     \
+                              struct ureg_src src3 )                    \
+{                                                                       \
+   unsigned opcode = TGSI_OPCODE_##op;                                  \
+   unsigned insn = ureg_emit_insn(ureg,                                 \
+                                  opcode,                               \
+                                  dst.Saturate,                         \
+                                  dst.Predicate,                        \
+                                  dst.PredNegate,                       \
+                                  dst.PredSwizzleX,                     \
+                                  dst.PredSwizzleY,                     \
+                                  dst.PredSwizzleZ,                     \
+                                  dst.PredSwizzleW,                     \
+                                  1,                                    \
+                                  4).insn_token;                        \
+   ureg_emit_dst( ureg, dst );                                          \
+   ureg_emit_src( ureg, src0 );                                         \
+   ureg_emit_src( ureg, src1 );                                         \
+   ureg_emit_src( ureg, src2 );                                         \
+   ureg_emit_src( ureg, src3 );                                         \
+   ureg_fixup_insn_size( ureg, insn );                                  \
+}
+
+
+#define OP15( op )                                                      \
+static INLINE void ureg_##op( struct ureg_program *ureg,                \
+                              struct ureg_dst dst,                      \
+                              struct ureg_src src0,                     \
+                              struct ureg_src src1,                     \
+                              struct ureg_src src2,                     \
+                              struct ureg_src src3,                     \
+                              struct ureg_src src4 )                    \
+{                                                                       \
+   unsigned opcode = TGSI_OPCODE_##op;                                  \
+   unsigned insn = ureg_emit_insn(ureg,                                 \
+                                  opcode,                               \
+                                  dst.Saturate,                         \
+                                  dst.Predicate,                        \
+                                  dst.PredNegate,                       \
+                                  dst.PredSwizzleX,                     \
+                                  dst.PredSwizzleY,                     \
+                                  dst.PredSwizzleZ,                     \
+                                  dst.PredSwizzleW,                     \
+                                  1,                                    \
+                                  5).insn_token;                        \
+   ureg_emit_dst( ureg, dst );                                          \
+   ureg_emit_src( ureg, src0 );                                         \
+   ureg_emit_src( ureg, src1 );                                         \
+   ureg_emit_src( ureg, src2 );                                         \
+   ureg_emit_src( ureg, src3 );                                         \
+   ureg_emit_src( ureg, src4 );                                         \
+   ureg_fixup_insn_size( ureg, insn );                                  \
+}
+
+
 /* Use a template include to generate a correctly-typed ureg_OP()
  * function for each TGSI opcode:
  */
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 436c3f6..788f28b 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -35,6 +35,16 @@
 extern "C" {
 #endif
 
+
+enum pipe_type {
+   PIPE_TYPE_UNORM = 0,
+   PIPE_TYPE_SNORM,
+   PIPE_TYPE_SINT,
+   PIPE_TYPE_UINT,
+   PIPE_TYPE_FLOAT,
+   PIPE_TYPE_COUNT
+};
+
 /**
  * Texture/surface image formats (preliminary)
  */
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 0a70237..a4461eb 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -75,6 +75,7 @@ enum tgsi_file_type {
    TGSI_FILE_IMMEDIATE    =7,
    TGSI_FILE_PREDICATE    =8,
    TGSI_FILE_SYSTEM_VALUE =9,
+   TGSI_FILE_RESOURCE     =10,
    TGSI_FILE_COUNT      /**< how many TGSI_FILE_ types */
 };
 
@@ -152,6 +153,14 @@ struct tgsi_declaration_semantic
    unsigned Padding        : 8;
 };
 
+struct tgsi_declaration_resource {
+   unsigned Resource    : 8; /**< one of TGSI_TEXTURE_ */
+   unsigned ReturnTypeX : 6; /**< one of enum pipe_type */
+   unsigned ReturnTypeY : 6; /**< one of enum pipe_type */
+   unsigned ReturnTypeZ : 6; /**< one of enum pipe_type */
+   unsigned ReturnTypeW : 6; /**< one of enum pipe_type */
+};
+
 #define TGSI_IMM_FLOAT32   0
 #define TGSI_IMM_UINT32    1
 #define TGSI_IMM_INT32     2
@@ -337,7 +346,22 @@ struct tgsi_property_data {
 #define TGSI_OPCODE_CASE                142
 #define TGSI_OPCODE_DEFAULT             143
 #define TGSI_OPCODE_ENDSWITCH           144
-#define TGSI_OPCODE_LAST                145
+
+/* resource related opcodes */
+#define TGSI_OPCODE_LOAD                145
+#define TGSI_OPCODE_LOAD_MS             146
+#define TGSI_OPCODE_SAMPLE              147
+#define TGSI_OPCODE_SAMPLE_B            148
+#define TGSI_OPCODE_SAMPLE_C            149
+#define TGSI_OPCODE_SAMPLE_C_LZ         150
+#define TGSI_OPCODE_SAMPLE_D            151
+#define TGSI_OPCODE_SAMPLE_L            152
+#define TGSI_OPCODE_GATHER4             153
+#define TGSI_OPCODE_RESINFO             154
+#define TGSI_OPCODE_SAMPLE_POS          155
+#define TGSI_OPCODE_SAMPLE_INFO         156
+
+#define TGSI_OPCODE_LAST                157
 
 #define TGSI_SAT_NONE            0  /* do not saturate */
 #define TGSI_SAT_ZERO_ONE        1  /* clamp to [0,1] */
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 5ed1cca..d7a319a 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -60,6 +60,7 @@ extern "C" {
 #define PIPE_MAX_CONSTANT_BUFFERS 32
 #define PIPE_MAX_SAMPLERS         16
 #define PIPE_MAX_VERTEX_SAMPLERS  16
+#define PIPE_MAX_SHADER_RESOURCES 16
 #define PIPE_MAX_SHADER_INPUTS    16
 #define PIPE_MAX_SHADER_OUTPUTS   16
 #define PIPE_MAX_TEXTURE_LEVELS   16



More information about the mesa-commit mailing list