[virglrenderer-devel] [PATCH 08/12] arb_gpu_shader5: add support for interpolation instructions

Gurchetan Singh gurchetansingh at chromium.org
Wed May 16 03:42:43 UTC 2018


On Mon, May 14, 2018 at 9:38 PM Dave Airlie <airlied at gmail.com> wrote:

> From: Dave Airlie <airlied at redhat.com>

> ---
>     src/vrend_shader.c | 95
+++++++++++++++++++++++++++++++++++++++++++++---------
>     src/vrend_shader.h |  1 +
>     2 files changed, 80 insertions(+), 16 deletions(-)

> diff --git a/src/vrend_shader.c b/src/vrend_shader.c
> index 2585155..2161766 100644
> --- a/src/vrend_shader.c
> +++ b/src/vrend_shader.c
> @@ -37,7 +37,7 @@ extern int vrend_dump_shaders;

>     /* start convert of tgsi to glsl */

> -#define INTERP_PREFIX "               "
> +#define INTERP_PREFIX "                           "
>     #define INVARI_PREFIX "invariant"

>     struct vrend_shader_io {
> @@ -153,6 +153,7 @@ struct dump_ctx {
>        bool uses_sample_shading;
>        bool uses_gpu_shader5;
>        bool write_mul_temp;
> +   bool write_interp_temp;
>     };

>     static inline const char *tgsi_proc_to_prefix(int shader_type)
> @@ -272,6 +273,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
>           ctx->inputs[i].name = decl->Semantic.Name;
>           ctx->inputs[i].sid = decl->Semantic.Index;
>           ctx->inputs[i].interpolate = decl->Interp.Interpolate;
> +      ctx->inputs[i].centroid = decl->Interp.Location ==
TGSI_INTERPOLATE_LOC_CENTROID;
>           ctx->inputs[i].first = decl->Range.First;
>           ctx->inputs[i].glsl_predefined_no_emit = false;
>           ctx->inputs[i].glsl_no_index = false;
> @@ -1632,6 +1634,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
>        bool override_no_wm[4];
>        bool dst_override_no_wm[2];
>        char *sret;
> +   char interpSrc0[255], interpSwizzle0[10];
>        int ret;
>        bool tg4_has_component = false;
>        if (ctx->prog_type == -1)
> @@ -1812,8 +1815,18 @@ iter_instruction(struct tgsi_iterate_context *iter,
>                       if (stype == TGSI_TYPE_UNSIGNED &&
>                           ctx->inputs[j].is_int)
>                          srcstypeprefix = "";
> -                  snprintf(srcs[i], 255, "%s(%s%s%s%s)",
> -                           srcstypeprefix, prefix,
ctx->inputs[j].glsl_name, arrayname, ctx->inputs[j].is_int ? "" : swizzle);
> +
> +                  if (inst->Instruction.Opcode ==
TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
> +                     snprintf(srcs[i], 255, "floatBitsToInt(%s%s%s%s)",
prefix, ctx->inputs[j].glsl_name, arrayname, swizzle);
> +                  }






else
> +                     snprintf(srcs[i], 255, "%s(%s%s%s%s)",
srcstypeprefix, prefix, ctx->inputs[j].glsl_name, arrayname,
ctx->inputs[j].is_int ? "" : swizzle);
> +               }
> +               if ((inst->Instruction.Opcode ==
TGSI_OPCODE_INTERP_SAMPLE ||
> +                    inst->Instruction.Opcode ==
TGSI_OPCODE_INTERP_OFFSET ||
> +                    inst->Instruction.Opcode ==
TGSI_OPCODE_INTERP_CENTROID) &&
> +                   i == 0) {
> +                  snprintf(interpSrc0, 255, "%s",
ctx->inputs[j].glsl_name);
> +                  snprintf(interpSwizzle0, 10, "%s", swizzle);
>                    }
>                    override_no_wm[i] = ctx->inputs[j].override_no_wm;
>                    break;
> @@ -1823,6 +1836,11 @@ iter_instruction(struct tgsi_iterate_context *iter,
>              struct vrend_temp_range *range = find_temp_range(ctx,
src->Register.Index);
>              if (!range)
>                 return FALSE;
> +         if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i
== 1) {
> +            stprefix = true;
> +            stypeprefix = "floatBitsToInt";
> +         }
> +
>              if (src->Register.Indirect) {
>                 snprintf(srcs[i], 255, "%s%c%stemp%d[addr0 + %d]%s%c",
stypeprefix, stprefix ? '(' : ' ', prefix, range->first,
src->Register.Index - range->first, swizzle, stprefix ? ')' : ' ');
>              } else
> @@ -1839,7 +1857,9 @@ iter_instruction(struct tgsi_iterate_context *iter,
>              } else {
>                 const char *csp;
>                 ctx->has_ints = true;
> -            if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED)
> +            if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE &&
i == 1)
> +               csp = "ivec4";
> +            else if (stype == TGSI_TYPE_FLOAT || stype ==
TGSI_TYPE_UNTYPED)
>                    csp = "uintBitsToFloat";
>                 else if (stype == TGSI_TYPE_SIGNED)
>                    csp = "ivec4";
> @@ -1866,7 +1886,8 @@ iter_instruction(struct tgsi_iterate_context *iter,
>              const char *vtype = "vec4";
>              const char *imm_stypeprefix = stypeprefix;

> -         if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1))
> +         if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1) ||
> +             (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i
== 1))
>                 stype = TGSI_TYPE_SIGNED;

>              if (imd->type == TGSI_IMM_UINT32 || imd->type ==
TGSI_IMM_INT32) {
> @@ -2343,6 +2364,30 @@ iter_instruction(struct tgsi_iterate_context *iter,
>           EMIT_BUF_WITH_RET(ctx, buf);
>           break;
>        }
> +   case TGSI_OPCODE_INTERP_CENTROID:
> +      snprintf(buf, 255, "interp_temp = interpolateAtCentroid(%s);\n",
interpSrc0);
> +      EMIT_BUF_WITH_RET(ctx, buf);
> +      snprintf(buf, 255, "%s = %s(%s(interp_temp%s));\n", dsts[0],
dstconv, dtypeprefix, interpSwizzle0);

Why is an interp_temp needed?  Also, shouldn't the destination write-mask
also work (that's what's used for other functions):

%s = %s(%s(interpolateAtCentroid(%s)%s));\n", dsts[0], dstconv,
dtypeprefix, srcs[0], writemask);

If that doesn't work, it's probably better to name it src_swizzle[0] if
other instructions need that information.


> +      EMIT_BUF_WITH_RET(ctx, buf);
> +      ctx->write_interp_temp = true;
> +      ctx->uses_gpu_shader5 = true;
> +      break;
> +   case TGSI_OPCODE_INTERP_SAMPLE:
> +      snprintf(buf, 255, "interp_temp = interpolateAtSample(%s,
%s.x);\n", interpSrc0, srcs[1]);
> +      EMIT_BUF_WITH_RET(ctx, buf);
> +      snprintf(buf, 255, "%s = %s(%s(interp_temp%s));\n", dsts[0],
dstconv, dtypeprefix, interpSwizzle0);
> +      EMIT_BUF_WITH_RET(ctx, buf);
> +      ctx->write_interp_temp = true;
> +      ctx->uses_gpu_shader5 = true;
> +      break;
> +   case TGSI_OPCODE_INTERP_OFFSET:
> +      snprintf(buf, 255, "interp_temp = interpolateAtOffset(%s,
%s.xy);\n", interpSrc0, srcs[1]);
> +      EMIT_BUF_WITH_RET(ctx, buf);
> +      snprintf(buf, 255, "%s = %s(%s(interp_temp%s));\n", dsts[0],
dstconv, dtypeprefix, interpSwizzle0);
> +      EMIT_BUF_WITH_RET(ctx, buf);
> +      ctx->write_interp_temp = true;
> +      ctx->uses_gpu_shader5 = true;
> +      break;
>        case TGSI_OPCODE_UMUL_HI:
>           snprintf(buf, 255, "umulExtended(%s, %s, umul_temp,
mul_temp);\n",
srcs[0], srcs[1]);
>           EMIT_BUF_WITH_RET(ctx, buf);
> @@ -2541,13 +2586,20 @@ static const char *get_interp_string(struct
vrend_shader_cfg *cfg, int interpola
>        }
>     }

> +static const char *get_aux_string(struct vrend_shader_cfg *cfg, bool
centroid)
> +{
> +   return centroid ? "centroid " : "";
> +}
> +
>     static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
>     {
>        int i;
>        char buf[255];
>        char postfix[8];
> -   const char *prefix = "";
> +   const char *prefix = "", *auxprefix = "";
>        bool fcolor_emitted[2], bcolor_emitted[2];
> +   int nsamp;
> +   const char *sname = tgsi_proc_to_prefix(ctx->prog_type);
>        ctx->num_interps = 0;

>        if (ctx->so && ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
> @@ -2595,6 +2647,7 @@ static char *emit_ios(struct dump_ctx *ctx, char
*glsl_hdr)
>                 prefix = get_interp_string(ctx->cfg,
ctx->inputs[i].interpolate, ctx->key->flatshade);
>                 if (!prefix)
>                    prefix = "";
> +            auxprefix = get_aux_string(ctx->cfg,
ctx->inputs[i].centroid);
>                 ctx->num_interps++;
>              }

> @@ -2602,7 +2655,7 @@ static char *emit_ios(struct dump_ctx *ctx, char
*glsl_hdr)
>                 snprintf(postfix, 8, "[%d]",
gs_input_prim_to_size(ctx->gs_in_prim));
>              } else
>                 postfix[0] = 0;
> -         snprintf(buf, 255, "%sin vec4 %s%s;\n", prefix,
ctx->inputs[i].glsl_name, postfix);
> +         snprintf(buf, 255, "%s%sin vec4 %s%s;\n", prefix, auxprefix,
ctx->inputs[i].glsl_name, postfix);
>              STRCAT_WITH_RET(glsl_hdr, buf);
>           }
>        }
> @@ -2775,6 +2828,11 @@ static char *emit_ios(struct dump_ctx *ctx, char
*glsl_hdr)
>           STRCAT_WITH_RET(glsl_hdr, buf);
>        }

> +   if (ctx->write_interp_temp) {
> +      snprintf(buf, 255, "vec4 interp_temp;\n");
> +      STRCAT_WITH_RET(glsl_hdr, buf);
> +   }
> +
>        for (i = 0; i < ctx->num_address; i++) {
>           snprintf(buf, 255, "int addr%d;\n", i);
>           STRCAT_WITH_RET(glsl_hdr, buf);
> @@ -2870,6 +2928,7 @@ static boolean fill_fragment_interpolants(struct
dump_ctx *ctx, struct vrend_sha
>           sinfo->interpinfo[index].semantic_name = ctx->inputs[i].name;
>           sinfo->interpinfo[index].semantic_index = ctx->inputs[i].sid;
>           sinfo->interpinfo[index].interpolate =
ctx->inputs[i].interpolate;
> +      sinfo->interpinfo[index].centroid = ctx->inputs[i].centroid;
>           index++;
>        }
>        return TRUE;
> @@ -3000,7 +3059,7 @@ char *vrend_convert_shader(struct vrend_shader_cfg
*cfg,

>     static void replace_interp(char *program,
>                                const char *var_name,
> -                           const char *pstring)
> +                           const char *pstring, const char *auxstring)
>     {
>        char *ptr;
>        int mylen = strlen(INTERP_PREFIX) + strlen("out vec4 ");
> @@ -3012,7 +3071,9 @@ static void replace_interp(char *program,

>        ptr -= mylen;

> +   memset(ptr, ' ', strlen(INTERP_PREFIX));
>        memcpy(ptr, pstring, strlen(pstring));
> +   memcpy(ptr + strlen(pstring), auxstring, strlen(auxstring));
>     }

>     bool vrend_patch_vertex_shader_interpolants(struct vrend_shader_cfg
*cfg, char *program,
> @@ -3020,7 +3081,7 @@ bool vrend_patch_vertex_shader_interpolants(struct
vrend_shader_cfg *cfg, char *
>                                                 struct vrend_shader_info
*fs_info, const char *oprefix, bool flatshade)
>     {
>        int i;
> -   const char *pstring;
> +   const char *pstring, *auxstring;
>        char glsl_name[64];
>        if (!vs_info || !fs_info)
>           return true;
> @@ -3033,27 +3094,29 @@ bool
vrend_patch_vertex_shader_interpolants(struct vrend_shader_cfg *cfg, char *
>           if (!pstring)
>              continue;

> +      auxstring = get_aux_string(cfg, fs_info->interpinfo[i].centroid);
> +
>           switch (fs_info->interpinfo[i].semantic_name) {
>           case TGSI_SEMANTIC_COLOR:
>              /* color is a bit trickier */
>              if (fs_info->glsl_ver < 140) {
>                 if (fs_info->interpinfo[i].semantic_index == 1) {
> -               replace_interp(program, "gl_FrontSecondaryColor",
pstring);
> -               replace_interp(program, "gl_BackSecondaryColor", pstring);
> +               replace_interp(program, "gl_FrontSecondaryColor",
pstring, auxstring);
> +               replace_interp(program, "gl_BackSecondaryColor", pstring,
auxstring);
>                 } else {
> -               replace_interp(program, "gl_FrontColor", pstring);
> -               replace_interp(program, "gl_BackColor", pstring);
> +               replace_interp(program, "gl_FrontColor", pstring,
auxstring);
> +               replace_interp(program, "gl_BackColor", pstring,
auxstring);
>                 }
>              } else {
>                 snprintf(glsl_name, 64, "ex_c%d",
fs_info->interpinfo[i].semantic_index);
> -            replace_interp(program, glsl_name, pstring);
> +            replace_interp(program, glsl_name, pstring, auxstring);
>                 snprintf(glsl_name, 64, "ex_bc%d",
fs_info->interpinfo[i].semantic_index);
> -            replace_interp(program, glsl_name, pstring);
> +            replace_interp(program, glsl_name, pstring, auxstring);
>              }
>              break;
>           case TGSI_SEMANTIC_GENERIC:
>              snprintf(glsl_name, 64, "%s_g%d", oprefix,
fs_info->interpinfo[i].semantic_index);
> -         replace_interp(program, glsl_name, pstring);
> +         replace_interp(program, glsl_name, pstring, auxstring);
>              break;
>           default:
>              fprintf(stderr,"unhandled semantic: %x\n",
fs_info->interpinfo[i].semantic_name);
> diff --git a/src/vrend_shader.h b/src/vrend_shader.h
> index 681bfe2..230a3c1 100644
> --- a/src/vrend_shader.h
> +++ b/src/vrend_shader.h
> @@ -32,6 +32,7 @@ struct vrend_interp_info {
>        int semantic_name;
>        int semantic_index;
>        int interpolate;
> +   bool centroid;
>     };

>     struct vrend_shader_info {
> --
> 2.14.3

> _______________________________________________
> virglrenderer-devel mailing list
> virglrenderer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel


More information about the virglrenderer-devel mailing list