summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/tgsi/tgsi_ureg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/tgsi/tgsi_ureg.c')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c122
1 files changed, 100 insertions, 22 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index c0a0627e0b2..f7096bd8e2c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -29,6 +29,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_ureg.h"
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_dump.h"
#include "util/u_memory.h"
#include "util/u_math.h"
@@ -71,6 +72,7 @@ struct ureg_tokens {
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_IMMEDIATE 32
#define UREG_MAX_TEMP 256
+#define UREG_MAX_ADDR 2
#define DOMAIN_DECL 0
#define DOMAIN_INSN 1
@@ -99,11 +101,15 @@ struct ureg_program
} immediate[UREG_MAX_IMMEDIATE];
unsigned nr_immediates;
+ struct ureg_src sampler[PIPE_MAX_SAMPLERS];
+ unsigned nr_samplers;
+
unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps;
+ unsigned nr_addrs;
+
unsigned nr_constants;
- unsigned nr_samplers;
unsigned nr_instructions;
struct ureg_tokens domain[2];
@@ -187,6 +193,8 @@ ureg_dst_register( unsigned file,
dst.File = file;
dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = 0;
+ dst.IndirectIndex = 0;
+ dst.IndirectSwizzle = 0;
dst.Saturate = 0;
dst.Index = index;
dst.Pad1 = 0;
@@ -208,6 +216,8 @@ ureg_src_register( unsigned file,
src.SwizzleW = TGSI_SWIZZLE_W;
src.Pad = 0;
src.Indirect = 0;
+ src.IndirectIndex = 0;
+ src.IndirectSwizzle = 0;
src.Absolute = 0;
src.Index = index;
src.Negate = 0;
@@ -254,6 +264,7 @@ ureg_DECL_fs_input( struct ureg_program *ureg,
unsigned index,
unsigned interp )
{
+ assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
return ureg_DECL_input( ureg, name, index, interp );
}
@@ -263,6 +274,7 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
unsigned name,
unsigned index )
{
+ assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT );
}
@@ -346,11 +358,36 @@ void ureg_release_temporary( struct ureg_program *ureg,
}
+/* Allocate a new address register.
+ */
+struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
+{
+ if (ureg->nr_addrs < UREG_MAX_ADDR)
+ return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );
+
+ assert( 0 );
+ return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
+}
+
/* Allocate a new sampler.
*/
-struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg )
+struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
+ unsigned nr )
{
- return ureg_src_register( TGSI_FILE_SAMPLER, ureg->nr_samplers++ );
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_samplers; i++)
+ if (ureg->sampler[i].Index == nr)
+ return ureg->sampler[i];
+
+ if (i < PIPE_MAX_SAMPLERS) {
+ ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
+ ureg->nr_samplers++;
+ return ureg->sampler[i];
+ }
+
+ assert( 0 );
+ return ureg->sampler[0];
}
@@ -363,6 +400,8 @@ static int match_or_expand_immediate( const float *v,
unsigned *swizzle )
{
unsigned i, j;
+
+ *swizzle = 0;
for (i = 0; i < nr; i++) {
boolean found = FALSE;
@@ -394,8 +433,8 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
const float *v,
unsigned nr )
{
- unsigned i;
- unsigned swizzle = 0;
+ unsigned i, j;
+ unsigned swizzle;
/* Could do a first pass where we examine all existing immediates
* without expanding.
@@ -423,6 +462,12 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *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++)
+ swizzle |= (swizzle & 0x3) << (j * 2);
+
return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
(swizzle >> 0) & 0x3,
(swizzle >> 2) & 0x3,
@@ -442,31 +487,39 @@ ureg_emit_src( struct ureg_program *ureg,
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0;
+ assert(src.File != TGSI_FILE_NULL);
+ assert(src.File != TGSI_FILE_OUTPUT);
+ assert(src.File < TGSI_FILE_COUNT);
+
out[n].value = 0;
out[n].src.File = src.File;
out[n].src.SwizzleX = src.SwizzleX;
out[n].src.SwizzleY = src.SwizzleY;
out[n].src.SwizzleZ = src.SwizzleZ;
out[n].src.SwizzleW = src.SwizzleW;
- out[n].src.Indirect = src.Indirect;
out[n].src.Index = src.Index;
+ out[n].src.Negate = src.Negate;
n++;
if (src.Absolute) {
+ out[0].src.Extended = 1;
+ out[0].src.Negate = 0;
out[n].value = 0;
+ out[n].src_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
out[n].src_ext_mod.Absolute = 1;
+ out[n].src_ext_mod.Negate = src.Negate;
n++;
}
if (src.Indirect) {
+ out[0].src.Indirect = 1;
out[n].value = 0;
out[n].src.File = TGSI_FILE_ADDRESS;
- out[n].src.SwizzleX = TGSI_SWIZZLE_X;
- out[n].src.SwizzleY = TGSI_SWIZZLE_X;
- out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
- out[n].src.SwizzleW = TGSI_SWIZZLE_X;
- out[n].src.Indirect = 0;
- out[n].src.Index = 0;
+ out[n].src.SwizzleX = src.IndirectSwizzle;
+ out[n].src.SwizzleY = src.IndirectSwizzle;
+ out[n].src.SwizzleZ = src.IndirectSwizzle;
+ out[n].src.SwizzleW = src.IndirectSwizzle;
+ out[n].src.Index = src.IndirectIndex;
n++;
}
@@ -484,6 +537,13 @@ ureg_emit_dst( struct ureg_program *ureg,
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0;
+ assert(dst.File != TGSI_FILE_NULL);
+ assert(dst.File != TGSI_FILE_CONSTANT);
+ assert(dst.File != TGSI_FILE_INPUT);
+ assert(dst.File != TGSI_FILE_SAMPLER);
+ assert(dst.File != TGSI_FILE_IMMEDIATE);
+ assert(dst.File < TGSI_FILE_COUNT);
+
out[n].value = 0;
out[n].dst.File = dst.File;
out[n].dst.WriteMask = dst.WriteMask;
@@ -494,12 +554,11 @@ ureg_emit_dst( struct ureg_program *ureg,
if (dst.Indirect) {
out[n].value = 0;
out[n].src.File = TGSI_FILE_ADDRESS;
- out[n].src.SwizzleX = TGSI_SWIZZLE_X;
- out[n].src.SwizzleY = TGSI_SWIZZLE_X;
- out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
- out[n].src.SwizzleW = TGSI_SWIZZLE_X;
- out[n].src.Indirect = 0;
- out[n].src.Index = 0;
+ out[n].src.SwizzleX = dst.IndirectSwizzle;
+ out[n].src.SwizzleY = dst.IndirectSwizzle;
+ out[n].src.SwizzleZ = dst.IndirectSwizzle;
+ out[n].src.SwizzleW = dst.IndirectSwizzle;
+ out[n].src.Index = dst.IndirectIndex;
n++;
}
@@ -523,7 +582,6 @@ ureg_emit_insn(struct ureg_program *ureg,
out[0].insn.NrTokens = 0;
out[0].insn.Opcode = opcode;
out[0].insn.Saturate = saturate;
- out[0].insn.NrTokens = 0;
out[0].insn.NumDstRegs = num_dst;
out[0].insn.NumSrcRegs = num_src;
out[0].insn.Padding = 0;
@@ -542,6 +600,9 @@ ureg_emit_label(struct ureg_program *ureg,
{
union tgsi_any_token *out, *insn;
+ if(!label_token)
+ return;
+
out = get_tokens( ureg, DOMAIN_INSN, 1 );
insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
@@ -617,6 +678,17 @@ ureg_insn(struct ureg_program *ureg,
unsigned insn, i;
boolean saturate;
+#ifdef DEBUG
+ {
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
+ assert(info);
+ if(info) {
+ assert(nr_dst == info->num_dst);
+ assert(nr_src == info->num_src);
+ }
+ }
+#endif
+
saturate = nr_dst ? dst[0].Saturate : FALSE;
insn = ureg_emit_insn( ureg, opcode, saturate, nr_dst, nr_src );
@@ -723,10 +795,10 @@ static void emit_decls( struct ureg_program *ureg )
TGSI_INTERPOLATE_CONSTANT );
}
- if (ureg->nr_samplers) {
+ for (i = 0; i < ureg->nr_samplers; i++) {
emit_decl_range( ureg,
TGSI_FILE_SAMPLER,
- 0, ureg->nr_samplers );
+ ureg->sampler[i].Index, 1 );
}
if (ureg->nr_constants) {
@@ -741,6 +813,12 @@ static void emit_decls( struct ureg_program *ureg )
0, ureg->nr_temps );
}
+ if (ureg->nr_addrs) {
+ emit_decl_range( ureg,
+ TGSI_FILE_ADDRESS,
+ 0, ureg->nr_addrs );
+ }
+
for (i = 0; i < ureg->nr_immediates; i++) {
emit_immediate( ureg,
ureg->immediate[i].v );
@@ -764,7 +842,7 @@ static void copy_instructions( struct ureg_program *ureg )
static void
-fixup_header_size(struct ureg_program *ureg )
+fixup_header_size(struct ureg_program *ureg)
{
union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );