adds support for properties to all parts of the tgsi framework, plus introduces a new register which will be used for system generated values.tags/7.8-rc1
@@ -942,3 +942,107 @@ tgsi_default_full_dst_register( void ) | |||
return full_dst_register; | |||
} | |||
struct tgsi_property | |||
tgsi_default_property( void ) | |||
{ | |||
struct tgsi_property property; | |||
property.Type = TGSI_TOKEN_TYPE_PROPERTY; | |||
property.NrTokens = 1; | |||
property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM; | |||
property.Padding = 0; | |||
return property; | |||
} | |||
struct tgsi_property | |||
tgsi_build_property(unsigned property_name, | |||
struct tgsi_header *header) | |||
{ | |||
struct tgsi_property property; | |||
property = tgsi_default_property(); | |||
property.PropertyName = property_name; | |||
header_bodysize_grow( header ); | |||
return property; | |||
} | |||
struct tgsi_full_property | |||
tgsi_default_full_property( void ) | |||
{ | |||
struct tgsi_full_property full_property; | |||
full_property.Property = tgsi_default_property(); | |||
memset(full_property.u, 0, | |||
sizeof(struct tgsi_property_data) * 8); | |||
return full_property; | |||
} | |||
static void | |||
property_grow( | |||
struct tgsi_property *property, | |||
struct tgsi_header *header ) | |||
{ | |||
assert( property->NrTokens < 0xFF ); | |||
property->NrTokens++; | |||
header_bodysize_grow( header ); | |||
} | |||
struct tgsi_property_data | |||
tgsi_build_property_data( | |||
unsigned value, | |||
struct tgsi_property *property, | |||
struct tgsi_header *header ) | |||
{ | |||
struct tgsi_property_data property_data; | |||
property_data.Data = value; | |||
property_grow( property, header ); | |||
return property_data; | |||
} | |||
unsigned | |||
tgsi_build_full_property( | |||
const struct tgsi_full_property *full_prop, | |||
struct tgsi_token *tokens, | |||
struct tgsi_header *header, | |||
unsigned maxsize ) | |||
{ | |||
unsigned size = 0, i; | |||
struct tgsi_property *property; | |||
if( maxsize <= size ) | |||
return 0; | |||
property = (struct tgsi_property *) &tokens[size]; | |||
size++; | |||
*property = tgsi_build_property( | |||
TGSI_PROPERTY_GS_INPUT_PRIM, | |||
header ); | |||
assert( full_prop->Property.NrTokens <= 8 + 1 ); | |||
for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) { | |||
struct tgsi_property_data *data; | |||
if( maxsize <= size ) | |||
return 0; | |||
data = (struct tgsi_property_data *) &tokens[size]; | |||
size++; | |||
*data = tgsi_build_property_data( | |||
full_prop->u[i].Data, | |||
property, | |||
header ); | |||
} | |||
return size; | |||
} |
@@ -126,6 +126,34 @@ tgsi_build_full_immediate( | |||
struct tgsi_header *header, | |||
unsigned maxsize ); | |||
/* | |||
* properties | |||
*/ | |||
struct tgsi_property | |||
tgsi_default_property( void ); | |||
struct tgsi_property | |||
tgsi_build_property( | |||
unsigned property_name, | |||
struct tgsi_header *header ); | |||
struct tgsi_full_property | |||
tgsi_default_full_property( void ); | |||
struct tgsi_property_data | |||
tgsi_build_property_data( | |||
unsigned value, | |||
struct tgsi_property *property, | |||
struct tgsi_header *header ); | |||
unsigned | |||
tgsi_build_full_property( | |||
const struct tgsi_full_property *full_prop, | |||
struct tgsi_token *tokens, | |||
struct tgsi_header *header, | |||
unsigned maxsize ); | |||
/* | |||
* instruction | |||
*/ |
@@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] = | |||
"ADDR", | |||
"IMM", | |||
"LOOP", | |||
"PRED" | |||
"PRED", | |||
"SV" | |||
}; | |||
static const char *interpolate_names[] = | |||
@@ -149,6 +150,27 @@ static const char *texture_names[] = | |||
"SHADOWRECT" | |||
}; | |||
static const char *property_names[] = | |||
{ | |||
"GS_INPUT_PRIMITIVE", | |||
"GS_OUTPUT_PRIMITIVE", | |||
"GS_MAX_OUTPUT_VERTICES" | |||
}; | |||
static const char *primitive_names[] = | |||
{ | |||
"POINTS", | |||
"LINES", | |||
"LINE_LOOP", | |||
"LINE_STRIP", | |||
"TRIANGLES", | |||
"TRIANGLE_STRIP", | |||
"TRIANGLE_FAN", | |||
"QUADS", | |||
"QUAD_STRIP", | |||
"POLYGON" | |||
}; | |||
static void | |||
_dump_register( | |||
@@ -272,6 +294,50 @@ tgsi_dump_declaration( | |||
iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl ); | |||
} | |||
static boolean | |||
iter_property( | |||
struct tgsi_iterate_context *iter, | |||
struct tgsi_full_property *prop ) | |||
{ | |||
int i; | |||
struct dump_ctx *ctx = (struct dump_ctx *)iter; | |||
assert(Elements(property_names) == TGSI_PROPERTY_COUNT); | |||
TXT( "PROPERTY " ); | |||
ENM(prop->Property.PropertyName, property_names); | |||
if (prop->Property.NrTokens > 1) | |||
TXT(" "); | |||
for (i = 0; i < prop->Property.NrTokens - 1; ++i) { | |||
switch (prop->Property.PropertyName) { | |||
case TGSI_PROPERTY_GS_INPUT_PRIM: | |||
case TGSI_PROPERTY_GS_OUTPUT_PRIM: | |||
ENM(prop->u[i].Data, primitive_names); | |||
break; | |||
default: | |||
SID( prop->u[i].Data ); | |||
break; | |||
} | |||
if (i < prop->Property.NrTokens - 2) | |||
TXT( ", " ); | |||
} | |||
EOL(); | |||
return TRUE; | |||
} | |||
void tgsi_dump_property( | |||
const struct tgsi_full_property *prop ) | |||
{ | |||
struct dump_ctx ctx; | |||
ctx.printf = dump_ctx_printf; | |||
iter_property( &ctx.iter, (struct tgsi_full_property *)prop ); | |||
} | |||
static boolean | |||
iter_immediate( | |||
struct tgsi_iterate_context *iter, | |||
@@ -492,6 +558,7 @@ tgsi_dump( | |||
ctx.iter.iterate_instruction = iter_instruction; | |||
ctx.iter.iterate_declaration = iter_declaration; | |||
ctx.iter.iterate_immediate = iter_immediate; | |||
ctx.iter.iterate_property = iter_property; | |||
ctx.iter.epilog = NULL; | |||
ctx.instno = 0; | |||
@@ -546,6 +613,7 @@ tgsi_dump_str( | |||
ctx.base.iter.iterate_instruction = iter_instruction; | |||
ctx.base.iter.iterate_declaration = iter_declaration; | |||
ctx.base.iter.iterate_immediate = iter_immediate; | |||
ctx.base.iter.iterate_property = iter_property; | |||
ctx.base.iter.epilog = NULL; | |||
ctx.base.instno = 0; |
@@ -49,6 +49,7 @@ tgsi_dump( | |||
struct tgsi_full_immediate; | |||
struct tgsi_full_instruction; | |||
struct tgsi_full_declaration; | |||
struct tgsi_full_property; | |||
void | |||
tgsi_dump_immediate( | |||
@@ -63,6 +64,10 @@ void | |||
tgsi_dump_declaration( | |||
const struct tgsi_full_declaration *decl ); | |||
void | |||
tgsi_dump_property( | |||
const struct tgsi_full_property *prop ); | |||
#if defined __cplusplus | |||
} | |||
#endif |
@@ -336,6 +336,9 @@ tgsi_exec_machine_bind_shader( | |||
numInstructions++; | |||
break; | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
break; | |||
default: | |||
assert( 0 ); | |||
} | |||
@@ -1158,6 +1161,7 @@ fetch_src_file_channel( | |||
break; | |||
case TGSI_FILE_INPUT: | |||
case TGSI_FILE_SYSTEM_VALUE: | |||
chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; | |||
chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; | |||
chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; | |||
@@ -1302,6 +1306,7 @@ fetch_source( | |||
*/ | |||
switch (reg->Register.File) { | |||
case TGSI_FILE_INPUT: | |||
case TGSI_FILE_SYSTEM_VALUE: | |||
index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; | |||
index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; | |||
index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; | |||
@@ -1892,7 +1897,8 @@ exec_declaration(struct tgsi_exec_machine *mach, | |||
const struct tgsi_full_declaration *decl) | |||
{ | |||
if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { | |||
if (decl->Declaration.File == TGSI_FILE_INPUT) { | |||
if (decl->Declaration.File == TGSI_FILE_INPUT || | |||
decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) { | |||
uint first, last, mask; | |||
first = decl->Range.First; |
@@ -66,6 +66,12 @@ tgsi_iterate_shader( | |||
goto fail; | |||
break; | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
if (ctx->iterate_property) | |||
if (!ctx->iterate_property( ctx, &parse.FullToken.FullProperty )) | |||
goto fail; | |||
break; | |||
default: | |||
assert( 0 ); | |||
} |
@@ -56,6 +56,11 @@ struct tgsi_iterate_context | |||
struct tgsi_iterate_context *ctx, | |||
struct tgsi_full_immediate *imm ); | |||
boolean | |||
(* iterate_property)( | |||
struct tgsi_iterate_context *ctx, | |||
struct tgsi_full_property *prop ); | |||
boolean | |||
(* epilog)( | |||
struct tgsi_iterate_context *ctx ); |
@@ -220,6 +220,22 @@ tgsi_parse_token( | |||
break; | |||
} | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
{ | |||
struct tgsi_full_property *prop = &ctx->FullToken.FullProperty; | |||
uint prop_count; | |||
memset(prop, 0, sizeof *prop); | |||
copy_token(&prop->Property, &token); | |||
prop_count = prop->Property.NrTokens - 1; | |||
for (i = 0; i < prop_count; i++) { | |||
next_token(ctx, &prop->u[i]); | |||
} | |||
break; | |||
} | |||
default: | |||
assert( 0 ); | |||
} |
@@ -67,6 +67,12 @@ struct tgsi_full_immediate | |||
union tgsi_immediate_data u[4]; | |||
}; | |||
struct tgsi_full_property | |||
{ | |||
struct tgsi_property Property; | |||
struct tgsi_property_data u[8]; | |||
}; | |||
#define TGSI_FULL_MAX_DST_REGISTERS 2 | |||
#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */ | |||
@@ -86,6 +92,7 @@ union tgsi_full_token | |||
struct tgsi_full_declaration FullDeclaration; | |||
struct tgsi_full_immediate FullImmediate; | |||
struct tgsi_full_instruction FullInstruction; | |||
struct tgsi_full_property FullProperty; | |||
}; | |||
struct tgsi_parse_context |
@@ -293,6 +293,7 @@ emit_fetch(struct gen_context *gen, | |||
case TGSI_SWIZZLE_W: | |||
switch (reg->Register.File) { | |||
case TGSI_FILE_INPUT: | |||
case TGSI_FILE_SYSTEM_VALUE: | |||
{ | |||
int offset = (reg->Register.Index * 4 + swizzle) * 16; | |||
int offset_reg = emit_li_offset(gen, offset); | |||
@@ -1173,7 +1174,8 @@ emit_declaration( | |||
struct ppc_function *func, | |||
struct tgsi_full_declaration *decl ) | |||
{ | |||
if( decl->Declaration.File == TGSI_FILE_INPUT ) { | |||
if( decl->Declaration.File == TGSI_FILE_INPUT || | |||
decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) { | |||
#if 0 | |||
unsigned first, last, mask; | |||
unsigned i, j; | |||
@@ -1339,6 +1341,9 @@ tgsi_emit_ppc(const struct tgsi_token *tokens, | |||
} | |||
break; | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
break; | |||
default: | |||
ok = 0; | |||
assert( 0 ); |
@@ -324,6 +324,17 @@ iter_immediate( | |||
return TRUE; | |||
} | |||
static boolean | |||
iter_property( | |||
struct tgsi_iterate_context *iter, | |||
struct tgsi_full_property *prop ) | |||
{ | |||
/*struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;*/ | |||
return TRUE; | |||
} | |||
static boolean | |||
epilog( | |||
struct tgsi_iterate_context *iter ) | |||
@@ -367,6 +378,7 @@ tgsi_sanity_check( | |||
ctx.iter.iterate_instruction = iter_instruction; | |||
ctx.iter.iterate_declaration = iter_declaration; | |||
ctx.iter.iterate_immediate = iter_immediate; | |||
ctx.iter.iterate_property = iter_property; | |||
ctx.iter.epilog = epilog; | |||
memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); |
@@ -97,7 +97,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, | |||
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) { | |||
const struct tgsi_full_src_register *src = | |||
&fullinst->Src[i]; | |||
if (src->Register.File == TGSI_FILE_INPUT) { | |||
if (src->Register.File == TGSI_FILE_INPUT || | |||
src->Register.File == TGSI_FILE_SYSTEM_VALUE) { | |||
const int ind = src->Register.Index; | |||
if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) { | |||
if (src->Register.SwizzleX == TGSI_SWIZZLE_X) { | |||
@@ -128,7 +129,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, | |||
info->file_count[file]++; | |||
info->file_max[file] = MAX2(info->file_max[file], (int)reg); | |||
if (file == TGSI_FILE_INPUT) { | |||
if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) { | |||
info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; | |||
info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; | |||
info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate; | |||
@@ -160,6 +161,19 @@ tgsi_scan_shader(const struct tgsi_token *tokens, | |||
info->file_max[file] = MAX2(info->file_max[file], (int)reg); | |||
} | |||
break; | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
{ | |||
const struct tgsi_full_property *fullprop | |||
= &parse.FullToken.FullProperty; | |||
info->properties[info->num_properties].name = | |||
fullprop->Property.PropertyName; | |||
memcpy(info->properties[info->num_properties].data, | |||
fullprop->u, 8 * sizeof(unsigned));; | |||
++info->num_properties; | |||
} | |||
break; | |||
default: | |||
assert( 0 ); | |||
@@ -212,6 +226,7 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens) | |||
/* Do a whole bunch of checks for a simple move */ | |||
if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV || | |||
src->Register.File != TGSI_FILE_INPUT || | |||
src->Register.File != TGSI_FILE_SYSTEM_VALUE || | |||
dst->Register.File != TGSI_FILE_OUTPUT || | |||
src->Register.Index != dst->Register.Index || | |||
@@ -235,6 +250,8 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens) | |||
/* fall-through */ | |||
case TGSI_TOKEN_TYPE_IMMEDIATE: | |||
/* fall-through */ | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
/* fall-through */ | |||
default: | |||
; /* no-op */ | |||
} |
@@ -33,7 +33,6 @@ | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_shader_tokens.h" | |||
/** | |||
* Shader summary info | |||
*/ | |||
@@ -61,8 +60,13 @@ struct tgsi_shader_info | |||
boolean uses_kill; /**< KIL or KILP instruction used? */ | |||
boolean uses_fogcoord; /**< fragment shader uses fog coord? */ | |||
boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */ | |||
}; | |||
struct { | |||
unsigned name; | |||
unsigned data[8]; | |||
} properties[TGSI_PROPERTY_COUNT]; | |||
uint num_properties; | |||
}; | |||
extern void | |||
tgsi_scan_shader(const struct tgsi_token *tokens, |
@@ -1288,6 +1288,7 @@ emit_fetch( | |||
break; | |||
case TGSI_FILE_INPUT: | |||
case TGSI_FILE_SYSTEM_VALUE: | |||
emit_inputf( | |||
func, | |||
xmm, | |||
@@ -2633,7 +2634,8 @@ emit_declaration( | |||
struct x86_function *func, | |||
struct tgsi_full_declaration *decl ) | |||
{ | |||
if( decl->Declaration.File == TGSI_FILE_INPUT ) { | |||
if( decl->Declaration.File == TGSI_FILE_INPUT || | |||
decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) { | |||
unsigned first, last, mask; | |||
unsigned i, j; | |||
@@ -2952,6 +2954,9 @@ tgsi_emit_sse2( | |||
num_immediates++; | |||
} | |||
break; | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
/* we just ignore them for now */ | |||
break; | |||
default: | |||
ok = 0; |
@@ -27,6 +27,7 @@ | |||
#include "util/u_debug.h" | |||
#include "util/u_memory.h" | |||
#include "pipe/p_defines.h" | |||
#include "tgsi_text.h" | |||
#include "tgsi_build.h" | |||
#include "tgsi_info.h" | |||
@@ -110,6 +111,20 @@ static boolean parse_uint( const char **pcur, uint *val ) | |||
return FALSE; | |||
} | |||
static boolean parse_identifier( const char **pcur, char *ret ) | |||
{ | |||
const char *cur = *pcur; | |||
int i = 0; | |||
if (is_alpha_underscore( cur )) { | |||
ret[i++] = *cur++; | |||
while (is_alpha_underscore( cur )) | |||
ret[i++] = *cur++; | |||
*pcur = cur; | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} | |||
/* Parse floating point. | |||
*/ | |||
static boolean parse_float( const char **pcur, float *val ) | |||
@@ -229,7 +244,8 @@ static const char *file_names[TGSI_FILE_COUNT] = | |||
"ADDR", | |||
"IMM", | |||
"LOOP", | |||
"PRED" | |||
"PRED", | |||
"SV" | |||
}; | |||
static boolean | |||
@@ -939,6 +955,107 @@ static boolean parse_immediate( struct translate_ctx *ctx ) | |||
return TRUE; | |||
} | |||
static const char *property_names[] = | |||
{ | |||
"GS_INPUT_PRIMITIVE", | |||
"GS_OUTPUT_PRIMITIVE", | |||
"GS_MAX_OUTPUT_VERTICES" | |||
}; | |||
static const char *primitive_names[] = | |||
{ | |||
"POINTS", | |||
"LINES", | |||
"LINE_LOOP", | |||
"LINE_STRIP", | |||
"TRIANGLES", | |||
"TRIANGLE_STRIP", | |||
"TRIANGLE_FAN", | |||
"QUADS", | |||
"QUAD_STRIP", | |||
"POLYGON" | |||
}; | |||
static boolean | |||
parse_primitive( const char **pcur, uint *primitive ) | |||
{ | |||
uint i; | |||
for (i = 0; i < PIPE_PRIM_MAX; i++) { | |||
const char *cur = *pcur; | |||
if (str_match_no_case( &cur, primitive_names[i])) { | |||
*primitive = i; | |||
*pcur = cur; | |||
return TRUE; | |||
} | |||
} | |||
return FALSE; | |||
} | |||
static boolean parse_property( struct translate_ctx *ctx ) | |||
{ | |||
struct tgsi_full_property prop; | |||
uint property_name; | |||
uint values[8]; | |||
uint advance; | |||
char id[64]; | |||
if (!eat_white( &ctx->cur )) { | |||
report_error( ctx, "Syntax error" ); | |||
return FALSE; | |||
} | |||
if (!parse_identifier( &ctx->cur, id )) { | |||
report_error( ctx, "Syntax error" ); | |||
return FALSE; | |||
} | |||
for (property_name = 0; property_name < TGSI_PROPERTY_COUNT; | |||
++property_name) { | |||
if (strncasecmp(id, property_names[property_name], | |||
strlen(property_names[property_name]))) { | |||
break; | |||
} | |||
} | |||
if (property_name >= TGSI_PROPERTY_COUNT) { | |||
debug_printf( "\nError: Unknown property : '%s'", id ); | |||
return FALSE; | |||
} | |||
eat_opt_white( &ctx->cur ); | |||
switch(property_name) { | |||
case TGSI_PROPERTY_GS_INPUT_PRIM: | |||
case TGSI_PROPERTY_GS_OUTPUT_PRIM: | |||
if (!parse_primitive(&ctx->cur, &values[0] )) { | |||
report_error( ctx, "Unknown primitive name as property!" ); | |||
return FALSE; | |||
} | |||
break; | |||
default: | |||
if (!parse_uint(&ctx->cur, &values[0] )) { | |||
report_error( ctx, "Expected unsigned integer as property!" ); | |||
return FALSE; | |||
} | |||
} | |||
prop = tgsi_default_full_property(); | |||
prop.Property.PropertyName = property_name; | |||
prop.Property.NrTokens += 1; | |||
prop.u[0].Data = values[0]; | |||
advance = tgsi_build_full_property( | |||
&prop, | |||
ctx->tokens_cur, | |||
ctx->header, | |||
(uint) (ctx->tokens_end - ctx->tokens_cur) ); | |||
if (advance == 0) | |||
return FALSE; | |||
ctx->tokens_cur += advance; | |||
return TRUE; | |||
} | |||
static boolean translate( struct translate_ctx *ctx ) | |||
{ | |||
eat_opt_white( &ctx->cur ); | |||
@@ -947,7 +1064,6 @@ static boolean translate( struct translate_ctx *ctx ) | |||
while (*ctx->cur != '\0') { | |||
uint label_val = 0; | |||
if (!eat_white( &ctx->cur )) { | |||
report_error( ctx, "Syntax error" ); | |||
return FALSE; | |||
@@ -955,7 +1071,6 @@ static boolean translate( struct translate_ctx *ctx ) | |||
if (*ctx->cur == '\0') | |||
break; | |||
if (parse_label( ctx, &label_val )) { | |||
if (!parse_instruction( ctx, TRUE )) | |||
return FALSE; | |||
@@ -968,6 +1083,10 @@ static boolean translate( struct translate_ctx *ctx ) | |||
if (!parse_immediate( ctx )) | |||
return FALSE; | |||
} | |||
else if (str_match_no_case( &ctx->cur, "PROPERTY" )) { | |||
if (!parse_property( ctx )) | |||
return FALSE; | |||
} | |||
else if (!parse_instruction( ctx, FALSE )) { | |||
return FALSE; | |||
} |
@@ -79,6 +79,19 @@ emit_immediate(struct tgsi_transform_context *ctx, | |||
} | |||
static void | |||
emit_property(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_property *prop) | |||
{ | |||
uint ti = ctx->ti; | |||
ti += tgsi_build_full_property(prop, | |||
ctx->tokens_out + ti, | |||
ctx->header, | |||
ctx->max_tokens_out - ti); | |||
ctx->ti = ti; | |||
} | |||
/** | |||
* Apply user-defined transformations to the input shader to produce | |||
@@ -110,6 +123,7 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in, | |||
ctx->emit_instruction = emit_instruction; | |||
ctx->emit_declaration = emit_declaration; | |||
ctx->emit_immediate = emit_immediate; | |||
ctx->emit_property = emit_property; | |||
ctx->tokens_out = tokens_out; | |||
ctx->max_tokens_out = max_tokens_out; | |||
@@ -182,6 +196,17 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in, | |||
ctx->emit_immediate(ctx, fullimm); | |||
} | |||
break; | |||
case TGSI_TOKEN_TYPE_PROPERTY: | |||
{ | |||
struct tgsi_full_property *fullprop | |||
= &parse.FullToken.FullProperty; | |||
if (ctx->transform_property) | |||
ctx->transform_property(ctx, fullprop); | |||
else | |||
ctx->emit_property(ctx, fullprop); | |||
} | |||
break; | |||
default: | |||
assert( 0 ); |
@@ -53,6 +53,8 @@ struct tgsi_transform_context | |||
void (*transform_immediate)(struct tgsi_transform_context *ctx, | |||
struct tgsi_full_immediate *imm); | |||
void (*transform_property)(struct tgsi_transform_context *ctx, | |||
struct tgsi_full_property *prop); | |||
/** | |||
* Called at end of input program to allow caller to append extra | |||
@@ -73,6 +75,8 @@ struct tgsi_transform_context | |||
const struct tgsi_full_declaration *decl); | |||
void (*emit_immediate)(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_immediate *imm); | |||
void (*emit_property)(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_property *prop); | |||
struct tgsi_header *header; | |||
uint max_tokens_out; |
@@ -55,6 +55,7 @@ struct tgsi_processor | |||
#define TGSI_TOKEN_TYPE_DECLARATION 0 | |||
#define TGSI_TOKEN_TYPE_IMMEDIATE 1 | |||
#define TGSI_TOKEN_TYPE_INSTRUCTION 2 | |||
#define TGSI_TOKEN_TYPE_PROPERTY 3 | |||
struct tgsi_token | |||
{ | |||
@@ -64,16 +65,17 @@ struct tgsi_token | |||
}; | |||
enum tgsi_file_type { | |||
TGSI_FILE_NULL =0, | |||
TGSI_FILE_CONSTANT =1, | |||
TGSI_FILE_INPUT =2, | |||
TGSI_FILE_OUTPUT =3, | |||
TGSI_FILE_TEMPORARY =4, | |||
TGSI_FILE_SAMPLER =5, | |||
TGSI_FILE_ADDRESS =6, | |||
TGSI_FILE_IMMEDIATE =7, | |||
TGSI_FILE_LOOP =8, | |||
TGSI_FILE_PREDICATE =9, | |||
TGSI_FILE_NULL =0, | |||
TGSI_FILE_CONSTANT =1, | |||
TGSI_FILE_INPUT =2, | |||
TGSI_FILE_OUTPUT =3, | |||
TGSI_FILE_TEMPORARY =4, | |||
TGSI_FILE_SAMPLER =5, | |||
TGSI_FILE_ADDRESS =6, | |||
TGSI_FILE_IMMEDIATE =7, | |||
TGSI_FILE_LOOP =8, | |||
TGSI_FILE_PREDICATE =9, | |||
TGSI_FILE_SYSTEM_VALUE =10, | |||
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */ | |||
}; | |||
@@ -151,6 +153,22 @@ union tgsi_immediate_data | |||
float Float; | |||
}; | |||
#define TGSI_PROPERTY_GS_INPUT_PRIM 0 | |||
#define TGSI_PROPERTY_GS_OUTPUT_PRIM 1 | |||
#define TGSI_PROPERTY_GS_MAX_VERTICES 2 | |||
#define TGSI_PROPERTY_COUNT 3 | |||
struct tgsi_property { | |||
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */ | |||
unsigned NrTokens : 8; /**< UINT */ | |||
unsigned PropertyName : 8; /**< one of TGSI_PROPERTY */ | |||
unsigned Padding : 12; | |||
}; | |||
struct tgsi_property_data { | |||
unsigned Data; | |||
}; | |||
/* TGSI opcodes. | |||
* | |||
* For more information on semantics of opcodes and |