struct lp_tgsi_info *info;
unsigned num_imms;
- float imm[128][4];
+ float imm[LP_MAX_TGSI_IMMEDIATES][4];
+ unsigned sample_target[PIPE_MAX_SHADER_SAMPLER_VIEWS];
struct lp_tgsi_channel_info temp[32][4];
};
if (!src->Indirect && !src->Absolute && !src->Negate) {
unsigned swizzle = tgsi_util_get_src_register_swizzle(src, chan);
if (src->File == TGSI_FILE_TEMPORARY) {
- if (src->Index < Elements(ctx->temp)) {
+ if (src->Index < ARRAY_SIZE(ctx->temp)) {
*chan_info = ctx->temp[src->Index][swizzle];
}
} else {
chan_info->file = src->File;
if (src->File == TGSI_FILE_IMMEDIATE) {
- assert(src->Index < Elements(ctx->imm));
- if (src->Index < Elements(ctx->imm)) {
+ assert(src->Index < ARRAY_SIZE(ctx->imm));
+ if (src->Index < ARRAY_SIZE(ctx->imm)) {
chan_info->u.value = ctx->imm[src->Index][swizzle];
}
} else {
struct lp_tgsi_info *info = ctx->info;
unsigned chan;
- if (info->num_texs < Elements(info->tex)) {
+ if (info->num_texs < ARRAY_SIZE(info->tex)) {
struct lp_tgsi_texture_info *tex_info = &info->tex[info->num_texs];
boolean indirect = FALSE;
unsigned readmask = 0;
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);
struct lp_tgsi_info *info = ctx->info;
unsigned chan;
- if (info->num_texs < Elements(info->tex)) {
+ if (info->num_texs < ARRAY_SIZE(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;
+ 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) {
if (dst->File == TGSI_FILE_TEMPORARY) {
regs = ctx->temp;
- max_regs = Elements(ctx->temp);
+ max_regs = ARRAY_SIZE(ctx->temp);
} else if (dst->File == TGSI_FILE_OUTPUT) {
regs = info->output;
- max_regs = Elements(info->output);
- } else if (dst->File == TGSI_FILE_ADDRESS ||
- dst->File == TGSI_FILE_PREDICATE) {
+ max_regs = ARRAY_SIZE(info->output);
+ } else if (dst->File == TGSI_FILE_ADDRESS) {
+ continue;
+ } else if (dst->File == TGSI_FILE_BUFFER) {
+ continue;
+ } else if (dst->File == TGSI_FILE_IMAGE) {
+ continue;
+ } else if (dst->File == TGSI_FILE_MEMORY) {
continue;
} else {
assert(0);
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;
memset(res, 0, sizeof res);
- if (!inst->Instruction.Predicate &&
- !inst->Instruction.Saturate) {
+ if (!inst->Instruction.Saturate) {
for (chan = 0; chan < 4; ++chan) {
if (dst->WriteMask & (1 << chan)) {
if (inst->Instruction.Opcode == TGSI_OPCODE_MOV) {
case TGSI_OPCODE_ENDIF:
case TGSI_OPCODE_BGNLOOP:
case TGSI_OPCODE_BRK:
- case TGSI_OPCODE_BREAKC:
case TGSI_OPCODE_CONT:
case TGSI_OPCODE_ENDLOOP:
- case TGSI_OPCODE_CALLNZ:
case TGSI_OPCODE_CAL:
case TGSI_OPCODE_BGNSUB:
case TGSI_OPCODE_ENDSUB:
}
-static INLINE void
+static inline void
dump_info(const struct tgsi_token *tokens,
struct lp_tgsi_info *info)
{
struct lp_tgsi_info *info)
{
struct tgsi_parse_context parse;
- struct analysis_context ctx;
+ struct analysis_context *ctx;
unsigned index;
unsigned chan;
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);
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:
goto finished;
}
- analyse_instruction(&ctx, inst);
+ analyse_instruction(ctx, inst);
}
break;
const unsigned size =
parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
assert(size <= 4);
- if (ctx.num_imms < Elements(ctx.imm)) {
+ if (ctx->num_imms < ARRAY_SIZE(ctx->imm)) {
for (chan = 0; chan < size; ++chan) {
float value = parse.FullToken.FullImmediate.u[chan].Float;
- ctx.imm[ctx.num_imms][chan] = value;
+ 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;
finished:
tgsi_parse_free(&parse);
+ FREE(ctx);
/*
*/
for (index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) {
- const struct lp_tgsi_channel_info null_output[4];
+ static const struct lp_tgsi_channel_info null_output[4];
info->cbuf[index] = null_output;
}