#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
+#include "util/u_debug.h"
#ifdef __cplusplus
extern "C" {
unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
- unsigned Pad : 1; /* BOOL */
unsigned Indirect : 1; /* BOOL */
+ unsigned DimIndirect : 1; /* BOOL */
+ unsigned Dimension : 1; /* BOOL */
unsigned Absolute : 1; /* BOOL */
- int Index : 16; /* SINT */
unsigned Negate : 1; /* BOOL */
- int IndirectIndex : 16; /* SINT */
- int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
+ int Index : 16; /* SINT */
+ unsigned IndirectFile : 4; /* TGSI_FILE_ */
+ int IndirectIndex : 16; /* SINT */
+ unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
+ int DimensionIndex : 16; /* SINT */
+ unsigned DimIndFile : 4; /* TGSI_FILE_ */
+ int DimIndIndex : 16; /* SINT */
+ unsigned DimIndSwizzle : 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_ */
};
const struct tgsi_token *
ureg_finalize( struct ureg_program * );
+/* Create and return a shader:
+ */
void *
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 );
+
+
+/* Free the tokens created by ureg_get_tokens() */
+void ureg_free_tokens( const struct tgsi_token *tokens );
+
+
void
ureg_destroy( struct ureg_program * );
}
+/***********************************************************************
+ * Build shader properties:
+ */
+
+void
+ureg_property_gs_input_prim(struct ureg_program *ureg,
+ unsigned input_prim);
+
+void
+ureg_property_gs_output_prim(struct ureg_program *ureg,
+ unsigned output_prim);
+
+void
+ureg_property_gs_max_vertices(struct ureg_program *ureg,
+ unsigned max_vertices);
+
+void
+ureg_property_fs_coord_origin(struct ureg_program *ureg,
+ unsigned fs_coord_origin);
+
+void
+ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
+ unsigned fs_coord_pixel_center);
/***********************************************************************
* Build shader declarations:
*/
struct ureg_src
-ureg_DECL_fs_input( struct ureg_program *,
- unsigned semantic_name,
- unsigned semantic_index,
- unsigned interp_mode );
+ureg_DECL_fs_input_cyl(struct ureg_program *,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned interp_mode,
+ unsigned cylindrical_wrap);
+
+static INLINE struct ureg_src
+ureg_DECL_fs_input(struct ureg_program *ureg,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned interp_mode)
+{
+ return ureg_DECL_fs_input_cyl(ureg,
+ semantic_name,
+ semantic_index,
+ interp_mode,
+ 0);
+}
struct ureg_src
ureg_DECL_vs_input( struct ureg_program *,
- unsigned semantic_name,
- unsigned semantic_index );
+ unsigned index );
+
+struct ureg_src
+ureg_DECL_gs_input(struct ureg_program *,
+ unsigned index,
+ unsigned semantic_name,
+ unsigned semantic_index);
+
+struct ureg_src
+ureg_DECL_system_value(struct ureg_program *,
+ unsigned index,
+ unsigned semantic_name,
+ unsigned semantic_index);
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
unsigned nr );
struct ureg_src
-ureg_DECL_constant( struct ureg_program * );
+ureg_DECL_immediate_uint( struct ureg_program *,
+ const unsigned *v,
+ unsigned nr );
+
+struct ureg_src
+ureg_DECL_immediate_block_uint( struct ureg_program *,
+ const unsigned *v,
+ unsigned nr );
+
+struct ureg_src
+ureg_DECL_immediate_int( struct ureg_program *,
+ const int *v,
+ unsigned nr );
+
+void
+ureg_DECL_constant2D(struct ureg_program *ureg,
+ unsigned first,
+ unsigned last,
+ unsigned index2D);
+
+struct ureg_src
+ureg_DECL_constant( struct ureg_program *,
+ unsigned index );
struct ureg_dst
ureg_DECL_temporary( struct ureg_program * );
struct ureg_dst
ureg_DECL_address( 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
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
*/
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:
*/
-unsigned
+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 ); \
}
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 )
{
ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
{
assert(reg.File != TGSI_FILE_NULL);
- assert(addr.File == TGSI_FILE_ADDRESS);
+ assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
reg.Indirect = 1;
+ reg.IndirectFile = addr.File;
reg.IndirectIndex = addr.Index;
reg.IndirectSwizzle = addr.SwizzleX;
return reg;
}
+static INLINE struct ureg_src
+ureg_src_dimension( struct ureg_src reg, int index )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.Dimension = 1;
+ reg.DimIndirect = 0;
+ reg.DimensionIndex = index;
+ return reg;
+}
+
+
+static INLINE struct ureg_src
+ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
+ int index )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.Dimension = 1;
+ reg.DimIndirect = 1;
+ reg.DimensionIndex = index;
+ reg.DimIndFile = addr.File;
+ reg.DimIndIndex = addr.Index;
+ reg.DimIndSwizzle = addr.SwizzleX;
+ return reg;
+}
+
static INLINE struct ureg_dst
ureg_dst( struct ureg_src src )
{
struct ureg_dst dst;
+ assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
+
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;
}
+static INLINE struct ureg_src
+ureg_src_register(unsigned file,
+ unsigned index)
+{
+ struct ureg_src src;
+
+ src.File = file;
+ src.SwizzleX = TGSI_SWIZZLE_X;
+ src.SwizzleY = TGSI_SWIZZLE_Y;
+ src.SwizzleZ = TGSI_SWIZZLE_Z;
+ src.SwizzleW = TGSI_SWIZZLE_W;
+ src.Indirect = 0;
+ src.IndirectFile = TGSI_FILE_NULL;
+ src.IndirectIndex = 0;
+ src.IndirectSwizzle = 0;
+ src.Absolute = 0;
+ src.Index = index;
+ src.Negate = 0;
+ src.Dimension = 0;
+ src.DimensionIndex = 0;
+ src.DimIndirect = 0;
+ src.DimIndFile = TGSI_FILE_NULL;
+ src.DimIndIndex = 0;
+ src.DimIndSwizzle = 0;
+
+ return src;
+}
+
static INLINE struct ureg_src
ureg_src( struct ureg_dst dst )
{
src.SwizzleY = TGSI_SWIZZLE_Y;
src.SwizzleZ = TGSI_SWIZZLE_Z;
src.SwizzleW = TGSI_SWIZZLE_W;
- src.Pad = 0;
src.Indirect = dst.Indirect;
+ src.IndirectFile = TGSI_FILE_ADDRESS;
src.IndirectIndex = dst.IndirectIndex;
src.IndirectSwizzle = dst.IndirectSwizzle;
src.Absolute = 0;
src.Index = dst.Index;
src.Negate = 0;
+ src.Dimension = 0;
+ src.DimensionIndex = 0;
+ src.DimIndirect = 0;
+ src.DimIndFile = TGSI_FILE_NULL;
+ src.DimIndIndex = 0;
+ src.DimIndSwizzle = 0;
return src;
}
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;
- dst.Pad1 = 0;
- dst.Pad2 = 0;
return dst;
}
src.SwizzleY = 0;
src.SwizzleZ = 0;
src.SwizzleW = 0;
- src.Pad = 0;
src.Indirect = 0;
+ src.IndirectFile = TGSI_FILE_NULL;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0;
src.Index = 0;
src.Negate = 0;
-
+ src.Dimension = 0;
+ src.DimensionIndex = 0;
+ src.DimIndirect = 0;
+ src.DimIndFile = TGSI_FILE_NULL;
+ src.DimIndIndex = 0;
+ src.DimIndSwizzle = 0;
+
return src;
}