#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct ureg_program;
/* Almost a tgsi_src_register, but we need to pull in the Absolute
unsigned Absolute : 1; /* BOOL */
int Index : 16; /* SINT */
unsigned Negate : 1; /* BOOL */
+ int IndirectIndex : 16; /* SINT */
+ int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
};
/* Very similar to a tgsi_dst_register, removing unsupported fields
unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
unsigned Indirect : 1; /* BOOL */
unsigned Saturate : 1; /* BOOL */
+ unsigned Predicate : 1;
+ unsigned PredNegate : 1; /* BOOL */
+ unsigned PredSwizzleX: 2; /* TGSI_SWIZZLE_ */
+ unsigned PredSwizzleY: 2; /* TGSI_SWIZZLE_ */
+ unsigned PredSwizzleZ: 2; /* TGSI_SWIZZLE_ */
+ unsigned PredSwizzleW: 2; /* TGSI_SWIZZLE_ */
int Index : 16; /* SINT */
- unsigned Pad1 : 5;
- unsigned Pad2 : 1; /* BOOL */
+ int IndirectIndex : 16; /* SINT */
+ int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
};
struct pipe_context;
struct ureg_program *
-ureg_create( struct pipe_context *pipe,
- unsigned processor );
+ureg_create( unsigned processor );
+
+const struct tgsi_token *
+ureg_finalize( struct ureg_program * );
+/* Create and return a shader:
+ */
void *
-ureg_create_shader( struct ureg_program * );
+ureg_create_shader( struct ureg_program *,
+ struct pipe_context *pipe );
+
+
+/* Alternately, return the built token stream and hand ownership of
+ * that memory to the caller:
+ */
+const struct tgsi_token *
+ureg_get_tokens( struct ureg_program *ureg,
+ unsigned *nr_tokens );
+
void
ureg_destroy( struct ureg_program * );
/***********************************************************************
* Convenience routine:
*/
-static INLINE void *ureg_create_shader_and_destroy( struct ureg_program *p )
+static INLINE void *
+ureg_create_shader_and_destroy( struct ureg_program *p,
+ struct pipe_context *pipe )
{
- void *result = ureg_create_shader( p );
+ void *result = ureg_create_shader( p, pipe );
ureg_destroy( p );
return result;
}
struct ureg_src
ureg_DECL_vs_input( struct ureg_program *,
- unsigned semantic_name,
- unsigned semantic_index );
+ unsigned index );
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
unsigned nr );
struct ureg_src
-ureg_DECL_constant( struct ureg_program * );
+ureg_DECL_constant( struct ureg_program *,
+ unsigned index );
struct ureg_dst
ureg_DECL_temporary( struct ureg_program * );
ureg_release_temporary( struct ureg_program *ureg,
struct ureg_dst tmp );
+struct ureg_dst
+ureg_DECL_address( struct ureg_program * );
+
+struct ureg_dst
+ureg_DECL_loop( struct ureg_program * );
+
+struct ureg_dst
+ureg_DECL_predicate(struct ureg_program *);
+
+/* Supply an index to the sampler declaration as this is the hook to
+ * the external pipe_sampler state. Users of this function probably
+ * don't want just any sampler, but a specific one which they've set
+ * up state for in the context.
+ */
struct ureg_src
-ureg_DECL_sampler( struct ureg_program * );
+ureg_DECL_sampler( struct ureg_program *,
+ unsigned index );
static INLINE struct ureg_src
-ureg_DECL_immediate4f( struct ureg_program *ureg,
+ureg_imm4f( struct ureg_program *ureg,
float a, float b,
float c, float d)
{
}
static INLINE struct ureg_src
-ureg_DECL_immediate3f( struct ureg_program *ureg,
+ureg_imm3f( struct ureg_program *ureg,
float a, float b,
float c)
{
}
static INLINE struct ureg_src
-ureg_DECL_immediate2f( struct ureg_program *ureg,
+ureg_imm2f( struct ureg_program *ureg,
float a, float b)
{
float v[2];
}
static INLINE struct ureg_src
-ureg_DECL_immediate1f( struct ureg_program *ureg,
+ureg_imm1f( struct ureg_program *ureg,
float a)
{
float v[1];
}
/***********************************************************************
- * Internal instruction helpers, don't call these directly:
+ * Functions for patching up labels
*/
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
unsigned
+ureg_get_instruction_number( struct ureg_program *ureg );
+
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ *
+ * Labels are obtained from instruction emitters, eg ureg_CAL().
+ * Instruction numbers are obtained from ureg_get_instruction_number(),
+ * above.
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+ unsigned label_token,
+ unsigned instruction_number );
+
+
+/* Generic instruction emitter. Use if you need to pass the opcode as
+ * a parameter, rather than using the emit_OP() varients below.
+ */
+void
+ureg_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ const struct ureg_src *src,
+ unsigned nr_src );
+
+
+void
+ureg_tex_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ unsigned target,
+ const struct ureg_src *src,
+ unsigned nr_src );
+
+
+void
+ureg_label_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_src *src,
+ unsigned nr_src,
+ unsigned *label);
+
+
+/***********************************************************************
+ * Internal instruction helpers, don't call these directly:
+ */
+
+struct ureg_emit_insn_result {
+ unsigned insn_token; /*< Used to fixup insn size. */
+ unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */
+};
+
+struct ureg_emit_insn_result
ureg_emit_insn(struct ureg_program *ureg,
unsigned opcode,
boolean saturate,
+ boolean predicate,
+ boolean pred_negate,
+ unsigned pred_swizzle_x,
+ unsigned pred_swizzle_y,
+ unsigned pred_swizzle_z,
+ unsigned pred_swizzle_w,
unsigned num_dst,
unsigned num_src );
static INLINE void ureg_##op( struct ureg_program *ureg ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ FALSE, \
+ FALSE, \
+ FALSE, \
+ TGSI_SWIZZLE_X, \
+ TGSI_SWIZZLE_Y, \
+ TGSI_SWIZZLE_Z, \
+ TGSI_SWIZZLE_W, \
+ 0, \
+ 0).insn_token; \
ureg_fixup_insn_size( ureg, insn ); \
}
struct ureg_src src ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ FALSE, \
+ FALSE, \
+ FALSE, \
+ TGSI_SWIZZLE_X, \
+ TGSI_SWIZZLE_Y, \
+ TGSI_SWIZZLE_Z, \
+ TGSI_SWIZZLE_W, \
+ 0, \
+ 1).insn_token; \
ureg_emit_src( ureg, src ); \
ureg_fixup_insn_size( ureg, insn ); \
}
unsigned *label_token ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
- ureg_emit_label( ureg, insn, label_token ); \
- ureg_fixup_insn_size( ureg, insn ); \
+ struct ureg_emit_insn_result insn; \
+ insn = ureg_emit_insn(ureg, \
+ opcode, \
+ FALSE, \
+ FALSE, \
+ FALSE, \
+ TGSI_SWIZZLE_X, \
+ TGSI_SWIZZLE_Y, \
+ TGSI_SWIZZLE_Z, \
+ TGSI_SWIZZLE_W, \
+ 0, \
+ 0); \
+ ureg_emit_label( ureg, insn.extended_token, label_token ); \
+ ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP01_LBL( op ) \
unsigned *label_token ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
- ureg_emit_label( ureg, insn, label_token ); \
+ struct ureg_emit_insn_result insn; \
+ insn = ureg_emit_insn(ureg, \
+ opcode, \
+ FALSE, \
+ FALSE, \
+ FALSE, \
+ TGSI_SWIZZLE_X, \
+ TGSI_SWIZZLE_Y, \
+ TGSI_SWIZZLE_Z, \
+ TGSI_SWIZZLE_W, \
+ 0, \
+ 1); \
+ ureg_emit_label( ureg, insn.extended_token, label_token ); \
ureg_emit_src( ureg, src ); \
- ureg_fixup_insn_size( ureg, insn ); \
+ ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP10( op ) \
struct ureg_dst dst ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 0 ); \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 0).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_fixup_insn_size( ureg, insn ); \
}
struct ureg_src src ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 1 ); \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 1).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src ); \
ureg_fixup_insn_size( ureg, insn ); \
struct ureg_src src1 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 2).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
struct ureg_src src1 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
- ureg_emit_texture( ureg, insn, target ); \
+ struct ureg_emit_insn_result insn; \
+ insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 2); \
+ ureg_emit_texture( ureg, insn.extended_token, target ); \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
- ureg_fixup_insn_size( ureg, insn ); \
+ ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP13( op ) \
struct ureg_src src2 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 3 ); \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 3).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
struct ureg_src src3 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
- unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 4 ); \
- ureg_emit_texture( ureg, insn, target ); \
+ struct ureg_emit_insn_result insn; \
+ insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 4); \
+ ureg_emit_texture( ureg, insn.extended_token, target ); \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_emit_src( ureg, src2 ); \
ureg_emit_src( ureg, src3 ); \
- ureg_fixup_insn_size( ureg, insn ); \
+ ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
static INLINE struct ureg_src
ureg_negate( struct ureg_src reg )
{
+ assert(reg.File != TGSI_FILE_NULL);
reg.Negate ^= 1;
return reg;
}
static INLINE struct ureg_src
ureg_abs( struct ureg_src reg )
{
+ assert(reg.File != TGSI_FILE_NULL);
reg.Absolute = 1;
reg.Negate = 0;
return reg;
(reg.SwizzleZ << 4) |
(reg.SwizzleW << 6));
+ assert(reg.File != TGSI_FILE_NULL);
+ assert(x < 4);
+ assert(y < 4);
+ assert(z < 4);
+ assert(w < 4);
+
reg.SwizzleX = (swz >> (x*2)) & 0x3;
reg.SwizzleY = (swz >> (y*2)) & 0x3;
reg.SwizzleZ = (swz >> (z*2)) & 0x3;
ureg_writemask( struct ureg_dst reg,
unsigned writemask )
{
+ assert(reg.File != TGSI_FILE_NULL);
reg.WriteMask &= writemask;
return reg;
}
static INLINE struct ureg_dst
ureg_saturate( struct ureg_dst reg )
{
+ assert(reg.File != TGSI_FILE_NULL);
reg.Saturate = 1;
return reg;
}
+static INLINE struct ureg_dst
+ureg_predicate(struct ureg_dst reg,
+ boolean negate,
+ unsigned swizzle_x,
+ unsigned swizzle_y,
+ unsigned swizzle_z,
+ unsigned swizzle_w)
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.Predicate = 1;
+ reg.PredNegate = negate;
+ reg.PredSwizzleX = swizzle_x;
+ reg.PredSwizzleY = swizzle_y;
+ reg.PredSwizzleZ = swizzle_z;
+ reg.PredSwizzleW = swizzle_w;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ assert(addr.File == TGSI_FILE_ADDRESS);
+ reg.Indirect = 1;
+ reg.IndirectIndex = addr.Index;
+ reg.IndirectSwizzle = addr.SwizzleX;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ assert(addr.File == TGSI_FILE_ADDRESS);
+ reg.Indirect = 1;
+ reg.IndirectIndex = addr.Index;
+ reg.IndirectSwizzle = addr.SwizzleX;
+ return reg;
+}
+
static INLINE struct ureg_dst
ureg_dst( struct ureg_src src )
{
dst.File = src.File;
dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = src.Indirect;
+ dst.IndirectIndex = src.IndirectIndex;
+ dst.IndirectSwizzle = src.IndirectSwizzle;
dst.Saturate = 0;
+ dst.Predicate = 0;
+ dst.PredNegate = 0;
+ dst.PredSwizzleX = TGSI_SWIZZLE_X;
+ dst.PredSwizzleY = TGSI_SWIZZLE_Y;
+ dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
+ dst.PredSwizzleW = TGSI_SWIZZLE_W;
dst.Index = src.Index;
- dst.Pad1 = 0;
- dst.Pad2 = 0;
return dst;
}
src.SwizzleW = TGSI_SWIZZLE_W;
src.Pad = 0;
src.Indirect = dst.Indirect;
+ src.IndirectIndex = dst.IndirectIndex;
+ src.IndirectSwizzle = dst.IndirectSwizzle;
src.Absolute = 0;
src.Index = dst.Index;
src.Negate = 0;
+static INLINE struct ureg_dst
+ureg_dst_undef( void )
+{
+ struct ureg_dst dst;
+
+ dst.File = TGSI_FILE_NULL;
+ dst.WriteMask = 0;
+ dst.Indirect = 0;
+ dst.IndirectIndex = 0;
+ dst.IndirectSwizzle = 0;
+ dst.Saturate = 0;
+ dst.Predicate = 0;
+ dst.PredNegate = 0;
+ dst.PredSwizzleX = TGSI_SWIZZLE_X;
+ dst.PredSwizzleY = TGSI_SWIZZLE_Y;
+ dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
+ dst.PredSwizzleW = TGSI_SWIZZLE_W;
+ dst.Index = 0;
+
+ return dst;
+}
+
+static INLINE struct ureg_src
+ureg_src_undef( void )
+{
+ struct ureg_src src;
+
+ src.File = TGSI_FILE_NULL;
+ src.SwizzleX = 0;
+ src.SwizzleY = 0;
+ src.SwizzleZ = 0;
+ src.SwizzleW = 0;
+ src.Pad = 0;
+ src.Indirect = 0;
+ src.IndirectIndex = 0;
+ src.IndirectSwizzle = 0;
+ src.Absolute = 0;
+ src.Index = 0;
+ src.Negate = 0;
+
+ return src;
+}
+
+static INLINE boolean
+ureg_src_is_undef( struct ureg_src src )
+{
+ return src.File == TGSI_FILE_NULL;
+}
+
+static INLINE boolean
+ureg_dst_is_undef( struct ureg_dst dst )
+{
+ return dst.File == TGSI_FILE_NULL;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
#endif