Counter Strike : Global Offensive Source Code
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.

1185 lines
31 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. $g_sfm = 1;
  42. while( 1 )
  43. {
  44. $fxc_filename = shift;
  45. if( $fxc_filename =~ m/-source/ )
  46. {
  47. shift;
  48. }
  49. elsif( $fxc_filename =~ m/-nv3x/i )
  50. {
  51. $nvidia = 1;
  52. }
  53. elsif( $fxc_filename =~ m/-ps20a/i )
  54. {
  55. $ps2a = 1;
  56. }
  57. elsif( $fxc_filename =~ m/-x360/i )
  58. {
  59. # enable x360
  60. $g_x360 = 1;
  61. }
  62. elsif( $fxc_filename =~ m/-ps3/i )
  63. {
  64. # enable ps3
  65. $g_ps3 = 1;
  66. }
  67. elsif( $fxc_filename =~ m/-novcs/i )
  68. {
  69. $g_produceCompiledVcs = 0;
  70. }
  71. elsif( $fxc_filename =~ m/-nocpp/i )
  72. {
  73. $g_produceCppClasses = 0;
  74. }
  75. else
  76. {
  77. last;
  78. }
  79. }
  80. $argstring = $fxc_filename;
  81. $fxc_basename = $fxc_filename;
  82. $fxc_basename =~ s/^.*-----//;
  83. $fxc_filename =~ s/-----.*$//;
  84. $debug = 0;
  85. $forcehalf = 0;
  86. sub ToUpper
  87. {
  88. local( $in ) = shift;
  89. $in =~ tr/a-z/A-Z/;
  90. return $in;
  91. }
  92. sub CreateCCodeToSpewDynamicCombo
  93. {
  94. local( $out ) = "";
  95. $out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename dynamic index\" );\n";
  96. $out .= "\t\tchar tmp[128];\n";
  97. $out .= "\t\tint shaderID = ";
  98. local( $scale ) = 1;
  99. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  100. {
  101. local( $name ) = @dynamicDefineNames[$i];
  102. local( $varname ) = "m_n" . $name;
  103. $out .= "( $scale * $varname ) + ";
  104. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  105. }
  106. $out .= "0;\n";
  107. if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
  108. {
  109. $out .= "\t\tint nCombo = shaderID;\n";
  110. }
  111. my $type = GetShaderType( $fxc_filename );
  112. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  113. {
  114. $out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % ";
  115. $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
  116. $out .= ";\n";
  117. $out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n";
  118. $out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]";
  119. $out .= "=\" );\n";
  120. $out .= "\t\tOutputDebugString( tmp );\n";
  121. $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
  122. $out .= "\n";
  123. }
  124. $out .= "\t\tOutputDebugString( \"\\n\" );\n";
  125. return $out;
  126. }
  127. sub CreateCCodeToSpewStaticCombo
  128. {
  129. local( $out ) = "";
  130. $out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename static index\" );\n";
  131. $out .= "\t\tchar tmp[128];\n";
  132. $out .= "\t\tint shaderID = ";
  133. local( $scale ) = 1;
  134. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  135. {
  136. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  137. }
  138. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  139. {
  140. local( $name ) = @staticDefineNames[$i];
  141. local( $varname ) = "m_n" . $name;
  142. $out .= "( $scale * $varname ) + ";
  143. $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  144. }
  145. $out .= "0;\n";
  146. # $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n";
  147. # $out .= "\t\tOutputDebugString( tmp );\n\n";
  148. if( scalar( @staticDefineNames ) + scalar( @staticDefineNames ) > 0 )
  149. {
  150. $out .= "\t\tint nCombo = shaderID;\n";
  151. }
  152. my $type = GetShaderType( $fxc_filename );
  153. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  154. {
  155. $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
  156. }
  157. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  158. {
  159. $out .= "\t\tint n$staticDefineNames[$i] = nCombo % ";
  160. $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
  161. $out .= ";\n";
  162. $out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n";
  163. $out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]";
  164. $out .= "=\" );\n";
  165. $out .= "\t\tOutputDebugString( tmp );\n";
  166. $out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n";
  167. $out .= "\n";
  168. }
  169. $out .= "\t\tOutputDebugString( \"\\n\" );\n";
  170. return $out;
  171. }
  172. # This code is used to inject information about combo names, ranges, etc, into the inc file so that we can know what combo is skipped when we run into a skipped combo that is trying to be used.
  173. sub CreateCFuntionToSpewSkippedCombo
  174. {
  175. local( $out ) = "";
  176. if ( scalar( @dynamicDefineNames ) )
  177. {
  178. $out .= "\nstatic const ShaderComboInformation_t s_DynamicComboArray_" . $fxc_basename . "[" . scalar( @dynamicDefineNames ) . "] = \n{\n";
  179. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  180. {
  181. $out .= "\t{ \"$dynamicDefineNames[$i]\", $dynamicDefineMin[$i], $dynamicDefineMax[$i] },\n";
  182. }
  183. $out .= "};\n";
  184. }
  185. if ( scalar( @staticDefineNames ) )
  186. {
  187. $out .= "\nstatic const ShaderComboInformation_t s_StaticComboArray_" . $fxc_basename . "[" . scalar( @staticDefineNames ) . "] = \n{\n";
  188. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  189. {
  190. $out .= "\t{ \"$staticDefineNames[$i]\", $staticDefineMin[$i], $staticDefineMax[$i] },\n";
  191. }
  192. $out .= "};\n";
  193. }
  194. $out .= "static const ShaderComboSemantics_t $fxc_basename" . "_combos =\n";
  195. $out .= "{\n";
  196. $out .= "\t\"$fxc_basename\", ";
  197. if ( scalar( @dynamicDefineNames ) )
  198. {
  199. $out .= "s_DynamicComboArray_" . $fxc_basename . ", " . scalar( @dynamicDefineNames ) . ", ";
  200. }
  201. else
  202. {
  203. $out .= "NULL, 0, ";
  204. }
  205. if ( scalar( @staticDefineNames ) )
  206. {
  207. $out .= "s_StaticComboArray_" . $fxc_basename . ", " . scalar( @staticDefineNames ) . " ";
  208. }
  209. else
  210. {
  211. $out .= "NULL, 0 ";
  212. }
  213. $out .= "\n};\n";
  214. $out .= "\nclass ConstructMe_$fxc_basename\n";
  215. $out .= "{\n";
  216. $out .= "public:\n";
  217. $out .= "\tConstructMe_$fxc_basename" . "()\n";
  218. $out .= "\t{\n";
  219. $out .= "\t\tGetShaderDLL()->AddShaderComboInformation( &$fxc_basename" . "_combos );\n";
  220. $out .= "\t}\n";
  221. $out .= "};\n";
  222. $out .= "\nstatic ConstructMe_$fxc_basename s_ConstructMe_$fxc_basename;\n";
  223. return $out;
  224. };
  225. sub WriteHelperVar
  226. {
  227. local( $name ) = shift;
  228. local( $min ) = shift;
  229. local( $max ) = shift;
  230. local( $varname ) = "m_n" . $name;
  231. local( $boolname ) = "m_b" . $name;
  232. push @outputHeader, "private:\n";
  233. push @outputHeader, "\tint $varname;\n";
  234. push @outputHeader, "#ifdef _DEBUG\n";
  235. push @outputHeader, "\tbool $boolname;\n";
  236. push @outputHeader, "#endif\n";
  237. push @outputHeader, "public:\n";
  238. # int version of set function
  239. push @outputHeader, "\tvoid Set" . $name . "( int i )\n";
  240. push @outputHeader, "\t{\n";
  241. push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n";
  242. push @outputHeader, "\t\t$varname = i;\n";
  243. push @outputHeader, "#ifdef _DEBUG\n";
  244. push @outputHeader, "\t\t$boolname = true;\n";
  245. push @outputHeader, "#endif\n";
  246. push @outputHeader, "\t}\n";
  247. # bool version of set function
  248. push @outputHeader, "\tvoid Set" . $name . "( bool i )\n";
  249. push @outputHeader, "\t{\n";
  250. push @outputHeader, "\t\tAssert( ( i ? 1 : 0 ) >= $min && ( i ? 1 : 0 ) <= $max );\n";
  251. push @outputHeader, "\t\t$varname = i ? 1 : 0;\n";
  252. push @outputHeader, "#ifdef _DEBUG\n";
  253. push @outputHeader, "\t\t$boolname = true;\n";
  254. push @outputHeader, "#endif\n";
  255. push @outputHeader, "\t}\n";
  256. }
  257. sub WriteStaticBoolExpression
  258. {
  259. local( $prefix ) = shift;
  260. local( $operator ) = shift;
  261. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  262. {
  263. if( $i )
  264. {
  265. push @outputHeader, " $operator ";
  266. }
  267. local( $name ) = @staticDefineNames[$i];
  268. local( $boolname ) = "m_b" . $name;
  269. push @outputHeader, "$prefix$boolname";
  270. }
  271. push @outputHeader, ";\n";
  272. }
  273. sub WriteDynamicBoolExpression
  274. {
  275. local( $prefix ) = shift;
  276. local( $operator ) = shift;
  277. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  278. {
  279. if( $i )
  280. {
  281. push @outputHeader, " $operator ";
  282. }
  283. local( $name ) = @dynamicDefineNames[$i];
  284. local( $boolname ) = "m_b" . $name;
  285. push @outputHeader, "$prefix$boolname";
  286. }
  287. push @outputHeader, ";\n";
  288. }
  289. sub WriteDynamicHelperClasses
  290. {
  291. local( $basename ) = $fxc_basename;
  292. $basename =~ tr/A-Z/a-z/;
  293. local( $classname ) = $basename . "_Dynamic_Index";
  294. push @outputHeader, "class $classname\n";
  295. push @outputHeader, "{\n";
  296. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  297. {
  298. $name = $dynamicDefineNames[$i];
  299. $min = $dynamicDefineMin[$i];
  300. $max = $dynamicDefineMax[$i];
  301. &WriteHelperVar( $name, $min, $max );
  302. }
  303. push @outputHeader, "public:\n";
  304. # push @outputHeader, "void SetPixelShaderIndex( IShaderAPI *pShaderAPI ) { pShaderAPI->SetPixelShaderIndex( GetIndex() ); }\n";
  305. # CONSTRUCTOR
  306. push @outputHeader, "\t// CONSTRUCTOR\n\t$classname( IShaderDynamicAPI *pShaderAPI )\n";
  307. push @outputHeader, "\t{\n";
  308. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  309. {
  310. local( $name ) = @dynamicDefineNames[$i];
  311. local( $boolname ) = "m_b" . $name;
  312. local( $varname ) = "m_n" . $name;
  313. if ( length( $dynamicDefineInit{$name} ) )
  314. {
  315. push @outputHeader, "#ifdef _DEBUG\n";
  316. push @outputHeader, "\t\t$boolname = true;\n";
  317. push @outputHeader, "#endif // _DEBUG\n";
  318. push @outputHeader, "\t\t$varname = $dynamicDefineInit{$name};\n";
  319. }
  320. else
  321. {
  322. push @outputHeader, "#ifdef _DEBUG\n";
  323. push @outputHeader, "\t\t$boolname = false;\n";
  324. push @outputHeader, "#endif // _DEBUG\n";
  325. push @outputHeader, "\t\t$varname = 0;\n";
  326. }
  327. }
  328. push @outputHeader, "\t}\n";
  329. push @outputHeader, "\tint GetIndex()\n";
  330. push @outputHeader, "\t{\n";
  331. push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n";
  332. foreach $skip (@perlskipcodeindividual)
  333. {
  334. # can't do this static and dynamic can see each other.
  335. # $skip =~ s/\$/m_n/g;
  336. # $skip =~ s/defined//g;
  337. # push @outputHeader, "\t\tAssert( !( $skip ) );\n";
  338. # print "\t\tAssert( !( $skip ) );\n";
  339. }
  340. push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n";
  341. push @outputHeader, "#ifdef _DEBUG\n";
  342. if( scalar( @dynamicDefineNames ) > 0 )
  343. {
  344. push @outputHeader, "\t\tbool bAllDynamicVarsDefined = ";
  345. WriteDynamicBoolExpression( "", "&&" );
  346. }
  347. if( scalar( @dynamicDefineNames ) > 0 )
  348. {
  349. push @outputHeader, "\t\tAssert( bAllDynamicVarsDefined );\n";
  350. }
  351. push @outputHeader, "#endif // _DEBUG\n";
  352. if( $spewCombos && scalar( @dynamicDefineNames ) )
  353. {
  354. push @outputHeader, &CreateCCodeToSpewDynamicCombo();
  355. }
  356. push @outputHeader, "\t\treturn ";
  357. local( $scale ) = 1;
  358. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  359. {
  360. local( $name ) = @dynamicDefineNames[$i];
  361. local( $varname ) = "m_n" . $name;
  362. push @outputHeader, "( $scale * $varname ) + ";
  363. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  364. }
  365. push @outputHeader, "0;\n";
  366. push @outputHeader, "\t}\n";
  367. push @outputHeader, "};\n";
  368. push @outputHeader, "\#define shaderDynamicTest_" . $basename . " ";
  369. my $prefix;
  370. my $shaderType = &GetShaderType( $fxc_filename );
  371. if( $g_ps3 )
  372. {
  373. if( $shaderType =~ m/vp/i )
  374. {
  375. $prefix = "vsh_";
  376. }
  377. else
  378. {
  379. $prefix = "psh_";
  380. }
  381. }
  382. else
  383. {
  384. if( $shaderType =~ m/^vs/i )
  385. {
  386. $prefix = "vsh_";
  387. }
  388. else
  389. {
  390. $prefix = "psh_";
  391. }
  392. }
  393. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  394. {
  395. local( $name ) = @dynamicDefineNames[$i];
  396. if ( !length( $dynamicDefineInit{$name} ) )
  397. {
  398. push @outputHeader, $prefix . "forgot_to_set_dynamic_" . $name . " + ";
  399. }
  400. }
  401. push @outputHeader, "0\n";
  402. }
  403. sub WriteSkips
  404. {
  405. my $skip;
  406. push @outputHeader, "// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!!\n";
  407. foreach $skip (@perlskipcodeindividual)
  408. {
  409. # $skip =~ s/\$/m_n/g;
  410. push @outputHeader, "// $skip\n";
  411. }
  412. }
  413. sub WriteStaticHelperClasses
  414. {
  415. local( $basename ) = $fxc_basename;
  416. $basename =~ tr/A-Z/a-z/;
  417. local( $classname ) = $basename . "_Static_Index";
  418. push @outputHeader, "#include \"shaderlib/cshader.h\"\n";
  419. push @outputHeader, "class $classname\n";
  420. push @outputHeader, "{\n";
  421. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  422. {
  423. $name = $staticDefineNames[$i];
  424. $min = $staticDefineMin[$i];
  425. $max = $staticDefineMax[$i];
  426. &WriteHelperVar( $name, $min, $max );
  427. }
  428. push @outputHeader, "public:\n";
  429. # push @outputHeader, "void SetShaderIndex( IShaderShadow *pShaderShadow ) { pShaderShadow->SetPixelShaderIndex( GetIndex() ); }\n";
  430. # WRITE THE CONSTRUCTOR
  431. push @outputHeader, "\t// CONSTRUCTOR\n\t$classname( IShaderShadow *pShaderShadow, IMaterialVar **params )\n";
  432. push @outputHeader, "\t{\n";
  433. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  434. {
  435. local( $name ) = @staticDefineNames[$i];
  436. local( $boolname ) = "m_b" . $name;
  437. local( $varname ) = "m_n" . $name;
  438. if ( length( $staticDefineInit{$name} ) )
  439. {
  440. push @outputHeader, "#ifdef _DEBUG\n";
  441. push @outputHeader, "\t\t$boolname = true;\n";
  442. push @outputHeader, "#endif // _DEBUG\n";
  443. push @outputHeader, "\t\t$varname = $staticDefineInit{$name};\n";
  444. }
  445. else
  446. {
  447. push @outputHeader, "#ifdef _DEBUG\n";
  448. push @outputHeader, "\t\t$boolname = false;\n";
  449. push @outputHeader, "#endif // _DEBUG\n";
  450. push @outputHeader, "\t\t$varname = 0;\n";
  451. }
  452. }
  453. push @outputHeader, "\t}\n";
  454. push @outputHeader, "\tint GetIndex()\n";
  455. push @outputHeader, "\t{\n";
  456. push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n";
  457. foreach $skip (@perlskipcodeindividual)
  458. {
  459. $skip =~ s/\$/m_n/g;
  460. # push @outputHeader, "\t\tAssert( !( $skip ) );\n";
  461. }
  462. push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n";
  463. push @outputHeader, "#ifdef _DEBUG\n";
  464. if( scalar( @staticDefineNames ) > 0 )
  465. {
  466. push @outputHeader, "\t\tbool bAllStaticVarsDefined = ";
  467. WriteStaticBoolExpression( "", "&&" );
  468. }
  469. if( scalar( @staticDefineNames ) > 0 )
  470. {
  471. push @outputHeader, "\t\tAssert( bAllStaticVarsDefined );\n";
  472. }
  473. push @outputHeader, "#endif // _DEBUG\n";
  474. if( $spewCombos && scalar( @staticDefineNames ) )
  475. {
  476. push @outputHeader, &CreateCCodeToSpewStaticCombo();
  477. }
  478. push @outputHeader, "\t\treturn ";
  479. local( $scale ) = 1;
  480. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  481. {
  482. $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  483. }
  484. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  485. {
  486. local( $name ) = @staticDefineNames[$i];
  487. local( $varname ) = "m_n" . $name;
  488. push @outputHeader, "( $scale * $varname ) + ";
  489. $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  490. }
  491. push @outputHeader, "0;\n";
  492. if( $scale > 0x7fffffff )
  493. {
  494. $g_toomanycombos = 1;
  495. $g_totalcombos = $scale;
  496. }
  497. push @outputHeader, "\t}\n";
  498. push @outputHeader, "};\n";
  499. push @outputHeader, "\#define shaderStaticTest_" . $basename . " ";
  500. my $prefix;
  501. my $shaderType = &GetShaderType( $fxc_filename );
  502. if( $g_ps3 )
  503. {
  504. if( $shaderType =~ m/vp/i )
  505. {
  506. $prefix = "vsh_";
  507. }
  508. else
  509. {
  510. $prefix = "psh_";
  511. }
  512. }
  513. else
  514. {
  515. if( $shaderType =~ m/^vs/i )
  516. {
  517. $prefix = "vsh_";
  518. }
  519. else
  520. {
  521. $prefix = "psh_";
  522. }
  523. }
  524. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  525. {
  526. local( $name ) = @staticDefineNames[$i];
  527. if ( !length( $staticDefineInit{$name} ) )
  528. {
  529. push @outputHeader, $prefix . "forgot_to_set_static_" . $name . " + ";
  530. }
  531. }
  532. push @outputHeader, "0\n";
  533. }
  534. sub GetNewMainName
  535. {
  536. local( $shadername ) = shift;
  537. local( $combo ) = shift;
  538. local( $i );
  539. $shadername =~ s/\./_/g;
  540. local( $name ) = $shadername;
  541. for( $i = 0; $i < scalar( @defineNames ); $i++ )
  542. {
  543. local( $val ) = ( $combo % ( $defineMax[$i] - $defineMin[$i] + 1 ) ) + $defineMin[$i];
  544. $name .= "_" . $defineNames[$i] . "_" . $val;
  545. $combo = $combo / ( $defineMax[$i] - $defineMin[$i] + 1 );
  546. }
  547. # return $name;
  548. return "main";
  549. }
  550. sub RenameMain
  551. {
  552. local( $shadername ) = shift;
  553. local( $combo ) = shift;
  554. local( $name ) = &GetNewMainName( $shadername, $combo );
  555. if ( $g_ps3)
  556. {
  557. return "-e $name "
  558. }
  559. else
  560. {
  561. return "/Dmain=$name /E$name ";
  562. }
  563. }
  564. sub GetShaderType
  565. {
  566. local( $shadername ) = shift; # hack - use global variables
  567. $shadername = $fxc_basename;
  568. if( $g_ps3 )
  569. {
  570. if( $shadername =~ m/_vs/i )
  571. {
  572. return "sce_vp_rsx"
  573. }
  574. elsif( $shadername =~ m/_ps/i )
  575. {
  576. return "sce_fp_rsx"
  577. }
  578. else
  579. {
  580. die "\n\nPS3 SHADERNAME = $shadername\n\n";
  581. }
  582. }
  583. elsif( $shadername =~ m/ps30/i )
  584. {
  585. if( $debug )
  586. {
  587. return "ps_3_sw";
  588. }
  589. else
  590. {
  591. return "ps_3_0";
  592. }
  593. }
  594. elsif( $shadername =~ m/ps20b/i )
  595. {
  596. return "ps_2_b";
  597. }
  598. elsif( $shadername =~ m/ps20/i )
  599. {
  600. if( $debug )
  601. {
  602. return "ps_2_sw";
  603. }
  604. else
  605. {
  606. if( $ps2a )
  607. {
  608. return "ps_2_a";
  609. }
  610. else
  611. {
  612. return "ps_2_0";
  613. }
  614. }
  615. }
  616. elsif( $shadername =~ m/ps14/i )
  617. {
  618. return "ps_1_4";
  619. }
  620. elsif( $shadername =~ m/ps11/i )
  621. {
  622. return "ps_1_1";
  623. }
  624. elsif( $shadername =~ m/vs30/i )
  625. {
  626. if( $debug )
  627. {
  628. return "vs_3_sw";
  629. }
  630. else
  631. {
  632. return "vs_3_0";
  633. }
  634. }
  635. elsif( $shadername =~ m/vs20/i )
  636. {
  637. if( $debug )
  638. {
  639. return "vs_2_sw";
  640. }
  641. else
  642. {
  643. return "vs_2_0";
  644. }
  645. }
  646. elsif( $shadername =~ m/vs14/i )
  647. {
  648. return "vs_1_1";
  649. }
  650. elsif( $shadername =~ m/vs11/i )
  651. {
  652. return "vs_1_1";
  653. }
  654. else
  655. {
  656. die "\n\nSHADERNAME = $shadername\n\n";
  657. }
  658. }
  659. sub CalcNumCombos
  660. {
  661. local( $i, $numCombos );
  662. $numCombos = 1;
  663. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  664. {
  665. $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  666. }
  667. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  668. {
  669. $numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  670. }
  671. return $numCombos;
  672. }
  673. sub CalcNumDynamicCombos
  674. {
  675. local( $i, $numCombos );
  676. $numCombos = 1;
  677. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  678. {
  679. $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  680. }
  681. return $numCombos;
  682. }
  683. sub CreateCFuncToCreateCompileCommandLine
  684. {
  685. local( $out ) = "";
  686. $out .= "\t\tOutputDebugString( \"compiling src:$fxc_filename vcs:$fxc_basename \" );\n";
  687. $out .= "\t\tchar tmp[128];\n";
  688. $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n";
  689. $out .= "\t\tOutputDebugString( tmp );\n";
  690. $out .= "\t\tstatic PrecompiledShaderByteCode_t byteCode;\n";
  691. if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
  692. {
  693. $out .= "\t\tint nCombo = shaderID;\n";
  694. }
  695. # $out .= "\tvoid BuildCompileCommandLine( int nCombo, char *pResult, int maxLength )\n";
  696. # $out .= "\t{\n";
  697. $out .= "\t\tD3DXMACRO ";
  698. $out .= "defineMacros";
  699. $out .= "[";
  700. $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) + 1; # add 1 for null termination
  701. $out .= "];\n";
  702. if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 )
  703. {
  704. $out .= "\t\tchar tmpStringBuf[1024];\n";
  705. $out .= "\t\tchar *pTmpString = tmpStringBuf;\n\n";
  706. }
  707. local( $i );
  708. my $type = GetShaderType( $fxc_filename );
  709. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  710. {
  711. $out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % ";
  712. $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
  713. $out .= " );\n";
  714. $out .= "\t\tdefineMacros";
  715. $out .= "[";
  716. $out .= $i;
  717. $out .= "]";
  718. $out .= "\.Name = ";
  719. $out .= "\"$dynamicDefineNames[$i]\";\n";
  720. $out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % ";
  721. $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i];
  722. $out .= ";\n";
  723. $out .= "\t\tUNUSED( n$dynamicDefineNames[$i] );\n";
  724. $out .= "\t\tdefineMacros";
  725. $out .= "[";
  726. $out .= $i;
  727. $out .= "]";
  728. $out .= "\.Definition = ";
  729. $out .= "pTmpString;\n";
  730. $out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n";
  731. $out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n";
  732. $out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]";
  733. $out .= "=\" );\n";
  734. $out .= "\t\tOutputDebugString( tmp );\n";
  735. $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n";
  736. $out .= "\n";
  737. }
  738. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  739. {
  740. $out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % ";
  741. $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
  742. $out .= " );\n";
  743. $out .= "\t\tdefineMacros";
  744. $out .= "[";
  745. $out .= $i + scalar( @dynamicDefineNames );
  746. $out .= "]";
  747. $out .= "\.Name = ";
  748. $out .= "\"$staticDefineNames[$i]\";\n";
  749. $out .= "\t\tint n$staticDefineNames[$i] = nCombo % ";
  750. $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i];
  751. $out .= ";\n";
  752. $out .= "\t\tUNUSED( n$staticDefineNames[$i] );\n";
  753. $out .= "\t\tdefineMacros";
  754. $out .= "[";
  755. $out .= $i + scalar( @dynamicDefineNames );
  756. $out .= "]";
  757. $out .= "\.Definition = ";
  758. $out .= "pTmpString;\n";
  759. $out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n";
  760. $out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n";
  761. $out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]";
  762. $out .= "=\" );\n";
  763. $out .= "\t\tOutputDebugString( tmp );\n";
  764. $out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n";
  765. $out .= "\n";
  766. }
  767. $out .= "\t\tOutputDebugString( \"\\n\" );\n";
  768. $cskipcode = $perlskipcode;
  769. $cskipcode =~ s/\$/n/g;
  770. $out .= "\t\tif( $cskipcode )\n\t\t{\n";
  771. $out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n";
  772. $out .= "\t\t\tbyteCode.m_pRawData = blah;\n";
  773. $out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n";
  774. $out .= "\t\t\treturn byteCode;\n";
  775. $out .= "\t\t}\n";
  776. $out .= "\t\t// Must null terminate macros.\n";
  777. $out .= "\t\tdefineMacros[";
  778. $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames );
  779. $out .= "]";
  780. $out .= ".Name = NULL;\n";
  781. $out .= "\t\tdefineMacros[";
  782. $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames );
  783. $out .= "]";
  784. $out .= ".Definition = NULL;\n\n";
  785. $out .= "\t\tLPD3DXBUFFER pShader; // NOTE: THESE LEAK!!!\n";
  786. $out .= "\t\tLPD3DXBUFFER pErrorMessages; // NOTE: THESE LEAK!!!\n";
  787. $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";
  788. $out .= "\t\tif( hr != D3D_OK )\n";
  789. $out .= "\t\t{\n";
  790. $out .= "\t\t\tconst char *pErrorMessageString = ( const char * )pErrorMessages->GetBufferPointer();\n";
  791. $out .= "\t\t\tOutputDebugString( pErrorMessageString );\n";
  792. $out .= "\t\t\tOutputDebugString( \"\\n\" );\n";
  793. $out .= "\t\t\tAssert( 0 );\n";
  794. $out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n";
  795. $out .= "\t\t\tbyteCode.m_pRawData = blah;\n";
  796. $out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n";
  797. $out .= "\t\t}\n";
  798. $out .= "\t\telse\n";
  799. $out .= "\t\t{\n";
  800. $out .= "\t\t\tbyteCode.m_pRawData = pShader->GetBufferPointer();\n";
  801. $out .= "\t\t\tbyteCode.m_nSizeInBytes = pShader->GetBufferSize();\n";
  802. $out .= "\t\t}\n";
  803. $out .= "\t\treturn byteCode;\n";
  804. return $out;
  805. }
  806. #print "--------\n";
  807. if ( $g_x360 )
  808. {
  809. $fxctmp = "fxctmp9_360_tmp";
  810. }
  811. elsif ( $g_ps3 )
  812. {
  813. $fxctmp = "fxctmp9_ps3_tmp";
  814. }
  815. else
  816. {
  817. $fxctmp = "fxctmp9_tmp";
  818. }
  819. if( !stat $fxctmp )
  820. {
  821. mkdir $fxctmp, 0777 || die $!;
  822. }
  823. # suck in an input file (using includes)
  824. #print "$fxc_filename...";
  825. @fxc = ReadInputFile( $fxc_filename );
  826. # READ THE TOP OF THE FILE TO FIND SHADER COMBOS
  827. foreach $line ( @fxc )
  828. {
  829. $line="" if ( ( $g_x360 || $g_ps3 ) && ($line=~/\[PC\]/)); # line marked as [PC] when building for x360 or PS3
  830. $line="" if ( ( $g_x360 == 0 ) && ( $g_ps3 == 0) && ($line=~/\[CONSOLE\]/)); # line marked as [CONSOLE] when building for pc
  831. $line="" if ( ( $g_x360 == 0 ) && ($line=~/\[XBOX\]/)); # line marked as [XBOX] when building for pc / ps3
  832. $line="" if ( ( $g_ps3 == 0 ) && ($line=~/\[SONYPS3\]/)); # line marked as [SONYPS3] when building for pc / xbox
  833. $line="" if ( ( $g_ps3 == 1 ) && ($line=~/\[!SONYPS3\]/)); # line marked as [!SONYPS3] when building for ps3
  834. $line="" if ( ( $g_sfm == 0 ) && ( $line =~ /\[SFM\]/ ) ); # line marked as [SFM] when not building for sfm
  835. $line="" if ( ( $g_sfm ) && ( $line =~ /\[\!SFM\]/ ) ); # line marked as [!SFM] when building for sfm
  836. if ( $fxc_basename =~ m/_ps(\d+\w?)$/i )
  837. {
  838. my $psver = $1;
  839. $line="" if (($line =~/\[ps\d+\w?\]/i) && ($line!~/\[ps$psver\]/i)); # line marked for a version of compiler and not what we build
  840. }
  841. if ( $fxc_basename =~ m/_vs(\d+\w?)$/i )
  842. {
  843. my $vsver = $1;
  844. $line="" if (($line =~/\[vs\d+\w?\]/i) && ($line!~/\[vs$vsver\]/i)); # line marked for a version of compiler and not what we build
  845. }
  846. my $init_expr;
  847. # looks for something like [=0] after the base part of the combo definition.
  848. if ( $line =~ /\[\s*\=\s*([^\]]+)\]/ )
  849. {
  850. $init_expr = $1; # parse default init expression for combos
  851. }
  852. $line=~s/\[[^\[\]]*\]//; # cut out all occurrences of
  853. # square brackets and whatever is
  854. # inside all these modifications
  855. # to the line are seen later when
  856. # processing skips and centroids
  857. next if( $line =~ m/^\s*$/ );
  858. if( $line =~ m/^\s*\/\/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
  859. {
  860. local( $name, $min, $max );
  861. $name = $1;
  862. $min = $2;
  863. $max = $3;
  864. # print STDERR "STATIC: \"$name\" \"$min..$max\"\n";
  865. push @staticDefineNames, $name;
  866. push @staticDefineMin, $min;
  867. push @staticDefineMax, $max;
  868. $staticDefineInit{$name} = $init_expr;
  869. }
  870. elsif( $line =~ m/^\s*\/\/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
  871. {
  872. local( $name, $min, $max );
  873. $name = $1;
  874. $min = $2;
  875. $max = $3;
  876. # print STDERR "DYNAMIC: \"$name\" \"$min..$max\"\n";
  877. push @dynamicDefineNames, $name;
  878. push @dynamicDefineMin, $min;
  879. push @dynamicDefineMax, $max;
  880. $dynamicDefineInit{$name} = $init_expr;
  881. }
  882. }
  883. # READ THE WHOLE FILE AND FIND SKIP STATEMENTS
  884. foreach $line ( @fxc )
  885. {
  886. if( $line =~ m/^\s*\/\/\s*SKIP\s*\s*\:\s*(.*)$/ )
  887. {
  888. # print $1 . "\n";
  889. $perlskipcode .= "(" . $1 . ")||";
  890. push @perlskipcodeindividual, $1;
  891. }
  892. }
  893. if( defined $perlskipcode )
  894. {
  895. $perlskipcode .= "0";
  896. $perlskipcode =~ s/\n//g;
  897. }
  898. else
  899. {
  900. $perlskipcode = "0";
  901. }
  902. # READ THE WHOLE FILE AND FIND CENTROID STATEMENTS
  903. foreach $line ( @fxc )
  904. {
  905. if( $line =~ m/^\s*\/\/\s*CENTROID\s*\:\s*TEXCOORD(\d+)\s*$/ )
  906. {
  907. $centroidEnable{$1} = 1;
  908. # print "CENTROID: $1\n";
  909. }
  910. }
  911. if( $spewCombos )
  912. {
  913. push @outputHeader, "#include \"windows.h\"\n";
  914. }
  915. #push @outputHeader, "\#include \"shaderlib\\baseshader.h\"\n";
  916. #push @outputHeader, "IShaderDynamicAPI *CBaseShader::s_pShaderAPI;\n";
  917. # Go ahead an compute the mask of samplers that need to be centroid sampled
  918. $centroidMask = 0;
  919. foreach $centroidRegNum ( keys( %centroidEnable ) )
  920. {
  921. # print "THING: $samplerName $centroidRegNum\n";
  922. $centroidMask += 1 << $centroidRegNum;
  923. }
  924. #printf "0x%x\n", $centroidMask;
  925. $numCombos = &CalcNumCombos();
  926. #print "$numCombos combos\n";
  927. if( $g_produceCompiledVcs && !$dynamic_compile )
  928. {
  929. open FOUT, ">>filelistgen.txt" || die "can't open filelistgen.txt";
  930. print FOUT "**** generated by fxc_prep.pl ****\n";
  931. print FOUT "#BEGIN " . $fxc_basename . "\n";
  932. print FOUT "$fxc_filename" . "\n";
  933. print FOUT "#DEFINES-D:\n";
  934. for( $i = 0; $i < scalar( @dynamicDefineNames ); \$i++ )
  935. {
  936. print FOUT "$dynamicDefineNames[$i]=";
  937. print FOUT $dynamicDefineMin[$i];
  938. print FOUT "..";
  939. print FOUT $dynamicDefineMax[$i];
  940. print FOUT "\n";
  941. }
  942. print FOUT "#DEFINES-S:\n";
  943. for( $i = 0; $i < scalar( @staticDefineNames ); \$i++ )
  944. {
  945. print FOUT "$staticDefineNames[$i]=";
  946. print FOUT $staticDefineMin[$i];
  947. print FOUT "..";
  948. print FOUT $staticDefineMax[$i];
  949. print FOUT "\n";
  950. }
  951. print FOUT "#SKIP:\n";
  952. print FOUT "$perlskipcode\n";
  953. print FOUT "#COMMAND:\n";
  954. # first line (prefix of shader compile command)
  955. if ( $g_ps3 )
  956. {
  957. print FOUT "sce-cgc.exe ";
  958. print FOUT "-DTOTALSHADERCOMBOS=$numCombos ";
  959. print FOUT "-DCENTROIDMASK=$centroidMask ";
  960. print FOUT "-DNUMDYNAMICCOMBOS=" . &CalcNumDynamicCombos() . " ";
  961. print FOUT "-DFLAGS=0x0 "; # Nothing here for now.
  962. }
  963. else
  964. {
  965. print FOUT "fxc.exe ";
  966. print FOUT "/DTOTALSHADERCOMBOS=$numCombos ";
  967. print FOUT "/DCENTROIDMASK=$centroidMask ";
  968. print FOUT "/DNUMDYNAMICCOMBOS=" . &CalcNumDynamicCombos() . " ";
  969. print FOUT "/DFLAGS=0x0 "; # Nothing here for now.
  970. }
  971. print FOUT "\n";
  972. # defines will be appended here by the shader compiler
  973. # second line (suffix of shader compile command)
  974. print FOUT &RenameMain( $fxc_filename, $i );
  975. if( $g_ps3 )
  976. {
  977. my $shaderType = &GetShaderType( $fxc_filename );
  978. print FOUT "-p " . $shaderType . " ";
  979. print FOUT "-DSHADER_MODEL_" . &ToUpper( $shaderType ) . "=1 ";
  980. print FOUT "-D_PS3=1 -D_CONSOLE=1 "; # shaders can identify PS3 centric code
  981. if ( $shaderType eq "sce_fp_rsx" )
  982. {
  983. print FOUT "-DSHADER_MODEL_PS_2_B=1 " ;
  984. }
  985. elsif ( $shaderType eq "sce_vp_rsx" )
  986. {
  987. print FOUT "-DSHADER_MODEL_VS_2_0=1 " ;
  988. }
  989. else
  990. {
  991. die ( "Invalid shader type " . $shaderType );
  992. }
  993. if ( $debug )
  994. {
  995. print FOUT "-nofastmath "; # disable most of the optimisations
  996. }
  997. else
  998. {
  999. print FOUT "-inline all "; # inline all functions
  1000. print FOUT "-fastmath "; # enable most of the optimisations
  1001. }
  1002. # print FOUT "-q "; # quiet mode, disabled for now
  1003. print FOUT "-o shader.o ";
  1004. }
  1005. else
  1006. {
  1007. print FOUT "/T" . &GetShaderType( $fxc_filename ) . " ";
  1008. print FOUT "/DSHADER_MODEL_" . &ToUpper( &GetShaderType( $fxc_filename ) ) . "=1 ";
  1009. if( $nvidia )
  1010. {
  1011. print FOUT "/DNV3X=1 "; # enable NV3X codepath
  1012. }
  1013. if ( $g_x360 )
  1014. {
  1015. print FOUT "/D_X360=1 /D_CONSOLE=1 "; # shaders can identify X360 centric code
  1016. # print FOUT "/Xbe:2- "; # use the less-broken old back end
  1017. }
  1018. if( $debug )
  1019. {
  1020. print FOUT "/Od "; # disable optimizations
  1021. print FOUT "/Zi "; # enable debug info
  1022. }
  1023. # print FOUT "/Zi "; # enable debug info
  1024. print FOUT "/nologo ";
  1025. # print FOUT "/Fhtmpshader.h ";
  1026. print FOUT "/Foshader.o ";
  1027. }
  1028. print FOUT "$fxc_filename";
  1029. print FOUT ">output.txt 2>&1";
  1030. print FOUT "\n";
  1031. #end of command line
  1032. print FOUT "#END\n";
  1033. print FOUT "**** end ****\n";
  1034. close FOUT;
  1035. }
  1036. if ( $g_produceCppClasses )
  1037. {
  1038. # Write out the C++ helper class for picking shader combos
  1039. &WriteSkips();
  1040. &WriteStaticHelperClasses();
  1041. &WriteDynamicHelperClasses();
  1042. push @outputHeader, &CreateCFuntionToSpewSkippedCombo();
  1043. my $incfilename = "$fxctmp\\$fxc_basename" . ".inc";
  1044. if( $g_toomanycombos )
  1045. {
  1046. unlink $incfilename;
  1047. print STDERR "ERROR: too many combos in $fxc_filename ($g_totalcombos > 4294967295)!\n";
  1048. }
  1049. else
  1050. {
  1051. &WriteFile( $incfilename, join( "", @outputHeader ) );
  1052. }
  1053. }
  1054. if( $generateListingFile )
  1055. {
  1056. my $listFileName = "$fxctmp/$fxc_basename" . ".lst";
  1057. print "writing $listFileName\n";
  1058. if( !open FILE, ">$listFileName" )
  1059. {
  1060. die;
  1061. }
  1062. print FILE @listingOutput;
  1063. close FILE;
  1064. }
  1065. @endTimes = times;
  1066. $endTime = time;
  1067. #printf "Elapsed user time: %.2f seconds!\n", $endTimes[0] - $startTimes[0];
  1068. #printf "Elapsed system time: %.2f seconds!\n", $endTimes[1] - $startTimes[1];
  1069. #printf "Elapsed child user time: %.2f seconds!\n", $endTimes[2] - $startTimes[2];
  1070. #printf "Elapsed child system time: %.2f seconds!\n", $endTimes[3] - $startTimes[3];
  1071. #printf "Elapsed total time: %.2f seconds!\n", $endTime - $startTime;