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:
@@ -942,3 +942,107 @@ tgsi_default_full_dst_register( void )
|
|||||||
return full_dst_register;
|
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,
|
struct tgsi_header *header,
|
||||||
unsigned maxsize );
|
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
|
* instruction
|
||||||
*/
|
*/
|
||||||
|
@@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
|
|||||||
"ADDR",
|
"ADDR",
|
||||||
"IMM",
|
"IMM",
|
||||||
"LOOP",
|
"LOOP",
|
||||||
"PRED"
|
"PRED",
|
||||||
|
"SV"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *interpolate_names[] =
|
static const char *interpolate_names[] =
|
||||||
@@ -149,6 +150,27 @@ static const char *texture_names[] =
|
|||||||
"SHADOWRECT"
|
"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
|
static void
|
||||||
_dump_register(
|
_dump_register(
|
||||||
@@ -272,6 +294,50 @@ tgsi_dump_declaration(
|
|||||||
iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl );
|
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
|
static boolean
|
||||||
iter_immediate(
|
iter_immediate(
|
||||||
struct tgsi_iterate_context *iter,
|
struct tgsi_iterate_context *iter,
|
||||||
@@ -492,6 +558,7 @@ tgsi_dump(
|
|||||||
ctx.iter.iterate_instruction = iter_instruction;
|
ctx.iter.iterate_instruction = iter_instruction;
|
||||||
ctx.iter.iterate_declaration = iter_declaration;
|
ctx.iter.iterate_declaration = iter_declaration;
|
||||||
ctx.iter.iterate_immediate = iter_immediate;
|
ctx.iter.iterate_immediate = iter_immediate;
|
||||||
|
ctx.iter.iterate_property = iter_property;
|
||||||
ctx.iter.epilog = NULL;
|
ctx.iter.epilog = NULL;
|
||||||
|
|
||||||
ctx.instno = 0;
|
ctx.instno = 0;
|
||||||
@@ -546,6 +613,7 @@ tgsi_dump_str(
|
|||||||
ctx.base.iter.iterate_instruction = iter_instruction;
|
ctx.base.iter.iterate_instruction = iter_instruction;
|
||||||
ctx.base.iter.iterate_declaration = iter_declaration;
|
ctx.base.iter.iterate_declaration = iter_declaration;
|
||||||
ctx.base.iter.iterate_immediate = iter_immediate;
|
ctx.base.iter.iterate_immediate = iter_immediate;
|
||||||
|
ctx.base.iter.iterate_property = iter_property;
|
||||||
ctx.base.iter.epilog = NULL;
|
ctx.base.iter.epilog = NULL;
|
||||||
|
|
||||||
ctx.base.instno = 0;
|
ctx.base.instno = 0;
|
||||||
|
@@ -49,6 +49,7 @@ tgsi_dump(
|
|||||||
struct tgsi_full_immediate;
|
struct tgsi_full_immediate;
|
||||||
struct tgsi_full_instruction;
|
struct tgsi_full_instruction;
|
||||||
struct tgsi_full_declaration;
|
struct tgsi_full_declaration;
|
||||||
|
struct tgsi_full_property;
|
||||||
|
|
||||||
void
|
void
|
||||||
tgsi_dump_immediate(
|
tgsi_dump_immediate(
|
||||||
@@ -63,6 +64,10 @@ void
|
|||||||
tgsi_dump_declaration(
|
tgsi_dump_declaration(
|
||||||
const struct tgsi_full_declaration *decl );
|
const struct tgsi_full_declaration *decl );
|
||||||
|
|
||||||
|
void
|
||||||
|
tgsi_dump_property(
|
||||||
|
const struct tgsi_full_property *prop );
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -336,6 +336,9 @@ tgsi_exec_machine_bind_shader(
|
|||||||
numInstructions++;
|
numInstructions++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert( 0 );
|
assert( 0 );
|
||||||
}
|
}
|
||||||
@@ -1158,6 +1161,7 @@ fetch_src_file_channel(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TGSI_FILE_INPUT:
|
case TGSI_FILE_INPUT:
|
||||||
|
case TGSI_FILE_SYSTEM_VALUE:
|
||||||
chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
|
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[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
|
||||||
chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
|
chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
|
||||||
@@ -1302,6 +1306,7 @@ fetch_source(
|
|||||||
*/
|
*/
|
||||||
switch (reg->Register.File) {
|
switch (reg->Register.File) {
|
||||||
case TGSI_FILE_INPUT:
|
case TGSI_FILE_INPUT:
|
||||||
|
case TGSI_FILE_SYSTEM_VALUE:
|
||||||
index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
|
index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
|
||||||
index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
|
index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
|
||||||
index.i[2] *= 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)
|
const struct tgsi_full_declaration *decl)
|
||||||
{
|
{
|
||||||
if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
|
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;
|
uint first, last, mask;
|
||||||
|
|
||||||
first = decl->Range.First;
|
first = decl->Range.First;
|
||||||
|
@@ -66,6 +66,12 @@ tgsi_iterate_shader(
|
|||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||||
|
if (ctx->iterate_property)
|
||||||
|
if (!ctx->iterate_property( ctx, &parse.FullToken.FullProperty ))
|
||||||
|
goto fail;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert( 0 );
|
assert( 0 );
|
||||||
}
|
}
|
||||||
|
@@ -56,6 +56,11 @@ struct tgsi_iterate_context
|
|||||||
struct tgsi_iterate_context *ctx,
|
struct tgsi_iterate_context *ctx,
|
||||||
struct tgsi_full_immediate *imm );
|
struct tgsi_full_immediate *imm );
|
||||||
|
|
||||||
|
boolean
|
||||||
|
(* iterate_property)(
|
||||||
|
struct tgsi_iterate_context *ctx,
|
||||||
|
struct tgsi_full_property *prop );
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
(* epilog)(
|
(* epilog)(
|
||||||
struct tgsi_iterate_context *ctx );
|
struct tgsi_iterate_context *ctx );
|
||||||
|
@@ -220,6 +220,22 @@ tgsi_parse_token(
|
|||||||
break;
|
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:
|
default:
|
||||||
assert( 0 );
|
assert( 0 );
|
||||||
}
|
}
|
||||||
|
@@ -67,6 +67,12 @@ struct tgsi_full_immediate
|
|||||||
union tgsi_immediate_data u[4];
|
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_DST_REGISTERS 2
|
||||||
#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
|
#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_declaration FullDeclaration;
|
||||||
struct tgsi_full_immediate FullImmediate;
|
struct tgsi_full_immediate FullImmediate;
|
||||||
struct tgsi_full_instruction FullInstruction;
|
struct tgsi_full_instruction FullInstruction;
|
||||||
|
struct tgsi_full_property FullProperty;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tgsi_parse_context
|
struct tgsi_parse_context
|
||||||
|
@@ -293,6 +293,7 @@ emit_fetch(struct gen_context *gen,
|
|||||||
case TGSI_SWIZZLE_W:
|
case TGSI_SWIZZLE_W:
|
||||||
switch (reg->Register.File) {
|
switch (reg->Register.File) {
|
||||||
case TGSI_FILE_INPUT:
|
case TGSI_FILE_INPUT:
|
||||||
|
case TGSI_FILE_SYSTEM_VALUE:
|
||||||
{
|
{
|
||||||
int offset = (reg->Register.Index * 4 + swizzle) * 16;
|
int offset = (reg->Register.Index * 4 + swizzle) * 16;
|
||||||
int offset_reg = emit_li_offset(gen, offset);
|
int offset_reg = emit_li_offset(gen, offset);
|
||||||
@@ -1173,7 +1174,8 @@ emit_declaration(
|
|||||||
struct ppc_function *func,
|
struct ppc_function *func,
|
||||||
struct tgsi_full_declaration *decl )
|
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
|
#if 0
|
||||||
unsigned first, last, mask;
|
unsigned first, last, mask;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
@@ -1339,6 +1341,9 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ok = 0;
|
ok = 0;
|
||||||
assert( 0 );
|
assert( 0 );
|
||||||
|
@@ -324,6 +324,17 @@ iter_immediate(
|
|||||||
return TRUE;
|
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
|
static boolean
|
||||||
epilog(
|
epilog(
|
||||||
struct tgsi_iterate_context *iter )
|
struct tgsi_iterate_context *iter )
|
||||||
@@ -367,6 +378,7 @@ tgsi_sanity_check(
|
|||||||
ctx.iter.iterate_instruction = iter_instruction;
|
ctx.iter.iterate_instruction = iter_instruction;
|
||||||
ctx.iter.iterate_declaration = iter_declaration;
|
ctx.iter.iterate_declaration = iter_declaration;
|
||||||
ctx.iter.iterate_immediate = iter_immediate;
|
ctx.iter.iterate_immediate = iter_immediate;
|
||||||
|
ctx.iter.iterate_property = iter_property;
|
||||||
ctx.iter.epilog = epilog;
|
ctx.iter.epilog = epilog;
|
||||||
|
|
||||||
memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
|
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++) {
|
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
|
||||||
const struct tgsi_full_src_register *src =
|
const struct tgsi_full_src_register *src =
|
||||||
&fullinst->Src[i];
|
&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;
|
const int ind = src->Register.Index;
|
||||||
if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
|
if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
|
||||||
if (src->Register.SwizzleX == TGSI_SWIZZLE_X) {
|
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_count[file]++;
|
||||||
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
|
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_name[reg] = (ubyte)fulldecl->Semantic.Name;
|
||||||
info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
|
info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
|
||||||
info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
|
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);
|
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
assert( 0 );
|
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 */
|
/* Do a whole bunch of checks for a simple move */
|
||||||
if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
|
if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
|
||||||
src->Register.File != TGSI_FILE_INPUT ||
|
src->Register.File != TGSI_FILE_INPUT ||
|
||||||
|
src->Register.File != TGSI_FILE_SYSTEM_VALUE ||
|
||||||
dst->Register.File != TGSI_FILE_OUTPUT ||
|
dst->Register.File != TGSI_FILE_OUTPUT ||
|
||||||
src->Register.Index != dst->Register.Index ||
|
src->Register.Index != dst->Register.Index ||
|
||||||
|
|
||||||
@@ -235,6 +250,8 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
|
|||||||
/* fall-through */
|
/* fall-through */
|
||||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
|
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||||
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
; /* no-op */
|
; /* no-op */
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
#include "pipe/p_state.h"
|
#include "pipe/p_state.h"
|
||||||
#include "pipe/p_shader_tokens.h"
|
#include "pipe/p_shader_tokens.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shader summary info
|
* Shader summary info
|
||||||
*/
|
*/
|
||||||
@@ -61,8 +60,13 @@ struct tgsi_shader_info
|
|||||||
boolean uses_kill; /**< KIL or KILP instruction used? */
|
boolean uses_kill; /**< KIL or KILP instruction used? */
|
||||||
boolean uses_fogcoord; /**< fragment shader uses fog coord? */
|
boolean uses_fogcoord; /**< fragment shader uses fog coord? */
|
||||||
boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
|
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
|
extern void
|
||||||
tgsi_scan_shader(const struct tgsi_token *tokens,
|
tgsi_scan_shader(const struct tgsi_token *tokens,
|
||||||
|
@@ -1288,6 +1288,7 @@ emit_fetch(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TGSI_FILE_INPUT:
|
case TGSI_FILE_INPUT:
|
||||||
|
case TGSI_FILE_SYSTEM_VALUE:
|
||||||
emit_inputf(
|
emit_inputf(
|
||||||
func,
|
func,
|
||||||
xmm,
|
xmm,
|
||||||
@@ -2633,7 +2634,8 @@ emit_declaration(
|
|||||||
struct x86_function *func,
|
struct x86_function *func,
|
||||||
struct tgsi_full_declaration *decl )
|
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 first, last, mask;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
@@ -2952,6 +2954,9 @@ tgsi_emit_sse2(
|
|||||||
num_immediates++;
|
num_immediates++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||||
|
/* we just ignore them for now */
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ok = 0;
|
ok = 0;
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
|
#include "pipe/p_defines.h"
|
||||||
#include "tgsi_text.h"
|
#include "tgsi_text.h"
|
||||||
#include "tgsi_build.h"
|
#include "tgsi_build.h"
|
||||||
#include "tgsi_info.h"
|
#include "tgsi_info.h"
|
||||||
@@ -110,6 +111,20 @@ static boolean parse_uint( const char **pcur, uint *val )
|
|||||||
return FALSE;
|
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.
|
/* Parse floating point.
|
||||||
*/
|
*/
|
||||||
static boolean parse_float( const char **pcur, float *val )
|
static boolean parse_float( const char **pcur, float *val )
|
||||||
@@ -229,7 +244,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
|
|||||||
"ADDR",
|
"ADDR",
|
||||||
"IMM",
|
"IMM",
|
||||||
"LOOP",
|
"LOOP",
|
||||||
"PRED"
|
"PRED",
|
||||||
|
"SV"
|
||||||
};
|
};
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
@@ -939,6 +955,107 @@ static boolean parse_immediate( struct translate_ctx *ctx )
|
|||||||
return TRUE;
|
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 )
|
static boolean translate( struct translate_ctx *ctx )
|
||||||
{
|
{
|
||||||
eat_opt_white( &ctx->cur );
|
eat_opt_white( &ctx->cur );
|
||||||
@@ -947,7 +1064,6 @@ static boolean translate( struct translate_ctx *ctx )
|
|||||||
|
|
||||||
while (*ctx->cur != '\0') {
|
while (*ctx->cur != '\0') {
|
||||||
uint label_val = 0;
|
uint label_val = 0;
|
||||||
|
|
||||||
if (!eat_white( &ctx->cur )) {
|
if (!eat_white( &ctx->cur )) {
|
||||||
report_error( ctx, "Syntax error" );
|
report_error( ctx, "Syntax error" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -955,7 +1071,6 @@ static boolean translate( struct translate_ctx *ctx )
|
|||||||
|
|
||||||
if (*ctx->cur == '\0')
|
if (*ctx->cur == '\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (parse_label( ctx, &label_val )) {
|
if (parse_label( ctx, &label_val )) {
|
||||||
if (!parse_instruction( ctx, TRUE ))
|
if (!parse_instruction( ctx, TRUE ))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -968,6 +1083,10 @@ static boolean translate( struct translate_ctx *ctx )
|
|||||||
if (!parse_immediate( ctx ))
|
if (!parse_immediate( ctx ))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
else if (str_match_no_case( &ctx->cur, "PROPERTY" )) {
|
||||||
|
if (!parse_property( ctx ))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
else if (!parse_instruction( ctx, FALSE )) {
|
else if (!parse_instruction( ctx, FALSE )) {
|
||||||
return 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
|
* 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_instruction = emit_instruction;
|
||||||
ctx->emit_declaration = emit_declaration;
|
ctx->emit_declaration = emit_declaration;
|
||||||
ctx->emit_immediate = emit_immediate;
|
ctx->emit_immediate = emit_immediate;
|
||||||
|
ctx->emit_property = emit_property;
|
||||||
ctx->tokens_out = tokens_out;
|
ctx->tokens_out = tokens_out;
|
||||||
ctx->max_tokens_out = max_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);
|
ctx->emit_immediate(ctx, fullimm);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
assert( 0 );
|
assert( 0 );
|
||||||
|
@@ -53,6 +53,8 @@ struct tgsi_transform_context
|
|||||||
|
|
||||||
void (*transform_immediate)(struct tgsi_transform_context *ctx,
|
void (*transform_immediate)(struct tgsi_transform_context *ctx,
|
||||||
struct tgsi_full_immediate *imm);
|
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
|
* 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);
|
const struct tgsi_full_declaration *decl);
|
||||||
void (*emit_immediate)(struct tgsi_transform_context *ctx,
|
void (*emit_immediate)(struct tgsi_transform_context *ctx,
|
||||||
const struct tgsi_full_immediate *imm);
|
const struct tgsi_full_immediate *imm);
|
||||||
|
void (*emit_property)(struct tgsi_transform_context *ctx,
|
||||||
|
const struct tgsi_full_property *prop);
|
||||||
|
|
||||||
struct tgsi_header *header;
|
struct tgsi_header *header;
|
||||||
uint max_tokens_out;
|
uint max_tokens_out;
|
||||||
|
@@ -55,6 +55,7 @@ struct tgsi_processor
|
|||||||
#define TGSI_TOKEN_TYPE_DECLARATION 0
|
#define TGSI_TOKEN_TYPE_DECLARATION 0
|
||||||
#define TGSI_TOKEN_TYPE_IMMEDIATE 1
|
#define TGSI_TOKEN_TYPE_IMMEDIATE 1
|
||||||
#define TGSI_TOKEN_TYPE_INSTRUCTION 2
|
#define TGSI_TOKEN_TYPE_INSTRUCTION 2
|
||||||
|
#define TGSI_TOKEN_TYPE_PROPERTY 3
|
||||||
|
|
||||||
struct tgsi_token
|
struct tgsi_token
|
||||||
{
|
{
|
||||||
@@ -64,16 +65,17 @@ struct tgsi_token
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum tgsi_file_type {
|
enum tgsi_file_type {
|
||||||
TGSI_FILE_NULL =0,
|
TGSI_FILE_NULL =0,
|
||||||
TGSI_FILE_CONSTANT =1,
|
TGSI_FILE_CONSTANT =1,
|
||||||
TGSI_FILE_INPUT =2,
|
TGSI_FILE_INPUT =2,
|
||||||
TGSI_FILE_OUTPUT =3,
|
TGSI_FILE_OUTPUT =3,
|
||||||
TGSI_FILE_TEMPORARY =4,
|
TGSI_FILE_TEMPORARY =4,
|
||||||
TGSI_FILE_SAMPLER =5,
|
TGSI_FILE_SAMPLER =5,
|
||||||
TGSI_FILE_ADDRESS =6,
|
TGSI_FILE_ADDRESS =6,
|
||||||
TGSI_FILE_IMMEDIATE =7,
|
TGSI_FILE_IMMEDIATE =7,
|
||||||
TGSI_FILE_LOOP =8,
|
TGSI_FILE_LOOP =8,
|
||||||
TGSI_FILE_PREDICATE =9,
|
TGSI_FILE_PREDICATE =9,
|
||||||
|
TGSI_FILE_SYSTEM_VALUE =10,
|
||||||
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */
|
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,6 +153,22 @@ union tgsi_immediate_data
|
|||||||
float Float;
|
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.
|
/* TGSI opcodes.
|
||||||
*
|
*
|
||||||
* For more information on semantics of opcodes and
|
* For more information on semantics of opcodes and
|
||||||
|
Reference in New Issue
Block a user