tgsi: add properties and system value register

adds support for properties to all parts of the tgsi framework, plus
introduces a new register which will be used for system generated
values.
This commit is contained in:
Zack Rusin
2009-12-14 16:34:07 -05:00
parent 41b52aa336
commit 3ff688ea29
18 changed files with 475 additions and 21 deletions

View File

@@ -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;
}

View File

@@ -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
*/

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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 );
}

View File

@@ -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 );

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -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 );

View File

@@ -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 ) );

View File

@@ -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 */
}

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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
{
@@ -74,6 +75,7 @@ enum tgsi_file_type {
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