From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/devtools/bin/fxc_prep.pl | 949 +++++++++++++++++++++++++ mp/src/devtools/bin/linux/ccache | Bin 0 -> 308586 bytes mp/src/devtools/bin/osx32/ccache | Bin 0 -> 89116 bytes mp/src/devtools/bin/osx32/protoc | Bin 0 -> 1387919 bytes mp/src/devtools/bin/psh_prep.pl | 333 +++++++++ mp/src/devtools/bin/updateshaders.pl | 305 ++++++++ mp/src/devtools/bin/vsh_prep.pl | 1106 ++++++++++++++++++++++++++++++ mp/src/devtools/gendbg.sh | 44 ++ mp/src/devtools/makefile_base_posix.mak | 494 +++++++++++++ mp/src/devtools/sourcesdk_def.mak | 3 + mp/src/devtools/version_script.linux.txt | 14 + 11 files changed, 3248 insertions(+) create mode 100644 mp/src/devtools/bin/fxc_prep.pl create mode 100644 mp/src/devtools/bin/linux/ccache create mode 100644 mp/src/devtools/bin/osx32/ccache create mode 100644 mp/src/devtools/bin/osx32/protoc create mode 100644 mp/src/devtools/bin/psh_prep.pl create mode 100644 mp/src/devtools/bin/updateshaders.pl create mode 100644 mp/src/devtools/bin/vsh_prep.pl create mode 100644 mp/src/devtools/gendbg.sh create mode 100644 mp/src/devtools/makefile_base_posix.mak create mode 100644 mp/src/devtools/sourcesdk_def.mak create mode 100644 mp/src/devtools/version_script.linux.txt (limited to 'mp/src/devtools') diff --git a/mp/src/devtools/bin/fxc_prep.pl b/mp/src/devtools/bin/fxc_prep.pl new file mode 100644 index 00000000..adc51ad8 --- /dev/null +++ b/mp/src/devtools/bin/fxc_prep.pl @@ -0,0 +1,949 @@ +BEGIN {use File::Basename; push @INC, dirname($0); } +require "valve_perl_helpers.pl"; + +sub ReadInputFile +{ + local( $filename ) = shift; + local( *INPUT ); + local( @output ); + open INPUT, "<$filename" || die; + + local( $line ); + local( $linenum ) = 1; + while( $line = ) + { +# print "LINE: $line"; +# $line =~ s/\n//g; +# 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"; +# $postfix .= "; LINEINFO($filename)($linenum)\n"; + if( $line =~ m/\#include\s+\"(.*)\"/i ) + { + push @output, &ReadInputFile( $1 ); + } + else + { +# push @output, $line . $postfix; + push @output, $line; + } + $linenum++; + } + + close INPUT; +# print "-----------------\n"; +# print @output; +# print "-----------------\n"; + return @output; +} + +$dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0; +$generateListingFile = 0; +$spewCombos = 0; + +@startTimes = times; +$startTime = time; + +$g_produceCppClasses = 1; +$g_produceCompiledVcs = 1; + +while( 1 ) +{ + $fxc_filename = shift; + if( $fxc_filename =~ m/-source/ ) + { + shift; + } + elsif( $fxc_filename =~ m/-nv3x/i ) + { + $nvidia = 1; + } + elsif( $fxc_filename =~ m/-ps20a/i ) + { + $ps2a = 1; + } + elsif( $fxc_filename =~ m/-x360/i ) + { + # enable x360 + $g_x360 = 1; + } + elsif( $fxc_filename =~ m/-novcs/i ) + { + $g_produceCompiledVcs = 0; + } + elsif( $fxc_filename =~ m/-nocpp/i ) + { + $g_produceCppClasses = 0; + } + else + { + last; + } +} + +$argstring = $fxc_filename; +$fxc_basename = $fxc_filename; +$fxc_basename =~ s/^.*-----//; +$fxc_filename =~ s/-----.*$//; + +$debug = 0; +$forcehalf = 0; + +sub ToUpper +{ + local( $in ) = shift; + $in =~ tr/a-z/A-Z/; + return $in; +} + +sub CreateCCodeToSpewDynamicCombo +{ + local( $out ) = ""; + + $out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename dynamic index\" );\n"; + $out .= "\t\tchar tmp[128];\n"; + $out .= "\t\tint shaderID = "; + local( $scale ) = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + local( $name ) = @dynamicDefineNames[$i]; + local( $varname ) = "m_n" . $name; + $out .= "( $scale * $varname ) + "; + $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + $out .= "0;\n"; + if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 ) + { + $out .= "\t\tint nCombo = shaderID;\n"; + } + + my $type = GetShaderType( $fxc_filename ); + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % "; + $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i]; + $out .= ";\n"; + + $out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n"; + $out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]"; + $out .= "=\" );\n"; + $out .= "\t\tOutputDebugString( tmp );\n"; + + $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n"; + $out .= "\n"; + } + $out .= "\t\tOutputDebugString( \"\\n\" );\n"; + return $out; +} + +sub CreateCCodeToSpewStaticCombo +{ + local( $out ) = ""; + + $out .= "\t\tOutputDebugString( \"src:$fxc_filename vcs:$fxc_basename static index\" );\n"; + $out .= "\t\tchar tmp[128];\n"; + $out .= "\t\tint shaderID = "; + + local( $scale ) = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + local( $name ) = @staticDefineNames[$i]; + local( $varname ) = "m_n" . $name; + $out .= "( $scale * $varname ) + "; + $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1; + } + $out .= "0;\n"; + +# $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n"; +# $out .= "\t\tOutputDebugString( tmp );\n\n"; + if( scalar( @staticDefineNames ) + scalar( @staticDefineNames ) > 0 ) + { + $out .= "\t\tint nCombo = shaderID;\n"; + } + + my $type = GetShaderType( $fxc_filename ); + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n"; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $out .= "\t\tint n$staticDefineNames[$i] = nCombo % "; + $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i]; + $out .= ";\n"; + + $out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n"; + $out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]"; + $out .= "=\" );\n"; + $out .= "\t\tOutputDebugString( tmp );\n"; + + $out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n"; + $out .= "\n"; + } + $out .= "\t\tOutputDebugString( \"\\n\" );\n"; + return $out; +} + +sub WriteHelperVar +{ + local( $name ) = shift; + local( $min ) = shift; + local( $max ) = shift; + local( $varname ) = "m_n" . $name; + local( $boolname ) = "m_b" . $name; + push @outputHeader, "private:\n"; + push @outputHeader, "\tint $varname;\n"; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\tbool $boolname;\n"; + push @outputHeader, "#endif\n"; + push @outputHeader, "public:\n"; + # int version of set function + push @outputHeader, "\tvoid Set" . $name . "( int i )\n"; + push @outputHeader, "\t{\n"; + push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n"; + push @outputHeader, "\t\t$varname = i;\n"; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = true;\n"; + push @outputHeader, "#endif\n"; + push @outputHeader, "\t}\n"; + # bool version of set function + push @outputHeader, "\tvoid Set" . $name . "( bool i )\n"; + push @outputHeader, "\t{\n"; +# push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n"; + push @outputHeader, "\t\t$varname = i ? 1 : 0;\n"; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = true;\n"; + push @outputHeader, "#endif\n"; + push @outputHeader, "\t}\n"; +} + +sub WriteStaticBoolExpression +{ + local( $prefix ) = shift; + local( $operator ) = shift; + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + if( $i ) + { + push @outputHeader, " $operator "; + } + local( $name ) = @staticDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + push @outputHeader, "$prefix$boolname"; + } + push @outputHeader, ";\n"; +} + +sub WriteDynamicBoolExpression +{ + local( $prefix ) = shift; + local( $operator ) = shift; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + if( $i ) + { + push @outputHeader, " $operator "; + } + local( $name ) = @dynamicDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + push @outputHeader, "$prefix$boolname"; + } + push @outputHeader, ";\n"; +} + +sub WriteDynamicHelperClasses +{ + local( $basename ) = $fxc_basename; + $basename =~ tr/A-Z/a-z/; + local( $classname ) = $basename . "_Dynamic_Index"; + push @outputHeader, "class $classname\n"; + push @outputHeader, "{\n"; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $name = $dynamicDefineNames[$i]; + $min = $dynamicDefineMin[$i]; + $max = $dynamicDefineMax[$i]; + &WriteHelperVar( $name, $min, $max ); + } + push @outputHeader, "public:\n"; +# push @outputHeader, "void SetPixelShaderIndex( IShaderAPI *pShaderAPI ) { pShaderAPI->SetPixelShaderIndex( GetIndex() ); }\n"; + push @outputHeader, "\t$classname()\n"; + push @outputHeader, "\t{\n"; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + local( $name ) = @dynamicDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + local( $varname ) = "m_n" . $name; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = false;\n"; + push @outputHeader, "#endif // _DEBUG\n"; + push @outputHeader, "\t\t$varname = 0;\n"; + } + push @outputHeader, "\t}\n"; + push @outputHeader, "\tint GetIndex()\n"; + push @outputHeader, "\t{\n"; + push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n"; + foreach $skip (@perlskipcodeindividual) + { + # can't do this static and dynamic can see each other. +# $skip =~ s/\$/m_n/g; +# $skip =~ s/defined//g; +# push @outputHeader, "\t\tAssert( !( $skip ) );\n"; +# print "\t\tAssert( !( $skip ) );\n"; + } + push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n"; + + push @outputHeader, "#ifdef _DEBUG\n"; + if( scalar( @dynamicDefineNames ) > 0 ) + { + push @outputHeader, "\t\tbool bAllDynamicVarsDefined = "; + WriteDynamicBoolExpression( "", "&&" ); + } + if( scalar( @dynamicDefineNames ) > 0 ) + { + push @outputHeader, "\t\tAssert( bAllDynamicVarsDefined );\n"; + } + push @outputHeader, "#endif // _DEBUG\n"; + + if( $spewCombos && scalar( @dynamicDefineNames ) ) + { + push @outputHeader, &CreateCCodeToSpewDynamicCombo(); + } + push @outputHeader, "\t\treturn "; + local( $scale ) = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + local( $name ) = @dynamicDefineNames[$i]; + local( $varname ) = "m_n" . $name; + push @outputHeader, "( $scale * $varname ) + "; + $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + push @outputHeader, "0;\n"; + push @outputHeader, "\t}\n"; + push @outputHeader, "};\n"; + push @outputHeader, "\#define shaderDynamicTest_" . $basename . " "; + my $prefix; + my $shaderType = &GetShaderType( $fxc_filename ); + if( $shaderType =~ m/^vs/i ) + { + $prefix = "vsh_"; + } + else + { + $prefix = "psh_"; + } + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + local( $name ) = @dynamicDefineNames[$i]; + push @outputHeader, $prefix . "forgot_to_set_dynamic_" . $name . " + "; + } + push @outputHeader, "0\n"; +} + +sub WriteStaticHelperClasses +{ + local( $basename ) = $fxc_basename; + $basename =~ tr/A-Z/a-z/; + local( $classname ) = $basename . "_Static_Index"; + push @outputHeader, "#include \"shaderlib/cshader.h\"\n"; + push @outputHeader, "class $classname\n"; + push @outputHeader, "{\n"; + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $name = $staticDefineNames[$i]; + $min = $staticDefineMin[$i]; + $max = $staticDefineMax[$i]; + &WriteHelperVar( $name, $min, $max ); + } + push @outputHeader, "public:\n"; +# push @outputHeader, "void SetShaderIndex( IShaderShadow *pShaderShadow ) { pShaderShadow->SetPixelShaderIndex( GetIndex() ); }\n"; + push @outputHeader, "\t$classname( )\n"; + push @outputHeader, "\t{\n"; + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + local( $name ) = @staticDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + local( $varname ) = "m_n" . $name; + if ( length( $staticDefineInit{$name} ) ) + { + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = true;\n"; + push @outputHeader, "#endif // _DEBUG\n"; + push @outputHeader, "\t\t$varname = $staticDefineInit{$name};\n"; + } + else + { + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = false;\n"; + push @outputHeader, "#endif // _DEBUG\n"; + push @outputHeader, "\t\t$varname = 0;\n"; + } + } + push @outputHeader, "\t}\n"; + push @outputHeader, "\tint GetIndex()\n"; + push @outputHeader, "\t{\n"; + push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n"; + foreach $skip (@perlskipcodeindividual) + { + $skip =~ s/\$/m_n/g; +# push @outputHeader, "\t\tAssert( !( $skip ) );\n"; + } + push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n"; + + push @outputHeader, "#ifdef _DEBUG\n"; + if( scalar( @staticDefineNames ) > 0 ) + { + push @outputHeader, "\t\tbool bAllStaticVarsDefined = "; + WriteStaticBoolExpression( "", "&&" ); + + } + if( scalar( @staticDefineNames ) > 0 ) + { + push @outputHeader, "\t\tAssert( bAllStaticVarsDefined );\n"; + } + push @outputHeader, "#endif // _DEBUG\n"; + + if( $spewCombos && scalar( @staticDefineNames ) ) + { + push @outputHeader, &CreateCCodeToSpewStaticCombo(); + } + push @outputHeader, "\t\treturn "; + local( $scale ) = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + local( $name ) = @staticDefineNames[$i]; + local( $varname ) = "m_n" . $name; + push @outputHeader, "( $scale * $varname ) + "; + $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1; + } + push @outputHeader, "0;\n"; + push @outputHeader, "\t}\n"; + push @outputHeader, "};\n"; + push @outputHeader, "\#define shaderStaticTest_" . $basename . " "; + my $prefix; + my $shaderType = &GetShaderType( $fxc_filename ); + if( $shaderType =~ m/^vs/i ) + { + $prefix = "vsh_"; + } + else + { + $prefix = "psh_"; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + local( $name ) = @staticDefineNames[$i]; + push @outputHeader, $prefix . "forgot_to_set_static_" . $name . " + " unless (length($staticDefineInit{$name} )); + } + push @outputHeader, "0\n"; +} + +sub GetNewMainName +{ + local( $shadername ) = shift; + local( $combo ) = shift; + local( $i ); + $shadername =~ s/\./_/g; + local( $name ) = $shadername; + for( $i = 0; $i < scalar( @defineNames ); $i++ ) + { + local( $val ) = ( $combo % ( $defineMax[$i] - $defineMin[$i] + 1 ) ) + $defineMin[$i]; + $name .= "_" . $defineNames[$i] . "_" . $val; + $combo = $combo / ( $defineMax[$i] - $defineMin[$i] + 1 ); + } +# return $name; + return "main"; +} + +sub RenameMain +{ + local( $shadername ) = shift; + local( $combo ) = shift; + local( $name ) = &GetNewMainName( $shadername, $combo ); + return "/Dmain=$name /E$name "; +} + +sub GetShaderType +{ + local( $shadername ) = shift; # hack - use global variables + $shadername = $fxc_basename; + if( $shadername =~ m/ps30/i ) + { + if( $debug ) + { + return "ps_3_sw"; + } + else + { + return "ps_3_0"; + } + } + elsif( $shadername =~ m/ps20b/i ) + { + return "ps_2_b"; + } + elsif( $shadername =~ m/ps20/i ) + { + if( $debug ) + { + return "ps_2_sw"; + } + else + { + if( $ps2a ) + { + return "ps_2_a"; + } + else + { + return "ps_2_0"; + } + } + } + elsif( $shadername =~ m/ps14/i ) + { + return "ps_1_4"; + } + elsif( $shadername =~ m/ps11/i ) + { + return "ps_1_1"; + } + elsif( $shadername =~ m/vs30/i ) + { + if( $debug ) + { + return "vs_3_sw"; + } + else + { + return "vs_3_0"; + } + } + elsif( $shadername =~ m/vs20/i ) + { + if( $debug ) + { + return "vs_2_sw"; + } + else + { + return "vs_2_0"; + } + } + elsif( $shadername =~ m/vs14/i ) + { + return "vs_1_1"; + } + elsif( $shadername =~ m/vs11/i ) + { + return "vs_1_1"; + } + else + { + die "\n\nSHADERNAME = $shadername\n\n"; + } +} + +sub CalcNumCombos +{ + local( $i, $numCombos ); + $numCombos = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1; + } + return $numCombos; +} + +sub CalcNumDynamicCombos +{ + local( $i, $numCombos ); + $numCombos = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + return $numCombos; +} + +sub CreateCFuncToCreateCompileCommandLine +{ + local( $out ) = ""; + + $out .= "\t\tOutputDebugString( \"compiling src:$fxc_filename vcs:$fxc_basename \" );\n"; + $out .= "\t\tchar tmp[128];\n"; + $out .= "\t\tsprintf( tmp, \"\%d\\n\", shaderID );\n"; + $out .= "\t\tOutputDebugString( tmp );\n"; + $out .= "\t\tstatic PrecompiledShaderByteCode_t byteCode;\n"; + if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 ) + { + $out .= "\t\tint nCombo = shaderID;\n"; + } + +# $out .= "\tvoid BuildCompileCommandLine( int nCombo, char *pResult, int maxLength )\n"; +# $out .= "\t{\n"; + $out .= "\t\tD3DXMACRO "; + $out .= "defineMacros"; + $out .= "["; + $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) + 1; # add 1 for null termination + $out .= "];\n"; + if( scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ) > 0 ) + { + $out .= "\t\tchar tmpStringBuf[1024];\n"; + $out .= "\t\tchar *pTmpString = tmpStringBuf;\n\n"; + } + + local( $i ); + my $type = GetShaderType( $fxc_filename ); + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % "; + $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i]; + $out .= " );\n"; + $out .= "\t\tdefineMacros"; + $out .= "["; + $out .= $i; + $out .= "]"; + $out .= "\.Name = "; + $out .= "\"$dynamicDefineNames[$i]\";\n"; + + $out .= "\t\tint n$dynamicDefineNames[$i] = nCombo % "; + $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i]; + $out .= ";\n"; + $out .= "\t\tUNUSED( n$dynamicDefineNames[$i] );\n"; + + $out .= "\t\tdefineMacros"; + $out .= "["; + $out .= $i; + $out .= "]"; + $out .= "\.Definition = "; + $out .= "pTmpString;\n"; + $out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n"; + + $out .= "\t\tsprintf( tmp, \"\%d\", n$dynamicDefineNames[$i] );\n"; + $out .= "\t\tOutputDebugString( \" $dynamicDefineNames[$i]"; + $out .= "=\" );\n"; + $out .= "\t\tOutputDebugString( tmp );\n"; + + $out .= "\t\tnCombo = nCombo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n"; + $out .= "\n"; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $out .= "\t\tsprintf( pTmpString, \"%d\", nCombo % "; + $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i]; + $out .= " );\n"; + $out .= "\t\tdefineMacros"; + $out .= "["; + $out .= $i + scalar( @dynamicDefineNames ); + $out .= "]"; + $out .= "\.Name = "; + $out .= "\"$staticDefineNames[$i]\";\n"; + + $out .= "\t\tint n$staticDefineNames[$i] = nCombo % "; + $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i]; + $out .= ";\n"; + $out .= "\t\tUNUSED( n$staticDefineNames[$i] );\n"; + + $out .= "\t\tdefineMacros"; + $out .= "["; + $out .= $i + scalar( @dynamicDefineNames ); + $out .= "]"; + $out .= "\.Definition = "; + $out .= "pTmpString;\n"; + $out .= "\t\tpTmpString += strlen( pTmpString ) + 1;\n"; + + $out .= "\t\tsprintf( tmp, \"\%d\", n$staticDefineNames[$i] );\n"; + $out .= "\t\tOutputDebugString( \" $staticDefineNames[$i]"; + $out .= "=\" );\n"; + $out .= "\t\tOutputDebugString( tmp );\n"; + + $out .= "\t\tnCombo = nCombo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n"; + $out .= "\n"; + } + + $out .= "\t\tOutputDebugString( \"\\n\" );\n"; + + $cskipcode = $perlskipcode; + $cskipcode =~ s/\$/n/g; + $out .= "\t\tif( $cskipcode )\n\t\t{\n"; + $out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n"; + $out .= "\t\t\tbyteCode.m_pRawData = blah;\n"; + $out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n"; + $out .= "\t\t\treturn byteCode;\n"; + $out .= "\t\t}\n"; + + + + $out .= "\t\t// Must null terminate macros.\n"; + $out .= "\t\tdefineMacros["; + $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ); + $out .= "]"; + $out .= ".Name = NULL;\n"; + $out .= "\t\tdefineMacros["; + $out .= scalar( @dynamicDefineNames ) + scalar( @staticDefineNames ); + $out .= "]"; + $out .= ".Definition = NULL;\n\n"; + + + $out .= "\t\tLPD3DXBUFFER pShader; // NOTE: THESE LEAK!!!\n"; + $out .= "\t\tLPD3DXBUFFER pErrorMessages; // NOTE: THESE LEAK!!!\n"; + $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"; + $out .= "\t\tif( hr != D3D_OK )\n"; + $out .= "\t\t{\n"; + $out .= "\t\t\tconst char *pErrorMessageString = ( const char * )pErrorMessages->GetBufferPointer();\n"; + $out .= "\t\t\tOutputDebugString( pErrorMessageString );\n"; + $out .= "\t\t\tOutputDebugString( \"\\n\" );\n"; + $out .= "\t\t\tAssert( 0 );\n"; + $out .= "\t\t\tstatic char blah[4] = { 0, 0, 0, 0 };\n"; + $out .= "\t\t\tbyteCode.m_pRawData = blah;\n"; + $out .= "\t\t\tbyteCode.m_nSizeInBytes = 4;\n"; + $out .= "\t\t}\n"; + $out .= "\t\telse\n"; + $out .= "\t\t{\n"; + $out .= "\t\t\tbyteCode.m_pRawData = pShader->GetBufferPointer();\n"; + $out .= "\t\t\tbyteCode.m_nSizeInBytes = pShader->GetBufferSize();\n"; + $out .= "\t\t}\n"; + $out .= "\t\treturn byteCode;\n"; + return $out; +} + +#print "--------\n"; + +if ( $g_x360 ) +{ + $fxctmp = "fxctmp9_360_tmp"; +} +else +{ + $fxctmp = "fxctmp9_tmp"; +} + +if( !stat $fxctmp ) +{ + mkdir $fxctmp, 0777 || die $!; +} + +# suck in an input file (using includes) +#print "$fxc_filename..."; +@fxc = ReadInputFile( $fxc_filename ); + +# READ THE TOP OF THE FILE TO FIND SHADER COMBOS +foreach $line ( @fxc ) +{ + $line="" if ($g_x360 && ($line=~/\[PC\]/)); # line marked as [PC] when building for x360 + $line="" if (($g_x360 == 0) && ($line=~/\[XBOX\]/)); # line marked as [XBOX] when building for pc + + if ( $fxc_basename =~ m/_ps(\d+\w?)$/i ) + { + my $psver = $1; + $line="" if (($line =~/\[ps\d+\w?\]/i) && ($line!~/\[ps$psver\]/i)); # line marked for a version of compiler and not what we build + } + if ( $fxc_basename =~ m/_vs(\d+\w?)$/i ) + { + my $vsver = $1; + $line="" if (($line =~/\[vs\d+\w?\]/i) && ($line!~/\[vs$vsver\]/i)); # line marked for a version of compiler and not what we build + } + + my $init_expr; + + $init_expr = $1 if ( $line=~/\[\=([^\]]+)\]/); # parse default init expression for combos + + $line=~s/\[[^\[\]]*\]//; # cut out all occurrences of + # square brackets and whatever is + # inside all these modifications + # to the line are seen later when + # processing skips and centroids + + next if( $line =~ m/^\s*$/ ); + + if( $line =~ m/^\s*\/\/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ ) + { + local( $name, $min, $max ); + $name = $1; + $min = $2; + $max = $3; + # print STDERR "STATIC: \"$name\" \"$min..$max\"\n"; + push @staticDefineNames, $name; + push @staticDefineMin, $min; + push @staticDefineMax, $max; + $staticDefineInit{$name}=$init_expr; + } + elsif( $line =~ m/^\s*\/\/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ ) + { + local( $name, $min, $max ); + $name = $1; + $min = $2; + $max = $3; + # print STDERR "DYNAMIC: \"$name\" \"$min..$max\"\n"; + push @dynamicDefineNames, $name; + push @dynamicDefineMin, $min; + push @dynamicDefineMax, $max; + } +} +# READ THE WHOLE FILE AND FIND SKIP STATEMENTS +foreach $line ( @fxc ) +{ + if( $line =~ m/^\s*\/\/\s*SKIP\s*\s*\:\s*(.*)$/ ) + { + # print $1 . "\n"; + $perlskipcode .= "(" . $1 . ")||"; + push @perlskipcodeindividual, $1; + } +} + +if( defined $perlskipcode ) +{ + $perlskipcode .= "0"; + $perlskipcode =~ s/\n//g; +} +else +{ + $perlskipcode = "0"; +} + +# READ THE WHOLE FILE AND FIND CENTROID STATEMENTS +foreach $line ( @fxc ) +{ + if( $line =~ m/^\s*\/\/\s*CENTROID\s*\:\s*TEXCOORD(\d+)\s*$/ ) + { + $centroidEnable{$1} = 1; +# print "CENTROID: $1\n"; + } +} + +if( $spewCombos ) +{ + push @outputHeader, "#include \"windows.h\"\n"; +} + +#push @outputHeader, "\#include \"shaderlib\\baseshader.h\"\n"; +#push @outputHeader, "IShaderDynamicAPI *CBaseShader::s_pShaderAPI;\n"; + +# Go ahead an compute the mask of samplers that need to be centroid sampled +$centroidMask = 0; +foreach $centroidRegNum ( keys( %centroidEnable ) ) +{ +# print "THING: $samplerName $centroidRegNum\n"; + $centroidMask += 1 << $centroidRegNum; +} + +#printf "0x%x\n", $centroidMask; + +$numCombos = &CalcNumCombos(); +#print "$numCombos combos\n"; + + +if( $g_produceCompiledVcs && !$dynamic_compile ) +{ + open FOUT, ">>filelistgen.txt" || die "can't open filelistgen.txt"; + + print FOUT "**** generated by fxc_prep.pl ****\n"; + print FOUT "#BEGIN " . $fxc_basename . "\n"; + print FOUT "$fxc_filename" . "\n"; + print FOUT "#DEFINES-D:\n"; + for( $i = 0; $i < scalar( @dynamicDefineNames ); \$i++ ) + { + print FOUT "$dynamicDefineNames[$i]="; + print FOUT $dynamicDefineMin[$i]; + print FOUT ".."; + print FOUT $dynamicDefineMax[$i]; + print FOUT "\n"; + } + print FOUT "#DEFINES-S:\n"; + for( $i = 0; $i < scalar( @staticDefineNames ); \$i++ ) + { + print FOUT "$staticDefineNames[$i]="; + print FOUT $staticDefineMin[$i]; + print FOUT ".."; + print FOUT $staticDefineMax[$i]; + print FOUT "\n"; + } + print FOUT "#SKIP:\n"; + print FOUT "$perlskipcode\n"; + print FOUT "#COMMAND:\n"; + # first line + print FOUT "fxc.exe "; + print FOUT "/DTOTALSHADERCOMBOS=$numCombos "; + print FOUT "/DCENTROIDMASK=$centroidMask "; + print FOUT "/DNUMDYNAMICCOMBOS=" . &CalcNumDynamicCombos() . " "; + print FOUT "/DFLAGS=0x0 "; # Nothing here for now. + print FOUT "\n"; +#defines go here +# second line + print FOUT &RenameMain( $fxc_filename, $i ); + print FOUT "/T" . &GetShaderType( $fxc_filename ) . " "; + print FOUT "/DSHADER_MODEL_" . &ToUpper( &GetShaderType( $fxc_filename ) ) . "=1 "; + if( $nvidia ) + { + print FOUT "/DNV3X=1 "; # enable NV3X codepath + } + if ( $g_x360 ) + { + print FOUT "/D_X360=1 "; # shaders can identify X360 centric code + # print FOUT "/Xbe:2- "; # use the less-broken old back end + } + if( $debug ) + { + print FOUT "/Od "; # disable optimizations + print FOUT "/Zi "; # enable debug info + } +# print FOUT "/Zi "; # enable debug info + print FOUT "/nologo "; +# print FOUT "/Fhtmpshader.h "; + print FOUT "/Foshader.o "; + print FOUT "$fxc_filename"; + print FOUT ">output.txt 2>&1"; + print FOUT "\n"; + #end of command line + print FOUT "#END\n"; + print FOUT "**** end ****\n"; + + close FOUT; +} + +if ( $g_produceCppClasses ) +{ + # Write out the C++ helper class for picking shader combos + &WriteStaticHelperClasses(); + &WriteDynamicHelperClasses(); + my $incfilename = "$fxctmp\\$fxc_basename" . ".inc"; + &WriteFile( $incfilename, join( "", @outputHeader ) ); +} + + + +if( $generateListingFile ) +{ + my $listFileName = "$fxctmp/$fxc_basename" . ".lst"; + print "writing $listFileName\n"; + if( !open FILE, ">$listFileName" ) + { + die; + } + print FILE @listingOutput; + close FILE; +} + + +@endTimes = times; + +$endTime = time; + +#printf "Elapsed user time: %.2f seconds!\n", $endTimes[0] - $startTimes[0]; +#printf "Elapsed system time: %.2f seconds!\n", $endTimes[1] - $startTimes[1]; +#printf "Elapsed child user time: %.2f seconds!\n", $endTimes[2] - $startTimes[2]; +#printf "Elapsed child system time: %.2f seconds!\n", $endTimes[3] - $startTimes[3]; + +#printf "Elapsed total time: %.2f seconds!\n", $endTime - $startTime; + diff --git a/mp/src/devtools/bin/linux/ccache b/mp/src/devtools/bin/linux/ccache new file mode 100644 index 00000000..9846e22d Binary files /dev/null and b/mp/src/devtools/bin/linux/ccache differ diff --git a/mp/src/devtools/bin/osx32/ccache b/mp/src/devtools/bin/osx32/ccache new file mode 100644 index 00000000..36a7081d Binary files /dev/null and b/mp/src/devtools/bin/osx32/ccache differ diff --git a/mp/src/devtools/bin/osx32/protoc b/mp/src/devtools/bin/osx32/protoc new file mode 100644 index 00000000..9f535f44 Binary files /dev/null and b/mp/src/devtools/bin/osx32/protoc differ diff --git a/mp/src/devtools/bin/psh_prep.pl b/mp/src/devtools/bin/psh_prep.pl new file mode 100644 index 00000000..5aa49c11 --- /dev/null +++ b/mp/src/devtools/bin/psh_prep.pl @@ -0,0 +1,333 @@ +use String::CRC32; +BEGIN {use File::Basename; push @INC, dirname($0); } +require "valve_perl_helpers.pl"; + +sub BuildDefineOptions +{ + local( $output ); + local( $combo ) = shift; + local( $i ); + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + local( $val ) = ( $combo % ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) ) + $dynamicDefineMin[$i]; + $output .= "/D$dynamicDefineNames[$i]=$val "; + $combo = $combo / ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ); + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + local( $val ) = ( $combo % ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) ) + $staticDefineMin[$i]; + $output .= "/D$staticDefineNames[$i]=$val "; + $combo = $combo / ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ); + } + return $output; +} + +sub CalcNumCombos +{ + local( $i, $numCombos ); + $numCombos = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1; + } + return $numCombos; +} + +sub CalcNumDynamicCombos +{ + local( $i, $numCombos ); + $numCombos = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + return $numCombos; +} + +$g_dx9 = 1; + +while( 1 ) +{ + $psh_filename = shift; + + if( $psh_filename =~ m/-source/ ) + { + $g_SourceDir = shift; + } + elsif( $psh_filename =~ m/-x360/ ) + { + $g_x360 = 1; + } + else + { + last; + } +} + +$psh_filename =~ s/-----.*$//; + + +# Get the shader binary version number from a header file. +open FILE, "<$g_SourceDir\\public\\materialsystem\\shader_vcs_version.h" || die; +while( $line = ) +{ + if( $line =~ m/^\#define\s+SHADER_VCS_VERSION_NUMBER\s+(\d+)\s*$/ ) + { + $shaderVersion = $1; + last; + } +} +if( !defined $shaderVersion ) +{ + die "couldn't get shader version from shader_vcs_version.h"; +} +close FILE; + + + +local( @staticDefineNames ); +local( @staticDefineMin ); +local( @staticDefineMax ); +local( @dynamicDefineNames ); +local( @dynamicDefineMin ); +local( @dynamicDefineMax ); + +# Parse the combos. +open PSH, "<$psh_filename"; +while( ) +{ + last if( !m,^;, ); + s,^;\s*,,; + if( m/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ ) + { + local( $name, $min, $max ); + $name = $1; + $min = $2; + $max = $3; +# print "\"STATIC: $name\" \"$min..$max\"\n"; + if (/\[(.*)\]/) + { + $platforms=$1; + next if ( ($g_x360) && (!($platforms=~/XBOX/i)) ); + next if ( (!$g_x360) && (!($platforms=~/PC/i)) ); + } + push @staticDefineNames, $name; + push @staticDefineMin, $min; + push @staticDefineMax, $max; + } + elsif( m/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ ) + { + local( $name, $min, $max ); + $name = $1; + $min = $2; + $max = $3; +# print "\"DYNAMIC: $name\" \"$min..$max\"\n"; + if (/\[(.*)\]/) + { + $platforms=$1; + next if ( ($g_x360) && (!($platforms=~/XBOX/i)) ); + next if ( (!$g_x360) && (!($platforms=~/PC/i)) ); + } + push @dynamicDefineNames, $name; + push @dynamicDefineMin, $min; + push @dynamicDefineMax, $max; + } +} +close PSH; + +$numCombos = &CalcNumCombos(); +$numDynamicCombos = &CalcNumDynamicCombos(); +print "$psh_filename\n"; +#print "$numCombos combos\n"; +#print "$numDynamicCombos dynamic combos\n"; + +if( $g_x360 ) +{ + $pshtmp = "pshtmp9_360"; +} +elsif( $g_dx9 ) +{ + $pshtmp = "pshtmp9"; +} +else +{ + $pshtmp = "pshtmp8"; +} +$basename = $psh_filename; +$basename =~ s/\.psh$//i; + +for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ ) +{ + my $tempFilename = "shader$shaderCombo.o"; + unlink $tempFilename; + + if( $g_x360 ) + { + $cmd = "$g_SourceDir\\x360xdk\\bin\\win32\\psa /D_X360=1 /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL"; + } + else + { + $cmd = "$g_SourceDir\\dx9sdk\\utilities\\psa /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL"; + } + + if( !stat $pshtmp ) + { + mkdir $pshtmp, 0777 || die $!; + } + +# print $cmd . "\n"; + system $cmd || die $!; + + # Make sure a file got generated because sometimes the die above won't happen on compile errors. + my $filesize = (stat $tempFilename)[7]; + if ( !$filesize ) + { + die "Error compiling shader$shaderCombo.o"; + } + + push @outputHeader, @hdr; +} + +$basename =~ s/\.fxc//gi; +push @outputHeader, "static PrecompiledShaderByteCode_t " . $basename . "_pixel_shaders[" . $numCombos . "] = \n"; +push @outputHeader, "{\n"; +local( $j ); +for( $j = 0; $j < $numCombos; $j++ ) +{ + local( $thing ) = "pixelShader_" . $basename . "_" . $j; + push @outputHeader, "\t{ " . "$thing, sizeof( $thing ) },\n"; +} +push @outputHeader, "};\n"; + +push @outputHeader, "struct $basename" . "PixelShader_t : public PrecompiledShader_t\n"; +push @outputHeader, "{\n"; +push @outputHeader, "\t$basename" . "PixelShader_t()\n"; +push @outputHeader, "\t{\n"; +push @outputHeader, "\t\tm_nFlags = 0;\n"; +push @outputHeader, "\t\tm_pByteCode = " . $basename . "_pixel_shaders;\n"; +push @outputHeader, "\t\tm_nShaderCount = $numCombos;\n"; +#push @outputHeader, "\t\tm_nDynamicCombos = m_nShaderCount;\n"; +push @outputHeader, "\t\t// NOTE!!! psh_prep.pl shaders are always static combos!\n"; +push @outputHeader, "\t\tm_nDynamicCombos = 1;\n"; +push @outputHeader, "\t\tm_pName = \"$basename\";\n"; +if( $basename =~ /vs\d\d/ ) # hack +{ + push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_VERTEX_SHADER, this );\n"; +} +else +{ + push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_PIXEL_SHADER, this );\n"; +} +push @outputHeader, "\t}\n"; +push @outputHeader, "\tvirtual const PrecompiledShaderByteCode_t &GetByteCode( int shaderID )\n"; +push @outputHeader, "\t{\n"; +push @outputHeader, "\t\treturn m_pByteCode[shaderID];\n"; +push @outputHeader, "\t}\n"; +push @outputHeader, "};\n"; + +push @outputHeader, "static $basename" . "PixelShader_t $basename" . "_PixelShaderInstance;\n"; + + +&MakeDirHier( "shaders/psh" ); + +my $vcsName = ""; +if( $g_x360 ) +{ + $vcsName = $basename . ".360.vcs"; +} +else +{ + $vcsName = $basename . ".vcs"; +} + +open COMPILEDSHADER, ">shaders/psh/$vcsName" || die; +binmode( COMPILEDSHADER ); + +# +# Write out the part of the header that we know. . we'll write the rest after writing the object code. +# + +#print $numCombos . "\n"; + +# Pack arguments +my $sInt = "i"; +my $uInt = "I"; +if ( $g_x360 ) +{ + # Change arguments to "big endian long" + $sInt = "N"; + $uInt = "N"; +} + +open PSH, "<$psh_filename"; +my $crc = crc32( *PSH ); +close PSH; +#print STDERR "crc for $psh_filename: $crc\n"; + +# version +print COMPILEDSHADER pack $sInt, 4; +# totalCombos +print COMPILEDSHADER pack $sInt, $numCombos; +# dynamic combos +print COMPILEDSHADER pack $sInt, $numDynamicCombos; +# flags +print COMPILEDSHADER pack $uInt, 0x0; # nothing here for now. +# centroid mask +print COMPILEDSHADER pack $uInt, 0; +# reference size for diffs +print COMPILEDSHADER pack $uInt, 0; +# crc32 of the source code +print COMPILEDSHADER pack $uInt, $crc; + +my $beginningOfDir = tell COMPILEDSHADER; + +# Write out a blank directionary. . we'll fill it in later. +for( $i = 0; $i < $numCombos; $i++ ) +{ + # offset from beginning of file. + print COMPILEDSHADER pack $sInt, 0; + # size + print COMPILEDSHADER pack $sInt, 0; +} + +my $startByteCode = tell COMPILEDSHADER; +my @byteCodeStart; +my @byteCodeSize; + +# Write out the shader object code. +for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ ) +{ + my $filename = "shader$shaderCombo\.o"; + my $filesize = (stat $filename)[7]; + + $byteCodeStart[$shaderCombo] = tell COMPILEDSHADER; + $byteCodeSize[$shaderCombo] = $filesize; + open SHADERBYTECODE, "<$filename"; + binmode SHADERBYTECODE; + + my $bin; + my $numread = read SHADERBYTECODE, $bin, $filesize; +# print "filename: $filename numread: $numread filesize: $filesize\n"; + close SHADERBYTECODE; + unlink $filename; + + print COMPILEDSHADER $bin; +} + +# Seek back to the directory and write it out. +seek COMPILEDSHADER, $beginningOfDir, 0; +for( $i = 0; $i < $numCombos; $i++ ) +{ + # offset from beginning of file. + print COMPILEDSHADER pack $sInt, $byteCodeStart[$i]; + # size + print COMPILEDSHADER pack $sInt, $byteCodeSize[$i]; +} + +close COMPILEDSHADER; + + diff --git a/mp/src/devtools/bin/updateshaders.pl b/mp/src/devtools/bin/updateshaders.pl new file mode 100644 index 00000000..005e96a0 --- /dev/null +++ b/mp/src/devtools/bin/updateshaders.pl @@ -0,0 +1,305 @@ +use String::CRC32; +BEGIN {use File::Basename; push @INC, dirname($0); } +require "valve_perl_helpers.pl"; + +$dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0; + +$depnum = 0; +$baseSourceDir = "."; + +my %dep; + +sub GetAsmShaderDependencies_R +{ + local( $shadername ) = shift; + local( *SHADER ); + + open SHADER, "<$shadername"; + while( ) + { + if( m/^\s*\#\s*include\s+\"(.*)\"/ ) + { + # make sure it isn't in there already. + if( !defined( $dep{$1} ) ) + { + $dep{$1} = 1; + GetAsmShaderDependencies_R( $1 ); + } + } + } + close SHADER; +} + +sub GetAsmShaderDependencies +{ + local( $shadername ) = shift; + undef %dep; + GetAsmShaderDependencies_R( $shadername ); +# local( $i ); +# foreach $i ( keys( %dep ) ) +# { +# print "$shadername depends on $i\n"; +# } + return keys( %dep ); +} + +sub GetShaderType +{ + my $shadername = shift; + my $shadertype; + if( $shadername =~ m/\.vsh/i ) + { + $shadertype = "vsh"; + } + elsif( $shadername =~ m/\.psh/i ) + { + $shadertype = "psh"; + } + elsif( $shadername =~ m/\.fxc/i ) + { + $shadertype = "fxc"; + } + else + { + die; + } + return $shadertype; +} + +sub GetShaderSrc +{ + my $shadername = shift; + if ( $shadername =~ m/^(.*)-----/i ) + { + return $1; + } + else + { + return $shadername; + } +} + +sub GetShaderBase +{ + my $shadername = shift; + if ( $shadername =~ m/-----(.*)$/i ) + { + return $1; + } + else + { + my $shadertype = &GetShaderType( $shadername ); + $shadername =~ s/\.$shadertype//i; + return $shadername; + } +} + +sub DoAsmShader +{ + my $argstring = shift; + my $shadername = &GetShaderSrc( $argstring ); + my $shaderbase = &GetShaderBase( $argstring ); + my $shadertype = &GetShaderType( $argstring ); + my $incfile = ""; + if( $shadertype eq "fxc" || $shadertype eq "vsh" ) + { + $incfile = $shadertype . "tmp9" . $g_tmpfolder . "\\$shaderbase.inc "; + } + + my $vcsfile = $shaderbase . $g_vcsext; + my $bWillCompileVcs = 1; + if( ( $shadertype eq "fxc") && $dynamic_compile ) + { + $bWillCompileVcs = 0; + } + if( $shadercrcpass{$argstring} ) + { + $bWillCompileVcs = 0; + } + + if( $bWillCompileVcs ) + { + &output_makefile_line( $incfile . "shaders\\$shadertype\\$vcsfile: $shadername @dep\n") ; + } + else + { + # psh files don't need a rule at this point since they don't have inc files and we aren't compiling a vcs. + if( $shadertype eq "fxc" || $shadertype eq "vsh" ) + { + &output_makefile_line( $incfile . ": $shadername @dep\n") ; + } + } + + + my $x360switch = ""; + my $moreswitches = ""; + if( !$bWillCompileVcs && $shadertype eq "fxc" ) + { + $moreswitches .= "-novcs "; + } + if( $g_x360 ) + { + $x360switch = "-x360"; + + if( $bWillCompileVcs && ( $shaderbase =~ m/_ps20$/i ) ) + { + $moreswitches .= "-novcs "; + $bWillCompileVcs = 0; + } + } + + # if we are psh and we are compiling the vcs, we don't need this rule. + if( !( $shadertype eq "psh" && !$bWillCompileVcs ) ) + { + &output_makefile_line( "\tperl $g_SourceDir\\devtools\\bin\\" . $shadertype . "_prep.pl $moreswitches $x360switch -source \"$g_SourceDir\" $argstring\n") ; + } + + if( $bWillCompileVcs ) + { + &output_makefile_line( "\techo $shadername>> filestocopy.txt\n") ; + my $dep; + foreach $dep( @dep ) + { + &output_makefile_line( "\techo $dep>> filestocopy.txt\n") ; + } + } + &output_makefile_line( "\n") ; +} + +if( scalar( @ARGV ) == 0 ) +{ + die "Usage updateshaders.pl shaderprojectbasename\n\tie: updateshaders.pl stdshaders_dx6\n"; +} + +$g_x360 = 0; +$g_tmpfolder = "_tmp"; +$g_vcsext = ".vcs"; + +while( 1 ) +{ + $inputbase = shift; + + if( $inputbase =~ m/-source/ ) + { + $g_SourceDir = shift; + } + elsif( $inputbase =~ m/-x360/ ) + { + $g_x360 = 1; + $g_tmpfolder = "_360_tmp"; + $g_vcsext = ".360.vcs"; + } + elsif( $inputbase =~ m/-execute/ ) + { + $g_execute = 1; + } + elsif( $inputbase =~ m/-nv3x/ ) + { + $nv3x = 1; + } + else + { + last; + } +} + +my @srcfiles = &LoadShaderListFile( $inputbase ); + +open MAKEFILE, ">makefile\.$inputbase"; +open COPYFILE, ">makefile\.$inputbase\.copy"; +open INCLIST, ">inclist.txt"; +open VCSLIST, ">vcslist.txt"; + +# make a default dependency that depends on all of the shaders. +&output_makefile_line( "default: ") ; +foreach $shader ( @srcfiles ) +{ + my $shadertype = &GetShaderType( $shader ); + my $shaderbase = &GetShaderBase( $shader ); + my $shadersrc = &GetShaderSrc( $shader ); + if( $shadertype eq "fxc" || $shadertype eq "vsh" ) + { + # We only generate inc files for fxc and vsh files. + my $incFileName = "$shadertype" . "tmp9" . $g_tmpfolder . "\\" . $shaderbase . "\.inc"; + &output_makefile_line( " $incFileName" ); + &output_inclist_line( "$incFileName\n" ); + } + + my $vcsfile = $shaderbase . $g_vcsext; + + my $compilevcs = 1; + if( $shadertype eq "fxc" && $dynamic_compile ) + { + $compilevcs = 0; + } + if( $g_x360 && ( $shaderbase =~ m/_ps20$/i ) ) + { + $compilevcs = 0; + } + if( $compilevcs ) + { + my $vcsFileName = "..\\..\\..\\game\\hl2\\shaders\\$shadertype\\$shaderbase" . $g_vcsext; + # We want to check for perforce operations even if the crc matches in the event that a file has been manually reverted and needs to be checked out again. + &output_vcslist_line( "$vcsFileName\n" ); + $shadercrcpass{$shader} = &CheckCRCAgainstTarget( $shadersrc, $vcsFileName, 0 ); + if( $shadercrcpass{$shader} ) + { + $compilevcs = 0; + } + } + if( $compilevcs ) + { + &output_makefile_line( " shaders\\$shadertype\\$vcsfile" ); + # emit a list of vcs files to copy to the target since we want to build them. + &output_copyfile_line( GetShaderSrc($shader) . "-----" . GetShaderBase($shader) . "\n" ); + } +} +&output_makefile_line( "\n\n") ; + +# Insert all of our vertex shaders and depencencies +$lastshader = ""; +foreach $shader ( @srcfiles ) +{ + my $currentshader = &GetShaderSrc( $shader ); + if ( $lastshader ne $currentshader ) + { + $lastshader = $currentshader; + @dep = &GetAsmShaderDependencies( $lastshader ); + } + &DoAsmShader( $shader ); +} +close VCSLIST; +close INCLIST; +close COPYFILE; +close MAKEFILE; + +# nuke the copyfile if it is zero length +if( ( stat "makefile\.$inputbase\.copy" )[7] == 0 ) +{ + unlink "makefile\.$inputbase\.copy"; +} + +sub output_makefile_line +{ + local ($_)=@_; + print MAKEFILE $_; +} + +sub output_copyfile_line +{ + local ($_)=@_; + print COPYFILE $_; +} + +sub output_vcslist_line +{ + local ($_)=@_; + print VCSLIST $_; +} + +sub output_inclist_line +{ + local ($_)=@_; + print INCLIST $_; +} + diff --git a/mp/src/devtools/bin/vsh_prep.pl b/mp/src/devtools/bin/vsh_prep.pl new file mode 100644 index 00000000..1ba8b6f1 --- /dev/null +++ b/mp/src/devtools/bin/vsh_prep.pl @@ -0,0 +1,1106 @@ +use String::CRC32; +BEGIN {use File::Basename; push @INC, dirname($0); } +require "valve_perl_helpers.pl"; + +sub WriteHelperVar +{ + local( $name ) = shift; + local( $min ) = shift; + local( $max ) = shift; + local( $varname ) = "m_n" . $name; + local( $boolname ) = "m_b" . $name; + push @outputHeader, "private:\n"; + push @outputHeader, "\tint $varname;\n"; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\tbool $boolname;\n"; + push @outputHeader, "#endif\n"; + push @outputHeader, "public:\n"; + # int version of set function + push @outputHeader, "\tvoid Set" . $name . "( int i )\n"; + push @outputHeader, "\t{\n"; + if ( $min != $max ) + { + push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n"; + push @outputHeader, "\t\t$varname = i;\n"; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = true;\n"; + push @outputHeader, "#endif\n"; + } + push @outputHeader, "\t}\n"; + # bool version of set function + push @outputHeader, "\tvoid Set" . $name . "( bool i )\n"; + push @outputHeader, "\t{\n"; + if ( $min != $max ) + { +# push @outputHeader, "\t\tAssert( i >= $min && i <= $max );\n"; + push @outputHeader, "\t\t$varname = i ? 1 : 0;\n"; + push @outputHeader, "#ifdef _DEBUG\n"; + push @outputHeader, "\t\t$boolname = true;\n"; + push @outputHeader, "#endif\n"; + } + push @outputHeader, "\t}\n"; +} + +sub WriteStaticBoolExpression +{ + local( $prefix ) = shift; + local( $operator ) = shift; + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + if( $i ) + { + push @outputHeader, " $operator "; + } + local( $name ) = @staticDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + push @outputHeader, "$prefix$boolname"; + } + push @outputHeader, ";\n"; +} + +sub WriteDynamicBoolExpression +{ + local( $prefix ) = shift; + local( $operator ) = shift; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + if( $i ) + { + push @outputHeader, " $operator "; + } + local( $name ) = @dynamicDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + push @outputHeader, "$prefix$boolname"; + } + push @outputHeader, ";\n"; +} + +sub WriteDynamicHelperClasses +{ + local( $basename ) = $fxc_filename; + $basename =~ s/\.fxc//i; + $basename =~ tr/A-Z/a-z/; + local( $classname ) = $basename . "_Dynamic_Index"; + push @outputHeader, "class $classname\n"; + push @outputHeader, "{\n"; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $name = $dynamicDefineNames[$i]; + $min = $dynamicDefineMin[$i]; + $max = $dynamicDefineMax[$i]; + &WriteHelperVar( $name, $min, $max ); + } + push @outputHeader, "public:\n"; + push @outputHeader, "\t$classname()\n"; + push @outputHeader, "\t{\n"; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $min = $dynamicDefineMin[$i]; + $max = $dynamicDefineMax[$i]; + + local( $name ) = @dynamicDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + local( $varname ) = "m_n" . $name; + push @outputHeader, "#ifdef _DEBUG\n"; + if ( $min != $max ) + { + push @outputHeader, "\t\t$boolname = false;\n"; + } + else + { + push @outputHeader, "\t\t$boolname = true;\n"; + } + push @outputHeader, "#endif // _DEBUG\n"; + push @outputHeader, "\t\t$varname = 0;\n"; + } + push @outputHeader, "\t}\n"; + push @outputHeader, "\tint GetIndex()\n"; + push @outputHeader, "\t{\n"; + push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n"; + foreach $skip (@perlskipcodeindividual) + { + $skip =~ s/\$/m_n/g; +# push @outputHeader, "\t\tAssert( !( $skip ) );\n"; + } + push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n"; + + push @outputHeader, "#ifdef _DEBUG\n"; + if( scalar( @dynamicDefineNames ) > 0 ) + { + push @outputHeader, "\t\tbool bAllDynamicVarsDefined = "; + WriteDynamicBoolExpression( "", "&&" ); + } + if( scalar( @dynamicDefineNames ) > 0 ) + { + push @outputHeader, "\t\tAssert( bAllDynamicVarsDefined );\n"; + } + push @outputHeader, "#endif // _DEBUG\n"; + + if( $spewCombos && scalar( @dynamicDefineNames ) ) + { + push @outputHeader, &CreateCCodeToSpewDynamicCombo(); + } + push @outputHeader, "\t\treturn "; + local( $scale ) = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + local( $name ) = @dynamicDefineNames[$i]; + local( $varname ) = "m_n" . $name; + push @outputHeader, "( $scale * $varname ) + "; + $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + push @outputHeader, "0;\n"; + push @outputHeader, "\t}\n"; + push @outputHeader, "};\n"; +} + +sub WriteStaticHelperClasses +{ + local( $basename ) = $fxc_filename; + $basename =~ s/\.fxc//i; + $basename =~ tr/A-Z/a-z/; + local( $classname ) = $basename . "_Static_Index"; + push @outputHeader, "class $classname\n"; + push @outputHeader, "{\n"; + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $name = $staticDefineNames[$i]; + $min = $staticDefineMin[$i]; + $max = $staticDefineMax[$i]; + &WriteHelperVar( $name, $min, $max ); + } + push @outputHeader, "public:\n"; + push @outputHeader, "\t$classname()\n"; + push @outputHeader, "\t{\n"; + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $min = $staticDefineMin[$i]; + $max = $staticDefineMax[$i]; + + local( $name ) = @staticDefineNames[$i]; + local( $boolname ) = "m_b" . $name; + local( $varname ) = "m_n" . $name; + + push @outputHeader, "#ifdef _DEBUG\n"; + if ( $min != $max ) + { + push @outputHeader, "\t\t$boolname = false;\n"; + } + else + { + push @outputHeader, "\t\t$boolname = true;\n"; + } + push @outputHeader, "#endif // _DEBUG\n"; + push @outputHeader, "\t\t$varname = 0;\n"; + } + push @outputHeader, "\t}\n"; + push @outputHeader, "\tint GetIndex()\n"; + push @outputHeader, "\t{\n"; + push @outputHeader, "\t\t// Asserts to make sure that we aren't using any skipped combinations.\n"; + foreach $skip (@perlskipcodeindividual) + { + $skip =~ s/\$/m_n/g; +# push @outputHeader, "\t\tAssert( !( $skip ) );\n"; + } + push @outputHeader, "\t\t// Asserts to make sure that we are setting all of the combination vars.\n"; + + push @outputHeader, "#ifdef _DEBUG\n"; + if( scalar( @staticDefineNames ) > 0 ) + { + push @outputHeader, "\t\tbool bAllStaticVarsDefined = "; + WriteStaticBoolExpression( "", "&&" ); + + } + if( scalar( @staticDefineNames ) > 0 ) + { + push @outputHeader, "\t\tAssert( bAllStaticVarsDefined );\n"; + } + push @outputHeader, "#endif // _DEBUG\n"; + + if( $spewCombos && scalar( @staticDefineNames ) ) + { + push @outputHeader, &CreateCCodeToSpewStaticCombo(); + } + push @outputHeader, "\t\treturn "; + local( $scale ) = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $scale *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + local( $name ) = @staticDefineNames[$i]; + local( $varname ) = "m_n" . $name; + push @outputHeader, "( $scale * $varname ) + "; + $scale *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1; + } + push @outputHeader, "0;\n"; + push @outputHeader, "\t}\n"; + push @outputHeader, "};\n"; +} + +sub CreateFuncToSetPerlVars +{ + local( $out ) = ""; + + $out .= "sub SetPerlVarsFunc\n"; + $out .= "{\n"; + $out .= " local( \$combo ) = shift;\n"; + $out .= " local( \$i );\n"; + local( $i ); + for( $i = 0; $i < scalar( @dynamicDefineNames ); \$i++ ) + { + $out .= " \$$dynamicDefineNames[$i] = \$combo % "; + $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i]; + $out .= ";\n"; + $out .= " \$combo = \$combo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n"; + } + for( $i = 0; $i < scalar( @staticDefineNames ); \$i++ ) + { + $out .= " \$$staticDefineNames[$i] = \$combo % "; + $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i]; + $out .= ";\n"; + $out .= " \$combo = \$combo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n"; + } + $out .= "}\n"; + +# print $out; + eval $out; +} + +# These sections can be interchanged to enable profiling. +#$ShowTimers = 1; +#use Time::HiRes; +#sub SampleTime() +#{ +# return Time::HiRes::time(); +#} + +$ShowTimers = 0; +sub SampleTime() { return 0; } + +$total_start_time = SampleTime(); + +# NOTE: These must match the same values in macros.vsh! +$vPos = "v0"; +$vBoneWeights = "v1"; +$vBoneIndices = "v2"; +$vNormal = "v3"; +if( $g_x360 ) +{ + $vPosFlex = "v4"; + $vNormalFlex = "v13"; +} +$vColor = "v5"; +$vSpecular = "v6"; +$vTexCoord0 = "v7"; +$vTexCoord1 = "v8"; +$vTexCoord2 = "v9"; +$vTexCoord3 = "v10"; +$vTangentS = "v11"; +$vTangentT = "v12"; +$vUserData = "v14"; + +sub ReadInputFileWithLineInfo +{ + local( $base_filename ) = shift; + + local( *INPUT ); + local( @output ); + + # Look in the stdshaders directory, followed by the current directory. + # (This is for the SDK, since some of its files are under stdshaders). + local( $filename ) = $base_filename; + if ( !-e $filename ) + { + $filename = "$g_SourceDir\\materialsystem\\stdshaders\\$base_filename"; + if ( !-e $filename ) + { + die "\nvsh_prep.pl ERROR: missing include file: $filename.\n\n"; + } + } + + open INPUT, "<$filename" || die; + + local( $line ); + local( $linenum ) = 1; + while( $line = ) + { + $line =~ s/\n//g; + 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"; + $postfix .= "; LINEINFO($filename)($linenum)\n"; + if( $line =~ m/\#include\s+\"(.*)\"/i ) + { + push @output, &ReadInputFileWithLineInfo( $1 ); + } + else + { + push @output, $line . $postfix; + } + $linenum++; + } + + close INPUT; + return @output; +} + +sub ReadInputFileWithoutLineInfo +{ + local( $base_filename ) = shift; + + local( *INPUT ); + local( @output ); + + # Look in the stdshaders directory, followed by the current directory. + # (This is for the SDK, since some of its files are under stdshaders). + local( $filename ) = $base_filename; + if ( !-e $filename ) + { + $filename = "$g_SourceDir\\materialsystem\\stdshaders\\$base_filename"; + if ( !-e $filename ) + { + die "\nERROR: missing include file: $filename.\n\n"; + } + } + + open INPUT, "<$filename" || die; + + local( $line ); + while( $line = ) + { + if( $line =~ m/\#include\s+\"(.*)\"/i ) + { + push @output, &ReadInputFileWithoutLineInfo( $1 ); + } + else + { + push @output, $line; + } + } + + close INPUT; + return @output; +} + +sub IsPerl +{ + local( $line ) = shift; + if( $line =~ m/^\s*sub.*\,/ ) + { + return 0; + } + if( $line =~ m/^\#include/ || + $line =~ m/^\#define/ || + $line =~ m/^\#undef/ || + $line =~ m/^\#ifdef/ || + $line =~ m/^\#ifndef/ || + $line =~ m/^\#else/ || + $line =~ m/^\#endif/ || + $line =~ m/^\#error/ + ) + { + return 0; + } + if( $line =~ m/^\s*if\s*\(/ || + $line =~ m/^\s*else/ || + $line =~ m/^\s*elsif/ || + $line =~ m/^\s*for\s*\(/ || + $line =~ m/^\s*\{/ || + $line =~ m/^sub\s*/ || + $line =~ m/^\s*\}/ || + $line =~ m/^\s*\&/ || + $line =~ m/^\s*\#/ || + $line =~ m/^\s*\$/ || + $line =~ m/^\s*print/ || + $line =~ m/^\s*return/ || + $line =~ m/^\s*exit/ || + $line =~ m/^\s*die/ || + $line =~ m/^\s*eval/ || + $line =~ m/^\s*local/ || + $line =~ m/^\s*my\s+/ || + $line =~ m/^\s*@/ || + $line =~ m/^\s*alloc\s+/ || + $line =~ m/^\s*free\s+/ + ) + { + return 1; + } + return 0; +} + +# translate the output into something that takes us back to the source line +# that we care about in msdev +sub TranslateErrorMessages +{ + local( $origline ); + while( $origline = shift ) + { + if( $origline =~ m/(.*)\((\d+)\)\s*:\s*(.*)$/i ) + { + local( $filename ) = $1; + local( $linenum ) = $2; + local( $error ) = $3; + local( *FILE ); + open FILE, "<$filename" || die; + local( $i ); + local( $line ); + for( $i = 1; $i < $linenum; $i++ ) + { + $line = ; + } + if( $line =~ m/LINEINFO\((.*)\)\((.*)\)/ ) + { + print "$1\($2\) : $error\n"; + my $num = $linenum - 1; + print "$filename\($num\) : original error location\n"; + } + close FILE; + } + else + { + $origline =~ s/successful compile\!.*//gi; + if( !( $origline =~ m/^\s*$/ ) ) + { +# print "WTF: $origline\n"; + } + } + } +} + + +sub CountInstructions +{ + local( $line ); + local( $count ) = 0; + while( $line = shift ) + { + # get rid of comments + $line =~ s/;.*//gi; + $line =~ s/\/\/.*//gi; + # skip the vs1.1 statement + $line =~ s/^\s*vs.*//gi; + # if there's any text left, it's an instruction + if( $line =~ /\S/gi ) + { + $count++; + } + } + return $count; +} + + +%compiled = (); + +sub UsesRegister +{ + my $registerName = shift; + my $str = shift; + + # Cache a compiled RE for each register name. This makes UsesRegister about 2.5x faster. + if ( !$compiled{$registerName} ) + { + $compiled{$registerName} = qr/\b$registerName\b/; + } + + $ret = 0; + if( $str =~ /$compiled{$registerName}/gi ) + { + $ret = 1; + } + + return $ret; +} + +sub PadString +{ + local( $str ) = shift; + local( $desiredLen ) = shift; + local( $len ) = length $str; + while( $len < $desiredLen ) + { + $str .= " "; + $len++; + } + return $str; +} + +sub FixupAllocateFree +{ + local( $line ) = shift; + $line =~ s/\&AllocateRegister\s*\(\s*\\(\S+)\s*\)/&AllocateRegister( \\$1, \"\\$1\" )/g; + $line =~ s/\&FreeRegister\s*\(\s*\\(\S+)\s*\)/&FreeRegister( \\$1, \"\\$1\" )/g; + $line =~ s/alloc\s+(\S+)\s*/local( $1 ); &AllocateRegister( \\$1, \"\\$1\" );/g; + $line =~ s/free\s+(\S+)\s*/&FreeRegister( \\$1, \"\\$1\" );/g; + return $line; +} + +sub TranslateDXKeywords +{ + local( $line ) = shift; + $line =~ s/\bENDIF\b/endif/g; + $line =~ s/\bIF\b/if/g; + $line =~ s/\bELSE\b/else/g; + + return $line; +} + +# This is used to make the generated pl files all pretty. +sub GetLeadingWhiteSpace +{ + local( $str ) = shift; + if( $str =~ m/^;\S/ || $str =~ m/^; \S/ ) + { + return ""; + } + $str =~ s/^;/ /g; # count a leading ";" as whitespace as far as this is concerned. + $str =~ m/^(\s*)/; + return $1; +} + +$g_dx9 = 1; +$g_SourceDir = "..\\.."; + +while( 1 ) +{ + $filename = shift; + + if ( $filename =~ m/-source/i ) + { + $g_SourceDir = shift; + } + elsif( $filename =~ m/-x360/i ) + { + $g_x360 = 1; + } + else + { + last; + } +} + +$filename =~ s/-----.*$//; + + +# +# Get the shader binary version number from a header file. +# +open FILE, "<$g_SourceDir\\public\\materialsystem\\shader_vcs_version.h" || die; +while( $line = ) +{ + if( $line =~ m/^\#define\s+SHADER_VCS_VERSION_NUMBER\s+(\d+)\s*$/ ) + { + $shaderVersion = $1; + last; + } +} +if( !defined $shaderVersion ) +{ + die "couldn't get shader version from shader_vcs_version.h"; +} +close FILE; + + +if( $g_x360 ) +{ + $vshtmp = "vshtmp9_360_tmp"; +} +else +{ + $vshtmp = "vshtmp9_tmp"; +} + +if( !stat $vshtmp ) +{ + mkdir $vshtmp, 0777 || die $!; +} + +# suck in all files, including $include files. +@input = &ReadInputFileWithLineInfo( $filename ); + +sub CalcNumCombos +{ + local( $i, $numCombos ); + $numCombos = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) + { + $numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1; + } + return $numCombos; +} + +sub CalcNumDynamicCombos +{ + local( $i, $numCombos ); + $numCombos = 1; + for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) + { + $numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1; + } + return $numCombos; +} + +# READ THE TOP OF THE FILE TO FIND SHADER COMBOS +foreach $_ ( @input ) +{ + next if( m/^\s*$/ ); +# last if( !m,^//, ); + s,^//\s*,,; + if( m/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ ) + { + local( $name, $min, $max ); + $name = $1; + $min = $2; + $max = $3; +# print "\"$name\" \"$min..$max\"\n"; + if (/\[(.*)\]/) + { + $platforms=$1; + next if ( ($g_x360) && (!($platforms=~/XBOX/i)) ); + next if ( (!$g_x360) && (!($platforms=~/PC/i)) ); + } + push @staticDefineNames, $name; + push @staticDefineMin, $min; + push @staticDefineMax, $max; + } + elsif( m/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ ) + { + local( $name, $min, $max ); + $name = $1; + $min = $2; + $max = $3; + if (/\[(.*)\]/) + { + $platforms=$1; + next if ( ($g_x360) && (!($platforms=~/XBOX/i)) ); + next if ( (!$g_x360) && (!($platforms=~/PC/i)) ); + } +# print "\"$name\" \"$min..$max\"\n"; + push @dynamicDefineNames, $name; + push @dynamicDefineMin, $min; + push @dynamicDefineMax, $max; + } +} + +# READ THE WHOLE FILE AND FIND SKIP STATEMENTS +foreach $_ ( @input ) +{ + if( m/^\s*\#\s*SKIP\s*\:\s*(.*\S+)\s*\; LINEINFO.*$/ ) + { + $perlskipcode .= "(" . $1 . ")||"; + push @perlskipcodeindividual, $1; + } +} +if( defined $perlskipcode ) +{ + $perlskipcode .= "0"; + $perlskipcode =~ s/\n//g; +} +else +{ + $perlskipcode = "0"; +} + +#print $perlskipcode . "\n"; + + +# Translate the input into a perl program that'll unroll everything and +# substitute variables. +while( $inputLine = shift @input ) +{ + $inputLine =~ s/\n//g; + # leave out lines that are only whitespace. + if( $inputLine =~ m/^\s*; LINEINFO.*$/ ) + { + next; + } + local( $inputLineNoLineNum ) = $inputLine; + $inputLineNoLineNum =~ s/; LINEINFO.*//gi; + if( &IsPerl( $inputLineNoLineNum ) ) + { + $inputLineNoLineNum = &FixupAllocateFree( $inputLineNoLineNum ); + push @outputProgram, $inputLineNoLineNum . "\n"; + } + else + { + # make asm lines that have quotes in them not barf. + $inputLine =~ s/\"/\\\"/g; + $inputLine = &TranslateDXKeywords( $inputLine ); + push @outputProgram, &GetLeadingWhiteSpace( $inputLine ) . "push \@output, \"" . + $inputLine . "\\n\";\n"; + } +} + +$outputProgram = join "", @outputProgram; + +$filename_base = $filename; +$filename_base =~ s/\.vsh//i; + +open DEBUGOUT, ">$vshtmp" . "/$filename_base.pl" || die; +print DEBUGOUT $outputProgram; +close DEBUGOUT; + +# Make a function called OutputProgram() +$bigProg = "sub OutputProgram { " . $outputProgram . "}"; +eval( $bigProg ); + + +#print $outputProgram; + +#push @finalheader, "// hack to force dependency checking\n"; +#push @finalheader, "\#ifdef NEVER\n"; +#push @finalheader, "\#include \"" . $filename_base . "\.vsh\"\n"; +#push @finalheader, "\#include \"..\\..\\devtools\\bin\\vsh_prep.pl\"\n"; +#push @finalheader, "\#endif\n"; + +%g_TimingBlocks = (); +$main_start_time = SampleTime(); + +$numCombos = &CalcNumCombos(); +$numDynamicCombos = &CalcNumDynamicCombos(); +#print "$numCombos total combos\n"; +#print "$numDynamicCombos dynamic combos\n"; +#print $numCombos / $numDynamicCombos . " static combos\n"; + +# Write out the C++ helper class for picking shader combos +$fxc_filename = $filename_base; +&WriteStaticHelperClasses(); +&WriteDynamicHelperClasses(); + +# Create a subroutine out of $perlskipcode +$perlskipfunc = "sub SkipCombo { return $perlskipcode; }\n"; +#print $perlskipfunc; + +eval $perlskipfunc; +&CreateFuncToSetPerlVars(); + +my $incfilename = "$vshtmp/$filename_base" . ".inc"; + +# Write the inc file that has indexing helpers, etc. +&WriteFile( $incfilename, join( "", @outputHeader ) ); + + +# Run the output program for all the combinations of bones and lights. +print "$filename_base.vsh\n"; +for( $i = 0; $i < $numCombos; $i++ ) +{ +# print "combo $i\n"; + &SetPerlVarsFunc( $i ); + local( $compileFailed ); + $ret = &SkipCombo; + if( !defined $ret ) + { + die "$@\n"; + } + if( $ret ) + { + # skip this combo! + $compileFailed = 1; + $numSkipped++; + next; + } + + $start = SampleTime(); + + $g_usesPos = 0; + $g_usesPosFlex = 0; + $g_usesBoneWeights = 0; + $g_usesBoneIndices = 0; + $g_usesNormal = 0; + $g_usesNormalFlex = 0; + $g_usesColor = 0; + $g_usesSpecular = 0; + $g_usesTexCoord0 = 0; + $g_usesTexCoord1 = 0; + $g_usesTexCoord2 = 0; + $g_usesTexCoord3 = 0; + $g_usesTangentS = 0; + $g_usesTangentT = 0; + $g_usesUserData = 0; + + undef @output; + + $g_TimingBlocks{"inner1"} += SampleTime() - $start; + + $eval_start_time = SampleTime(); + &OutputProgram(); + $eval_total_time += (SampleTime() - $eval_start_time); + + $start = SampleTime(); + + # Strip out comments once so we don't have to do it in all the UsesRegister calls. + @stripped = @output; + map + { + $_ =~ s/;.*//gi; + $_ =~ s/\/\/.*//gi; + } @stripped; + my $strippedStr = join( "", @stripped ); + + $g_TimingBlocks{"inner2"} += SampleTime() - $start; + + $start = SampleTime(); + + # Have to make another pass through after we know which v registers are used. . yuck. + $g_usesPos = &UsesRegister( $vPos, $strippedStr ); + if( $g_x360 ) + { + $g_usesPosFlex = &UsesRegister( $vPosFlex, $strippedStr ); + $g_usesNormalFlex = &UsesRegister( $vNormalFlex, $strippedStr ); + } + $g_usesBoneWeights = &UsesRegister( $vBoneWeights, $strippedStr ); + $g_usesBoneIndices = &UsesRegister( $vBoneIndices, $strippedStr ); + $g_usesNormal = &UsesRegister( $vNormal, $strippedStr ); + $g_usesColor = &UsesRegister( $vColor, $strippedStr ); + $g_usesSpecular = &UsesRegister( $vSpecular, $strippedStr ); + $g_usesTexCoord0 = &UsesRegister( $vTexCoord0, $strippedStr ); + $g_usesTexCoord1 = &UsesRegister( $vTexCoord1, $strippedStr ); + $g_usesTexCoord2 = &UsesRegister( $vTexCoord2, $strippedStr ); + $g_usesTexCoord3 = &UsesRegister( $vTexCoord3, $strippedStr ); + $g_usesTangentS = &UsesRegister( $vTangentS, $strippedStr ); + $g_usesTangentT = &UsesRegister( $vTangentT, $strippedStr ); + $g_usesUserData = &UsesRegister( $vUserData, $strippedStr ); + undef @output; + + $g_TimingBlocks{"inner2"} += SampleTime() - $start; + + $eval_start_time = SampleTime(); + # Running OutputProgram generates $outfilename + &OutputProgram(); + $eval_total_time += (SampleTime() - $eval_start_time); + + $start = SampleTime(); + + &CheckUnfreedRegisters(); + + for( $j = 0; $j < scalar( @output ); $j++ ) + { + # remove whitespace from the beginning of each line. + $output[$j] =~ s/^\s+//; + # remove LINEINFO from empty lines. + $output[$j] =~ s/^; LINEINFO.*//; + } + + $g_TimingBlocks{"inner3"} += SampleTime() - $start; + $start = SampleTime(); + + + $outfilename_base = $filename_base . "_" . $i; + + # $outfilename is the name of the file generated from executing the perl code + # for this shader. This file is generated once per combo. + # We will assemble this shader with vsa.exe. + $outfilename = "$vshtmp\\" . $outfilename_base . ".tmp"; + +# $outhdrfilename = "$vshtmp\\" . $outfilename_base . ".h"; +# unlink $outhdrfilename; + + open OUTPUT, ">$outfilename" || die; + print OUTPUT @output; + close OUTPUT; + + $g_TimingBlocks{"inner4"} += SampleTime() - $start; + $start = SampleTime(); + + local( $instructionCount ) = &CountInstructions( @output ); + $g_TimingBlocks{"inner5"} += SampleTime() - $start; + + local( $debug ); + + $debug = 1; +# for( $debug = 1; $debug >= 0; $debug-- ) + { + # assemble the vertex shader + unlink "shader$i.o"; + if( $g_x360 ) + { + $vsa = "..\\..\\x360xdk\\bin\\win32\\vsa"; + } + else + { + $vsa = "..\\..\\dx9sdk\\utilities\\vsa"; + } + $vsadebug = "$vsa /nologo /Foshader$i.o $outfilename"; + $vsanodebug = "$vsa /nologo /Foshader$i.o $outfilename"; + + $vsa_start_time = SampleTime(); + + if( $debug ) + { +# print $vsadebug . "\n"; + @vsaoutput = `$vsadebug 2>&1`; +# print @vsaoutput; + } + else + { + @vsaoutput = `$vsanodebug 2>&1`; + } + + $vsa_total_time += SampleTime() - $vsa_start_time; + + $start = SampleTime(); + + &TranslateErrorMessages( @vsaoutput ); + + $g_TimingBlocks{"inner6"} += SampleTime() - $start; + + push @finalheader, @hdr; + } +} + + +$main_total_time = SampleTime() - $main_start_time; + +# stick info about the shaders at the end of the inc file. +push @finalheader, "static PrecompiledShaderByteCode_t $filename_base" . "_vertex_shaders[] = {\n"; +for( $i = 0; $i < $numCombos; $i++ ) +{ + $outfilename_base = $filename_base . "_" . $i; + push @finalheader, "{ $outfilename_base, sizeof( $outfilename_base ) },\n"; +} +push @finalheader, "};\n"; + + +push @finalheader, "struct $filename_base" . "_VertexShader_t : public PrecompiledShader_t\n"; +push @finalheader, "{\n"; +push @finalheader, "\t$filename_base" . "_VertexShader_t()\n"; +push @finalheader, "\t{\n"; +push @finalheader, "\t\tm_nFlags = 0;\n"; + +$flags = 0; +#push @finalheader, "\t\tppVertexShaders = $filename_base" . "_vertex_shaders;\n"; +push @finalheader, "\t\tm_pByteCode = $filename_base" . "_vertex_shaders;\n"; +push @finalheader, "\t\tm_pName = \"$filename_base\";\n"; +push @finalheader, "\t\tm_nShaderCount = " . ( $maxNumBones + 1 ) * $totalFogCombos * $totalLightCombos . ";\n"; +push @finalheader, "\t\tm_nDynamicCombos = m_nShaderCount;\n"; +push @finalheader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_VERTEX_SHADER, this );\n"; +push @finalheader, "\t}\n"; +push @finalheader, "\tvirtual const PrecompiledShaderByteCode_t &GetByteCode( int shaderID )\n"; +push @finalheader, "\t{\n"; +push @finalheader, "\t\treturn m_pByteCode[shaderID];\n"; +push @finalheader, "\t}\n"; +push @finalheader, "};\n"; +push @finalheader, "static $filename_base" . "_VertexShader_t $filename_base" . "_VertexShaderInstance;\n"; + +# Write the final header file with the compiled vertex shader programs. +$finalheadername = "$vshtmp\\" . $filename_base . ".inc"; +#print "writing $finalheadername\n"; +#open FINALHEADER, ">$finalheadername" || die; +#print FINALHEADER @finalheader; +#close FINALHEADER; + +&MakeDirHier( "shaders/vsh" ); + +my $vcsName = ""; +if( $g_x360 ) +{ + $vcsName = $filename_base . ".360.vcs"; +} +else +{ + $vcsName = $filename_base . ".vcs"; +} +open COMPILEDSHADER, ">shaders/vsh/$vcsName" || die; +binmode( COMPILEDSHADER ); + +# +# Write out the part of the header that we know. . we'll write the rest after writing the object code. +# + +# Pack arguments +my $sInt = "i"; +my $uInt = "I"; +if ( $g_x360 ) +{ + # Change arguments to "big endian long" + $sInt = "N"; + $uInt = "N"; +} + +my $undecoratedinput = join "", &ReadInputFileWithoutLineInfo( $filename ); +#print STDERR "undecoratedinput: $undecoratedinput\n"; +my $crc = crc32( $undecoratedinput ); +#print STDERR "crc for $filename: $crc\n"; + +# version +print COMPILEDSHADER pack $sInt, 4; +# totalCombos +print COMPILEDSHADER pack $sInt, $numCombos; +# dynamic combos +print COMPILEDSHADER pack $sInt, $numDynamicCombos; +# flags +print COMPILEDSHADER pack $uInt, $flags; +# centroid mask +print COMPILEDSHADER pack $uInt, 0; +# reference size +print COMPILEDSHADER pack $uInt, 0; +# crc32 of the source code +print COMPILEDSHADER pack $uInt, $crc; + +my $beginningOfDir = tell COMPILEDSHADER; + +# Write out a blank directionary. . we'll fill it in later. +for( $i = 0; $i < $numCombos; $i++ ) +{ + # offset from beginning of file. + print COMPILEDSHADER pack $sInt, 0; + # size + print COMPILEDSHADER pack $sInt, 0; +} + +my $startByteCode = tell COMPILEDSHADER; +my @byteCodeStart; +my @byteCodeSize; + +# Write out the shader object code. +for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ ) +{ + my $filename = "shader$shaderCombo\.o"; + my $filesize = (stat $filename)[7]; + $byteCodeStart[$shaderCombo] = tell COMPILEDSHADER; + $byteCodeSize[$shaderCombo] = $filesize; + open SHADERBYTECODE, "<$filename" || die; + binmode SHADERBYTECODE; + my $bin; + my $numread = read SHADERBYTECODE, $bin, $filesize; +# print "filename: $filename numread: $numread filesize: $filesize\n"; + close SHADERBYTECODE; + unlink $filename; + + print COMPILEDSHADER $bin; +} + +# Seek back to the directory and write it out. +seek COMPILEDSHADER, $beginningOfDir, 0; +for( $i = 0; $i < $numCombos; $i++ ) +{ + # offset from beginning of file. + print COMPILEDSHADER pack $sInt, $byteCodeStart[$i]; + # size + print COMPILEDSHADER pack $sInt, $byteCodeSize[$i]; +} + +close COMPILEDSHADER; + +$total_time = SampleTime() - $total_start_time; + +if ( $ShowTimers ) +{ + print "\n\n"; + print sprintf( "Main loop time : %0.4f sec, (%0.2f%%)\n", $main_total_time, 100*$main_total_time / $total_time ); + print sprintf( "Inner1 time : %0.4f sec, (%0.2f%%)\n", $inner1_total_time, 100*$inner1_total_time / $total_time ); + print sprintf( "VSA time : %0.4f sec, (%0.2f%%)\n", $vsa_total_time, 100*$vsa_total_time / $total_time ); + print sprintf( "eval() time : %0.4f sec, (%0.2f%%)\n", $eval_total_time, 100*$eval_total_time / $total_time ); + print sprintf( "UsesRegister time: %0.4f sec, (%0.2f%%)\n", $usesr_total_time, 100*$usesr_total_time / $total_time ); + + foreach $key ( keys %g_TimingBlocks ) + { + print sprintf( "$key time: %0.4f sec, (%0.2f%%)\n", $g_TimingBlocks{$key}, 100*$g_TimingBlocks{$key} / $total_time ); + } + + print sprintf( "Total time : %0.4f sec\n", $total_time ); +} + diff --git a/mp/src/devtools/gendbg.sh b/mp/src/devtools/gendbg.sh new file mode 100644 index 00000000..3bf30781 --- /dev/null +++ b/mp/src/devtools/gendbg.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +OBJCOPY=objcopy + +function usage { + echo "$0 /path/to/input/file [-o /path/to/output/file ]" + echo "" +} + +if [ $# == 0 ]; then + usage + exit 2 +fi + +if [ $(basename $1) == $1 ]; then + INFILEDIR=$PWD +else + INFILEDIR=$(cd ${1%/*} && echo $PWD) +fi +INFILE=$(basename $1) + +OUTFILEDIR=$INFILEDIR +OUTFILE=$INFILE.dbg + +while getopts "o:" opt; do + case $opt in + o) + OUTFILEDIR=$(cd ${OPTARG%/*} && echo $PWD) + OUTFILE=$(basename $OPTARG) + ;; + esac +done + +if [ "$OUTFILEDIR" != "$INFILEDIR" ]; then + INFILE=${INFILEDIR}/${INFILE} + OUTFILE=${OUTFILEDIR}/${OUTFILE} +fi + +pushd "$INFILEDIR" +$OBJCOPY "$INFILE" "$OUTFILE" +$OBJCOPY --add-gnu-debuglink="$OUTFILE" "$INFILE" +popd + + diff --git a/mp/src/devtools/makefile_base_posix.mak b/mp/src/devtools/makefile_base_posix.mak new file mode 100644 index 00000000..c529abdf --- /dev/null +++ b/mp/src/devtools/makefile_base_posix.mak @@ -0,0 +1,494 @@ +# +# Base makefile for Linux and OSX +# +# !!!!! Note to future editors !!!!! +# +# before you make changes, make sure you grok: +# 1. the difference between =, :=, +=, and ?= +# 2. how and when this base makefile gets included in the generated makefile(s) +# ( see http://www.gnu.org/software/make/manual/make.html#Flavors ) +# +# Command line prefixes: +# - errors are ignored +# @ command is not printed to stdout before being executed +# + command is executed even if Make is invoked in "do not exec" mode + +OS := $(shell uname) +HOSTNAME := $(shell hostname) + +-include $(SRCROOT)/devtools/steam_def.mak +-include $(SRCROOT)/devtools/sourcesdk_def.mak + +# To build with clang, set the following in your environment: +# CC = clang +# CXX = clang++ + +ifeq ($(CFG), release) + # With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3. + # There also was no speed difference running at 1280x1024. May 2012, mikesart. + # tonyp: The size increase was likely caused by -finline-functions and -fipa-cp-clone getting switched on with -O3. + # -fno-omit-frame-pointer: need this for stack traces with perf. + OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer -ftree-vectorize -fpredictive-commoning -funswitch-loops +else + OptimizerLevel_CompilerSpecific = -O0 + #-O1 -finline-functions +endif + +# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags" +ARCH_FLAGS = +BUILDING_MULTI_ARCH = 0 +CPPFLAGS = $(DEFINES) $(addprefix -I, $(abspath $(INCLUDEDIRS) )) +CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE +CXXFLAGS = $(CFLAGS) +DEFINES += -DVPROF_LEVEL=1 -DGNUC -DNO_HOOK_MALLOC -DNO_MALLOC_OVERRIDE +LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel) +GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P) +MAP_FLAGS = + +ifeq ($(STEAM_BRANCH),1) + WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof +else + WARN_FLAGS = -Wno-write-strings -Wno-multichar +endif + +WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security + + +ifeq ($(OS),Linux) + # We should always specify -Wl,--build-id, as documented at: + # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId + LDFLAGS += -Wl,--build-id + # Set USE_VALVE_BINDIR to build with /Steam/tools/linux in the /valve/bin path. + # Dedicated server uses this. + ifeq ($(USE_VALVE_BINDIR),1) + # dedicated server flags + ifeq ($(TARGET_PLATFORM),linux64) + VALVE_BINDIR = /valve/bin64/ + MARCH_TARGET = nocona + else + VALVE_BINDIR = /valve/bin/ + MARCH_TARGET = pentium4 + endif + STRIP_FLAGS = + else + # linux desktop client flags + VALVE_BINDIR = + # If the steam-runtime is available, use it. We should just default to using it when + # buildbot and everyone has a bit of time to get it installed. + ifneq "$(wildcard /valve/steam-runtime/bin/)" "" + VALVE_BINDIR = /valve/steam-runtime/bin/ + endif + GCC_VER = + MARCH_TARGET = pentium4 + # On dedicated servers, some plugins depend on global variable symbols in addition to functions. + # So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2. + STRIP_FLAGS = -x + endif + + ifeq ($(CXX),clang++) + # Clang does not support -mfpmath=sse because it uses whatever + # instruction set extensions are available by default. + SSE_GEN_FLAGS = -msse2 + else + SSE_GEN_FLAGS = -msse2 -mfpmath=sse + endif + + CCACHE := $(SRCROOT)/devtools/bin/linux/ccache + + ifeq ($(origin GCC_VER), undefined) + GCC_VER=-4.6 + endif + ifeq ($(origin AR), default) + AR = $(VALVE_BINDIR)ar crs + endif + ifeq ($(origin CC),default) + CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER) + endif + ifeq ($(origin CXX), default) + CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER) + endif + # Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to + # a ccache quirk. Could also upgrade ccache. + # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html + ifeq ($(CC),clang) + CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments + endif + ifeq ($(CXX),clang++) + CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments + endif + LINK ?= $(CC) + + ifeq ($(TARGET_PLATFORM),linux64) + # nocona = pentium4 + 64bit + MMX, SSE, SSE2, SSE3 - no SSSE3 (that's three s's - added in core2) + ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=core2 + LD_SO = ld-linux-x86_64.so.2 + LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.a) + LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++-pic.a) + else + # pentium4 = MMX, SSE, SSE2 - no SSE3 (added in prescott) # -msse3 -mfpmath=sse + ARCH_FLAGS += -m32 -march=$(MARCH_TARGET) -mtune=core2 $(SSE_GEN_FLAGS) + LD_SO = ld-linux.so.2 + LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LDFLAGS += -m32 + endif + + GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh + ifeq ($(CFG),release) + STRIP ?= strip $(STRIP_FLAGS) -S + # CFLAGS += -ffunction-sections -fdata-sections + # LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections + else + STRIP ?= true + endif + VSIGN ?= true + + LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map + + SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined + + _WRAP := -Xlinker --wrap= + PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \ + $(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \ + $(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \ + $(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \ + $(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath + + LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread + + LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_SHLIB = -Wl,--end-group -lm -ldl $(LIBSTDCXXPIC) -lpthread -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt + +endif + +ifeq ($(OS),Darwin) + OSXVER := $(shell sw_vers -productVersion) + CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache + DEVELOPER_DIR := $(shell /usr/bin/xcode-select -print-path) + + ifeq (,$(findstring 10.7, $(OSXVER))) + BUILDING_ON_LION := 0 + COMPILER_BIN_DIR := $(DEVELOPER_DIR)/usr/bin + SDK_DIR := $(DEVELOPER_DIR)/SDKs + else + BUILDING_ON_LION := 1 + # Need to figure out which version of XCode you have installed + # See if you have the clang compiler in $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang + ifeq ($(wildcard $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang),) + # no clang, you're running older Xcode + COMPILER_BIN_DIR := $(DEVELOPER_DIR)/usr/bin + SDK_DIR := $(DEVELOPER_DIR)/SDKs + else + # clang is in the new Toolchain, use it + COMPILER_BIN_DIR := $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/bin + SDK_DIR := $(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/SDKs + endif + endif + + #test to see if you have a compiler in the right place, if you don't abort with an error + + ifeq ($(wildcard $(COMPILER_BIN_DIR)/clang),) + $(error Unable to find compiler, install and configure XCode) + endif + + ifeq ($(wildcard $(COMPILER_BIN_DIR)/clang++),) + $(error Unable to find compiler, install and configure XCode) + endif + + + SDKROOT ?= $(SDK_DIR)/MacOSX10.6.sdk + + ifeq ($(origin AR), default) + AR = libtool -static -o + endif + ifeq ($(origin CC), default) + CC = $(CCACHE) $(COMPILER_BIN_DIR)/clang -Qunused-arguments + endif + ifeq ($(origin CXX), default) + CXX = $(CCACHE) $(COMPILER_BIN_DIR)/clang++ -Qunused-arguments + endif + LINK ?= $(CXX) + + ifeq (($TARGET_PLATFORM),osx64) + ARCH_FLAGS += -arch x86_64 -m64 -march=core2 + else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags))) + ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2 + else + # dirty hack to build a universal binary - don't specify the architecture + ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2 + endif + + #FIXME: NOTE:Full path specified because the xcode 4.0 preview has a terribly broken dsymutil, so ref the 3.2 one + GEN_SYM ?= $(DEVELOPER_DIR)/usr/bin/dsymutil + ifeq ($(CFG),release) + STRIP ?= strip -S + else + STRIP ?= true + endif + ifeq ($(SOURCE_SDK), 1) + VSIGN ?= true + else + VSIGN ?= $(SRCROOT)/devtools/bin/vsign + endif + + + CPPFLAGS += -I$(SDKROOT)/usr/include/malloc + CFLAGS += -isysroot $(SDKROOT) -mmacosx-version-min=10.5 -fasm-blocks + + LIB_START_EXE = -lm -ldl -lpthread + LIB_END_EXE = + + LIB_START_SHLIB = + LIB_END_SHLIB = + + SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + + ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE))) + SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + endif + +endif + +# +# Profile-directed optimizations. +# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%! +# +# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are. +# PROFILE_LINKER_FLAG=-fprofile-arcs +# PROFILE_COMPILER_FLAG=-fprofile-arcs +# +# Then, comment the above flags out again and rebuild with this flag uncommented: +# PROFILE_COMPILER_FLAG=-fprofile-use +# + +############################################################################# +# The compiler command lne for each src code file to compile +############################################################################# + +OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG) +CPP_TO_OBJ = $(CPPFILES:.cpp=.o) +CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o) +CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o) +MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o) +C_TO_OBJ = $(MM_TO_OBJ:.c=.o) +OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ))) + +ifeq ($(MAKE_VERBOSE),1) + QUIET_PREFIX = + QUIET_ECHO_POSTFIX = +else + QUIET_PREFIX = @ + QUIET_ECHO_POSTFIX = > /dev/null +endif + +ifeq ($(MAKE_CC_VERBOSE),1) +CC += -v +endif + +ifeq ($(CONFTYPE),lib) + LIB_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),dll) + SO_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),exe) + EXE_File = $(OUTPUTFILE) +endif + +# we generate dependencies as a side-effect of compilation now +GEN_DEP_FILE= + +PRE_COMPILE_FILE = + +POST_COMPILE_FILE = + +ifeq ($(BUILDING_MULTI_ARCH),1) + SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS)) + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \ + $(CXX) $(CXXFLAGS) -o $@ -c $< +else + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) ----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< +endif + +ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined" + P4_EDIT_START = chmod -R +w + P4_EDIT_END = || true + P4_REVERT_START = true + P4_REVERT_END = +else + ifndef P4_EDIT_CHANGELIST + # You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default + # setting is best, but here is an alternate example: + # export P4_EDIT_CHANGELIST_CMD="echo 1424335" + # ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed. + P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1 + P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD)) + endif + ifeq ($(P4_EDIT_CHANGELIST),) + # If we haven't found a changelist to check out to then create one. The name must match the one from a few + # lines above or else a new changelist will be created each time. + # Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be + # interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which + # confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command. + P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ') + endif + + P4_EDIT_START := for f in + P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) + P4_REVERT_START := for f in + P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) +endif + +ifeq ($(CONFTYPE),dll) +all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE) + @echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX) +else +all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE) + @echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX) +endif + +.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile + + +rebuild : + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) + + +# Use the relink target to force to relink the project. +relink: RemoveOutputFile all + +RemoveOutputFile: + rm -f $(OUTPUTFILE) + + +# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file. +# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that. +SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + @echo "" + +RemoveSingleFile: + $(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + +clean: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 revert $(OUTPUTFILE)"; \ + $(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \ + fi; +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)" + $(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END) +endif + + +# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the +# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave +# us with archive files that have extra unused symbols, and also potentially cause compilation errors +# when you rename a file and have many duplicate symbols. +cleanandremove: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) -rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \ + $(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \ + fi; + $(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT); +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)" + $(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END) + $(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE) +endif + + +# This just deletes the final targets so it'll do a relink next time we build. +cleantargets: + $(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE) + + +$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS) + $(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END); + $(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES); + +SO_GameOutputFile = $(GAMEOUTPUTFILE) + +# Remove the target before installing a file over it; this prevents existing +# instances of the game from crashing due to the overwrite. +$(SO_GameOutputFile): $(SO_File) + $(QUIET_PREFIX) \ + $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END); + $(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null; + $(QUIET_PREFIX) rm -f $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + $(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \ + mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \ + cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \ + fi; + + +$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB); + $(VSIGN) -signvalve $(OUTPUTFILE); + + +$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING EXE $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\ + $(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE); + + +tags: + etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx diff --git a/mp/src/devtools/sourcesdk_def.mak b/mp/src/devtools/sourcesdk_def.mak new file mode 100644 index 00000000..7912e08b --- /dev/null +++ b/mp/src/devtools/sourcesdk_def.mak @@ -0,0 +1,3 @@ +#defines these macros so that we skip VSIGN and P4 steps in the SDK +SOURCE_SDK=1 +VALVE_NO_AUTO_P4=1 diff --git a/mp/src/devtools/version_script.linux.txt b/mp/src/devtools/version_script.linux.txt new file mode 100644 index 00000000..c68a5ac1 --- /dev/null +++ b/mp/src/devtools/version_script.linux.txt @@ -0,0 +1,14 @@ +{ + global: *; + local: + extern "C++" { + *std::*; + __cxxabi*; + __gcc*; + __gxx*; + __gnu_cxx*; + __cxa*; + operator*; + __dynamic_cast + }; +}; -- cgit v1.2.3