**************************************************************************/
+#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_sanity.h"
#include "util/u_debug.h"
+#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_bitmask.h"
unsigned count;
};
-#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS
+#define UREG_MAX_INPUT PIPE_MAX_SHADER_INPUTS
#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS
#define UREG_MAX_OUTPUT PIPE_MAX_SHADER_OUTPUTS
#define UREG_MAX_CONSTANT_RANGE 32
#define UREG_MAX_IMMEDIATE 4096
-#define UREG_MAX_ADDR 2
+#define UREG_MAX_ADDR 3
#define UREG_MAX_PRED 1
#define UREG_MAX_ARRAY_TEMPS 256
struct ureg_program
{
unsigned processor;
- struct pipe_context *pipe;
+ bool supports_any_inout_decl_range;
struct {
unsigned semantic_name;
unsigned semantic_index;
unsigned interp;
unsigned char cylindrical_wrap;
- unsigned char centroid;
- } fs_input[UREG_MAX_INPUT];
- unsigned nr_fs_inputs;
-
- unsigned vs_inputs[UREG_MAX_INPUT/32];
+ unsigned interp_location;
+ unsigned first;
+ unsigned last;
+ unsigned array_id;
+ } input[UREG_MAX_INPUT];
+ unsigned nr_inputs, nr_input_regs;
- struct {
- unsigned index;
- unsigned semantic_name;
- unsigned semantic_index;
- } gs_input[UREG_MAX_INPUT];
- unsigned nr_gs_inputs;
+ unsigned vs_inputs[PIPE_MAX_ATTRIBS/32];
struct {
- unsigned index;
unsigned semantic_name;
unsigned semantic_index;
} system_value[UREG_MAX_SYSTEM_VALUE];
unsigned semantic_name;
unsigned semantic_index;
unsigned usage_mask; /* = TGSI_WRITEMASK_* */
+ unsigned first;
+ unsigned last;
+ unsigned array_id;
} output[UREG_MAX_OUTPUT];
- unsigned nr_outputs;
+ unsigned nr_outputs, nr_output_regs;
struct {
union {
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 property_gs_invocations;
- unsigned char property_fs_coord_origin; /* = TGSI_FS_COORD_ORIGIN_* */
- unsigned char property_fs_coord_pixel_center; /* = TGSI_FS_COORD_PIXEL_CENTER_* */
- unsigned char property_fs_color0_writes_all_cbufs; /* = TGSI_FS_COLOR0_WRITES_ALL_CBUFS * */
- unsigned char property_fs_depth_layout; /* TGSI_FS_DEPTH_LAYOUT */
+ unsigned properties[TGSI_PROPERTY_COUNT];
unsigned nr_addrs;
unsigned nr_preds;
return &ureg->domain[domain].tokens[nr];
}
-
-
-static INLINE struct ureg_dst
-ureg_dst_register( unsigned file,
- unsigned index )
-{
- struct ureg_dst dst;
-
- dst.File = file;
- dst.WriteMask = TGSI_WRITEMASK_XYZW;
- dst.Indirect = 0;
- dst.IndirectFile = TGSI_FILE_NULL;
- 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 = index;
- dst.ArrayID = 0;
-
- return dst;
-}
-
-
-void
-ureg_property_gs_input_prim(struct ureg_program *ureg,
- unsigned input_prim)
-{
- 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_invocations(struct ureg_program *ureg,
- unsigned invocations)
-{
- ureg->property_gs_invocations = invocations;
-}
-
-void
-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_fs_coord_pixel_center = fs_coord_pixel_center;
-}
-
-void
-ureg_property_fs_color0_writes_all_cbufs(struct ureg_program *ureg,
- unsigned fs_color0_writes_all_cbufs)
-{
- ureg->property_fs_color0_writes_all_cbufs = fs_color0_writes_all_cbufs;
-}
-
void
-ureg_property_fs_depth_layout(struct ureg_program *ureg,
- unsigned fs_depth_layout)
+ureg_property(struct ureg_program *ureg, unsigned name, unsigned value)
{
- ureg->property_fs_depth_layout = fs_depth_layout;
+ assert(name < Elements(ureg->properties));
+ ureg->properties[name] = value;
}
struct ureg_src
unsigned semantic_index,
unsigned interp_mode,
unsigned cylindrical_wrap,
- unsigned centroid)
+ unsigned interp_location,
+ unsigned array_id,
+ unsigned array_size)
{
unsigned i;
- for (i = 0; i < ureg->nr_fs_inputs; i++) {
- if (ureg->fs_input[i].semantic_name == semantic_name &&
- ureg->fs_input[i].semantic_index == semantic_index) {
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ if (ureg->input[i].semantic_name == semantic_name &&
+ ureg->input[i].semantic_index == semantic_index) {
+ assert(ureg->input[i].interp == interp_mode);
+ assert(ureg->input[i].cylindrical_wrap == cylindrical_wrap);
+ assert(ureg->input[i].interp_location == interp_location);
+ assert(ureg->input[i].array_id == array_id);
goto out;
}
}
- if (ureg->nr_fs_inputs < UREG_MAX_INPUT) {
- ureg->fs_input[i].semantic_name = semantic_name;
- ureg->fs_input[i].semantic_index = semantic_index;
- ureg->fs_input[i].interp = interp_mode;
- ureg->fs_input[i].cylindrical_wrap = cylindrical_wrap;
- ureg->fs_input[i].centroid = centroid;
- ureg->nr_fs_inputs++;
+ if (ureg->nr_inputs < UREG_MAX_INPUT) {
+ assert(array_size >= 1);
+ ureg->input[i].semantic_name = semantic_name;
+ ureg->input[i].semantic_index = semantic_index;
+ ureg->input[i].interp = interp_mode;
+ ureg->input[i].cylindrical_wrap = cylindrical_wrap;
+ ureg->input[i].interp_location = interp_location;
+ ureg->input[i].first = ureg->nr_input_regs;
+ ureg->input[i].last = ureg->nr_input_regs + array_size - 1;
+ ureg->input[i].array_id = array_id;
+ ureg->nr_input_regs += array_size;
+ ureg->nr_inputs++;
} else {
set_bad(ureg);
}
out:
- return ureg_src_register(TGSI_FILE_INPUT, i);
+ return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first,
+ array_id);
}
unsigned index )
{
assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
-
+ assert(index / 32 < ARRAY_SIZE(ureg->vs_inputs));
+
ureg->vs_inputs[index/32] |= 1 << (index % 32);
return ureg_src_register( TGSI_FILE_INPUT, index );
}
struct ureg_src
-ureg_DECL_gs_input(struct ureg_program *ureg,
- unsigned index,
- unsigned semantic_name,
- unsigned semantic_index)
+ureg_DECL_input(struct ureg_program *ureg,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned array_id,
+ unsigned array_size)
{
- if (ureg->nr_gs_inputs < UREG_MAX_INPUT) {
- ureg->gs_input[ureg->nr_gs_inputs].index = index;
- ureg->gs_input[ureg->nr_gs_inputs].semantic_name = semantic_name;
- ureg->gs_input[ureg->nr_gs_inputs].semantic_index = semantic_index;
- ureg->nr_gs_inputs++;
- } else {
- set_bad(ureg);
- }
-
- /* XXX: Add suport for true 2D input registers. */
- return ureg_src_register(TGSI_FILE_INPUT, index);
+ return ureg_DECL_fs_input_cyl_centroid(ureg, semantic_name, semantic_index,
+ 0, 0, 0, array_id, array_size);
}
struct ureg_src
ureg_DECL_system_value(struct ureg_program *ureg,
- unsigned index,
unsigned semantic_name,
unsigned semantic_index)
{
+ unsigned i = 0;
+
if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) {
- ureg->system_value[ureg->nr_system_values].index = index;
ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name;
ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index;
+ i = ureg->nr_system_values;
ureg->nr_system_values++;
} else {
set_bad(ureg);
}
- return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, index);
+ return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, i);
}
struct ureg_dst
-ureg_DECL_output_masked( struct ureg_program *ureg,
- unsigned name,
- unsigned index,
- unsigned usage_mask )
+ureg_DECL_output_masked(struct ureg_program *ureg,
+ unsigned name,
+ unsigned index,
+ unsigned usage_mask,
+ unsigned array_id,
+ unsigned array_size)
{
unsigned i;
for (i = 0; i < ureg->nr_outputs; i++) {
if (ureg->output[i].semantic_name == name &&
- ureg->output[i].semantic_index == index) {
+ ureg->output[i].semantic_index == index) {
+ assert(ureg->output[i].array_id == array_id);
ureg->output[i].usage_mask |= usage_mask;
goto out;
}
ureg->output[i].semantic_name = name;
ureg->output[i].semantic_index = index;
ureg->output[i].usage_mask = usage_mask;
+ ureg->output[i].first = ureg->nr_output_regs;
+ ureg->output[i].last = ureg->nr_output_regs + array_size - 1;
+ ureg->output[i].array_id = array_id;
+ ureg->nr_output_regs += array_size;
ureg->nr_outputs++;
}
else {
}
out:
- return ureg_dst_register( TGSI_FILE_OUTPUT, i );
+ return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first,
+ array_id);
}
struct ureg_dst
-ureg_DECL_output( struct ureg_program *ureg,
- unsigned name,
- unsigned index )
+ureg_DECL_output(struct ureg_program *ureg,
+ unsigned name,
+ unsigned index)
{
- return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW);
+ return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW,
+ 0, 1);
+}
+
+struct ureg_dst
+ureg_DECL_output_array(struct ureg_program *ureg,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned array_id,
+ unsigned array_size)
+{
+ return ureg_DECL_output_masked(ureg, semantic_name, semantic_index,
+ TGSI_WRITEMASK_XYZW,
+ array_id, array_size);
}
return reg;
}
+static int
+match_or_expand_immediate64( const unsigned *v,
+ int type,
+ unsigned nr,
+ unsigned *v2,
+ unsigned *pnr2,
+ unsigned *swizzle )
+{
+ unsigned nr2 = *pnr2;
+ unsigned i, j;
+ *swizzle = 0;
+
+ for (i = 0; i < nr; i += 2) {
+ boolean found = FALSE;
+
+ for (j = 0; j < nr2 && !found; j += 2) {
+ if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) {
+ *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2));
+ found = TRUE;
+ }
+ }
+ if (!found) {
+ if ((nr2) >= 4) {
+ return FALSE;
+ }
+
+ v2[nr2] = v[i];
+ v2[nr2 + 1] = v[i + 1];
+
+ *swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2));
+ nr2 += 2;
+ }
+ }
+
+ /* Actually expand immediate only when fully succeeded.
+ */
+ *pnr2 = nr2;
+ return TRUE;
+}
+
static int
match_or_expand_immediate( const unsigned *v,
+ int type,
unsigned nr,
unsigned *v2,
unsigned *pnr2,
unsigned nr2 = *pnr2;
unsigned i, j;
+ if (type == TGSI_IMM_FLOAT64)
+ return match_or_expand_immediate64(v, type, nr, v2, pnr2, swizzle);
+
*swizzle = 0;
for (i = 0; i < nr; i++) {
continue;
}
if (match_or_expand_immediate(v,
+ type,
nr,
ureg->immediate[i].value.u,
&ureg->immediate[i].nr,
i = ureg->nr_immediates++;
ureg->immediate[i].type = type;
if (match_or_expand_immediate(v,
+ type,
nr,
ureg->immediate[i].value.u,
&ureg->immediate[i].nr,
/* 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);
+ if (type == TGSI_IMM_FLOAT64) {
+ for (j = nr; j < 4; j+=2) {
+ swizzle |= (swizzle & 0xf) << (j * 2);
+ }
+ } else {
+ 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,
return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
}
+struct ureg_src
+ureg_DECL_immediate_f64( struct ureg_program *ureg,
+ const double *v,
+ unsigned nr )
+{
+ union {
+ unsigned u[4];
+ double d[2];
+ } fu;
+ unsigned int i;
+
+ assert((nr / 2) < 3);
+ for (i = 0; i < nr / 2; i++) {
+ fu.d[i] = v[i];
+ }
+
+ return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64);
+}
struct ureg_src
ureg_DECL_immediate_uint( struct ureg_program *ureg,
out[n].ind.File = src.IndirectFile;
out[n].ind.Swizzle = src.IndirectSwizzle;
out[n].ind.Index = src.IndirectIndex;
- out[n].ind.ArrayID = src.ArrayID;
+ if (!ureg->supports_any_inout_decl_range &&
+ (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))
+ out[n].ind.ArrayID = 0;
+ else
+ out[n].ind.ArrayID = src.ArrayID;
n++;
}
out[n].ind.File = src.DimIndFile;
out[n].ind.Swizzle = src.DimIndSwizzle;
out[n].ind.Index = src.DimIndIndex;
- out[n].ind.ArrayID = src.ArrayID;
+ if (!ureg->supports_any_inout_decl_range &&
+ (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))
+ out[n].ind.ArrayID = 0;
+ else
+ out[n].ind.ArrayID = src.ArrayID;
} else {
out[n].dim.Indirect = 0;
out[n].dim.Index = src.DimensionIndex;
ureg_emit_dst( struct ureg_program *ureg,
struct ureg_dst dst )
{
- unsigned size = (1 +
- (dst.Indirect ? 1 : 0));
+ unsigned size = 1 + (dst.Indirect ? 1 : 0) +
+ (dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0);
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0;
out[n].ind.File = dst.IndirectFile;
out[n].ind.Swizzle = dst.IndirectSwizzle;
out[n].ind.Index = dst.IndirectIndex;
- out[n].ind.ArrayID = dst.ArrayID;
+ if (!ureg->supports_any_inout_decl_range &&
+ (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))
+ out[n].ind.ArrayID = 0;
+ else
+ out[n].ind.ArrayID = dst.ArrayID;
+ n++;
+ }
+
+ if (dst.Dimension) {
+ out[0].dst.Dimension = 1;
+ out[n].dim.Dimension = 0;
+ out[n].dim.Padding = 0;
+ if (dst.DimIndirect) {
+ out[n].dim.Indirect = 1;
+ out[n].dim.Index = dst.DimensionIndex;
+ n++;
+ out[n].value = 0;
+ out[n].ind.File = dst.DimIndFile;
+ out[n].ind.Swizzle = dst.DimIndSwizzle;
+ out[n].ind.Index = dst.DimIndIndex;
+ if (!ureg->supports_any_inout_decl_range &&
+ (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))
+ out[n].ind.ArrayID = 0;
+ else
+ out[n].ind.ArrayID = dst.ArrayID;
+ } else {
+ out[n].dim.Indirect = 0;
+ out[n].dim.Index = dst.DimensionIndex;
+ }
n++;
}
#ifdef DEBUG
const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
assert(info);
- if(info) {
+ if (info) {
assert(nr_dst == info->num_dst);
assert(nr_src == info->num_src);
}
}
+/**
+ * Emit a label token.
+ * \param label_token returns a token number indicating where the label
+ * needs to be patched later. Later, this value should be passed to the
+ * ureg_fixup_label() function.
+ */
void
ureg_emit_label(struct ureg_program *ureg,
unsigned extended_token,
{
union tgsi_any_token *out, *insn;
- if(!label_token)
+ if (!label_token)
return;
out = get_tokens( ureg, DOMAIN_INSN, 1 );
static void
emit_decl_semantic(struct ureg_program *ureg,
unsigned file,
- unsigned index,
+ unsigned first,
+ unsigned last,
unsigned semantic_name,
unsigned semantic_index,
- unsigned usage_mask)
+ unsigned usage_mask,
+ unsigned array_id)
{
- union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
+ union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
out[0].value = 0;
out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
out[0].decl.File = file;
out[0].decl.UsageMask = usage_mask;
out[0].decl.Semantic = 1;
+ out[0].decl.Array = array_id != 0;
out[1].value = 0;
- out[1].decl_range.First = index;
- out[1].decl_range.Last = index;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = last;
out[2].value = 0;
out[2].decl_semantic.Name = semantic_name;
out[2].decl_semantic.Index = semantic_index;
+
+ if (array_id) {
+ out[3].value = 0;
+ out[3].array.ArrayID = array_id;
+ }
}
static void
emit_decl_fs(struct ureg_program *ureg,
unsigned file,
- unsigned index,
+ unsigned first,
+ unsigned last,
unsigned semantic_name,
unsigned semantic_index,
unsigned interpolate,
unsigned cylindrical_wrap,
- unsigned centroid)
+ unsigned interpolate_location,
+ unsigned array_id)
{
- union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 4);
+ union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL,
+ array_id ? 5 : 4);
out[0].value = 0;
out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */
out[0].decl.Interpolate = 1;
out[0].decl.Semantic = 1;
+ out[0].decl.Array = array_id != 0;
out[1].value = 0;
- out[1].decl_range.First = index;
- out[1].decl_range.Last = index;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = last;
out[2].value = 0;
out[2].decl_interp.Interpolate = interpolate;
out[2].decl_interp.CylindricalWrap = cylindrical_wrap;
- out[2].decl_interp.Centroid = centroid;
+ out[2].decl_interp.Location = interpolate_location;
out[3].value = 0;
out[3].decl_semantic.Name = semantic_name;
out[3].decl_semantic.Index = semantic_index;
+
+ if (array_id) {
+ out[4].value = 0;
+ out[4].array.ArrayID = array_id;
+ }
}
static void
static void emit_decls( struct ureg_program *ureg )
{
- unsigned i;
+ unsigned i,j;
- if (ureg->property_gs_input_prim != ~0) {
- assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY);
-
- emit_property(ureg,
- TGSI_PROPERTY_GS_INPUT_PRIM,
- 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_OUTPUT_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->property_fs_color0_writes_all_cbufs) {
- assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
-
- emit_property(ureg,
- TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS,
- ureg->property_fs_color0_writes_all_cbufs);
- }
-
- if (ureg->property_fs_depth_layout) {
- assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
-
- emit_property(ureg,
- TGSI_PROPERTY_FS_DEPTH_LAYOUT,
- ureg->property_fs_depth_layout);
- }
+ for (i = 0; i < Elements(ureg->properties); i++)
+ if (ureg->properties[i] != ~0)
+ emit_property(ureg, i, ureg->properties[i]);
if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
- for (i = 0; i < UREG_MAX_INPUT; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
}
}
} else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) {
- for (i = 0; i < ureg->nr_fs_inputs; i++) {
- emit_decl_fs(ureg,
- TGSI_FILE_INPUT,
- i,
- ureg->fs_input[i].semantic_name,
- ureg->fs_input[i].semantic_index,
- ureg->fs_input[i].interp,
- ureg->fs_input[i].cylindrical_wrap,
- ureg->fs_input[i].centroid);
+ if (ureg->supports_any_inout_decl_range) {
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ emit_decl_fs(ureg,
+ TGSI_FILE_INPUT,
+ ureg->input[i].first,
+ ureg->input[i].last,
+ ureg->input[i].semantic_name,
+ ureg->input[i].semantic_index,
+ ureg->input[i].interp,
+ ureg->input[i].cylindrical_wrap,
+ ureg->input[i].interp_location,
+ ureg->input[i].array_id);
+ }
}
- } else {
- for (i = 0; i < ureg->nr_gs_inputs; i++) {
- emit_decl_semantic(ureg,
+ else {
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
+ emit_decl_fs(ureg,
TGSI_FILE_INPUT,
- ureg->gs_input[i].index,
- ureg->gs_input[i].semantic_name,
- ureg->gs_input[i].semantic_index,
- TGSI_WRITEMASK_XYZW);
+ j, j,
+ ureg->input[i].semantic_name,
+ ureg->input[i].semantic_index +
+ (j - ureg->input[i].first),
+ ureg->input[i].interp,
+ ureg->input[i].cylindrical_wrap,
+ ureg->input[i].interp_location, 0);
+ }
+ }
+ }
+ } else {
+ if (ureg->supports_any_inout_decl_range) {
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ emit_decl_semantic(ureg,
+ TGSI_FILE_INPUT,
+ ureg->input[i].first,
+ ureg->input[i].last,
+ ureg->input[i].semantic_name,
+ ureg->input[i].semantic_index,
+ TGSI_WRITEMASK_XYZW,
+ ureg->input[i].array_id);
+ }
+ }
+ else {
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
+ emit_decl_semantic(ureg,
+ TGSI_FILE_INPUT,
+ j, j,
+ ureg->input[i].semantic_name,
+ ureg->input[i].semantic_index +
+ (j - ureg->input[i].first),
+ TGSI_WRITEMASK_XYZW, 0);
+ }
+ }
}
}
for (i = 0; i < ureg->nr_system_values; i++) {
emit_decl_semantic(ureg,
TGSI_FILE_SYSTEM_VALUE,
- ureg->system_value[i].index,
+ i,
+ i,
ureg->system_value[i].semantic_name,
ureg->system_value[i].semantic_index,
- TGSI_WRITEMASK_XYZW);
+ TGSI_WRITEMASK_XYZW, 0);
}
- for (i = 0; i < ureg->nr_outputs; i++) {
- emit_decl_semantic(ureg,
- TGSI_FILE_OUTPUT,
- i,
- ureg->output[i].semantic_name,
- ureg->output[i].semantic_index,
- ureg->output[i].usage_mask);
+ if (ureg->supports_any_inout_decl_range) {
+ for (i = 0; i < ureg->nr_outputs; i++) {
+ emit_decl_semantic(ureg,
+ TGSI_FILE_OUTPUT,
+ ureg->output[i].first,
+ ureg->output[i].last,
+ ureg->output[i].semantic_name,
+ ureg->output[i].semantic_index,
+ ureg->output[i].usage_mask,
+ ureg->output[i].array_id);
+ }
+ }
+ else {
+ for (i = 0; i < ureg->nr_outputs; i++) {
+ for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) {
+ emit_decl_semantic(ureg,
+ TGSI_FILE_OUTPUT,
+ j, j,
+ ureg->output[i].semantic_name,
+ ureg->output[i].semantic_index +
+ (j - ureg->output[i].first),
+ ureg->output[i].usage_mask, 0);
+ }
+ }
}
for (i = 0; i < ureg->nr_samplers; i++) {
else
memset(&state.stream_output, 0, sizeof(state.stream_output));
- if (ureg->processor == TGSI_PROCESSOR_VERTEX)
- return pipe->create_vs_state( pipe, &state );
- else
- return pipe->create_fs_state( pipe, &state );
+ switch (ureg->processor) {
+ case TGSI_PROCESSOR_VERTEX:
+ return pipe->create_vs_state(pipe, &state);
+ case TGSI_PROCESSOR_TESS_CTRL:
+ return pipe->create_tcs_state(pipe, &state);
+ case TGSI_PROCESSOR_TESS_EVAL:
+ return pipe->create_tes_state(pipe, &state);
+ case TGSI_PROCESSOR_GEOMETRY:
+ return pipe->create_gs_state(pipe, &state);
+ case TGSI_PROCESSOR_FRAGMENT:
+ return pipe->create_fs_state(pipe, &state);
+ default:
+ return NULL;
+ }
}
}
-struct ureg_program *ureg_create( unsigned processor )
+struct ureg_program *
+ureg_create(unsigned processor)
{
+ return ureg_create_with_screen(processor, NULL);
+}
+
+
+struct ureg_program *
+ureg_create_with_screen(unsigned processor, struct pipe_screen *screen)
+{
+ int i;
struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
- if (ureg == NULL)
+ if (!ureg)
goto no_ureg;
ureg->processor = processor;
- ureg->property_gs_input_prim = ~0;
- ureg->property_gs_output_prim = ~0;
- ureg->property_gs_max_vertices = ~0;
+ ureg->supports_any_inout_decl_range =
+ screen &&
+ screen->get_shader_param(screen,
+ util_pipe_shader_from_tgsi_processor(processor),
+ PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0;
+
+ for (i = 0; i < Elements(ureg->properties); i++)
+ ureg->properties[i] = ~0;
ureg->free_temps = util_bitmask_create();
if (ureg->free_temps == NULL)
}
-const unsigned
+unsigned
ureg_get_nr_outputs( const struct ureg_program *ureg )
{
if (!ureg)