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.

333 lines
7.9 KiB

  1. use String::CRC32;
  2. BEGIN {use File::Basename; push @INC, dirname($0); }
  3. require "valve_perl_helpers.pl";
  4. sub BuildDefineOptions
  5. {
  6. local( $output );
  7. local( $combo ) = shift;
  8. local( $i );
  9. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  10. {
  11. local( $val ) = ( $combo % ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) ) + $dynamicDefineMin[$i];
  12. $output .= "/D$dynamicDefineNames[$i]=$val ";
  13. $combo = $combo / ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 );
  14. }
  15. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  16. {
  17. local( $val ) = ( $combo % ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) ) + $staticDefineMin[$i];
  18. $output .= "/D$staticDefineNames[$i]=$val ";
  19. $combo = $combo / ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 );
  20. }
  21. return $output;
  22. }
  23. sub CalcNumCombos
  24. {
  25. local( $i, $numCombos );
  26. $numCombos = 1;
  27. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  28. {
  29. $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  30. }
  31. for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
  32. {
  33. $numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
  34. }
  35. return $numCombos;
  36. }
  37. sub CalcNumDynamicCombos
  38. {
  39. local( $i, $numCombos );
  40. $numCombos = 1;
  41. for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
  42. {
  43. $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
  44. }
  45. return $numCombos;
  46. }
  47. $g_dx9 = 1;
  48. while( 1 )
  49. {
  50. $psh_filename = shift;
  51. if( $psh_filename =~ m/-source/ )
  52. {
  53. $g_SourceDir = shift;
  54. }
  55. elsif( $psh_filename =~ m/-x360/ )
  56. {
  57. $g_x360 = 1;
  58. }
  59. else
  60. {
  61. last;
  62. }
  63. }
  64. $psh_filename =~ s/-----.*$//;
  65. # Get the shader binary version number from a header file.
  66. open FILE, "<$g_SourceDir\\public\\materialsystem\\shader_vcs_version.h" || die;
  67. while( $line = <FILE> )
  68. {
  69. if( $line =~ m/^\#define\s+SHADER_VCS_VERSION_NUMBER\s+(\d+)\s*$/ )
  70. {
  71. $shaderVersion = $1;
  72. last;
  73. }
  74. }
  75. if( !defined $shaderVersion )
  76. {
  77. die "couldn't get shader version from shader_vcs_version.h";
  78. }
  79. close FILE;
  80. local( @staticDefineNames );
  81. local( @staticDefineMin );
  82. local( @staticDefineMax );
  83. local( @dynamicDefineNames );
  84. local( @dynamicDefineMin );
  85. local( @dynamicDefineMax );
  86. # Parse the combos.
  87. open PSH, "<$psh_filename";
  88. while( <PSH> )
  89. {
  90. last if( !m,^;, );
  91. s,^;\s*,,;
  92. if( m/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
  93. {
  94. local( $name, $min, $max );
  95. $name = $1;
  96. $min = $2;
  97. $max = $3;
  98. # print "\"STATIC: $name\" \"$min..$max\"\n";
  99. if (/\[(.*)\]/)
  100. {
  101. $platforms=$1;
  102. next if ( ($g_x360) && (!($platforms=~/XBOX/i)) );
  103. next if ( (!$g_x360) && (!($platforms=~/PC/i)) );
  104. }
  105. push @staticDefineNames, $name;
  106. push @staticDefineMin, $min;
  107. push @staticDefineMax, $max;
  108. }
  109. elsif( m/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
  110. {
  111. local( $name, $min, $max );
  112. $name = $1;
  113. $min = $2;
  114. $max = $3;
  115. # print "\"DYNAMIC: $name\" \"$min..$max\"\n";
  116. if (/\[(.*)\]/)
  117. {
  118. $platforms=$1;
  119. next if ( ($g_x360) && (!($platforms=~/XBOX/i)) );
  120. next if ( (!$g_x360) && (!($platforms=~/PC/i)) );
  121. }
  122. push @dynamicDefineNames, $name;
  123. push @dynamicDefineMin, $min;
  124. push @dynamicDefineMax, $max;
  125. }
  126. }
  127. close PSH;
  128. $numCombos = &CalcNumCombos();
  129. $numDynamicCombos = &CalcNumDynamicCombos();
  130. print "$psh_filename\n";
  131. #print "$numCombos combos\n";
  132. #print "$numDynamicCombos dynamic combos\n";
  133. if( $g_x360 )
  134. {
  135. $pshtmp = "pshtmp9_360";
  136. }
  137. elsif( $g_dx9 )
  138. {
  139. $pshtmp = "pshtmp9";
  140. }
  141. else
  142. {
  143. $pshtmp = "pshtmp8";
  144. }
  145. $basename = $psh_filename;
  146. $basename =~ s/\.psh$//i;
  147. for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ )
  148. {
  149. my $tempFilename = "shader$shaderCombo.o";
  150. unlink $tempFilename;
  151. if( $g_x360 )
  152. {
  153. $cmd = "psa /D_X360=1 /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL";
  154. }
  155. else
  156. {
  157. $cmd = "$g_SourceDir\\dx9sdk\\utilities\\psa /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL";
  158. }
  159. if( !stat $pshtmp )
  160. {
  161. mkdir $pshtmp, 0777 || die $!;
  162. }
  163. # print $cmd . "\n";
  164. system $cmd || die $!;
  165. # Make sure a file got generated because sometimes the die above won't happen on compile errors.
  166. my $filesize = (stat $tempFilename)[7];
  167. if ( !$filesize )
  168. {
  169. die "Error compiling shader$shaderCombo.o";
  170. }
  171. push @outputHeader, @hdr;
  172. }
  173. $basename =~ s/\.fxc//gi;
  174. push @outputHeader, "static PrecompiledShaderByteCode_t " . $basename . "_pixel_shaders[" . $numCombos . "] = \n";
  175. push @outputHeader, "{\n";
  176. local( $j );
  177. for( $j = 0; $j < $numCombos; $j++ )
  178. {
  179. local( $thing ) = "pixelShader_" . $basename . "_" . $j;
  180. push @outputHeader, "\t{ " . "$thing, sizeof( $thing ) },\n";
  181. }
  182. push @outputHeader, "};\n";
  183. push @outputHeader, "struct $basename" . "PixelShader_t : public PrecompiledShader_t\n";
  184. push @outputHeader, "{\n";
  185. push @outputHeader, "\t$basename" . "PixelShader_t()\n";
  186. push @outputHeader, "\t{\n";
  187. push @outputHeader, "\t\tm_nFlags = 0;\n";
  188. push @outputHeader, "\t\tm_pByteCode = " . $basename . "_pixel_shaders;\n";
  189. push @outputHeader, "\t\tm_nShaderCount = $numCombos;\n";
  190. #push @outputHeader, "\t\tm_nDynamicCombos = m_nShaderCount;\n";
  191. push @outputHeader, "\t\t// NOTE!!! psh_prep.pl shaders are always static combos!\n";
  192. push @outputHeader, "\t\tm_nDynamicCombos = 1;\n";
  193. push @outputHeader, "\t\tm_pName = \"$basename\";\n";
  194. if( $basename =~ /vs\d\d/ ) # hack
  195. {
  196. push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_VERTEX_SHADER, this );\n";
  197. }
  198. else
  199. {
  200. push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_PIXEL_SHADER, this );\n";
  201. }
  202. push @outputHeader, "\t}\n";
  203. push @outputHeader, "\tvirtual const PrecompiledShaderByteCode_t &GetByteCode( int shaderID )\n";
  204. push @outputHeader, "\t{\n";
  205. push @outputHeader, "\t\treturn m_pByteCode[shaderID];\n";
  206. push @outputHeader, "\t}\n";
  207. push @outputHeader, "};\n";
  208. push @outputHeader, "static $basename" . "PixelShader_t $basename" . "_PixelShaderInstance;\n";
  209. &MakeDirHier( "shaders/psh" );
  210. my $vcsName = "";
  211. if( $g_x360 )
  212. {
  213. $vcsName = $basename . ".360.vcs";
  214. }
  215. else
  216. {
  217. $vcsName = $basename . ".vcs";
  218. }
  219. open COMPILEDSHADER, ">shaders/psh/$vcsName" || die;
  220. binmode( COMPILEDSHADER );
  221. #
  222. # Write out the part of the header that we know. . we'll write the rest after writing the object code.
  223. #
  224. #print $numCombos . "\n";
  225. # Pack arguments
  226. my $sInt = "i";
  227. my $uInt = "I";
  228. if ( $g_x360 )
  229. {
  230. # Change arguments to "big endian long"
  231. $sInt = "N";
  232. $uInt = "N";
  233. }
  234. open PSH, "<$psh_filename";
  235. my $crc = crc32( *PSH );
  236. close PSH;
  237. #print STDERR "crc for $psh_filename: $crc\n";
  238. # version
  239. print COMPILEDSHADER pack $sInt, 4;
  240. # totalCombos
  241. print COMPILEDSHADER pack $sInt, $numCombos;
  242. # dynamic combos
  243. print COMPILEDSHADER pack $sInt, $numDynamicCombos;
  244. # flags
  245. print COMPILEDSHADER pack $uInt, 0x0; # nothing here for now.
  246. # centroid mask
  247. print COMPILEDSHADER pack $uInt, 0;
  248. # reference size for diffs
  249. print COMPILEDSHADER pack $uInt, 0;
  250. # crc32 of the source code
  251. print COMPILEDSHADER pack $uInt, $crc;
  252. my $beginningOfDir = tell COMPILEDSHADER;
  253. # Write out a blank directionary. . we'll fill it in later.
  254. for( $i = 0; $i < $numCombos; $i++ )
  255. {
  256. # offset from beginning of file.
  257. print COMPILEDSHADER pack $sInt, 0;
  258. # size
  259. print COMPILEDSHADER pack $sInt, 0;
  260. }
  261. my $startByteCode = tell COMPILEDSHADER;
  262. my @byteCodeStart;
  263. my @byteCodeSize;
  264. # Write out the shader object code.
  265. for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ )
  266. {
  267. my $filename = "shader$shaderCombo\.o";
  268. my $filesize = (stat $filename)[7];
  269. $byteCodeStart[$shaderCombo] = tell COMPILEDSHADER;
  270. $byteCodeSize[$shaderCombo] = $filesize;
  271. open SHADERBYTECODE, "<$filename";
  272. binmode SHADERBYTECODE;
  273. my $bin;
  274. my $numread = read SHADERBYTECODE, $bin, $filesize;
  275. # print "filename: $filename numread: $numread filesize: $filesize\n";
  276. close SHADERBYTECODE;
  277. unlink $filename;
  278. print COMPILEDSHADER $bin;
  279. }
  280. # Seek back to the directory and write it out.
  281. seek COMPILEDSHADER, $beginningOfDir, 0;
  282. for( $i = 0; $i < $numCombos; $i++ )
  283. {
  284. # offset from beginning of file.
  285. print COMPILEDSHADER pack $sInt, $byteCodeStart[$i];
  286. # size
  287. print COMPILEDSHADER pack $sInt, $byteCodeSize[$i];
  288. }
  289. close COMPILEDSHADER;