static int schedule_pvv() { pervertex_prog_length = gfpus_schedule(&pvv_fragment, (unsigned int *)pervertex_prog, (unsigned int *)pervertex_regs); if(pervertex_prog_length < 0) { printf("EVL: per-vertex VLIW scheduling failed\n"); return 0; } #ifdef EVAL_DEBUG printf("EVL: per-vertex PFPU fragment:\n"); pfpu_dump(pervertex_prog, pervertex_prog_length); #endif return 1; }
static int schedule_pfv() { perframe_prog_length = gfpus_schedule(&pfv_fragment, (unsigned int *)perframe_prog, (unsigned int *)perframe_regs); eval_reinit_all_pfv(); if(perframe_prog_length < 0) { printf("EVL: per-frame VLIW scheduling failed\n"); return 0; } #ifdef EVAL_DEBUG printf("EVL: per-frame PFPU fragment:\n"); pfpu_dump(perframe_prog, perframe_prog_length); #endif return 1; }
static void parse_only(const char *pgm) { static struct patch patch; static struct compiler_sc sc = { .p = &patch, }; struct parser_comm comm = { .u.sc = &sc, .assign_default = assign_default, .assign_per_frame = assign_per_frame, .assign_per_vertex = assign_per_vertex, .assign_image_name = assign_image_name, }; int ok; symtab_init(); ok = parse(pgm, TOK_START_ASSIGN, &comm); if (symbols) { const struct sym *sym; int user = 0; foreach_sym(sym) { if (!user && !(sym->flags & SF_SYSTEM)) { printf("\n"); user = 1; } if (sym->flags & SF_CONST) printf("%s = %g\n", sym->fpvm_sym.name, sym->f); else printf("%s\n", sym->fpvm_sym.name); } } symtab_free(); stim_db_free(); /* @@@ */ stim_put(patch.stim); if (ok) return; fflush(stdout); fprintf(stderr, "%s\n", comm.msg); free((void *) comm.msg); exit(1); } /* ----- Compile the patch into PFPU code ---------------------------------- */ /* * "sym" and "field" are used to access a field chosen by the caller in the * "struct sym". For this, the caller provides a buffer (sym) and a pointer to * the respective field inside the buffer. This way, it's perfectly type-safe * and we don't need offsetof acrobatics. */ static const char *lookup_name(int idx, struct sym *sym, const int *field) { const struct sym *walk; foreach_sym(walk) { *sym = *walk; if (*field == idx) return walk->fpvm_sym.name; } return NULL; } static void dump_regs(const int *alloc, struct sym *sym, const int *field, const float *values, int n) { const char *mapped[n]; int i; for (i = 0; i != n; i++) mapped[i] = NULL; for (i = 0; i != n; i++) if (alloc[i] != -1) mapped[alloc[i]] = lookup_name(i, sym, field); for (i = 0; i != n; i++) { if (!values[i] && !mapped[i]) continue; printf("R%03d = %f", i, values[i]); if (mapped[i]) printf(" %s", mapped[i]); printf("\n"); } } static void show_patch(const struct patch *patch) { int i; struct sym sym; printf("global:\n"); for (i = 0; i != COMP_PFV_COUNT; i++) if (patch->pfv_initial[i]) printf("R%03d = %f %s\n", i, patch->pfv_initial[i], lookup_name(i, &sym, &sym.pfv_idx)); printf("per-frame PFPU fragment:\n"); dump_regs(patch->pfv_allocation, &sym, &sym.pfv_idx, patch->perframe_regs, COMP_PFV_COUNT); pfpu_dump(patch->perframe_prog, patch->perframe_prog_length); printf("per-vertex PFPU fragment:\n"); dump_regs(patch->pvv_allocation, &sym, &sym.pvv_idx, patch->pervertex_regs, COMP_PVV_COUNT); pfpu_dump(patch->pervertex_prog, patch->pervertex_prog_length); }