summaryrefslogtreecommitdiff
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.c268
1 files changed, 208 insertions, 60 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 8bd6f68dcc..0ae46785bb 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -44,6 +44,7 @@ union tgsi_any_token {
struct tgsi_property_data prop_data;
struct tgsi_declaration decl;
struct tgsi_declaration_range decl_range;
+ struct tgsi_declaration_dimension decl_dim;
struct tgsi_declaration_semantic decl_semantic;
struct tgsi_immediate imm;
union tgsi_immediate_data imm_data;
@@ -75,6 +76,14 @@ struct ureg_tokens {
#define UREG_MAX_LOOP 1
#define UREG_MAX_PRED 1
+struct const_decl {
+ struct {
+ unsigned first;
+ unsigned last;
+ } constant_range[UREG_MAX_CONSTANT_RANGE];
+ unsigned nr_constant_ranges;
+};
+
#define DOMAIN_DECL 0
#define DOMAIN_INSN 1
@@ -127,13 +136,14 @@ struct ureg_program
unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps;
- struct {
- unsigned first;
- unsigned last;
- } constant_range[UREG_MAX_CONSTANT_RANGE];
- unsigned nr_constant_ranges;
+ struct const_decl const_decls;
+ struct const_decl const_decls2D[PIPE_MAX_CONSTANT_BUFFERS];
unsigned property_gs_input_prim;
+ unsigned property_gs_output_prim;
+ unsigned property_gs_max_vertices;
+ unsigned char property_fs_coord_origin; /* = TGSI_FS_COORD_ORIGIN_* */
+ unsigned char property_fs_coord_pixel_center; /* = TGSI_FS_COORD_PIXEL_CENTER_* */
unsigned nr_addrs;
unsigned nr_preds;
@@ -235,36 +245,40 @@ ureg_dst_register( unsigned file,
return dst;
}
-static INLINE struct ureg_src
-ureg_src_register( unsigned file,
- unsigned index )
+
+void
+ureg_property_gs_input_prim(struct ureg_program *ureg,
+ unsigned input_prim)
{
- 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.IndirectIndex = 0;
- src.IndirectSwizzle = 0;
- src.Absolute = 0;
- src.Index = index;
- src.Negate = 0;
- src.Dimension = 0;
- src.DimensionIndex = 0;
-
- return src;
+ ureg->property_gs_input_prim = input_prim;
}
+void
+ureg_property_gs_output_prim(struct ureg_program *ureg,
+ unsigned output_prim)
+{
+ ureg->property_gs_output_prim = output_prim;
+}
+void
+ureg_property_gs_max_vertices(struct ureg_program *ureg,
+ unsigned max_vertices)
+{
+ ureg->property_gs_max_vertices = max_vertices;
+}
void
-ureg_property_gs_input_prim(struct ureg_program *ureg,
- unsigned gs_input_prim)
+ureg_property_fs_coord_origin(struct ureg_program *ureg,
+ unsigned fs_coord_origin)
+{
+ ureg->property_fs_coord_origin = fs_coord_origin;
+}
+
+void
+ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
+ unsigned fs_coord_pixel_center)
{
- ureg->property_gs_input_prim = gs_input_prim;
+ ureg->property_fs_coord_pixel_center = fs_coord_pixel_center;
}
@@ -374,62 +388,92 @@ out:
/* Returns a new constant register. Keep track of which have been
* referred to so that we can emit decls later.
*
+ * Constant operands declared with this function must be addressed
+ * with a two-dimensional index.
+ *
* There is nothing in this code to bind this constant to any tracked
* value or manage any constant_buffer contents -- that's the
* resposibility of the calling code.
*/
-struct ureg_src ureg_DECL_constant(struct ureg_program *ureg,
- unsigned index )
+void
+ureg_DECL_constant2D(struct ureg_program *ureg,
+ unsigned first,
+ unsigned last,
+ unsigned index2D)
+{
+ struct const_decl *decl = &ureg->const_decls2D[index2D];
+
+ assert(index2D < PIPE_MAX_CONSTANT_BUFFERS);
+
+ if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
+ uint i = decl->nr_constant_ranges++;
+
+ decl->constant_range[i].first = first;
+ decl->constant_range[i].last = last;
+ }
+}
+
+
+/* A one-dimensional, depricated version of ureg_DECL_constant2D().
+ *
+ * Constant operands declared with this function must be addressed
+ * with a one-dimensional index.
+ */
+struct ureg_src
+ureg_DECL_constant(struct ureg_program *ureg,
+ unsigned index)
{
+ struct const_decl *decl = &ureg->const_decls;
unsigned minconst = index, maxconst = index;
unsigned i;
/* Inside existing range?
*/
- for (i = 0; i < ureg->nr_constant_ranges; i++) {
- if (ureg->constant_range[i].first <= index &&
- ureg->constant_range[i].last >= index)
+ for (i = 0; i < decl->nr_constant_ranges; i++) {
+ if (decl->constant_range[i].first <= index &&
+ decl->constant_range[i].last >= index) {
goto out;
+ }
}
/* Extend existing range?
*/
- for (i = 0; i < ureg->nr_constant_ranges; i++) {
- if (ureg->constant_range[i].last == index - 1) {
- ureg->constant_range[i].last = index;
+ for (i = 0; i < decl->nr_constant_ranges; i++) {
+ if (decl->constant_range[i].last == index - 1) {
+ decl->constant_range[i].last = index;
goto out;
}
- if (ureg->constant_range[i].first == index + 1) {
- ureg->constant_range[i].first = index;
+ if (decl->constant_range[i].first == index + 1) {
+ decl->constant_range[i].first = index;
goto out;
}
- minconst = MIN2(minconst, ureg->constant_range[i].first);
- maxconst = MAX2(maxconst, ureg->constant_range[i].last);
+ minconst = MIN2(minconst, decl->constant_range[i].first);
+ maxconst = MAX2(maxconst, decl->constant_range[i].last);
}
/* Create new range?
*/
- if (ureg->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
- i = ureg->nr_constant_ranges++;
- ureg->constant_range[i].first = index;
- ureg->constant_range[i].last = index;
+ if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
+ i = decl->nr_constant_ranges++;
+ decl->constant_range[i].first = index;
+ decl->constant_range[i].last = index;
goto out;
}
/* Collapse all ranges down to one:
*/
i = 0;
- ureg->constant_range[0].first = minconst;
- ureg->constant_range[0].last = maxconst;
- ureg->nr_constant_ranges = 1;
+ decl->constant_range[0].first = minconst;
+ decl->constant_range[0].last = maxconst;
+ decl->nr_constant_ranges = 1;
out:
- assert(i < ureg->nr_constant_ranges);
- assert(ureg->constant_range[i].first <= index);
- assert(ureg->constant_range[i].last >= index);
- return ureg_src_register( TGSI_FILE_CONSTANT, index );
+ assert(i < decl->nr_constant_ranges);
+ assert(decl->constant_range[i].first <= index);
+ assert(decl->constant_range[i].last >= index);
+ return ureg_src_register(TGSI_FILE_CONSTANT, index);
}
@@ -578,7 +622,7 @@ decl_immediate( struct ureg_program *ureg,
unsigned type )
{
unsigned i, j;
- unsigned swizzle;
+ unsigned swizzle = 0;
/* Could do a first pass where we examine all existing immediates
* without expanding.
@@ -656,6 +700,35 @@ ureg_DECL_immediate_uint( struct ureg_program *ureg,
struct ureg_src
+ureg_DECL_immediate_block_uint( struct ureg_program *ureg,
+ const unsigned *v,
+ unsigned nr )
+{
+ uint index;
+ uint i;
+
+ if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) {
+ set_bad(ureg);
+ return ureg_src_register(TGSI_FILE_IMMEDIATE, 0);
+ }
+
+ index = ureg->nr_immediates;
+ ureg->nr_immediates += (nr + 3) / 4;
+
+ for (i = index; i < ureg->nr_immediates; i++) {
+ ureg->immediate[i].type = TGSI_IMM_UINT32;
+ ureg->immediate[i].nr = nr > 4 ? 4 : nr;
+ memcpy(ureg->immediate[i].value.u,
+ &v[(i - index) * 4],
+ ureg->immediate[i].nr * sizeof(uint));
+ nr -= 4;
+ }
+
+ return ureg_src_register(TGSI_FILE_IMMEDIATE, index);
+}
+
+
+struct ureg_src
ureg_DECL_immediate_int( struct ureg_program *ureg,
const int *v,
unsigned nr )
@@ -691,7 +764,7 @@ ureg_emit_src( struct ureg_program *ureg,
if (src.Indirect) {
out[0].src.Indirect = 1;
out[n].value = 0;
- out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.File = src.IndirectFile;
out[n].src.SwizzleX = src.IndirectSwizzle;
out[n].src.SwizzleY = src.IndirectSwizzle;
out[n].src.SwizzleZ = src.IndirectSwizzle;
@@ -1058,6 +1131,31 @@ static void emit_decl_range( struct ureg_program *ureg,
}
static void
+emit_decl_range2D(struct ureg_program *ureg,
+ unsigned file,
+ unsigned first,
+ unsigned last,
+ unsigned index2D)
+{
+ union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 3;
+ out[0].decl.File = file;
+ out[0].decl.UsageMask = 0xf;
+ out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+ out[0].decl.Dimension = 1;
+
+ out[1].value = 0;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = last;
+
+ out[2].value = 0;
+ out[2].decl_dim.Index2D = index2D;
+}
+
+static void
emit_immediate( struct ureg_program *ureg,
const unsigned *v,
unsigned type )
@@ -1104,6 +1202,38 @@ static void emit_decls( struct ureg_program *ureg )
ureg->property_gs_input_prim);
}
+ if (ureg->property_gs_output_prim != ~0) {
+ assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_GS_OUTPUT_PRIM,
+ ureg->property_gs_output_prim);
+ }
+
+ if (ureg->property_gs_max_vertices != ~0) {
+ assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_GS_MAX_VERTICES,
+ ureg->property_gs_max_vertices);
+ }
+
+ if (ureg->property_fs_coord_origin) {
+ assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_FS_COORD_ORIGIN,
+ ureg->property_fs_coord_origin);
+ }
+
+ if (ureg->property_fs_coord_pixel_center) {
+ assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_FS_COORD_PIXEL_CENTER,
+ ureg->property_fs_coord_pixel_center);
+ }
+
if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
for (i = 0; i < UREG_MAX_INPUT; i++) {
if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
@@ -1152,13 +1282,29 @@ static void emit_decls( struct ureg_program *ureg )
ureg->sampler[i].Index, 1 );
}
- if (ureg->nr_constant_ranges) {
- for (i = 0; i < ureg->nr_constant_ranges; i++)
- emit_decl_range( ureg,
- TGSI_FILE_CONSTANT,
- ureg->constant_range[i].first,
- (ureg->constant_range[i].last + 1 -
- ureg->constant_range[i].first) );
+ if (ureg->const_decls.nr_constant_ranges) {
+ for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) {
+ emit_decl_range(ureg,
+ TGSI_FILE_CONSTANT,
+ ureg->const_decls.constant_range[i].first,
+ ureg->const_decls.constant_range[i].last - ureg->const_decls.constant_range[i].first + 1);
+ }
+ }
+
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ struct const_decl *decl = &ureg->const_decls2D[i];
+
+ if (decl->nr_constant_ranges) {
+ uint j;
+
+ for (j = 0; j < decl->nr_constant_ranges; j++) {
+ emit_decl_range2D(ureg,
+ TGSI_FILE_CONSTANT,
+ decl->constant_range[j].first,
+ decl->constant_range[j].last,
+ i);
+ }
+ }
}
if (ureg->nr_temps) {
@@ -1314,6 +1460,8 @@ struct ureg_program *ureg_create( unsigned processor )
ureg->processor = processor;
ureg->property_gs_input_prim = ~0;
+ ureg->property_gs_output_prim = ~0;
+ ureg->property_gs_max_vertices = ~0;
return ureg;
}