[Mesa-dev] [PATCH 3/8] tgsi: provide a way to encode memory qualifiers for SSBO

Marek Olšák maraeo at gmail.com
Mon Jan 4 04:59:00 PST 2016


On Sun, Jan 3, 2016 at 5:37 AM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> Each load/store on most hardware can specify what caching to do. Since
> SSBO allows individual variables to also have separate caching modes,
> allow loads/stores to have the qualifiers instead of attempting to
> encode them in declarations.
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>  src/gallium/auxiliary/tgsi/tgsi_build.c    | 50 +++++++++++++++++++++++++++-
>  src/gallium/auxiliary/tgsi/tgsi_dump.c     | 10 ++++++
>  src/gallium/auxiliary/tgsi/tgsi_parse.c    |  4 +++
>  src/gallium/auxiliary/tgsi/tgsi_parse.h    |  1 +
>  src/gallium/auxiliary/tgsi/tgsi_strings.c  |  7 ++++
>  src/gallium/auxiliary/tgsi/tgsi_strings.h  |  2 ++
>  src/gallium/auxiliary/tgsi/tgsi_text.c     | 27 +++++++++++++++
>  src/gallium/auxiliary/tgsi/tgsi_ureg.c     | 53 ++++++++++++++++++++++++++++++
>  src/gallium/auxiliary/tgsi/tgsi_ureg.h     | 13 ++++++++
>  src/gallium/include/pipe/p_shader_tokens.h | 16 ++++++++-
>  10 files changed, 181 insertions(+), 2 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
> index bb9d0cb..ea20746 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_build.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
> @@ -620,7 +620,8 @@ tgsi_default_instruction( void )
>     instruction.NumSrcRegs = 1;
>     instruction.Label = 0;
>     instruction.Texture = 0;
> -   instruction.Padding  = 0;
> +   instruction.Memory = 0;
> +   instruction.Padding = 0;
>
>     return instruction;
>  }
> @@ -766,6 +767,34 @@ tgsi_build_instruction_texture(
>     return instruction_texture;
>  }
>
> +static struct tgsi_instruction_memory
> +tgsi_default_instruction_memory( void )
> +{
> +   struct tgsi_instruction_memory instruction_memory;
> +
> +   instruction_memory.Qualifier = 0;
> +   instruction_memory.Padding = 0;
> +
> +   return instruction_memory;
> +}
> +
> +static struct tgsi_instruction_memory
> +tgsi_build_instruction_memory(
> +   unsigned qualifier,
> +   struct tgsi_token *prev_token,
> +   struct tgsi_instruction *instruction,
> +   struct tgsi_header *header )
> +{
> +   struct tgsi_instruction_memory instruction_memory;
> +
> +   instruction_memory.Qualifier = qualifier;
> +   instruction_memory.Padding = 0;
> +   instruction->Memory = 1;
> +
> +   instruction_grow( instruction, header );
> +
> +   return instruction_memory;
> +}
>
>  static struct tgsi_texture_offset
>  tgsi_default_texture_offset( void )
> @@ -1012,6 +1041,7 @@ tgsi_default_full_instruction( void )
>     full_instruction.Predicate = tgsi_default_instruction_predicate();
>     full_instruction.Label = tgsi_default_instruction_label();
>     full_instruction.Texture = tgsi_default_instruction_texture();
> +   full_instruction.Memory = tgsi_default_instruction_memory();
>     for( i = 0;  i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
>        full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
>     }
> @@ -1123,6 +1153,24 @@ tgsi_build_full_instruction(
>           prev_token = (struct tgsi_token *) texture_offset;
>        }
>     }
> +
> +   if (full_inst->Instruction.Memory) {
> +      struct tgsi_instruction_memory *instruction_memory;
> +
> +      if( maxsize <= size )
> +         return 0;
> +      instruction_memory =
> +         (struct  tgsi_instruction_memory *) &tokens[size];
> +      size++;
> +
> +      *instruction_memory = tgsi_build_instruction_memory(
> +         full_inst->Memory.Qualifier,
> +         prev_token,
> +         instruction,
> +         header );
> +      prev_token = (struct tgsi_token  *) instruction_memory;
> +   }
> +
>     for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
>        const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
>        struct tgsi_dst_register *dst_register;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> index de3aae5..2ad29b9 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> @@ -624,6 +624,16 @@ iter_instruction(
>        }
>     }
>
> +   if (inst->Instruction.Memory) {
> +      uint32_t qualifier = inst->Memory.Qualifier;
> +      while (qualifier) {
> +         int bit = ffs(qualifier) - 1;
> +         qualifier &= ~(1U << bit);
> +         TXT(", ");
> +         ENM(bit, tgsi_memory_names);
> +      }
> +   }
> +
>     switch (inst->Instruction.Opcode) {
>     case TGSI_OPCODE_IF:
>     case TGSI_OPCODE_UIF:
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
> index 9a52bbb..ae95ebd 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
> @@ -195,6 +195,10 @@ tgsi_parse_token(
>           }
>        }
>
> +      if (inst->Instruction.Memory) {
> +         next_token(ctx, &inst->Memory);
> +      }
> +
>        assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
>
>        for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
> index 5ed1a83..4689fb7 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
> @@ -91,6 +91,7 @@ struct tgsi_full_instruction
>     struct tgsi_instruction_predicate   Predicate;
>     struct tgsi_instruction_label       Label;
>     struct tgsi_instruction_texture     Texture;
> +   struct tgsi_instruction_memory      Memory;
>     struct tgsi_full_dst_register       Dst[TGSI_FULL_MAX_DST_REGISTERS];
>     struct tgsi_full_src_register       Src[TGSI_FULL_MAX_SRC_REGISTERS];
>     struct tgsi_texture_offset          TexOffsets[TGSI_FULL_MAX_TEX_OFFSETS];
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c
> index c0dd044..f2d70d4 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c
> @@ -208,6 +208,13 @@ const char *tgsi_immediate_type_names[4] =
>     "FLT64"
>  };
>
> +const char *tgsi_memory_names[3] =
> +{
> +   "COHERENT",
> +   "RESTRICT",
> +   "VOLATILE",
> +};
> +
>
>  static inline void
>  tgsi_strings_check(void)
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.h b/src/gallium/auxiliary/tgsi/tgsi_strings.h
> index 71e7437..031d322 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_strings.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.h
> @@ -60,6 +60,8 @@ extern const char *tgsi_fs_coord_pixel_center_names[2];
>
>  extern const char *tgsi_immediate_type_names[4];
>
> +extern const char *tgsi_memory_names[3];
> +
>
>  const char *
>  tgsi_file_name(unsigned file);
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
> index d72d843..97b1869 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_text.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
> @@ -1039,6 +1039,12 @@ parse_instruction(
>        inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
>     }
>
> +   if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) ||
> +       i == TGSI_OPCODE_RESQ) {
> +      inst.Instruction.Memory = 1;
> +      inst.Memory.Qualifier = 0;
> +   }
> +
>     /* Parse instruction operands.
>      */
>     for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
> @@ -1091,6 +1097,27 @@ parse_instruction(
>     inst.Texture.NumOffsets = i;
>
>     cur = ctx->cur;
> +   eat_opt_white(&cur);
> +   for (i = 0; inst.Instruction.Memory && *cur == ','; i++) {
> +      uint j;
> +      cur++;
> +      eat_opt_white(&cur);
> +      ctx->cur = cur;
> +      for (j = 0; j < 3; j++) {
> +         if (str_match_nocase_whole(&ctx->cur, tgsi_memory_names[j])) {
> +            inst.Memory.Qualifier |= 1U << j;
> +            break;
> +         }
> +      }
> +      if (j == 3) {
> +         report_error(ctx, "Expected memory qualifier");
> +         return FALSE;
> +      }
> +      cur = ctx->cur;
> +      eat_opt_white(&cur);
> +   }
> +
> +   cur = ctx->cur;
>     eat_opt_white( &cur );
>     if (info->is_branch && *cur == ':') {
>        uint target;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> index 6d5092b..201ad46 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> @@ -60,6 +60,7 @@ union tgsi_any_token {
>     struct tgsi_instruction_predicate insn_predicate;
>     struct tgsi_instruction_label insn_label;
>     struct tgsi_instruction_texture insn_texture;
> +   struct tgsi_instruction_memory insn_memory;
>     struct tgsi_texture_offset insn_texture_offset;
>     struct tgsi_src_register src;
>     struct tgsi_ind_register ind;
> @@ -1218,6 +1219,22 @@ ureg_emit_texture_offset(struct ureg_program *ureg,
>
>  }
>
> +void
> +ureg_emit_memory(struct ureg_program *ureg,
> +                 unsigned extended_token,
> +                 unsigned qualifier)
> +{
> +   union tgsi_any_token *out, *insn;
> +
> +   out = get_tokens( ureg, DOMAIN_INSN, 1 );
> +   out[0].value = 0;
> +
> +   insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
> +   insn->insn.Memory = 1;
> +
> +   out[0].value = 0;

Doing "out[0].value = 0" twice?

Marek


More information about the mesa-dev mailing list