tgsi: break gigantic tgsi_scan_shader() function into pieces

New functions for examining instructions, declarations, etc.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
This commit is contained in:
Brian Paul 2016-02-08 09:29:38 -07:00
parent 3c3ef69696
commit 37eb3f0400
1 changed files with 375 additions and 364 deletions

View File

@ -44,59 +44,12 @@
/**
* Scan the given TGSI shader to collect information such as number of
* registers used, special instructions used, etc.
* \return info the result of the scan
*/
void
tgsi_scan_shader(const struct tgsi_token *tokens,
struct tgsi_shader_info *info)
static void
scan_instruction(struct tgsi_shader_info *info,
const struct tgsi_full_instruction *fullinst,
unsigned *current_depth)
{
uint procType, i;
struct tgsi_parse_context parse;
unsigned current_depth = 0;
memset(info, 0, sizeof(*info));
for (i = 0; i < TGSI_FILE_COUNT; i++)
info->file_max[i] = -1;
for (i = 0; i < Elements(info->const_file_max); i++)
info->const_file_max[i] = -1;
info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = 1;
/**
** Setup to begin parsing input shader
**/
if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) {
debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n");
return;
}
procType = parse.FullHeader.Processor.Processor;
assert(procType == TGSI_PROCESSOR_FRAGMENT ||
procType == TGSI_PROCESSOR_VERTEX ||
procType == TGSI_PROCESSOR_GEOMETRY ||
procType == TGSI_PROCESSOR_TESS_CTRL ||
procType == TGSI_PROCESSOR_TESS_EVAL ||
procType == TGSI_PROCESSOR_COMPUTE);
info->processor = procType;
/**
** Loop over incoming program tokens/instructions
*/
while( !tgsi_parse_end_of_tokens( &parse ) ) {
info->num_tokens++;
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_INSTRUCTION:
{
const struct tgsi_full_instruction *fullinst
= &parse.FullToken.FullInstruction;
uint i;
unsigned i;
assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST);
info->opcode_count[fullinst->Instruction.Opcode]++;
@ -105,12 +58,12 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
case TGSI_OPCODE_IF:
case TGSI_OPCODE_UIF:
case TGSI_OPCODE_BGNLOOP:
current_depth++;
info->max_depth = MAX2(info->max_depth, current_depth);
(*current_depth)++;
info->max_depth = MAX2(info->max_depth, *current_depth);
break;
case TGSI_OPCODE_ENDIF:
case TGSI_OPCODE_ENDLOOP:
current_depth--;
(*current_depth)--;
break;
default:
break;
@ -168,8 +121,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->uses_doubles = true;
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *src =
&fullinst->Src[i];
const struct tgsi_full_src_register *src = &fullinst->Src[i];
int ind = src->Register.Index;
/* Mark which inputs are effectively used */
@ -186,7 +138,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->input_usage_mask[ind] |= usage_mask;
}
if (procType == TGSI_PROCESSOR_FRAGMENT &&
if (info->processor == TGSI_PROCESSOR_FRAGMENT &&
!src->Register.Indirect) {
unsigned name =
info->input_semantic_name[src->Register.Index];
@ -242,13 +194,14 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->num_instructions++;
}
break;
case TGSI_TOKEN_TYPE_DECLARATION:
static void
scan_declaration(struct tgsi_shader_info *info,
const struct tgsi_full_declaration *fulldecl)
{
const struct tgsi_full_declaration *fulldecl
= &parse.FullToken.FullDeclaration;
const uint file = fulldecl->Declaration.File;
const unsigned procType = info->processor;
uint reg;
if (fulldecl->Declaration.Array) {
@ -269,12 +222,10 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->array_max[file] = MAX2(info->array_max[file], array_id);
}
for (reg = fulldecl->Range.First;
reg <= fulldecl->Range.Last;
reg++) {
for (reg = fulldecl->Range.First; reg <= fulldecl->Range.Last; reg++) {
unsigned semName = fulldecl->Semantic.Name;
unsigned semIndex =
fulldecl->Semantic.Index + (reg - fulldecl->Range.First);
unsigned semIndex = fulldecl->Semantic.Index +
(reg - fulldecl->Range.First);
/* only first 32 regs will appear in this bitfield */
info->file_mask[file] |= (1 << reg);
@ -354,8 +305,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
unsigned index = fulldecl->Range.First;
info->system_value_semantic_name[index] = semName;
info->num_system_values = MAX2(info->num_system_values,
index + 1);
info->num_system_values = MAX2(info->num_system_values, index + 1);
if (semName == TGSI_SEMANTIC_INSTANCEID) {
info->uses_instanceid = TRUE;
@ -427,9 +377,10 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
}
}
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
static void
scan_immediate(struct tgsi_shader_info *info)
{
uint reg = info->immediate_count++;
uint file = TGSI_FILE_IMMEDIATE;
@ -438,12 +389,12 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->file_count[file]++;
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
}
break;
case TGSI_TOKEN_TYPE_PROPERTY:
static void
scan_property(struct tgsi_shader_info *info,
const struct tgsi_full_property *fullprop)
{
const struct tgsi_full_property *fullprop
= &parse.FullToken.FullProperty;
unsigned name = fullprop->Property.PropertyName;
unsigned value = fullprop->u[0].Data;
@ -461,10 +412,70 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
break;
}
}
break;
/**
* Scan the given TGSI shader to collect information such as number of
* registers used, special instructions used, etc.
* \return info the result of the scan
*/
void
tgsi_scan_shader(const struct tgsi_token *tokens,
struct tgsi_shader_info *info)
{
uint procType, i;
struct tgsi_parse_context parse;
unsigned current_depth = 0;
memset(info, 0, sizeof(*info));
for (i = 0; i < TGSI_FILE_COUNT; i++)
info->file_max[i] = -1;
for (i = 0; i < Elements(info->const_file_max); i++)
info->const_file_max[i] = -1;
info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = 1;
/**
** Setup to begin parsing input shader
**/
if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) {
debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n");
return;
}
procType = parse.FullHeader.Processor.Processor;
assert(procType == TGSI_PROCESSOR_FRAGMENT ||
procType == TGSI_PROCESSOR_VERTEX ||
procType == TGSI_PROCESSOR_GEOMETRY ||
procType == TGSI_PROCESSOR_TESS_CTRL ||
procType == TGSI_PROCESSOR_TESS_EVAL ||
procType == TGSI_PROCESSOR_COMPUTE);
info->processor = procType;
/**
** Loop over incoming program tokens/instructions
*/
while( !tgsi_parse_end_of_tokens( &parse ) ) {
info->num_tokens++;
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_INSTRUCTION:
scan_instruction(info, &parse.FullToken.FullInstruction,
&current_depth);
break;
case TGSI_TOKEN_TYPE_DECLARATION:
scan_declaration(info, &parse.FullToken.FullDeclaration);
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
scan_immediate(info);
break;
case TGSI_TOKEN_TYPE_PROPERTY:
scan_property(info, &parse.FullToken.FullProperty);
break;
default:
assert( 0 );
assert(!"Unexpected TGSI token type");
}
}