tgsi: Support signed/unsigned integer immediate types.

This commit is contained in:
Michal Krol 2009-12-23 18:33:44 +01:00
parent b1c55e80aa
commit ff56a12051
5 changed files with 215 additions and 47 deletions

View File

@ -128,7 +128,9 @@ static const char *semantic_names[] =
static const char *immediate_type_names[] =
{
"FLT32"
"FLT32",
"UINT32",
"INT32"
};
static const char *swizzle_names[] =
@ -412,6 +414,12 @@ iter_immediate(
case TGSI_IMM_FLOAT32:
FLT( imm->u[i].Float );
break;
case TGSI_IMM_UINT32:
UID(imm->u[i].Uint);
break;
case TGSI_IMM_INT32:
SID(imm->u[i].Int);
break;
default:
assert( 0 );
}

View File

@ -119,17 +119,29 @@ tgsi_parse_token(
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;
uint imm_count;
memset(imm, 0, sizeof *imm);
copy_token(&imm->Immediate, &token);
imm_count = imm->Immediate.NrTokens - 1;
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
{
uint imm_count = imm->Immediate.NrTokens - 1;
for (i = 0; i < imm_count; i++) {
next_token(ctx, &imm->u[i]);
}
for (i = 0; i < imm_count; i++) {
next_token(ctx, &imm->u[i].Float);
}
break;
case TGSI_IMM_UINT32:
for (i = 0; i < imm_count; i++) {
next_token(ctx, &imm->u[i].Uint);
}
break;
case TGSI_IMM_INT32:
for (i = 0; i < imm_count; i++) {
next_token(ctx, &imm->u[i].Int);
}
break;

View File

@ -445,7 +445,9 @@ iter_immediate(
/* Check data type validity.
*/
if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) {
if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 &&
imm->Immediate.DataType != TGSI_IMM_UINT32 &&
imm->Immediate.DataType != TGSI_IMM_INT32) {
report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType );
return TRUE;
}

View File

@ -101,8 +101,13 @@ struct ureg_program
unsigned nr_outputs;
struct {
float v[4];
union {
float f[4];
unsigned u[4];
int i[4];
} value;
unsigned nr;
unsigned type;
} immediate[UREG_MAX_IMMEDIATE];
unsigned nr_immediates;
@ -486,16 +491,15 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
}
static int match_or_expand_immediate( const float *v,
unsigned nr,
float *v2,
unsigned *nr2,
unsigned *swizzle )
static int
match_or_expand_immediate( const unsigned *v,
unsigned nr,
unsigned *v2,
unsigned *nr2,
unsigned *swizzle )
{
unsigned i, j;
*swizzle = 0;
for (i = 0; i < nr; i++) {
@ -509,8 +513,9 @@ static int match_or_expand_immediate( const float *v,
}
if (!found) {
if (*nr2 >= 4)
if (*nr2 >= 4) {
return FALSE;
}
v2[*nr2] = v[i];
*swizzle |= *nr2 << (i * 2);
@ -522,11 +527,11 @@ static int match_or_expand_immediate( const float *v,
}
struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
const float *v,
unsigned nr )
static struct ureg_src
decl_immediate( struct ureg_program *ureg,
const unsigned *v,
unsigned nr,
unsigned type )
{
unsigned i, j;
unsigned swizzle;
@ -536,38 +541,82 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
*/
for (i = 0; i < ureg->nr_immediates; i++) {
if (match_or_expand_immediate( v,
nr,
ureg->immediate[i].v,
&ureg->immediate[i].nr,
&swizzle ))
if (ureg->immediate[i].type != type) {
continue;
}
if (match_or_expand_immediate(v,
nr,
ureg->immediate[i].value.u,
&ureg->immediate[i].nr,
&swizzle)) {
goto out;
}
}
if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
i = ureg->nr_immediates++;
if (match_or_expand_immediate( v,
nr,
ureg->immediate[i].v,
&ureg->immediate[i].nr,
&swizzle ))
ureg->immediate[i].type = type;
if (match_or_expand_immediate(v,
nr,
ureg->immediate[i].value.u,
&ureg->immediate[i].nr,
&swizzle)) {
goto out;
}
}
set_bad( ureg );
set_bad(ureg);
out:
/* Make sure that all referenced elements are from this immediate.
* Has the effect of making size-one immediates into scalars.
*/
for (j = nr; j < 4; j++)
for (j = nr; j < 4; j++) {
swizzle |= (swizzle & 0x3) << (j * 2);
}
return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
(swizzle >> 0) & 0x3,
(swizzle >> 2) & 0x3,
(swizzle >> 4) & 0x3,
(swizzle >> 6) & 0x3);
return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
(swizzle >> 0) & 0x3,
(swizzle >> 2) & 0x3,
(swizzle >> 4) & 0x3,
(swizzle >> 6) & 0x3);
}
struct ureg_src
ureg_DECL_immediate( struct ureg_program *ureg,
const float *v,
unsigned nr )
{
union {
float f[4];
unsigned u[4];
} fu;
unsigned int i;
for (i = 0; i < nr; i++) {
fu.f[i] = v[i];
}
return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
}
struct ureg_src
ureg_DECL_immediate_uint( struct ureg_program *ureg,
const unsigned *v,
unsigned nr )
{
return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32);
}
struct ureg_src
ureg_DECL_immediate_int( struct ureg_program *ureg,
const int *v,
unsigned nr )
{
return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);
}
@ -955,21 +1004,23 @@ static void emit_decl_range( struct ureg_program *ureg,
out[1].decl_range.Last = first + count - 1;
}
static void emit_immediate( struct ureg_program *ureg,
const float *v )
static void
emit_immediate( struct ureg_program *ureg,
const unsigned *v,
unsigned type )
{
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
out[0].value = 0;
out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
out[0].imm.NrTokens = 5;
out[0].imm.DataType = TGSI_IMM_FLOAT32;
out[0].imm.DataType = type;
out[0].imm.Padding = 0;
out[1].imm_data.Float = v[0];
out[2].imm_data.Float = v[1];
out[3].imm_data.Float = v[2];
out[4].imm_data.Float = v[3];
out[1].imm_data.Uint = v[0];
out[2].imm_data.Uint = v[1];
out[3].imm_data.Uint = v[2];
out[4].imm_data.Uint = v[3];
}
@ -1055,7 +1106,8 @@ static void emit_decls( struct ureg_program *ureg )
for (i = 0; i < ureg->nr_immediates; i++) {
emit_immediate( ureg,
ureg->immediate[i].v );
ureg->immediate[i].value.u,
ureg->immediate[i].type );
}
}

View File

@ -147,6 +147,16 @@ ureg_DECL_immediate( struct ureg_program *,
const float *v,
unsigned nr );
struct ureg_src
ureg_DECL_immediate_uint( struct ureg_program *,
const unsigned *v,
unsigned nr );
struct ureg_src
ureg_DECL_immediate_int( struct ureg_program *,
const int *v,
unsigned nr );
struct ureg_src
ureg_DECL_constant( struct ureg_program *,
unsigned index );
@ -221,6 +231,90 @@ ureg_imm1f( struct ureg_program *ureg,
return ureg_DECL_immediate( ureg, v, 1 );
}
static INLINE struct ureg_src
ureg_imm4u( struct ureg_program *ureg,
unsigned a, unsigned b,
unsigned c, unsigned d)
{
unsigned v[4];
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
return ureg_DECL_immediate_uint( ureg, v, 4 );
}
static INLINE struct ureg_src
ureg_imm3u( struct ureg_program *ureg,
unsigned a, unsigned b,
unsigned c)
{
unsigned v[3];
v[0] = a;
v[1] = b;
v[2] = c;
return ureg_DECL_immediate_uint( ureg, v, 3 );
}
static INLINE struct ureg_src
ureg_imm2u( struct ureg_program *ureg,
unsigned a, unsigned b)
{
unsigned v[2];
v[0] = a;
v[1] = b;
return ureg_DECL_immediate_uint( ureg, v, 2 );
}
static INLINE struct ureg_src
ureg_imm1u( struct ureg_program *ureg,
unsigned a)
{
return ureg_DECL_immediate_uint( ureg, &a, 1 );
}
static INLINE struct ureg_src
ureg_imm4i( struct ureg_program *ureg,
int a, int b,
int c, int d)
{
int v[4];
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
return ureg_DECL_immediate_int( ureg, v, 4 );
}
static INLINE struct ureg_src
ureg_imm3i( struct ureg_program *ureg,
int a, int b,
int c)
{
int v[3];
v[0] = a;
v[1] = b;
v[2] = c;
return ureg_DECL_immediate_int( ureg, v, 3 );
}
static INLINE struct ureg_src
ureg_imm2i( struct ureg_program *ureg,
int a, int b)
{
int v[2];
v[0] = a;
v[1] = b;
return ureg_DECL_immediate_int( ureg, v, 2 );
}
static INLINE struct ureg_src
ureg_imm1i( struct ureg_program *ureg,
int a)
{
return ureg_DECL_immediate_int( ureg, &a, 1 );
}
/***********************************************************************
* Functions for patching up labels
*/