PageRenderTime 98ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/cgcomp/source/main.cpp

https://github.com/yeahren/PSL1GHT
C++ | 471 lines | 394 code | 77 blank | 0 comment | 44 complexity | 273a34ca4e3ce0c5dae16818ad036bf1 MD5 | raw file
  1. #include "types.h"
  2. #include "fpparser.h"
  3. #include "vpparser.h"
  4. #include "compiler.h"
  5. #include "compilerfp.h"
  6. #if !defined(WIN32)
  7. #include <dlfcn.h>
  8. #endif
  9. #define PROG_TYPE_NONE 0
  10. #define PROG_TYPE_VP 1
  11. #define PROG_TYPE_FP 2
  12. #ifdef __BIG_ENDIAN__
  13. #define SWAP16(v) (v)
  14. #define SWAP32(v) (v)
  15. #else
  16. #define SWAP16(v) ((v)>>8)|((v)<<8)
  17. #define SWAP32(v) ((v)>>24)|((v)<<24)|(((v)&0xFF00)<<8)|(((v)&0xFF0000)>>8)
  18. #endif
  19. struct _options
  20. {
  21. const char *src_file;
  22. const char *dst_file;
  23. const char *entry;
  24. int prog_type;
  25. bool gen_asm;
  26. bool compile;
  27. bool strip;
  28. } Options = {
  29. NULL,
  30. NULL,
  31. "main",
  32. PROG_TYPE_NONE,
  33. false,
  34. true,
  35. false
  36. };
  37. #define CG_SOURCE 4112
  38. #define CG_COMPILED_PROGRAM 4106
  39. #define CG_PROFILE_VP30 6148
  40. #define CG_PROFILE_FP30 6149
  41. #define CG_PROFILE_FP40 6151
  42. #define CG_PROFILE_VP40 7001
  43. typedef void*(*_cgCreateContext)();
  44. typedef void(*_cgDestroyContext)(void *context);
  45. typedef void*(*_cgCreateProgramFromFile)(void* context, int program_type, const char *program, int profile, const char *entry, const char **args);
  46. typedef const char*(*_cgGetProgramString)(void *program,int pname);
  47. typedef const char *(*_cgGetLastListing)(void *context);
  48. _cgCreateContext cgCreateContext=NULL;
  49. _cgDestroyContext cgDestroyContext=NULL;
  50. _cgCreateProgramFromFile cgCreateProgramFromFile=NULL;
  51. _cgGetProgramString cgGetProgramString=NULL;
  52. _cgGetLastListing cgGetLastListing=NULL;
  53. static bool InitCompiler()
  54. {
  55. #if defined(WIN32)
  56. HMODULE libcgc=LoadLibrary("cg.dll");
  57. #elif defined(__APPLE__)
  58. void *libcgc=dlopen("cg.dylib", RTLD_LAZY);
  59. #else
  60. void *libcgc=dlopen("libCg.so", RTLD_LAZY);
  61. #endif
  62. if (libcgc==NULL) return false;
  63. #ifdef WIN32
  64. cgCreateContext=(_cgCreateContext)GetProcAddress(libcgc,"cgCreateContext");
  65. cgDestroyContext=(_cgDestroyContext)GetProcAddress(libcgc,"cgDestroyContext");
  66. cgCreateProgramFromFile=(_cgCreateProgramFromFile)GetProcAddress(libcgc,"cgCreateProgramFromFile");
  67. cgGetProgramString=(_cgGetProgramString)GetProcAddress(libcgc,"cgGetProgramString");
  68. cgGetLastListing=(_cgGetLastListing)GetProcAddress(libcgc,"cgGetLastListing");
  69. #else
  70. cgCreateContext=(_cgCreateContext)dlsym(libcgc, "cgCreateContext");
  71. cgDestroyContext=(_cgDestroyContext)dlsym(libcgc, "cgDestroyContext");
  72. cgCreateProgramFromFile=(_cgCreateProgramFromFile)dlsym(libcgc, "cgCreateProgramFromFile");
  73. cgGetProgramString=(_cgGetProgramString)dlsym(libcgc, "cgGetProgramString");
  74. cgGetLastListing=(_cgGetLastListing)dlsym(libcgc, "cgGetLastListing");
  75. #endif
  76. return (cgCreateContext!=NULL);
  77. }
  78. static u32 endian_fp(u32 v)
  79. {
  80. return ( ( ( v >> 16 ) & 0xffff ) << 0 ) |
  81. ( ( ( v >> 0 ) & 0xffff ) << 16 );
  82. }
  83. void usage()
  84. {
  85. printf("cgcomp [options] input output\n");
  86. printf("\t-f Input is fragment program\n");
  87. printf("\t-v Input is vertex program\n");
  88. printf("\t-e Entry function name for program\n");
  89. printf("\t-a Assemble only, no compile\n");
  90. }
  91. void readoptions(struct _options *options,int argc,char *argv[])
  92. {
  93. int i;
  94. for(i=1;i<argc;i++) {
  95. if(argv[i][0]=='-') {
  96. switch(argv[i][1]) {
  97. case 'f': options->prog_type = PROG_TYPE_FP; break;
  98. case 'v': options->prog_type = PROG_TYPE_VP; break;
  99. case 'e': options->entry = argv[++i]; break;
  100. case 'a': options->gen_asm = true; break;
  101. }
  102. } else
  103. break;
  104. }
  105. if(i+2!=argc) usage();
  106. options->src_file = argv[i];
  107. options->dst_file = argv[i+1];
  108. }
  109. char* readFile(const char *filename)
  110. {
  111. char *prg = NULL;
  112. unsigned int len = 0;
  113. FILE *f = fopen(filename,"rb");
  114. if(f==NULL) {
  115. fprintf(stderr,"Unable to open input file %s\n",filename);
  116. return NULL;
  117. }
  118. fseek(f,0,SEEK_END);
  119. len = ftell(f);
  120. fseek(f,0,SEEK_SET);
  121. prg = (char*)malloc(len + 1);
  122. if(fread(prg,1,len,f)!=len) {
  123. fprintf(stderr,"Input file read error\n");
  124. fclose(f);
  125. free(prg);
  126. return NULL;
  127. }
  128. fclose(f);
  129. return prg;
  130. }
  131. int compileVP()
  132. {
  133. char *prg;
  134. if(Options.gen_asm==true) {
  135. prg = readFile(Options.src_file);
  136. } else {
  137. void *context = cgCreateContext();
  138. void *program = cgCreateProgramFromFile(context,CG_SOURCE,Options.src_file,CG_PROFILE_VP40,Options.entry,NULL);
  139. if(program==NULL) {
  140. const char *error = cgGetLastListing(context);
  141. fprintf(stderr,"%s\n",error);
  142. return EXIT_FAILURE;
  143. }
  144. prg = (char*)cgGetProgramString(program,CG_COMPILED_PROGRAM);
  145. }
  146. if(prg) {
  147. CVPParser parser;
  148. CCompiler compiler;
  149. parser.Parse(prg);
  150. compiler.Compile(&parser);
  151. int n,i;
  152. u16 magic = ('V'<<8)|'P';
  153. u32 lastoff = sizeof(rsxVertexProgram);
  154. unsigned char *vertexprogram = (unsigned char*)calloc(2*1024*1024,1);
  155. rsxVertexProgram *vp = (rsxVertexProgram*)vertexprogram;
  156. vp->magic = SWAP16(magic);
  157. vp->start_insn = SWAP16(0);
  158. vp->const_start = SWAP16(0);
  159. vp->input_mask = SWAP32(compiler.GetInputMask());
  160. vp->output_mask = SWAP32(compiler.GetOutputMask());
  161. while(lastoff&3)
  162. vertexprogram[lastoff++] = 0;
  163. rsxProgramAttrib *attribs = (rsxProgramAttrib*)(vertexprogram + lastoff);
  164. vp->attrib_off = SWAP32(lastoff);
  165. n = 0;
  166. std::list<param> params = parser.GetParameters();
  167. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  168. if(!it->is_const) {
  169. it->user = lastoff + (n*sizeof(rsxProgramAttrib));
  170. attribs[n].index = SWAP32(it->index);
  171. attribs[n].name_off = SWAP32(0);
  172. n++;
  173. }
  174. }
  175. vp->num_attrib = SWAP16(n);
  176. lastoff += (n*sizeof(rsxProgramAttrib));
  177. while(lastoff&3)
  178. vertexprogram[lastoff++] = 0;
  179. rsxProgramConst *consts = (rsxProgramConst*)(vertexprogram + lastoff);
  180. struct vertex_program_exec *vpi = compiler.GetInstructions();
  181. std::list<struct nvfx_relocation> const_reloc = compiler.GetConstRelocations();
  182. for(std::list<struct nvfx_relocation>::iterator it = const_reloc.begin();it!=const_reloc.end();it++) {
  183. struct vertex_program_exec *vpe = &vpi[it->location];
  184. vpe->data[1] &= ~NVFX_VP(INST_CONST_SRC_MASK);
  185. vpe->data[1] |= (it->target) << NVFX_VP(INST_CONST_SRC_SHIFT);
  186. }
  187. vp->const_off = SWAP32(lastoff);
  188. n = 0;
  189. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  190. if(it->is_const) {
  191. it->user = lastoff + (n*sizeof(rsxProgramConst));
  192. consts[n].count = it->count;
  193. consts[n].type = it->type;
  194. consts[n].is_internal = it->is_internal;
  195. consts[n].name_off = SWAP32(0);
  196. for(i=0;i<(s32)it->count;i++) {
  197. f32 *pVal = it->values[i];
  198. consts[n].index = SWAP32(it->index + i);
  199. consts[n].values[0].f = pVal[0];
  200. consts[n].values[0].u = SWAP32(consts[n].values[0].u);
  201. consts[n].values[1].f = pVal[1];
  202. consts[n].values[1].u = SWAP32(consts[n].values[1].u);
  203. consts[n].values[2].f = pVal[2];
  204. consts[n].values[2].u = SWAP32(consts[n].values[2].u);
  205. consts[n].values[3].f = pVal[3];
  206. consts[n].values[3].u = SWAP32(consts[n].values[3].u);
  207. n++;
  208. }
  209. }
  210. }
  211. vp->num_const = SWAP16(n);
  212. lastoff += (n*sizeof(rsxProgramConst));
  213. while(lastoff&3)
  214. vertexprogram[lastoff++] = 0;
  215. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  216. if(!it->name.empty() && !it->is_internal) {
  217. const char *name = it->name.c_str();
  218. int off = lastoff;
  219. while(*name)
  220. vertexprogram[lastoff++] = *name++;
  221. vertexprogram[lastoff++] = 0;
  222. *((u32*)(vertexprogram + it->user)) = SWAP32(off);
  223. }
  224. }
  225. while(lastoff&15)
  226. vertexprogram[lastoff++] = 0;
  227. vp->ucode_off = SWAP32(lastoff);
  228. vp->num_insn = SWAP16(compiler.GetInstructionCount());
  229. u32 *dstcodeptr = (u32*)(vertexprogram + lastoff);
  230. for(i=0,n=0;i<compiler.GetInstructionCount();i++,n+=4,lastoff+=16) {
  231. dstcodeptr[n+0] = SWAP32(vpi[i].data[0]);
  232. dstcodeptr[n+1] = SWAP32(vpi[i].data[1]);
  233. dstcodeptr[n+2] = SWAP32(vpi[i].data[2]);
  234. dstcodeptr[n+3] = SWAP32(vpi[i].data[3]);
  235. }
  236. FILE *fOut = fopen(Options.dst_file,"wb");
  237. fwrite(vertexprogram,lastoff,1,fOut);
  238. fclose(fOut);
  239. return EXIT_SUCCESS;
  240. }
  241. return EXIT_FAILURE;
  242. }
  243. int compileFP()
  244. {
  245. char *prg;
  246. if(Options.gen_asm==true) {
  247. prg = readFile(Options.src_file);
  248. } else {
  249. void *context = cgCreateContext();
  250. void *program = cgCreateProgramFromFile(context,CG_SOURCE,Options.src_file,CG_PROFILE_FP40,Options.entry,NULL);
  251. if(program==NULL) {
  252. const char *error = cgGetLastListing(context);
  253. fprintf(stderr,"%s\n",error);
  254. return EXIT_FAILURE;
  255. }
  256. prg = (char*)cgGetProgramString(program,CG_COMPILED_PROGRAM);
  257. }
  258. if(prg) {
  259. CFPParser parser;
  260. CCompilerFP compiler;
  261. parser.Parse(prg);
  262. compiler.Compile(&parser);
  263. int n,i;
  264. u16 magic = ('F'<<8)|'P';
  265. u32 lastoff = sizeof(rsxFragmentProgram);
  266. unsigned char *fragmentprogram = (unsigned char*)calloc(2*1024*1024,1);
  267. rsxFragmentProgram *fp = (rsxFragmentProgram*)fragmentprogram;
  268. fp->magic = SWAP16(magic);
  269. fp->num_regs = SWAP32(compiler.GetNumRegs());
  270. fp->fp_control = SWAP32(compiler.GetFPControl());
  271. while(lastoff&3)
  272. fragmentprogram[lastoff++] = 0;
  273. fp->attrib_off = SWAP32(lastoff);
  274. rsxProgramAttrib *attribs = (rsxProgramAttrib*)(fragmentprogram + lastoff);
  275. n = 0;
  276. std::list<param> params = parser.GetParameters();
  277. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  278. if(!it->is_const) {
  279. it->user = lastoff + (n*sizeof(rsxProgramAttrib));
  280. attribs[n].index = SWAP32(it->index);
  281. attribs[n].name_off = SWAP32(0);
  282. n++;
  283. }
  284. }
  285. fp->num_attrib = SWAP16(n);
  286. lastoff += (n*sizeof(rsxProgramAttrib));
  287. while(lastoff&3)
  288. fragmentprogram[lastoff++] = 0;
  289. std::list<struct fragment_program_data> const_relocs = compiler.GetConstRelocations();
  290. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  291. if(it->is_const && !it->is_internal) {
  292. for(i=0;i<(s32)it->count;i++) {
  293. s32 k = 0;
  294. rsxConstOffsetTable *const_table = (rsxConstOffsetTable*)(fragmentprogram + lastoff);
  295. const_table->num = SWAP32(0);
  296. for(std::list<struct fragment_program_data>::iterator d=const_relocs.begin();d!=const_relocs.end();d++) {
  297. if(d->index==(it->index + i)) {
  298. const_table->offset[k++] = SWAP32((d->offset*16));
  299. d->user = lastoff;
  300. }
  301. }
  302. const_table->num = SWAP32(k);
  303. lastoff += (4*k + 4);
  304. }
  305. }
  306. }
  307. while(lastoff&3)
  308. fragmentprogram[lastoff++] = 0;
  309. fp->const_off = SWAP32(lastoff);
  310. rsxProgramConst *consts = (rsxProgramConst*)(fragmentprogram + lastoff);
  311. n = 0;
  312. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  313. if(it->is_const && !it->is_internal) {
  314. it->user = lastoff + (n*sizeof(rsxProgramConst));
  315. consts[n].count = it->count;
  316. consts[n].type = it->type;
  317. consts[n].is_internal = it->is_internal;
  318. consts[n].name_off = SWAP32(0);
  319. for(i=0;i<(s32)it->count;i++) {
  320. s32 table_off = -1;
  321. for(std::list<struct fragment_program_data>::iterator d=const_relocs.begin();d!=const_relocs.end();d++) {
  322. if(d->index==(it->index + i)) {
  323. table_off = d->user;
  324. break;
  325. }
  326. }
  327. f32 *pVal = it->values[i];
  328. consts[n].index = SWAP32(table_off);
  329. consts[n].values[0].f = pVal[0];
  330. consts[n].values[0].u = SWAP32(consts[n].values[0].u);
  331. consts[n].values[1].f = pVal[1];
  332. consts[n].values[1].u = SWAP32(consts[n].values[1].u);
  333. consts[n].values[2].f = pVal[2];
  334. consts[n].values[2].u = SWAP32(consts[n].values[2].u);
  335. consts[n].values[3].f = pVal[3];
  336. consts[n].values[3].u = SWAP32(consts[n].values[3].u);
  337. n++;
  338. }
  339. }
  340. }
  341. fp->num_const = SWAP16(n);
  342. lastoff += (n*sizeof(rsxProgramConst));
  343. while(lastoff&3)
  344. fragmentprogram[lastoff++] = 0;
  345. for(std::list<param>::iterator it = params.begin();it!=params.end();it++) {
  346. if(!it->name.empty() && !it->is_internal) {
  347. const char *name = it->name.c_str();
  348. int off = lastoff;
  349. while(*name)
  350. fragmentprogram[lastoff++] = *name++;
  351. fragmentprogram[lastoff++] = 0;
  352. *((u32*)(fragmentprogram + it->user)) = SWAP32(off);
  353. }
  354. }
  355. while(lastoff&15)
  356. fragmentprogram[lastoff++] = 0;
  357. fp->ucode_off = SWAP32(lastoff);
  358. fp->num_insn = SWAP16(compiler.GetInstructionCount());
  359. struct fragment_program_exec *fpi = compiler.GetInstructions();
  360. u32 *dstcodeptr = (u32*)(fragmentprogram + lastoff);
  361. for(i=0,n=0;i<compiler.GetInstructionCount();i++,n+=4,lastoff+=16) {
  362. dstcodeptr[n+0] = endian_fp((SWAP32(fpi[i].data[0])));
  363. dstcodeptr[n+1] = endian_fp((SWAP32(fpi[i].data[1])));
  364. dstcodeptr[n+2] = endian_fp((SWAP32(fpi[i].data[2])));
  365. dstcodeptr[n+3] = endian_fp((SWAP32(fpi[i].data[3])));
  366. }
  367. FILE *fOut = fopen(Options.dst_file,"wb");
  368. fwrite(fragmentprogram,lastoff,1,fOut);
  369. fclose(fOut);
  370. return EXIT_SUCCESS;
  371. }
  372. return EXIT_FAILURE;
  373. }
  374. int main(int argc,char *argv[])
  375. {
  376. int ret = 0;
  377. readoptions(&Options,argc,argv);
  378. if(Options.gen_asm!=true && !InitCompiler()) {
  379. fprintf(stderr, "Unable to load Cg, aborting.\n");
  380. fprintf(stderr, "Please install Cg toolkit and/or set the path (i.e. LD_LIBRARY_PATH) to the shared library accordingly.\n");
  381. return EXIT_FAILURE;
  382. }
  383. switch(Options.prog_type) {
  384. case PROG_TYPE_VP:
  385. ret = compileVP();
  386. break;
  387. case PROG_TYPE_FP:
  388. ret = compileFP();
  389. break;
  390. default:
  391. break;
  392. }
  393. return ret;
  394. }