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;
+}
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
*/
"ADDR",
"IMM",
"LOOP",
- "PRED"
+ "PRED",
+ "SV"
};
static const char *interpolate_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(
}
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,
struct tgsi_full_immediate *imm )
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;
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;
struct tgsi_full_immediate;
struct tgsi_full_instruction;
struct tgsi_full_declaration;
+struct tgsi_full_property;
void
tgsi_dump_immediate(
tgsi_dump_declaration(
const struct tgsi_full_declaration *decl );
+void
+tgsi_dump_property(
+ const struct tgsi_full_property *prop );
+
#if defined __cplusplus
}
#endif
numInstructions++;
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ break;
+
default:
assert( 0 );
}
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];
*/
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;
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;
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 );
}
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 );
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 );
}
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 */
struct tgsi_full_declaration FullDeclaration;
struct tgsi_full_immediate FullImmediate;
struct tgsi_full_instruction FullInstruction;
+ struct tgsi_full_property FullProperty;
};
struct tgsi_parse_context
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);
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;
}
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ break;
+
default:
ok = 0;
assert( 0 );
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 )
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 ) );
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) {
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;
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 );
/* 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 ||
/* fall-through */
case TGSI_TOKEN_TYPE_IMMEDIATE:
/* fall-through */
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ /* fall-through */
default:
; /* no-op */
}
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
-
/**
* Shader summary 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,
break;
case TGSI_FILE_INPUT:
+ case TGSI_FILE_SYSTEM_VALUE:
emit_inputf(
func,
xmm,
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;
num_immediates++;
}
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ /* we just ignore them for now */
+ break;
default:
ok = 0;
#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"
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 )
"ADDR",
"IMM",
"LOOP",
- "PRED"
+ "PRED",
+ "SV"
};
static boolean
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 );
while (*ctx->cur != '\0') {
uint label_val = 0;
-
if (!eat_white( &ctx->cur )) {
report_error( ctx, "Syntax error" );
return FALSE;
if (*ctx->cur == '\0')
break;
-
if (parse_label( ctx, &label_val )) {
if (!parse_instruction( ctx, TRUE ))
return FALSE;
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;
}
}
+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
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;
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 );
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
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;
#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
{
};
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 */
};
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