static void _dump_register_src( struct dump_ctx *ctx, const struct tgsi_full_src_register *src ) { TXT(tgsi_file_name(src->Register.File)); if (src->Register.Dimension) { if (src->Dimension.Indirect) { CHR( '[' ); TXT(tgsi_file_name(src->DimIndirect.File)); CHR( '[' ); SID( src->DimIndirect.Index ); TXT( "]." ); ENM( src->DimIndirect.Swizzle, tgsi_swizzle_names ); if (src->Dimension.Index != 0) { if (src->Dimension.Index > 0) CHR( '+' ); SID( src->Dimension.Index ); } CHR( ']' ); if (src->DimIndirect.ArrayID) { CHR( '(' ); SID( src->DimIndirect.ArrayID ); CHR( ')' ); } } else { CHR('['); SID(src->Dimension.Index); CHR(']'); } } if (src->Register.Indirect) { CHR( '[' ); TXT(tgsi_file_name(src->Indirect.File)); CHR( '[' ); SID( src->Indirect.Index ); TXT( "]." ); ENM( src->Indirect.Swizzle, tgsi_swizzle_names ); if (src->Register.Index != 0) { if (src->Register.Index > 0) CHR( '+' ); SID( src->Register.Index ); } CHR( ']' ); if (src->Indirect.ArrayID) { CHR( '(' ); SID( src->Indirect.ArrayID ); CHR( ')' ); } } else { CHR( '[' ); SID( src->Register.Index ); CHR( ']' ); } }
static struct ir2_src_register * add_src_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu, const struct tgsi_src_register *src) { static const char swiz_vals[] = { 'x', 'y', 'z', 'w', }; char swiz[5]; unsigned flags = 0, num = 0; switch (src->File) { case TGSI_FILE_CONSTANT: num = src->Index; flags |= IR2_REG_CONST; break; case TGSI_FILE_INPUT: if (ctx->type == PIPE_SHADER_VERTEX) { num = src->Index + 1; } else { flags |= IR2_REG_INPUT; num = export_linkage(ctx, ctx->input_export_idx[src->Index]); } break; case TGSI_FILE_TEMPORARY: num = get_temp_gpr(ctx, src->Index); break; case TGSI_FILE_IMMEDIATE: num = src->Index + ctx->num_regs[TGSI_FILE_CONSTANT]; flags |= IR2_REG_CONST; break; default: DBG("unsupported src register file: %s", tgsi_file_name(src->File)); assert(0); break; } if (src->Absolute) flags |= IR2_REG_ABS; if (src->Negate) flags |= IR2_REG_NEGATE; swiz[0] = swiz_vals[src->SwizzleX]; swiz[1] = swiz_vals[src->SwizzleY]; swiz[2] = swiz_vals[src->SwizzleZ]; swiz[3] = swiz_vals[src->SwizzleW]; swiz[4] = '\0'; if ((ctx->need_sync & ((uint64_t)1 << num)) && !(flags & IR2_REG_CONST)) { alu->sync = true; ctx->need_sync &= ~((uint64_t)1 << num); } return ir2_reg_create(alu, num, swiz, flags); }
static boolean parse_file( const char **pcur, uint *file ) { uint i; for (i = 0; i < TGSI_FILE_COUNT; i++) { const char *cur = *pcur; if (str_match_nocase_whole( &cur, tgsi_file_name(i) )) { *pcur = cur; *file = i; return TRUE; } } return FALSE; }
static struct ir2_register * add_dst_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu, const struct tgsi_dst_register *dst) { unsigned flags = 0, num = 0; char swiz[5]; switch (dst->File) { case TGSI_FILE_OUTPUT: flags |= IR2_REG_EXPORT; if (ctx->type == PIPE_SHADER_VERTEX) { if (dst->Index == ctx->position) { num = 62; } else if (dst->Index == ctx->psize) { num = 63; } else { num = export_linkage(ctx, ctx->output_export_idx[dst->Index]); } } else { num = dst->Index; } break; case TGSI_FILE_TEMPORARY: num = get_temp_gpr(ctx, dst->Index); break; default: DBG("unsupported dst register file: %s", tgsi_file_name(dst->File)); assert(0); break; } swiz[0] = (dst->WriteMask & TGSI_WRITEMASK_X) ? 'x' : '_'; swiz[1] = (dst->WriteMask & TGSI_WRITEMASK_Y) ? 'y' : '_'; swiz[2] = (dst->WriteMask & TGSI_WRITEMASK_Z) ? 'z' : '_'; swiz[3] = (dst->WriteMask & TGSI_WRITEMASK_W) ? 'w' : '_'; swiz[4] = '\0'; return ir2_reg_create(alu, num, swiz, flags); }
static INLINE void dump_info(const struct tgsi_token *tokens, struct lp_tgsi_info *info) { unsigned index; unsigned chan; tgsi_dump(tokens, 0); for (index = 0; index < info->num_texs; ++index) { const struct lp_tgsi_texture_info *tex_info = &info->tex[index]; debug_printf("TEX[%u] =", index); for (chan = 0; chan < 4; ++chan) { const struct lp_tgsi_channel_info *chan_info = &tex_info->coord[chan]; if (chan_info->file != TGSI_FILE_NULL) { debug_printf(" %s[%u].%c", tgsi_file_name(chan_info->file), chan_info->u.index, "xyzw01"[chan_info->swizzle]); } else { debug_printf(" _"); } } debug_printf(", RES[%u], SAMP[%u], %s\n", tex_info->texture_unit, tex_info->sampler_unit, tgsi_texture_names[tex_info->target]); } for (index = 0; index < PIPE_MAX_SHADER_OUTPUTS; ++index) { for (chan = 0; chan < 4; ++chan) { const struct lp_tgsi_channel_info *chan_info = &info->output[index][chan]; if (chan_info->file != TGSI_FILE_NULL) { debug_printf("OUT[%u].%c = ", index, "xyzw"[chan]); if (chan_info->file == TGSI_FILE_IMMEDIATE) { debug_printf("%f", chan_info->u.value); } else { const char *file_name; switch (chan_info->file) { case TGSI_FILE_CONSTANT: file_name = "CONST"; break; case TGSI_FILE_INPUT: file_name = "IN"; break; default: file_name = "???"; break; } debug_printf("%s[%u].%c", file_name, chan_info->u.index, "xyzw01"[chan_info->swizzle]); } debug_printf("\n"); } } } }
static boolean iter_instruction( struct tgsi_iterate_context *iter, struct tgsi_full_instruction *inst ) { struct dump_ctx *ctx = (struct dump_ctx *) iter; uint instno = ctx->instno++; const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode ); uint i; boolean first_reg = TRUE; INSTID( instno ); TXT( ": " ); ctx->indent -= info->pre_dedent; for(i = 0; (int)i < ctx->indent; ++i) TXT( " " ); ctx->indent += info->post_indent; if (inst->Instruction.Predicate) { CHR( '(' ); if (inst->Predicate.Negate) CHR( '!' ); TXT( "PRED[" ); SID( inst->Predicate.Index ); CHR( ']' ); if (inst->Predicate.SwizzleX != TGSI_SWIZZLE_X || inst->Predicate.SwizzleY != TGSI_SWIZZLE_Y || inst->Predicate.SwizzleZ != TGSI_SWIZZLE_Z || inst->Predicate.SwizzleW != TGSI_SWIZZLE_W) { CHR( '.' ); ENM( inst->Predicate.SwizzleX, tgsi_swizzle_names ); ENM( inst->Predicate.SwizzleY, tgsi_swizzle_names ); ENM( inst->Predicate.SwizzleZ, tgsi_swizzle_names ); ENM( inst->Predicate.SwizzleW, tgsi_swizzle_names ); } TXT( ") " ); } TXT( info->mnemonic ); switch (inst->Instruction.Saturate) { case TGSI_SAT_NONE: break; case TGSI_SAT_ZERO_ONE: TXT( "_SAT" ); break; case TGSI_SAT_MINUS_PLUS_ONE: TXT( "_SATNV" ); break; default: assert( 0 ); } for (i = 0; i < inst->Instruction.NumDstRegs; i++) { const struct tgsi_full_dst_register *dst = &inst->Dst[i]; if (!first_reg) CHR( ',' ); CHR( ' ' ); _dump_register_dst( ctx, dst ); _dump_writemask( ctx, dst->Register.WriteMask ); first_reg = FALSE; } for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *src = &inst->Src[i]; if (!first_reg) CHR( ',' ); CHR( ' ' ); if (src->Register.Negate) CHR( '-' ); if (src->Register.Absolute) CHR( '|' ); _dump_register_src(ctx, src); if (src->Register.SwizzleX != TGSI_SWIZZLE_X || src->Register.SwizzleY != TGSI_SWIZZLE_Y || src->Register.SwizzleZ != TGSI_SWIZZLE_Z || src->Register.SwizzleW != TGSI_SWIZZLE_W) { CHR( '.' ); ENM( src->Register.SwizzleX, tgsi_swizzle_names ); ENM( src->Register.SwizzleY, tgsi_swizzle_names ); ENM( src->Register.SwizzleZ, tgsi_swizzle_names ); ENM( src->Register.SwizzleW, tgsi_swizzle_names ); } if (src->Register.Absolute) CHR( '|' ); first_reg = FALSE; } if (inst->Instruction.Texture) { if (!(inst->Instruction.Opcode >= TGSI_OPCODE_SAMPLE && inst->Instruction.Opcode <= TGSI_OPCODE_GATHER4)) { TXT( ", " ); ENM( inst->Texture.Texture, tgsi_texture_names ); } for (i = 0; i < inst->Texture.NumOffsets; i++) { TXT( ", " ); TXT(tgsi_file_name(inst->TexOffsets[i].File)); CHR( '[' ); SID( inst->TexOffsets[i].Index ); CHR( ']' ); CHR( '.' ); ENM( inst->TexOffsets[i].SwizzleX, tgsi_swizzle_names); ENM( inst->TexOffsets[i].SwizzleY, tgsi_swizzle_names); ENM( inst->TexOffsets[i].SwizzleZ, tgsi_swizzle_names); } } switch (inst->Instruction.Opcode) { case TGSI_OPCODE_IF: case TGSI_OPCODE_UIF: case TGSI_OPCODE_ELSE: case TGSI_OPCODE_BGNLOOP: case TGSI_OPCODE_ENDLOOP: case TGSI_OPCODE_CAL: case TGSI_OPCODE_BGNSUB: TXT( " :" ); UID( inst->Label.Label ); break; } /* update indentation */ if (inst->Instruction.Opcode == TGSI_OPCODE_IF || inst->Instruction.Opcode == TGSI_OPCODE_UIF || inst->Instruction.Opcode == TGSI_OPCODE_ELSE || inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) { ctx->indentation += indent_spaces; } EOL(); return TRUE; }
static boolean iter_declaration( struct tgsi_iterate_context *iter, struct tgsi_full_declaration *decl ) { struct dump_ctx *ctx = (struct dump_ctx *)iter; boolean patch = decl->Semantic.Name == TGSI_SEMANTIC_PATCH || decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER || decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER || decl->Semantic.Name == TGSI_SEMANTIC_PRIMID; TXT( "DCL " ); TXT(tgsi_file_name(decl->Declaration.File)); /* all geometry shader inputs and non-patch tessellation shader inputs are * two dimensional */ if (decl->Declaration.File == TGSI_FILE_INPUT && (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY || (!patch && (iter->processor.Processor == TGSI_PROCESSOR_TESSCTRL || iter->processor.Processor == TGSI_PROCESSOR_TESSEVAL)))) { TXT("[]"); } /* all non-patch tess ctrl shader outputs are two dimensional */ if (decl->Declaration.File == TGSI_FILE_OUTPUT && !patch && iter->processor.Processor == TGSI_PROCESSOR_TESSCTRL) { TXT("[]"); } if (decl->Declaration.Dimension) { CHR('['); SID(decl->Dim.Index2D); CHR(']'); } CHR('['); SID(decl->Range.First); if (decl->Range.First != decl->Range.Last) { TXT(".."); SID(decl->Range.Last); } CHR(']'); _dump_writemask( ctx, decl->Declaration.UsageMask ); if (decl->Declaration.Array) { TXT( ", ARRAY(" ); SID(decl->Array.ArrayID); CHR(')'); } if (decl->Declaration.Local) TXT( ", LOCAL" ); if (decl->Declaration.Semantic) { TXT( ", " ); ENM( decl->Semantic.Name, tgsi_semantic_names ); if (decl->Semantic.Index != 0 || decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD || decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { CHR( '[' ); UID( decl->Semantic.Index ); CHR( ']' ); } } if (decl->Declaration.File == TGSI_FILE_RESOURCE) { TXT(", "); ENM(decl->Resource.Resource, tgsi_texture_names); if (decl->Resource.Writable) TXT(", WR"); if (decl->Resource.Raw) TXT(", RAW"); } if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { TXT(", "); ENM(decl->SamplerView.Resource, tgsi_texture_names); TXT(", "); if ((decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeY) && (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeZ) && (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeW)) { ENM(decl->SamplerView.ReturnTypeX, tgsi_return_type_names); } else { ENM(decl->SamplerView.ReturnTypeX, tgsi_return_type_names); TXT(", "); ENM(decl->SamplerView.ReturnTypeY, tgsi_return_type_names); TXT(", "); ENM(decl->SamplerView.ReturnTypeZ, tgsi_return_type_names); TXT(", "); ENM(decl->SamplerView.ReturnTypeW, tgsi_return_type_names); } } if (decl->Declaration.Interpolate) { if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT && decl->Declaration.File == TGSI_FILE_INPUT) { TXT( ", " ); ENM( decl->Interp.Interpolate, tgsi_interpolate_names ); } if (decl->Interp.Location != TGSI_INTERPOLATE_LOC_CENTER) { TXT( ", " ); ENM( decl->Interp.Location, tgsi_interpolate_locations ); } if (decl->Interp.CylindricalWrap) { TXT(", CYLWRAP_"); if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_X) { CHR('X'); } if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Y) { CHR('Y'); } if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Z) { CHR('Z'); } if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_W) { CHR('W'); } } } if (decl->Declaration.Invariant) { TXT( ", INVARIANT" ); } EOL(); return TRUE; }