gallivm: add texture target information for sample opcodes to tgsi info
authorRoland Scheidegger <sroland@vmware.com>
Tue, 16 Sep 2014 01:48:45 +0000 (03:48 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 17 Sep 2014 16:31:54 +0000 (18:31 +0200)
sample opcodes don't have valid texture target information (and I don't think
this should be changed), however it would be nice if we had that information
ready elsewhere, so stuff that information into the tgsi info when analyzing
a shader.

v2: Ilja Mirkin spotted some bugs wrt not handling msaa resources. So add them
and while there also add them to the tex opcode analysis this was cloned from
as well (plus get rid of some bug not detecting indirect textures there in some
cases too).

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c

index 3bbf2603a688bd43a6272859e901488e9e7e22b0..fcaa20143e6a10840b11da0dbee8201e9128d34c 100644 (file)
@@ -48,6 +48,7 @@ struct analysis_context
 
    unsigned num_imms;
    float imm[LP_MAX_TGSI_IMMEDIATES][4];
+   unsigned sample_target[PIPE_MAX_SHADER_SAMPLER_VIEWS];
 
    struct lp_tgsi_channel_info temp[32][4];
 };
@@ -129,29 +130,29 @@ analyse_tex(struct analysis_context *ctx,
       case TGSI_TEXTURE_SHADOW2D:
       case TGSI_TEXTURE_SHADOWRECT:
       case TGSI_TEXTURE_2D_ARRAY:
+      case TGSI_TEXTURE_2D_MSAA:
       case TGSI_TEXTURE_3D:
       case TGSI_TEXTURE_CUBE:
          readmask = TGSI_WRITEMASK_XYZ;
          break;
       case TGSI_TEXTURE_SHADOW2D_ARRAY:
       case TGSI_TEXTURE_SHADOWCUBE:
-         readmask = TGSI_WRITEMASK_XYZW;
-         break;
+      case TGSI_TEXTURE_2D_ARRAY_MSAA:
       case TGSI_TEXTURE_CUBE_ARRAY:
          readmask = TGSI_WRITEMASK_XYZW;
+         /* modifier would be in another not analyzed reg so just say indirect */
+         if (modifier != LP_BLD_TEX_MODIFIER_NONE) {
+            indirect = TRUE;
+         }
          break;
       case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
          readmask = TGSI_WRITEMASK_XYZW;
+         indirect = TRUE;
          break;
       default:
          assert(0);
          return;
       }
-      /* XXX
-       * For cube map arrays, this will not analyze lod or shadow argument.
-       * For shadow cube, this will not analyze lod bias argument.
-       * "Indirect" really has no meaning for such textures anyway though.
-       */
 
       if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
          /* We don't track explicit derivatives, although we could */
@@ -207,17 +208,38 @@ analyse_sample(struct analysis_context *ctx,
 
    if (info->num_texs < Elements(info->tex)) {
       struct lp_tgsi_texture_info *tex_info = &info->tex[info->num_texs];
+      unsigned target = ctx->sample_target[inst->Src[1].Register.Index];
       boolean indirect = FALSE;
       boolean shadow = FALSE;
       unsigned readmask;
 
-      /*
-       * We don't really get much information here, in particular not
-       * the target info, hence no useful writemask neither. Maybe should just
-       * forget the whole function.
-       */
-      readmask = TGSI_WRITEMASK_XYZW;
+      switch (target) {
+      /* note no shadow targets here */
+      case TGSI_TEXTURE_BUFFER:
+      case TGSI_TEXTURE_1D:
+         readmask = TGSI_WRITEMASK_X;
+         break;
+      case TGSI_TEXTURE_1D_ARRAY:
+      case TGSI_TEXTURE_2D:
+      case TGSI_TEXTURE_RECT:
+         readmask = TGSI_WRITEMASK_XY;
+         break;
+      case TGSI_TEXTURE_2D_ARRAY:
+      case TGSI_TEXTURE_2D_MSAA:
+      case TGSI_TEXTURE_3D:
+      case TGSI_TEXTURE_CUBE:
+         readmask = TGSI_WRITEMASK_XYZ;
+         break;
+      case TGSI_TEXTURE_CUBE_ARRAY:
+      case TGSI_TEXTURE_2D_ARRAY_MSAA:
+         readmask = TGSI_WRITEMASK_XYZW;
+         break;
+      default:
+         assert(0);
+         return;
+      }
 
+      tex_info->target = target;
       tex_info->texture_unit = inst->Src[1].Register.Index;
       tex_info->sampler_unit = inst->Src[2].Register.Index;
 
@@ -524,7 +546,14 @@ lp_build_tgsi_info(const struct tgsi_token *tokens,
       tgsi_parse_token(&parse);
 
       switch (parse.FullToken.Token.Type) {
-      case TGSI_TOKEN_TYPE_DECLARATION:
+      case TGSI_TOKEN_TYPE_DECLARATION: {
+         struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
+         if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
+            for (index = decl->Range.First; index <= decl->Range.Last; index++) {
+               ctx->sample_target[index] = decl->SamplerView.Resource;
+            }
+         }
+      }
          break;
 
       case TGSI_TOKEN_TYPE_INSTRUCTION: