[Mesa-dev] [PATCH 05/11] gallium/tgsi: Add support for raw resources.

Francisco Jerez currojerez at riseup.net
Thu Mar 22 17:40:34 PDT 2012


Normal resource access (e.g. the LOAD TGSI opcode) is supposed to
perform a series of conversions to turn the texture data as it's found
in memory into the data format that was specified in the resource
declaration.

In compute programs it's often the case that we only want to access
the raw bits as they're stored in some buffer object, and any kind of
channel conversion and scaling is harmful or inefficient, especially
in implementations that lack proper hardware support to take care of
it -- in those cases the conversion has to be implemented in software
and it's likely to result in a performance hit even if the pipe_buffer
and declaration data types are set up in a way that would just pass
the data through.

Add a declaration flag that marks a resource as typeless.  No channel
conversion will be performed in that case, and the X coordinate of the
address vector will be interpreted in byte units instead of elements
for obvious reasons.

This is similar to D3D11's ByteAddressBuffer, and will be used to
implement OpenCL's constant arguments.  The remaining four compute
memory spaces can also be understood as raw resources.
---
 src/gallium/auxiliary/tgsi/tgsi_build.c    |    4 +
 src/gallium/auxiliary/tgsi/tgsi_dump.c     |   27 ++++---
 src/gallium/auxiliary/tgsi/tgsi_text.c     |  114 ++++++++++++++++------------
 src/gallium/docs/source/tgsi.rst           |   31 ++++++--
 src/gallium/include/pipe/p_shader_tokens.h |   10 ++-
 5 files changed, 116 insertions(+), 70 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index f0e0c65..9901479 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -258,6 +258,7 @@ tgsi_default_declaration_resource(void)
    struct tgsi_declaration_resource declaration_resource;
 
    declaration_resource.Resource = TGSI_BUFFER;
+   declaration_resource.Raw = 0;
    declaration_resource.ReturnTypeX = PIPE_TYPE_UNORM;
    declaration_resource.ReturnTypeY = PIPE_TYPE_UNORM;
    declaration_resource.ReturnTypeZ = PIPE_TYPE_UNORM;
@@ -268,6 +269,7 @@ tgsi_default_declaration_resource(void)
 
 static struct tgsi_declaration_resource
 tgsi_build_declaration_resource(unsigned texture,
+                                unsigned raw,
                                 unsigned return_type_x,
                                 unsigned return_type_y,
                                 unsigned return_type_z,
@@ -279,6 +281,7 @@ tgsi_build_declaration_resource(unsigned texture,
 
    declaration_resource = tgsi_default_declaration_resource();
    declaration_resource.Resource = texture;
+   declaration_resource.Raw = raw;
    declaration_resource.ReturnTypeX = return_type_x;
    declaration_resource.ReturnTypeY = return_type_y;
    declaration_resource.ReturnTypeZ = return_type_z;
@@ -414,6 +417,7 @@ tgsi_build_full_declaration(
       size++;
 
       *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource,
+                                            full_decl->Resource.Raw,
                                             full_decl->Resource.ReturnTypeX,
                                             full_decl->Resource.ReturnTypeY,
                                             full_decl->Resource.ReturnTypeZ,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index fc114de..0f1a839 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -285,21 +285,24 @@ iter_declaration(
    if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
       TXT(", ");
       ENM(decl->Resource.Resource, tgsi_texture_names);
-      TXT(", ");
-      if ((decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeY) &&
-          (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeZ) &&
-          (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeW)) {
-         ENM(decl->Resource.ReturnTypeX, tgsi_type_names);
+      if (decl->Resource.Raw) {
+         TXT(", RAW");
       } else {
-         ENM(decl->Resource.ReturnTypeX, tgsi_type_names);
-         TXT(", ");
-         ENM(decl->Resource.ReturnTypeY, tgsi_type_names);
-         TXT(", ");
-         ENM(decl->Resource.ReturnTypeZ, tgsi_type_names);
          TXT(", ");
-         ENM(decl->Resource.ReturnTypeW, tgsi_type_names);
+         if ((decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeY) &&
+             (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeZ) &&
+             (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeW)) {
+            ENM(decl->Resource.ReturnTypeX, tgsi_type_names);
+         } else {
+            ENM(decl->Resource.ReturnTypeX, tgsi_type_names);
+            TXT(", ");
+            ENM(decl->Resource.ReturnTypeY, tgsi_type_names);
+            TXT(", ");
+            ENM(decl->Resource.ReturnTypeZ, tgsi_type_names);
+            TXT(", ");
+            ENM(decl->Resource.ReturnTypeW, tgsi_type_names);
+         }
       }
-
    }
 
    if (decl->Declaration.Interpolate) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 15509f9..1ca2c5d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -1015,7 +1015,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
    struct parsed_dcl_bracket brackets[2];
    int num_brackets;
    uint writemask;
-   const char *cur;
+   const char *cur, *cur2;
    uint advance;
    boolean is_vs_input;
    boolean is_imm_array;
@@ -1069,59 +1069,79 @@ static boolean parse_declaration( struct translate_ctx *ctx )
             return FALSE;
          }
          eat_opt_white( &cur );
-         if (*cur != ',') {
-            report_error( ctx, "Expected `,'" );
-            return FALSE;
+
+         cur2 = cur;
+         while (*cur2 == ',') {
+            cur2++;
+            eat_opt_white(&cur2);
+            if (str_match_no_case(&cur2, "RAW") &&
+                !is_digit_alpha_underscore(cur2)) {
+               decl.Resource.Raw = 1;
+
+            } else {
+               break;
+            }
+            cur = cur2;
+            eat_opt_white(&cur2);
          }
-         ++cur;
-         eat_opt_white( &cur );
-         for (j = 0; j < 4; ++j) {
-            for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
-               if (str_match_no_case(&cur, tgsi_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;
+
+         if (!decl.Resource.Raw) {
+            eat_opt_white(&cur);
+            if (*cur != ',') {
+               report_error( ctx, "Expected `,'" );
+               return FALSE;
+            }
+            ++cur;
+            eat_opt_white( &cur );
+
+            cur2 = cur;
+            for (j = 0; j < 4; ++j) {
+               for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
+                  if (str_match_no_case(&cur2, tgsi_type_names[i])) {
+                     if (!is_digit_alpha_underscore(cur2)) {
+                        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;
-                     default:
-                        assert(0);
                      }
-                     break;
                   }
                }
-            }
-            if (i == PIPE_TYPE_COUNT) {
-               if (j == 0 || j >  2) {
-                  report_error(ctx, "Expected type name");
-                  return FALSE;
-               }
-               break;
-            } else {
-               const char *cur2 = cur;
-               eat_opt_white( &cur2 );
-               if (*cur2 == ',') {
-                  cur2++;
-                  eat_opt_white( &cur2 );
-                  cur = cur2;
-                  continue;
-               } else
+               if (i == PIPE_TYPE_COUNT) {
+                  if (j == 0 || j >  2) {
+                     report_error(ctx, "Expected type name");
+                     return FALSE;
+                  }
                   break;
+               } else {
+                  cur = cur2;
+                  eat_opt_white( &cur2 );
+                  if (*cur2 == ',') {
+                     cur2++;
+                     eat_opt_white( &cur2 );
+                     continue;
+                  } else
+                     break;
+               }
+            }
+            if (j < 4) {
+               decl.Resource.ReturnTypeY =
+                  decl.Resource.ReturnTypeZ =
+                  decl.Resource.ReturnTypeW =
+                  decl.Resource.ReturnTypeX;
             }
-         }
-         if (j < 4) {
-            decl.Resource.ReturnTypeY =
-               decl.Resource.ReturnTypeZ =
-               decl.Resource.ReturnTypeW =
-               decl.Resource.ReturnTypeX;
          }
          ctx->cur = cur;
       } else {
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
index 2132447..ca4559c 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -1334,8 +1334,10 @@ instructions. If in doubt double check Direct3D documentation.
                As such the instruction doesn't honor address wrap
                modes, in cases where that behavior is desirable
                'sample' instruction should be used.
-               address.w always provides an unsigned integer mipmap
-               level. If the value is out of the range then the
+               address.w provides an unsigned integer mipmap level.
+               Its value is always ignored for buffers or raw
+               resources, and the first mipmap level is used
+               instead. If the value is out of the range then the
                instruction always returns 0 in all components.
                address.yz are ignored for buffers and 1d textures.
                address.z is ignored for 1d texture arrays and 2d
@@ -1361,8 +1363,8 @@ instructions. If in doubt double check Direct3D documentation.
                PIPE_TEXTURE_1D_ARRAY x    idx           mpl
                PIPE_TEXTURE_2D_ARRAY x     y    idx     mpl
 
-               Where 'mpl' is a mipmap level and 'idx' is the
-               array index.
+               Where 'mpl' is a mipmap level (ignored for raw
+               resources) and 'idx' is the array index.
 
 
 .. opcode:: LOAD_MS - Just like LOAD but allows fetch data from
@@ -1701,7 +1703,7 @@ Declaration Resource
 
    Follows Declaration token if file is TGSI_FILE_RESOURCE.
 
-   DCL RES[#], resource, type(s)
+   DCL RES[#], resource [, RAW] [, type(s)]
 
    Declares a shader input resource and assigns it to a RES[#]
    register.
@@ -1709,8 +1711,23 @@ Declaration Resource
    resource can be one of BUFFER, 1D, 2D, 3D, CUBE, 1DArray and
    2DArray.
 
-   type must be 1 or 4 entries (if specifying on a per-component
-   level) out of UNORM, SNORM, SINT, UINT and FLOAT.
+   If the RAW keyword is not specified, type must be 1 or 4 entries
+   (if specifying on a per-component level) out of UNORM, SNORM, SINT,
+   UINT and FLOAT.  In this case the texture data will be subject to
+   conversion, swizzling and scaling as required to yield the
+   specified data type from the physical data format of the bound
+   resource.
+
+   If the RAW keyword is specified no types may be provided.  In this
+   case no channel conversion will be performed: the values read for
+   each of the channels (X,Y,Z,W) will correspond to consecutive words
+   in the same order and format they're found in memory.  No
+   element-to-address conversion will be performed either: the value
+   of the provided X coordinate will be interpreted in byte units
+   instead of texel units.  The result of accessing a misaligned
+   address is undefined.
+
+   Usage of the SAMPLE opcodes is not allowed on raw resources.
 
 
 Properties
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 3c6441d..bdcd164 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -168,10 +168,12 @@ struct tgsi_declaration_semantic
 
 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 */
+   unsigned Raw         : 1;
+   unsigned ReturnTypeX : 3; /**< one of enum pipe_type */
+   unsigned ReturnTypeY : 3; /**< one of enum pipe_type */
+   unsigned ReturnTypeZ : 3; /**< one of enum pipe_type */
+   unsigned ReturnTypeW : 3; /**< one of enum pipe_type */
+   unsigned Padding     : 11;
 };
 
 /*
-- 
1.7.9.2



More information about the mesa-dev mailing list