gallium/tgsi: Introduce the "LOCAL" register declaration modifier.
This change will be useful to implement function parameter passing on top of TGSI. As we don't have a proper stack, a register-based calling convention will be used instead, which isn't necessarily a bad thing given that GPUs often have plenty of registers to spare. Using the same register space for local temporaries and inter-procedural communication caused some inefficiencies, because in some cases the register allocator would lose the freedom to merge temporary values together into the same physical register, leading to suboptimal register (and sometimes, as a side effect, instruction) usage. The LOCAL declaration modifier specifies that the value isn't intended for parameter passing and as a result the compiler doesn't have to give any guarantees of it being preserved across function boundaries. Ignoring the LOCAL flag doesn't change the semantics of a valid program in any way, because local variables are just supposed to get a more relaxed treatment. IOW, this should be a backwards-compatible change.
This commit is contained in:
@@ -108,6 +108,7 @@ tgsi_default_declaration( void )
|
|||||||
declaration.Dimension = 0;
|
declaration.Dimension = 0;
|
||||||
declaration.Semantic = 0;
|
declaration.Semantic = 0;
|
||||||
declaration.Invariant = 0;
|
declaration.Invariant = 0;
|
||||||
|
declaration.Local = 0;
|
||||||
|
|
||||||
return declaration;
|
return declaration;
|
||||||
}
|
}
|
||||||
@@ -120,6 +121,7 @@ tgsi_build_declaration(
|
|||||||
unsigned dimension,
|
unsigned dimension,
|
||||||
unsigned semantic,
|
unsigned semantic,
|
||||||
unsigned invariant,
|
unsigned invariant,
|
||||||
|
unsigned local,
|
||||||
struct tgsi_header *header )
|
struct tgsi_header *header )
|
||||||
{
|
{
|
||||||
struct tgsi_declaration declaration;
|
struct tgsi_declaration declaration;
|
||||||
@@ -134,6 +136,7 @@ tgsi_build_declaration(
|
|||||||
declaration.Dimension = dimension;
|
declaration.Dimension = dimension;
|
||||||
declaration.Semantic = semantic;
|
declaration.Semantic = semantic;
|
||||||
declaration.Invariant = invariant;
|
declaration.Invariant = invariant;
|
||||||
|
declaration.Local = local;
|
||||||
|
|
||||||
header_bodysize_grow( header );
|
header_bodysize_grow( header );
|
||||||
|
|
||||||
@@ -359,6 +362,7 @@ tgsi_build_full_declaration(
|
|||||||
full_decl->Declaration.Dimension,
|
full_decl->Declaration.Dimension,
|
||||||
full_decl->Declaration.Semantic,
|
full_decl->Declaration.Semantic,
|
||||||
full_decl->Declaration.Invariant,
|
full_decl->Declaration.Invariant,
|
||||||
|
full_decl->Declaration.Local,
|
||||||
header );
|
header );
|
||||||
|
|
||||||
if (maxsize <= size)
|
if (maxsize <= size)
|
||||||
|
@@ -271,6 +271,9 @@ iter_declaration(
|
|||||||
ctx,
|
ctx,
|
||||||
decl->Declaration.UsageMask );
|
decl->Declaration.UsageMask );
|
||||||
|
|
||||||
|
if (decl->Declaration.Local)
|
||||||
|
TXT( ", LOCAL" );
|
||||||
|
|
||||||
if (decl->Declaration.Semantic) {
|
if (decl->Declaration.Semantic) {
|
||||||
TXT( ", " );
|
TXT( ", " );
|
||||||
ENM( decl->Semantic.Name, tgsi_semantic_names );
|
ENM( decl->Semantic.Name, tgsi_semantic_names );
|
||||||
|
@@ -1161,13 +1161,25 @@ static boolean parse_declaration( struct translate_ctx *ctx )
|
|||||||
}
|
}
|
||||||
ctx->cur = cur;
|
ctx->cur = cur;
|
||||||
} else {
|
} else {
|
||||||
|
if (str_match_no_case(&cur, "LOCAL") &&
|
||||||
|
!is_digit_alpha_underscore(cur)) {
|
||||||
|
decl.Declaration.Local = 1;
|
||||||
|
ctx->cur = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = ctx->cur;
|
||||||
|
eat_opt_white( &cur );
|
||||||
|
if (*cur == ',') {
|
||||||
|
cur++;
|
||||||
|
eat_opt_white( &cur );
|
||||||
|
|
||||||
for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
|
for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
|
||||||
if (str_match_no_case( &cur, tgsi_semantic_names[i] )) {
|
if (str_match_no_case( &cur, tgsi_semantic_names[i] )) {
|
||||||
const char *cur2 = cur;
|
|
||||||
uint index;
|
uint index;
|
||||||
|
|
||||||
if (is_digit_alpha_underscore( cur ))
|
if (is_digit_alpha_underscore( cur ))
|
||||||
continue;
|
continue;
|
||||||
|
cur2 = cur;
|
||||||
eat_opt_white( &cur2 );
|
eat_opt_white( &cur2 );
|
||||||
if (*cur2 == '[') {
|
if (*cur2 == '[') {
|
||||||
cur2++;
|
cur2++;
|
||||||
@@ -1196,6 +1208,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (is_imm_array) {
|
} else if (is_imm_array) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
float *vals_itr;
|
float *vals_itr;
|
||||||
|
@@ -1795,6 +1795,12 @@ of TGSI_FILE.
|
|||||||
UsageMask field specifies which of the register components can be accessed
|
UsageMask field specifies which of the register components can be accessed
|
||||||
and is one of TGSI_WRITEMASK.
|
and is one of TGSI_WRITEMASK.
|
||||||
|
|
||||||
|
The Local flag specifies that a given value isn't intended for
|
||||||
|
subroutine parameter passing and, as a result, the implementation
|
||||||
|
isn't required to give any guarantees of it being preserved across
|
||||||
|
subroutine boundaries. As it's merely a compiler hint, the
|
||||||
|
implementation is free to ignore it.
|
||||||
|
|
||||||
If Dimension flag is set to 1, a Declaration Dimension token follows.
|
If Dimension flag is set to 1, a Declaration Dimension token follows.
|
||||||
|
|
||||||
If Semantic flag is set to 1, a Declaration Semantic token follows.
|
If Semantic flag is set to 1, a Declaration Semantic token follows.
|
||||||
|
@@ -120,7 +120,8 @@ struct tgsi_declaration
|
|||||||
unsigned Semantic : 1; /**< BOOL, any semantic info? */
|
unsigned Semantic : 1; /**< BOOL, any semantic info? */
|
||||||
unsigned Interpolate : 1; /**< any interpolation info? */
|
unsigned Interpolate : 1; /**< any interpolation info? */
|
||||||
unsigned Invariant : 1; /**< invariant optimization? */
|
unsigned Invariant : 1; /**< invariant optimization? */
|
||||||
unsigned Padding : 8;
|
unsigned Local : 1; /**< optimize as subroutine local variable? */
|
||||||
|
unsigned Padding : 7;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tgsi_declaration_range
|
struct tgsi_declaration_range
|
||||||
|
Reference in New Issue
Block a user