Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

949 lines
25 KiB

  1. BEGIN {use File::Basename; push @INC, dirname($0); }
  2. require "valve_perl_helpers.pl";
  3. sub ReadInputFile
  4. {
  5. local( $filename ) = shift;
  6. local( *INPUT );
  7. local( @output );
  8. open INPUT, "<$filename" || die;
  9. local( $line );
  10. local( $linenum ) = 1;
  11. while( $line = <INPUT> )
  12. {
  13. # print "LINE: $line";
  14. # $line =~ s/\n//g;
  15. # local( $postfix ) = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
  16. # $postfix .= "; LINEINFO($filename)($linenum)\n";
  17. if( $line =~ m/\#include\s+\"(.*)\"/i )
  18. {
  19. push @output, &ReadInputFile( $1 );
  20. }
  21. else
  22. {
  23. # push @output, $line . $postfix;
  24. push @output, $line;
  25. }
  26. $linenum++;
  27. }
  28. close INPUT;
  29. # print "-----------------\n";
  30. # print @output;
  31. # print "-----------------\n";
  32. return @output;
  33. }
  34. $dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0;
  35. $generateListingFile = 0;
  36. $spewCombos = 0;
  37. @startTimes = times;
  38. $startTime = time;
  39. $g_produceCppClasses = 1;
  40. $g_produceCompiledVcs = 1;
  41. while( 1 )
  42. {
  43. $fxc_filename = shift;
  44. if( $fxc_filename =~ m/-source/ )
  45. {
  46. shift;
  47. }
  48. elsif( $fxc_filename =~ m/-nv3x/i )
  49. {
  50. $nvidia = 1;
  51. }
  52. elsif( $fxc_filename =~ m/-ps20a/i )
  53. {
  54. $ps2a = 1;
  55. }
  56. elsif( $fxc_filename =~ m/-x360/i )
  57. {
  58. # enable x360
  59. $g_x360 = 1;
  60. }
  61. elsif( $fxc_filename =~ m/-novcs/i )
  62. {
  63. $g_produceCompiledVcs = 0;
  64. }
  65. elsif( $fxc_filename =~ m/-nocpp/i )
  66. {
  67. $g_produceCppClasses = 0;
  68. }
  69. else
  70. {
  71. last;
  72. }
  73. }
  74. $argstring = $fxc_filename;
  75. $fxc_basename = $fxc_filename;
  76. $fxc_basename =~ s/^.*-----//;
  77. $fxc_filename =~ s/-----.*$//;
  78. $debug = 0;
  79. $forcehalf = 0;
  80. sub ToUpper
  81. {
  82. local( $in ) = shift;
  83. $in =~ tr/a-z/A-Z/;
  84. return $in;
  85. }
  86. sub CreateCCodeToSpewDynamicCombo
  87. {
  88. local( $out ) = "";
  89. $out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename dynamic index\" );\n";
  90. $out .= "\t\tchar tmp[128];\n";
  91. $out .= "\t\tint shaderID = ";
  92. local( $scale ) = 1;
  93. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  94. {
  95. local( $name ) = @dynamicDefineNames[$i];
  96. local( $varname ) = "m_n" . $name;
  97. $out .= "( $scale * $varname ) + ";
  98. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  99. }
  100. $out .= "0;\n";
  101. if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
  102. {
  103. $out .= "\t\tint nCombo = shaderID;\n";
  104. }
  105. my $type = GetShaderType( $fxc_filename );
  106. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  107. {
  108. $out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % ";
  109. $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
  110. $out .= ";\n";
  111. $out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n";
  112. $out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]";
  113. $out .= "=\" );\n";
  114. $out .= "\t\tOutputDebugString( tmp );\n";
  115. $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
  116. $out .= "\n";
  117. }
  118. $out .= "\t\tOutputDebugString( \"\\n\" );\n";
  119. return $out;
  120. }
  121. sub CreateCCodeToSpewStaticCombo
  122. {
  123. local( $out ) = "";
  124. $out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename static index\" );\n";
  125. $out .= "\t\tchar tmp[128];\n";
  126. $out .= "\t\tint shaderID = ";
  127. local( $scale ) = 1;
  128. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  129. {
  130. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  131. }
  132. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  133. {
  134. local( $name ) = @staticDefineNames[$i];
  135. local( $varname ) = "m_n" . $name;
  136. $out .= "( $scale * $varname ) + ";
  137. $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  138. }
  139. $out .= "0;\n";
  140. # $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n";
  141. # $out .= "\t\tOutputDebugString( tmp );\n\n";
  142. if( scalar( @staticDefineNames ) + scalar( @staticDefineNames ) > 0 )
  143. {
  144. $out .= "\t\tint nCombo = shaderID;\n";
  145. }
  146. my $type = GetShaderType( $fxc_filename );
  147. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  148. {
  149. $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
  150. }
  151. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  152. {
  153. $out .= "\t\tint n$staticDefineNames[$i] = nCombo % ";
  154. $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
  155. $out .= ";\n";
  156. $out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n";
  157. $out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]";
  158. $out .= "=\" );\n";
  159. $out .= "\t\tOutputDebugString( tmp );\n";
  160. $out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n";
  161. $out .= "\n";
  162. }
  163. $out .= "\t\tOutputDebugString( \"\\n\" );\n";
  164. return $out;
  165. }
  166. sub WriteHelperVar
  167. {
  168. local( $name ) = shift;
  169. local( $min ) = shift;
  170. local( $max ) = shift;
  171. local( $varname ) = "m_n" . $name;
  172. local( $boolname ) = "m_b" . $name;
  173. push @outputHeader, "private:\n";
  174. push @outputHeader, "\tint $varname;\n";
  175. push @outputHeader, "#ifdef _DEBUG\n";
  176. push @outputHeader, "\tbool $boolname;\n";
  177. push @outputHeader, "#endif\n";
  178. push @outputHeader, "public:\n";
  179. # int version of set function
  180. push @outputHeader, "\tvoid Set" . $name . "( int i )\n";
  181. push @outputHeader, "\t{\n";
  182. push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n";
  183. push @outputHeader, "\t\t$varname = i;\n";
  184. push @outputHeader, "#ifdef _DEBUG\n";
  185. push @outputHeader, "\t\t$boolname = true;\n";
  186. push @outputHeader, "#endif\n";
  187. push @outputHeader, "\t}\n";
  188. # bool version of set function
  189. push @outputHeader, "\tvoid Set" . $name . "( bool i )\n";
  190. push @outputHeader, "\t{\n";
  191. # push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n";
  192. push @outputHeader, "\t\t$varname = i ? 1 : 0;\n";
  193. push @outputHeader, "#ifdef _DEBUG\n";
  194. push @outputHeader, "\t\t$boolname = true;\n";
  195. push @outputHeader, "#endif\n";
  196. push @outputHeader, "\t}\n";
  197. }
  198. sub WriteStaticBoolExpression
  199. {
  200. local( $prefix ) = shift;
  201. local( $operator ) = shift;
  202. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  203. {
  204. if( $i )
  205. {
  206. push @outputHeader, " $operator ";
  207. }
  208. local( $name ) = @staticDefineNames[$i];
  209. local( $boolname ) = "m_b" . $name;
  210. push @outputHeader, "$prefix$boolname";
  211. }
  212. push @outputHeader, ";\n";
  213. }
  214. sub WriteDynamicBoolExpression
  215. {
  216. local( $prefix ) = shift;
  217. local( $operator ) = shift;
  218. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  219. {
  220. if( $i )
  221. {
  222. push @outputHeader, " $operator ";
  223. }
  224. local( $name ) = @dynamicDefineNames[$i];
  225. local( $boolname ) = "m_b" . $name;
  226. push @outputHeader, "$prefix$boolname";
  227. }
  228. push @outputHeader, ";\n";
  229. }
  230. sub WriteDynamicHelperClasses
  231. {
  232. local( $basename ) = $fxc_basename;
  233. $basename =~ tr/A-Z/a-z/;
  234. local( $classname ) = $basename . "_Dynamic_Index";
  235. push @outputHeader, "class $classname\n";
  236. push @outputHeader, "{\n";
  237. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  238. {
  239. $name = $dynamicDefineNames[$i];
  240. $min = $dynamicDefineMin[$i];
  241. $max = $dynamicDefineMax[$i];
  242. &WriteHelperVar( $name, $min, $max );
  243. }
  244. push @outputHeader, "public:\n";
  245. # push @outputHeader, "void SetPixelShaderIndex( IShaderAPI *pShaderAPI ) { pShaderAPI->SetPixelShaderIndex( GetIndex() ); }\n";
  246. push @outputHeader, "\t$classname()\n";
  247. push @outputHeader, "\t{\n";
  248. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  249. {
  250. local( $name ) = @dynamicDefineNames[$i];
  251. local( $boolname ) = "m_b" . $name;
  252. local( $varname ) = "m_n" . $name;
  253. push @outputHeader, "#ifdef _DEBUG\n";
  254. push @outputHeader, "\t\t$boolname = false;\n";
  255. push @outputHeader, "#endif // _DEBUG\n";
  256. push @outputHeader, "\t\t$varname = 0;\n";
  257. }
  258. push @outputHeader, "\t}\n";
  259. push @outputHeader, "\tint GetIndex()\n";
  260. push @outputHeader, "\t{\n";
  261. push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n";
  262. foreach $skip (@perlskipcodeindividual)
  263. {
  264. # can't do this static and dynamic can see each other.
  265. # $skip =~ s/\$/m_n/g;
  266. # $skip =~ s/defined//g;
  267. # push @outputHeader, "\t\tAssert( !( $skip ) );\n";
  268. # print "\t\tAssert( !( $skip ) );\n";
  269. }
  270. push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n";
  271. push @outputHeader, "#ifdef _DEBUG\n";
  272. if( scalar( @dynamicDefineNames ) > 0 )
  273. {
  274. push @outputHeader, "\t\tbool bAllDynamicVarsDefined = ";
  275. WriteDynamicBoolExpression( "", "&&" );
  276. }
  277. if( scalar( @dynamicDefineNames ) > 0 )
  278. {
  279. push @outputHeader, "\t\tAssert( bAllDynamicVarsDefined );\n";
  280. }
  281. push @outputHeader, "#endif // _DEBUG\n";
  282. if( $spewCombos && scalar( @dynamicDefineNames ) )
  283. {
  284. push @outputHeader, &CreateCCodeToSpewDynamicCombo();
  285. }
  286. push @outputHeader, "\t\treturn ";
  287. local( $scale ) = 1;
  288. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  289. {
  290. local( $name ) = @dynamicDefineNames[$i];
  291. local( $varname ) = "m_n" . $name;
  292. push @outputHeader, "( $scale * $varname ) + ";
  293. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  294. }
  295. push @outputHeader, "0;\n";
  296. push @outputHeader, "\t}\n";
  297. push @outputHeader, "};\n";
  298. push @outputHeader, "\#define shaderDynamicTest_" . $basename . " ";
  299. my $prefix;
  300. my $shaderType = &GetShaderType( $fxc_filename );
  301. if( $shaderType =~ m/^vs/i )
  302. {
  303. $prefix = "vsh_";
  304. }
  305. else
  306. {
  307. $prefix = "psh_";
  308. }
  309. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  310. {
  311. local( $name ) = @dynamicDefineNames[$i];
  312. push @outputHeader, $prefix . "forgot_to_set_dynamic_" . $name . " + ";
  313. }
  314. push @outputHeader, "0\n";
  315. }
  316. sub WriteStaticHelperClasses
  317. {
  318. local( $basename ) = $fxc_basename;
  319. $basename =~ tr/A-Z/a-z/;
  320. local( $classname ) = $basename . "_Static_Index";
  321. push @outputHeader, "#include \"shaderlib/cshader.h\"\n";
  322. push @outputHeader, "class $classname\n";
  323. push @outputHeader, "{\n";
  324. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  325. {
  326. $name = $staticDefineNames[$i];
  327. $min = $staticDefineMin[$i];
  328. $max = $staticDefineMax[$i];
  329. &WriteHelperVar( $name, $min, $max );
  330. }
  331. push @outputHeader, "public:\n";
  332. # push @outputHeader, "void SetShaderIndex( IShaderShadow *pShaderShadow ) { pShaderShadow->SetPixelShaderIndex( GetIndex() ); }\n";
  333. push @outputHeader, "\t$classname( )\n";
  334. push @outputHeader, "\t{\n";
  335. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  336. {
  337. local( $name ) = @staticDefineNames[$i];
  338. local( $boolname ) = "m_b" . $name;
  339. local( $varname ) = "m_n" . $name;
  340. if ( length( $staticDefineInit{$name} ) )
  341. {
  342. push @outputHeader, "#ifdef _DEBUG\n";
  343. push @outputHeader, "\t\t$boolname = true;\n";
  344. push @outputHeader, "#endif // _DEBUG\n";
  345. push @outputHeader, "\t\t$varname = $staticDefineInit{$name};\n";
  346. }
  347. else
  348. {
  349. push @outputHeader, "#ifdef _DEBUG\n";
  350. push @outputHeader, "\t\t$boolname = false;\n";
  351. push @outputHeader, "#endif // _DEBUG\n";
  352. push @outputHeader, "\t\t$varname = 0;\n";
  353. }
  354. }
  355. push @outputHeader, "\t}\n";
  356. push @outputHeader, "\tint GetIndex()\n";
  357. push @outputHeader, "\t{\n";
  358. push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n";
  359. foreach $skip (@perlskipcodeindividual)
  360. {
  361. $skip =~ s/\$/m_n/g;
  362. # push @outputHeader, "\t\tAssert( !( $skip ) );\n";
  363. }
  364. push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n";
  365. push @outputHeader, "#ifdef _DEBUG\n";
  366. if( scalar( @staticDefineNames ) > 0 )
  367. {
  368. push @outputHeader, "\t\tbool bAllStaticVarsDefined = ";
  369. WriteStaticBoolExpression( "", "&&" );
  370. }
  371. if( scalar( @staticDefineNames ) > 0 )
  372. {
  373. push @outputHeader, "\t\tAssert( bAllStaticVarsDefined );\n";
  374. }
  375. push @outputHeader, "#endif // _DEBUG\n";
  376. if( $spewCombos && scalar( @staticDefineNames ) )
  377. {
  378. push @outputHeader, &CreateCCodeToSpewStaticCombo();
  379. }
  380. push @outputHeader, "\t\treturn ";
  381. local( $scale ) = 1;
  382. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  383. {
  384. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  385. }
  386. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  387. {
  388. local( $name ) = @staticDefineNames[$i];
  389. local( $varname ) = "m_n" . $name;
  390. push @outputHeader, "( $scale * $varname ) + ";
  391. $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  392. }
  393. push @outputHeader, "0;\n";
  394. push @outputHeader, "\t}\n";
  395. push @outputHeader, "};\n";
  396. push @outputHeader, "\#define shaderStaticTest_" . $basename . " ";
  397. my $prefix;
  398. my $shaderType = &GetShaderType( $fxc_filename );
  399. if( $shaderType =~ m/^vs/i )
  400. {
  401. $prefix = "vsh_";
  402. }
  403. else
  404. {
  405. $prefix = "psh_";
  406. }
  407. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  408. {
  409. local( $name ) = @staticDefineNames[$i];
  410. push @outputHeader, $prefix . "forgot_to_set_static_" . $name . " + " unless (length($staticDefineInit{$name} ));
  411. }
  412. push @outputHeader, "0\n";
  413. }
  414. sub GetNewMainName
  415. {
  416. local( $shadername ) = shift;
  417. local( $combo ) = shift;
  418. local( $i );
  419. $shadername =~ s/\./_/g;
  420. local( $name ) = $shadername;
  421. for( $i = 0; $i < scalar( @defineNames ); $i++ )
  422. {
  423. local( $val ) = ( $combo % ( $defineMax[$i] - $defineMin[$i] + 1 ) ) + $defineMin[$i];
  424. $name .= "_" . $defineNames[$i] . "_" . $val;
  425. $combo = $combo / ( $defineMax[$i] - $defineMin[$i] + 1 );
  426. }
  427. # return $name;
  428. return "main";
  429. }
  430. sub RenameMain
  431. {
  432. local( $shadername ) = shift;
  433. local( $combo ) = shift;
  434. local( $name ) = &GetNewMainName( $shadername, $combo );
  435. return "/Dmain=$name /E$name ";
  436. }
  437. sub GetShaderType
  438. {
  439. local( $shadername ) = shift; # hack - use global variables
  440. $shadername = $fxc_basename;
  441. if( $shadername =~ m/ps30/i )
  442. {
  443. if( $debug )
  444. {
  445. return "ps_3_sw";
  446. }
  447. else
  448. {
  449. return "ps_3_0";
  450. }
  451. }
  452. elsif( $shadername =~ m/ps20b/i )
  453. {
  454. return "ps_2_b";
  455. }
  456. elsif( $shadername =~ m/ps20/i )
  457. {
  458. if( $debug )
  459. {
  460. return "ps_2_sw";
  461. }
  462. else
  463. {
  464. if( $ps2a )
  465. {
  466. return "ps_2_a";
  467. }
  468. else
  469. {
  470. return "ps_2_0";
  471. }
  472. }
  473. }
  474. elsif( $shadername =~ m/ps14/i )
  475. {
  476. return "ps_1_4";
  477. }
  478. elsif( $shadername =~ m/ps11/i )
  479. {
  480. return "ps_1_1";
  481. }
  482. elsif( $shadername =~ m/vs30/i )
  483. {
  484. if( $debug )
  485. {
  486. return "vs_3_sw";
  487. }
  488. else
  489. {
  490. return "vs_3_0";
  491. }
  492. }
  493. elsif( $shadername =~ m/vs20/i )
  494. {
  495. if( $debug )
  496. {
  497. return "vs_2_sw";
  498. }
  499. else
  500. {
  501. return "vs_2_0";
  502. }
  503. }
  504. elsif( $shadername =~ m/vs14/i )
  505. {
  506. return "vs_1_1";
  507. }
  508. elsif( $shadername =~ m/vs11/i )
  509. {
  510. return "vs_1_1";
  511. }
  512. else
  513. {
  514. die "\n\nSHADERNAME = $shadername\n\n";
  515. }
  516. }
  517. sub CalcNumCombos
  518. {
  519. local( $i, $numCombos );
  520. $numCombos = 1;
  521. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  522. {
  523. $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  524. }
  525. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  526. {
  527. $numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  528. }
  529. return $numCombos;
  530. }
  531. sub CalcNumDynamicCombos
  532. {
  533. local( $i, $numCombos );
  534. $numCombos = 1;
  535. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  536. {
  537. $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  538. }
  539. return $numCombos;
  540. }
  541. sub CreateCFuncToCreateCompileCommandLine
  542. {
  543. local( $out ) = "";
  544. $out .= "\t\tOutputDebugString( \"compiling src:$fxc_filename vcs:$fxc_basename \" );\n";
  545. $out .= "\t\tchar tmp[128];\n";
  546. $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n";
  547. $out .= "\t\tOutputDebugString( tmp );\n";
  548. $out .= "\t\tstatic PrecompiledShaderByteCode_t byteCode;\n";
  549. if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
  550. {
  551. $out .= "\t\tint nCombo = shaderID;\n";
  552. }
  553. # $out .= "\tvoid BuildCompileCommandLine( int nCombo, char *pResult, int maxLength )\n";
  554. # $out .= "\t{\n";
  555. $out .= "\t\tD3DXMACRO ";
  556. $out .= "defineMacros";
  557. $out .= "[";
  558. $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) + 1; # add 1 for null termination
  559. $out .= "];\n";
  560. if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
  561. {
  562. $out .= "\t\tchar tmpStringBuf[1024];\n";
  563. $out .= "\t\tchar *pTmpString = tmpStringBuf;\n\n";
  564. }
  565. local( $i );
  566. my $type = GetShaderType( $fxc_filename );
  567. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  568. {
  569. $out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % ";
  570. $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
  571. $out .= " );\n";
  572. $out .= "\t\tdefineMacros";
  573. $out .= "[";
  574. $out .= $i;
  575. $out .= "]";
  576. $out .= "\.Name = ";
  577. $out .= "\"$dynamicDefineNames[$i]\";\n";
  578. $out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % ";
  579. $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
  580. $out .= ";\n";
  581. $out .= "\t\tUNUSED( n$dynamicDefineNames[$i] );\n";
  582. $out .= "\t\tdefineMacros";
  583. $out .= "[";
  584. $out .= $i;
  585. $out .= "]";
  586. $out .= "\.Definition = ";
  587. $out .= "pTmpString;\n";
  588. $out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n";
  589. $out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n";
  590. $out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]";
  591. $out .= "=\" );\n";
  592. $out .= "\t\tOutputDebugString( tmp );\n";
  593. $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
  594. $out .= "\n";
  595. }
  596. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  597. {
  598. $out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % ";
  599. $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
  600. $out .= " );\n";
  601. $out .= "\t\tdefineMacros";
  602. $out .= "[";
  603. $out .= $i + scalar( @dynamicDefineNames );
  604. $out .= "]";
  605. $out .= "\.Name = ";
  606. $out .= "\"$staticDefineNames[$i]\";\n";
  607. $out .= "\t\tint n$staticDefineNames[$i] = nCombo % ";
  608. $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
  609. $out .= ";\n";
  610. $out .= "\t\tUNUSED( n$staticDefineNames[$i] );\n";
  611. $out .= "\t\tdefineMacros";
  612. $out .= "[";
  613. $out .= $i + scalar( @dynamicDefineNames );
  614. $out .= "]";
  615. $out .= "\.Definition = ";
  616. $out .= "pTmpString;\n";
  617. $out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n";
  618. $out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n";
  619. $out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]";
  620. $out .= "=\" );\n";
  621. $out .= "\t\tOutputDebugString( tmp );\n";
  622. $out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n";
  623. $out .= "\n";
  624. }
  625. $out .= "\t\tOutputDebugString( \"\\n\" );\n";
  626. $cskipcode = $perlskipcode;
  627. $cskipcode =~ s/\$/n/g;
  628. $out .= "\t\tif( $cskipcode )\n\t\t{\n";
  629. $out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n";
  630. $out .= "\t\t\tbyteCode.m_pRawData = blah;\n";
  631. $out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n";
  632. $out .= "\t\t\treturn byteCode;\n";
  633. $out .= "\t\t}\n";
  634. $out .= "\t\t// Must null terminate macros.\n";
  635. $out .= "\t\tdefineMacros[";
  636. $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames );
  637. $out .= "]";
  638. $out .= ".Name = NULL;\n";
  639. $out .= "\t\tdefineMacros[";
  640. $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames );
  641. $out .= "]";
  642. $out .= ".Definition = NULL;\n\n";
  643. $out .= "\t\tLPD3DXBUFFER pShader; // NOTE: THESE LEAK!!!\n";
  644. $out .= "\t\tLPD3DXBUFFER pErrorMessages; // NOTE: THESE LEAK!!!\n";
  645. $out .= "\t\tHRESULT hr = D3DXCompileShaderFromFile( \"u:\\\\hl2_e3_2004\\\\src_e3_2004\\\\materialsystem\\\\stdshaders\\\\$fxc_filename\",\n\t\t\tdefineMacros,\n\t\t\tNULL, // LPD3DXINCLUDE \n\t\t\t\"main\",\n\t\t\t\"$type\",\n\t\t\t0, // DWORD Flags\n\t\t\t&pShader,\n\t\t\t&pErrorMessages,\n\t\t\tNULL // LPD3DXCONSTANTTABLE *ppConstantTable\n\t\t\t );\n";
  646. $out .= "\t\tif( hr != D3D_OK )\n";
  647. $out .= "\t\t{\n";
  648. $out .= "\t\t\tconst char *pErrorMessageString = ( const char * )pErrorMessages->GetBufferPointer();\n";
  649. $out .= "\t\t\tOutputDebugString( pErrorMessageString );\n";
  650. $out .= "\t\t\tOutputDebugString( \"\\n\" );\n";
  651. $out .= "\t\t\tAssert( 0 );\n";
  652. $out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n";
  653. $out .= "\t\t\tbyteCode.m_pRawData = blah;\n";
  654. $out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n";
  655. $out .= "\t\t}\n";
  656. $out .= "\t\telse\n";
  657. $out .= "\t\t{\n";
  658. $out .= "\t\t\tbyteCode.m_pRawData = pShader->GetBufferPointer();\n";
  659. $out .= "\t\t\tbyteCode.m_nSizeInBytes = pShader->GetBufferSize();\n";
  660. $out .= "\t\t}\n";
  661. $out .= "\t\treturn byteCode;\n";
  662. return $out;
  663. }
  664. #print "--------\n";
  665. if ( $g_x360 )
  666. {
  667. $fxctmp = "fxctmp9_360_tmp";
  668. }
  669. else
  670. {
  671. $fxctmp = "fxctmp9_tmp";
  672. }
  673. if( !stat $fxctmp )
  674. {
  675. mkdir $fxctmp, 0777 || die $!;
  676. }
  677. # suck in an input file (using includes)
  678. #print "$fxc_filename...";
  679. @fxc = ReadInputFile( $fxc_filename );
  680. # READ THE TOP OF THE FILE TO FIND SHADER COMBOS
  681. foreach $line ( @fxc )
  682. {
  683. $line="" if ($g_x360 && ($line=~/\[PC\]/)); # line marked as [PC] when building for x360
  684. $line="" if (($g_x360 == 0) && ($line=~/\[XBOX\]/)); # line marked as [XBOX] when building for pc
  685. if ( $fxc_basename =~ m/_ps(\d+\w?)$/i )
  686. {
  687. my $psver = $1;
  688. $line="" if (($line =~/\[ps\d+\w?\]/i) && ($line!~/\[ps$psver\]/i)); # line marked for a version of compiler and not what we build
  689. }
  690. if ( $fxc_basename =~ m/_vs(\d+\w?)$/i )
  691. {
  692. my $vsver = $1;
  693. $line="" if (($line =~/\[vs\d+\w?\]/i) && ($line!~/\[vs$vsver\]/i)); # line marked for a version of compiler and not what we build
  694. }
  695. my $init_expr;
  696. $init_expr = $1 if ( $line=~/\[\=([^\]]+)\]/); # parse default init expression for combos
  697. $line=~s/\[[^\[\]]*\]//; # cut out all occurrences of
  698. # square brackets and whatever is
  699. # inside all these modifications
  700. # to the line are seen later when
  701. # processing skips and centroids
  702. next if( $line =~ m/^\s*$/ );
  703. if( $line =~ m/^\s*\/\/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
  704. {
  705. local( $name, $min, $max );
  706. $name = $1;
  707. $min = $2;
  708. $max = $3;
  709. # print STDERR "STATIC: \"$name\" \"$min..$max\"\n";
  710. push @staticDefineNames, $name;
  711. push @staticDefineMin, $min;
  712. push @staticDefineMax, $max;
  713. $staticDefineInit{$name}=$init_expr;
  714. }
  715. elsif( $line =~ m/^\s*\/\/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
  716. {
  717. local( $name, $min, $max );
  718. $name = $1;
  719. $min = $2;
  720. $max = $3;
  721. # print STDERR "DYNAMIC: \"$name\" \"$min..$max\"\n";
  722. push @dynamicDefineNames, $name;
  723. push @dynamicDefineMin, $min;
  724. push @dynamicDefineMax, $max;
  725. }
  726. }
  727. # READ THE WHOLE FILE AND FIND SKIP STATEMENTS
  728. foreach $line ( @fxc )
  729. {
  730. if( $line =~ m/^\s*\/\/\s*SKIP\s*\s*\:\s*(.*)$/ )
  731. {
  732. # print $1 . "\n";
  733. $perlskipcode .= "(" . $1 . ")||";
  734. push @perlskipcodeindividual, $1;
  735. }
  736. }
  737. if( defined $perlskipcode )
  738. {
  739. $perlskipcode .= "0";
  740. $perlskipcode =~ s/\n//g;
  741. }
  742. else
  743. {
  744. $perlskipcode = "0";
  745. }
  746. # READ THE WHOLE FILE AND FIND CENTROID STATEMENTS
  747. foreach $line ( @fxc )
  748. {
  749. if( $line =~ m/^\s*\/\/\s*CENTROID\s*\:\s*TEXCOORD(\d+)\s*$/ )
  750. {
  751. $centroidEnable{$1} = 1;
  752. # print "CENTROID: $1\n";
  753. }
  754. }
  755. if( $spewCombos )
  756. {
  757. push @outputHeader, "#include \"windows.h\"\n";
  758. }
  759. #push @outputHeader, "\#include \"shaderlib\\baseshader.h\"\n";
  760. #push @outputHeader, "IShaderDynamicAPI *CBaseShader::s_pShaderAPI;\n";
  761. # Go ahead an compute the mask of samplers that need to be centroid sampled
  762. $centroidMask = 0;
  763. foreach $centroidRegNum ( keys( %centroidEnable ) )
  764. {
  765. # print "THING: $samplerName $centroidRegNum\n";
  766. $centroidMask += 1 << $centroidRegNum;
  767. }
  768. #printf "0x%x\n", $centroidMask;
  769. $numCombos = &CalcNumCombos();
  770. #print "$numCombos combos\n";
  771. if( $g_produceCompiledVcs && !$dynamic_compile )
  772. {
  773. open FOUT, ">>filelistgen.txt" || die "can't open filelistgen.txt";
  774. print FOUT "**** generated by fxc_prep.pl ****\n";
  775. print FOUT "#BEGIN " . $fxc_basename . "\n";
  776. print FOUT "$fxc_filename" . "\n";
  777. print FOUT "#DEFINES-D:\n";
  778. for( $i = 0; $i < scalar( @dynamicDefineNames ); \$i++ )
  779. {
  780. print FOUT "$dynamicDefineNames[$i]=";
  781. print FOUT $dynamicDefineMin[$i];
  782. print FOUT "..";
  783. print FOUT $dynamicDefineMax[$i];
  784. print FOUT "\n";
  785. }
  786. print FOUT "#DEFINES-S:\n";
  787. for( $i = 0; $i < scalar( @staticDefineNames ); \$i++ )
  788. {
  789. print FOUT "$staticDefineNames[$i]=";
  790. print FOUT $staticDefineMin[$i];
  791. print FOUT "..";
  792. print FOUT $staticDefineMax[$i];
  793. print FOUT "\n";
  794. }
  795. print FOUT "#SKIP:\n";
  796. print FOUT "$perlskipcode\n";
  797. print FOUT "#COMMAND:\n";
  798. # first line
  799. print FOUT "fxc.exe ";
  800. print FOUT "/DTOTALSHADERCOMBOS=$numCombos ";
  801. print FOUT "/DCENTROIDMASK=$centroidMask ";
  802. print FOUT "/DNUMDYNAMICCOMBOS=" . &CalcNumDynamicCombos() . " ";
  803. print FOUT "/DFLAGS=0x0 "; # Nothing here for now.
  804. print FOUT "\n";
  805. #defines go here
  806. # second line
  807. print FOUT &RenameMain( $fxc_filename, $i );
  808. print FOUT "/T" . &GetShaderType( $fxc_filename ) . " ";
  809. print FOUT "/DSHADER_MODEL_" . &ToUpper( &GetShaderType( $fxc_filename ) ) . "=1 ";
  810. if( $nvidia )
  811. {
  812. print FOUT "/DNV3X=1 "; # enable NV3X codepath
  813. }
  814. if ( $g_x360 )
  815. {
  816. print FOUT "/D_X360=1 "; # shaders can identify X360 centric code
  817. # print FOUT "/Xbe:2- "; # use the less-broken old back end
  818. }
  819. if( $debug )
  820. {
  821. print FOUT "/Od "; # disable optimizations
  822. print FOUT "/Zi "; # enable debug info
  823. }
  824. # print FOUT "/Zi "; # enable debug info
  825. print FOUT "/nologo ";
  826. # print FOUT "/Fhtmpshader.h ";
  827. print FOUT "/Foshader.o ";
  828. print FOUT "$fxc_filename";
  829. print FOUT ">output.txt 2>&1";
  830. print FOUT "\n";
  831. #end of command line
  832. print FOUT "#END\n";
  833. print FOUT "**** end ****\n";
  834. close FOUT;
  835. }
  836. if ( $g_produceCppClasses )
  837. {
  838. # Write out the C++ helper class for picking shader combos
  839. &WriteStaticHelperClasses();
  840. &WriteDynamicHelperClasses();
  841. my $incfilename = "$fxctmp\\$fxc_basename" . ".inc";
  842. &WriteFile( $incfilename, join( "", @outputHeader ) );
  843. }
  844. if( $generateListingFile )
  845. {
  846. my $listFileName = "$fxctmp/$fxc_basename" . ".lst";
  847. print "writing $listFileName\n";
  848. if( !open FILE, ">$listFileName" )
  849. {
  850. die;
  851. }
  852. print FILE @listingOutput;
  853. close FILE;
  854. }
  855. @endTimes = times;
  856. $endTime = time;
  857. #printf "Elapsed user time: %.2f seconds!\n", $endTimes[0] - $startTimes[0];
  858. #printf "Elapsed system time: %.2f seconds!\n", $endTimes[1] - $startTimes[1];
  859. #printf "Elapsed child user time: %.2f seconds!\n", $endTimes[2] - $startTimes[2];
  860. #printf "Elapsed child system time: %.2f seconds!\n", $endTimes[3] - $startTimes[3];
  861. #printf "Elapsed total time: %.2f seconds!\n", $endTime - $startTime;