/* 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 predicate register. */ struct ureg_dst ureg_DECL_predicate(struct ureg_program *ureg) { if (ureg->nr_preds < UREG_MAX_PRED) { return ureg_dst_register(TGSI_FILE_PREDICATE, ureg->nr_preds++); } assert(0); return ureg_dst_register(TGSI_FILE_PREDICATE, 0); }
struct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg, unsigned size, boolean local ) { unsigned i = ureg->nr_temps; struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i ); if (local) util_bitmask_set(ureg->local_temps, i); /* Always start a new declaration at the start */ util_bitmask_set(ureg->decl_temps, i); ureg->nr_temps += size; /* and also at the end of the array */ util_bitmask_set(ureg->decl_temps, ureg->nr_temps); if (ureg->nr_array_temps < UREG_MAX_ARRAY_TEMPS) { ureg->array_temps[ureg->nr_array_temps++] = i; dst.ArrayID = ureg->nr_array_temps; } return dst; }
static struct ureg_dst alloc_temporary( struct ureg_program *ureg, boolean local ) { unsigned i; /* Look for a released temporary. */ for (i = util_bitmask_get_first_index(ureg->free_temps); i != UTIL_BITMASK_INVALID_INDEX; i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) { if (util_bitmask_get(ureg->local_temps, i) == local) break; } /* Or allocate a new one. */ if (i == UTIL_BITMASK_INVALID_INDEX) { i = ureg->nr_temps++; if (local) util_bitmask_set(ureg->local_temps, i); /* Start a new declaration when the local flag changes */ if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local) util_bitmask_set(ureg->decl_temps, i); } util_bitmask_clear(ureg->free_temps, i); return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); }
struct ureg_dst ureg_DECL_output_masked( struct ureg_program *ureg, unsigned name, unsigned index, unsigned usage_mask ) { unsigned i; assert(usage_mask != 0); for (i = 0; i < ureg->nr_outputs; i++) { if (ureg->output[i].semantic_name == name && ureg->output[i].semantic_index == index) { ureg->output[i].usage_mask |= usage_mask; goto out; } } if (ureg->nr_outputs < UREG_MAX_OUTPUT) { ureg->output[i].semantic_name = name; ureg->output[i].semantic_index = index; ureg->output[i].usage_mask = usage_mask; ureg->nr_outputs++; } else { set_bad( ureg ); } out: return ureg_dst_register( TGSI_FILE_OUTPUT, i ); }
/* Allocate a new temporary. Temporaries greater than UREG_MAX_TEMP * are legal, but will not be released. */ struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) { unsigned i; for (i = 0; i < UREG_MAX_TEMP; i += 32) { int bit = ffs(~ureg->temps_active[i/32]); if (bit != 0) { i += bit - 1; goto out; } } /* No reusable temps, so allocate a new one: */ i = ureg->nr_temps++; out: if (i < UREG_MAX_TEMP) ureg->temps_active[i/32] |= 1 << (i % 32); if (i >= ureg->nr_temps) ureg->nr_temps = i + 1; return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); }
struct ureg_dst ureg_DECL_output( struct ureg_program *ureg, unsigned name, unsigned index ) { unsigned i; for (i = 0; i < ureg->nr_outputs; i++) { if (ureg->output[i].semantic_name == name && ureg->output[i].semantic_index == index) goto out; } if (ureg->nr_outputs < UREG_MAX_OUTPUT) { ureg->output[i].semantic_name = name; ureg->output[i].semantic_index = index; ureg->nr_outputs++; } else { set_bad( ureg ); } out: return ureg_dst_register( TGSI_FILE_OUTPUT, i ); }