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 ); }
static void emit_decls( struct ureg_program *ureg ) { unsigned i; 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); } if (ureg->processor == TGSI_PROCESSOR_VERTEX) { for (i = 0; i < UREG_MAX_INPUT; 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); } } else { for (i = 0; i < ureg->nr_gs_inputs; i++) { emit_decl_semantic(ureg, TGSI_FILE_INPUT, ureg->gs_input[i].index, ureg->gs_input[i].semantic_name, ureg->gs_input[i].semantic_index, TGSI_WRITEMASK_XYZW); } } for (i = 0; i < ureg->nr_system_values; i++) { emit_decl_semantic(ureg, TGSI_FILE_SYSTEM_VALUE, ureg->system_value[i].index, ureg->system_value[i].semantic_name, ureg->system_value[i].semantic_index, TGSI_WRITEMASK_XYZW); } 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); } for (i = 0; i < ureg->nr_samplers; i++) { emit_decl_range( ureg, TGSI_FILE_SAMPLER, ureg->sampler[i].Index, 1 ); } for (i = 0; i < ureg->nr_sampler_views; i++) { emit_decl_sampler_view(ureg, ureg->sampler_view[i].index, ureg->sampler_view[i].target, ureg->sampler_view[i].return_type_x, ureg->sampler_view[i].return_type_y, ureg->sampler_view[i].return_type_z, ureg->sampler_view[i].return_type_w); } 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) { unsigned array = 0; for (i = 0; i < ureg->nr_temps;) { boolean local = util_bitmask_get(ureg->local_temps, i); unsigned first = i; i = util_bitmask_get_next_index(ureg->decl_temps, i + 1); if (i == UTIL_BITMASK_INVALID_INDEX) i = ureg->nr_temps; if (array < ureg->nr_array_temps && ureg->array_temps[array] == first) emit_decl_temps( ureg, first, i - 1, local, ++array ); else emit_decl_temps( ureg, first, i - 1, local, 0 ); } } if (ureg->nr_addrs) { emit_decl_range( ureg, TGSI_FILE_ADDRESS, 0, ureg->nr_addrs ); } if (ureg->nr_preds) { emit_decl_range(ureg, TGSI_FILE_PREDICATE, 0, ureg->nr_preds); } for (i = 0; i < ureg->nr_immediates; i++) { emit_immediate( ureg, ureg->immediate[i].value.u, ureg->immediate[i].type ); } }
unsigned util_bitmask_get_first_index(struct util_bitmask *bm) { return util_bitmask_get_next_index(bm, 0); }