X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fgallivm%2Flp_bld_tgsi_info.c;h=55acea8379993109d5514b955fb262d198f4adff;hb=259ec77db9027ddc33b290010167c712c925a82d;hp=ad514463de08da05f0fbb5ce8f34d2610ee9c13e;hpb=dbf3a15313eed930a3d8fdde12e457259c43651b;p=mesa.git diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c index ad514463de0..55acea83799 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c @@ -31,6 +31,7 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_strings.h" #include "lp_bld_debug.h" #include "lp_bld_tgsi.h" @@ -46,7 +47,8 @@ struct analysis_context struct lp_tgsi_info *info; unsigned num_imms; - float imm[32][4]; + float imm[LP_MAX_TGSI_IMMEDIATES][4]; + unsigned sample_target[PIPE_MAX_SHADER_SAMPLER_VIEWS]; struct lp_tgsi_channel_info temp[32][4]; }; @@ -95,6 +97,11 @@ is_immediate(const struct lp_tgsi_channel_info *chan_info, float value) } +/** + * Analyse properties of tex instructions, in particular used + * to figure out if a texture is considered indirect. + * Not actually used by much except the tgsi dumping code. + */ static void analyse_tex(struct analysis_context *ctx, const struct tgsi_full_instruction *inst, @@ -105,7 +112,7 @@ analyse_tex(struct analysis_context *ctx, if (info->num_texs < Elements(info->tex)) { struct lp_tgsi_texture_info *tex_info = &info->tex[info->num_texs]; - bool indirect = FALSE; + boolean indirect = FALSE; unsigned readmask = 0; tex_info->target = inst->Texture.Texture; @@ -113,17 +120,35 @@ analyse_tex(struct analysis_context *ctx, 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_SHADOW1D: + case TGSI_TEXTURE_SHADOW1D_ARRAY: 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: + 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; @@ -132,14 +157,101 @@ analyse_tex(struct analysis_context *ctx, if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) { /* We don't track explicit derivatives, although we could */ indirect = TRUE; - tex_info->unit = inst->Src[3].Register.Index; + tex_info->sampler_unit = inst->Src[3].Register.Index; + tex_info->texture_unit = inst->Src[3].Register.Index; } else { if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED || modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS || modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) { readmask |= TGSI_WRITEMASK_W; } - tex_info->unit = inst->Src[1].Register.Index; + tex_info->sampler_unit = inst->Src[1].Register.Index; + tex_info->texture_unit = inst->Src[1].Register.Index; + } + + for (chan = 0; chan < 4; ++chan) { + struct lp_tgsi_channel_info *chan_info = &tex_info->coord[chan]; + if (readmask & (1 << chan)) { + analyse_src(ctx, chan_info, &inst->Src[0].Register, chan); + if (chan_info->file != TGSI_FILE_INPUT) { + indirect = TRUE; + } + } else { + memset(chan_info, 0, sizeof *chan_info); + } + } + + if (indirect) { + info->indirect_textures = TRUE; + } + + ++info->num_texs; + } else { + info->indirect_textures = TRUE; + } +} + + +/** + * Analyse properties of sample instructions, in particular used + * to figure out if a texture is considered indirect. + * Not actually used by much except the tgsi dumping code. + */ +static void +analyse_sample(struct analysis_context *ctx, + const struct tgsi_full_instruction *inst, + enum lp_build_tex_modifier modifier, + boolean shadow) +{ + struct lp_tgsi_info *info = ctx->info; + unsigned chan; + + 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; + + 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; + + if (tex_info->texture_unit != tex_info->sampler_unit) { + info->sampler_texture_units_different = TRUE; + } + + if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV || + modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD || + modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS || shadow) { + /* We don't track insts with additional regs, although we could */ + indirect = TRUE; } for (chan = 0; chan < 4; ++chan) { @@ -221,6 +333,33 @@ analyse_instruction(struct analysis_context *ctx, case TGSI_OPCODE_TXP: analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_PROJECTED); break; + case TGSI_OPCODE_TEX2: + analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_NONE); + break; + case TGSI_OPCODE_TXB2: + analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS); + break; + case TGSI_OPCODE_TXL2: + analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD); + break; + case TGSI_OPCODE_SAMPLE: + analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_NONE, FALSE); + break; + case TGSI_OPCODE_SAMPLE_C: + analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_NONE, TRUE); + break; + case TGSI_OPCODE_SAMPLE_C_LZ: + analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_LOD_ZERO, TRUE); + break; + case TGSI_OPCODE_SAMPLE_D: + analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV, FALSE); + break; + case TGSI_OPCODE_SAMPLE_B: + analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, FALSE); + break; + case TGSI_OPCODE_SAMPLE_L: + analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, FALSE); + break; default: break; } @@ -296,7 +435,7 @@ analyse_instruction(struct analysis_context *ctx, switch (inst->Instruction.Opcode) { case TGSI_OPCODE_IF: - case TGSI_OPCODE_IFC: + case TGSI_OPCODE_UIF: case TGSI_OPCODE_ELSE: case TGSI_OPCODE_ENDIF: case TGSI_OPCODE_BGNLOOP: @@ -340,15 +479,16 @@ dump_info(const struct tgsi_token *tokens, &tex_info->coord[chan]; if (chan_info->file != TGSI_FILE_NULL) { debug_printf(" %s[%u].%c", - tgsi_file_names[chan_info->file], + tgsi_file_name(chan_info->file), chan_info->u.index, "xyzw01"[chan_info->swizzle]); } else { debug_printf(" _"); } } - debug_printf(", SAMP[%u], %s\n", - tex_info->unit, + debug_printf(", RES[%u], SAMP[%u], %s\n", + tex_info->texture_unit, + tex_info->sampler_unit, tgsi_texture_names[tex_info->target]); } @@ -393,7 +533,7 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, struct lp_tgsi_info *info) { struct tgsi_parse_context parse; - struct analysis_context ctx; + struct analysis_context *ctx; unsigned index; unsigned chan; @@ -401,8 +541,8 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, tgsi_scan_shader(tokens, &info->base); - memset(&ctx, 0, sizeof ctx); - ctx.info = info; + ctx = CALLOC(1, sizeof(struct analysis_context)); + ctx->info = info; tgsi_parse_init(&parse, tokens); @@ -410,7 +550,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: @@ -424,7 +571,7 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, goto finished; } - analyse_instruction(&ctx, inst); + analyse_instruction(ctx, inst); } break; @@ -433,12 +580,16 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, const unsigned size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1; assert(size <= 4); - if (ctx.num_imms < Elements(ctx.imm)) { + if (ctx->num_imms < Elements(ctx->imm)) { for (chan = 0; chan < size; ++chan) { - ctx.imm[ctx.num_imms][chan] = - parse.FullToken.FullImmediate.u[chan].Float; + float value = parse.FullToken.FullImmediate.u[chan].Float; + ctx->imm[ctx->num_imms][chan] = value; + + if (value < 0.0f || value > 1.0f) { + info->unclamped_immediates = TRUE; + } } - ++ctx.num_imms; + ++ctx->num_imms; } } break; @@ -453,6 +604,7 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, finished: tgsi_parse_free(&parse); + FREE(ctx); /*