diff --git a/creategameprojects.bat b/creategameprojects.bat index fdad5a0..de5e9b0 100644 --- a/creategameprojects.bat +++ b/creategameprojects.bat @@ -1 +1 @@ -devtools\bin\vpc.exe /episodic +game /mksln games.sln +devtools\bin\vpc.exe /episodic +game +shaders /mksln games.sln diff --git a/devtools/bin/fxc_prep.pl b/devtools/bin/fxc_prep.pl index 9f67ca5..090e7ce 100644 --- a/devtools/bin/fxc_prep.pl +++ b/devtools/bin/fxc_prep.pl @@ -473,7 +473,18 @@ sub GetShaderType { local( $shadername ) = shift; # hack - use global variables $shadername = $fxc_basename; - if( $shadername =~ m/ps30/i ) + if( $shadername =~ m/ps40/i ) + { + if( $debug ) + { + return "ps_4_sw"; + } + else + { + return "ps_4_0"; + } + } + elsif( $shadername =~ m/ps30/i ) { if( $debug ) { @@ -514,6 +525,17 @@ sub GetShaderType { return "ps_1_1"; } + elsif( $shadername =~ m/vs40/i ) + { + if( $debug ) + { + return "vs_4_sw"; + } + else + { + return "vs_4_0"; + } + } elsif( $shadername =~ m/vs30/i ) { if( $debug ) diff --git a/materialsystem/cmaterial.cpp b/materialsystem/cmaterial.cpp index e51647f..b71ab37 100644 --- a/materialsystem/cmaterial.cpp +++ b/materialsystem/cmaterial.cpp @@ -1432,7 +1432,7 @@ static KeyValues *FindBuiltinFallbackBlock( char const *pShaderName, KeyValues * inline const char *MissingShaderName() { - return (IsWindows() && !IsEmulatingGL()) ? "Wireframe_DX8" : "Wireframe_DX9"; + return "Wireframe"; } //----------------------------------------------------------------------------- diff --git a/materialsystem/cmaterialsystem.cpp b/materialsystem/cmaterialsystem.cpp index 1309752..b615b50 100644 --- a/materialsystem/cmaterialsystem.cpp +++ b/materialsystem/cmaterialsystem.cpp @@ -62,7 +62,7 @@ static ConVar mat_tonemapping_occlusion_use_stencil( "mat_tonemapping_occlusion_ // In GL mode, we currently require mat_dxlevel to be between 90-92 static ConVar mat_dxlevel( "mat_dxlevel", "92", 0, "", true, 90, true, 92, NULL ); #else -static ConVar mat_dxlevel( "mat_dxlevel", "0", 0, "Current DirectX Level. Competitive play requires at least mat_dxlevel 90", true, 0, true, 95, NULL ); +static ConVar mat_dxlevel( "mat_dxlevel", "0", 0, "Current DirectX Level. Competitive play requires at least mat_dxlevel 90", true, 0, true, 110, NULL ); #endif IMaterialInternal *g_pErrorMaterial = NULL; @@ -620,9 +620,14 @@ void CMaterialSystem::SetShaderAPI( char const *pShaderAPIDLL ) Error( "Cannot set the shader API twice!\n" ); } - if ( !pShaderAPIDLL ) + // DX11FIXME + if (CommandLine()->ParmValue("-dxlevel", 90) >= 110) { - pShaderAPIDLL = "shaderapidx9"; + pShaderAPIDLL = "shaderapidx11.dll"; + } + else if ( !pShaderAPIDLL ) + { + pShaderAPIDLL = "shaderapidx9.dll"; } // m_pShaderDLL is needed to spew driver info diff --git a/materialsystem/shaderapidx11/Dx11Global.h b/materialsystem/shaderapidx11/Dx11Global.h new file mode 100644 index 0000000..9aca5c4 --- /dev/null +++ b/materialsystem/shaderapidx11/Dx11Global.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "utlstring.h" + +#ifndef MAX_DX11_STREAMS +#define MAX_DX11_STREAMS 16 +#endif + +#ifndef MAX_DX11_SAMPLERS +#define MAX_DX11_SAMPLERS 16 +#endif + +extern ID3D11Device *g_pD3DDevice; +extern ID3D11DeviceContext *g_pD3DDeviceContext; +extern IDXGISwapChain *g_pD3DSwapChain; + +//----------------------------------------------------------------------------- +// Utility methods +//----------------------------------------------------------------------------- +inline ID3D11Device *D3D11Device() +{ + return g_pD3DDevice; +} + +inline ID3D11DeviceContext *D3D11DeviceContext() +{ + return g_pD3DDeviceContext; +} + +inline IDXGISwapChain *D3D11SwapChain() +{ + return g_pD3DSwapChain; +} + +FORCEINLINE static void memcpy_SSE( void *dest, const void *src, size_t count ) +{ + __m128i *srcPtr = ( __m128i * )src; + __m128i *destPtr = ( __m128i * )dest; + + unsigned int index = 0; + while ( count ) + { + + __m128i x = _mm_load_si128( &srcPtr[index] ); + _mm_stream_si128( &destPtr[index], x ); + + count -= 16; + index++; + } +} + +#if 0 +FORCEINLINE static long FastMemCompare( const void *cmp1, const void *cmp2, unsigned long length ) +{ + if ( length >= 4 ) + { + long difference = *(unsigned long *)cmp1 - *(unsigned long *)cmp2; + if ( difference ) + return difference; + } + + return memcmp( cmp1, cmp2, length ); +} +#endif + +#define FastMemCompare memcmp \ No newline at end of file diff --git a/materialsystem/shaderapidx11/FastMemcpy.h b/materialsystem/shaderapidx11/FastMemcpy.h new file mode 100644 index 0000000..5e81946 --- /dev/null +++ b/materialsystem/shaderapidx11/FastMemcpy.h @@ -0,0 +1,706 @@ +//===================================================================== +// +// FastMemcpy.c - skywind3000@163.com, 2015 +// +// feature: +// 50% speed up in avg. vs standard memcpy (tested in vc2012/gcc5.1) +// +//===================================================================== +#ifndef __FAST_MEMCPY_H__ +#define __FAST_MEMCPY_H__ + +#include +#include +#include + + +//--------------------------------------------------------------------- +// force inline for compilers +//--------------------------------------------------------------------- +#ifndef INLINE +#ifdef __GNUC__ +#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) +#define INLINE __inline__ __attribute__((always_inline)) +#else +#define INLINE __inline__ +#endif +#elif defined(_MSC_VER) +#define INLINE __forceinline +#elif (defined(__BORLANDC__) || defined(__WATCOMC__)) +#define INLINE __inline +#else +#define INLINE +#endif +#endif + + + +//--------------------------------------------------------------------- +// fast copy for different sizes +//--------------------------------------------------------------------- +static INLINE void memcpy_sse2_16( void *dst, const void *src ) +{ + __m128i m0 = _mm_loadu_si128( ( ( const __m128i * )src ) + 0 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 0, m0 ); +} + +static INLINE void memcpy_sse2_32( void *dst, const void *src ) +{ + __m128i m0 = _mm_loadu_si128( ( ( const __m128i * )src ) + 0 ); + __m128i m1 = _mm_loadu_si128( ( ( const __m128i * )src ) + 1 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 0, m0 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 1, m1 ); +} + +static INLINE void memcpy_sse2_64( void *dst, const void *src ) +{ + __m128i m0 = _mm_loadu_si128( ( ( const __m128i * )src ) + 0 ); + __m128i m1 = _mm_loadu_si128( ( ( const __m128i * )src ) + 1 ); + __m128i m2 = _mm_loadu_si128( ( ( const __m128i * )src ) + 2 ); + __m128i m3 = _mm_loadu_si128( ( ( const __m128i * )src ) + 3 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 0, m0 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 1, m1 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 2, m2 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 3, m3 ); +} + +static INLINE void memcpy_sse2_128( void *dst, const void *src ) +{ + __m128i m0 = _mm_loadu_si128( ( ( const __m128i * )src ) + 0 ); + __m128i m1 = _mm_loadu_si128( ( ( const __m128i * )src ) + 1 ); + __m128i m2 = _mm_loadu_si128( ( ( const __m128i * )src ) + 2 ); + __m128i m3 = _mm_loadu_si128( ( ( const __m128i * )src ) + 3 ); + __m128i m4 = _mm_loadu_si128( ( ( const __m128i * )src ) + 4 ); + __m128i m5 = _mm_loadu_si128( ( ( const __m128i * )src ) + 5 ); + __m128i m6 = _mm_loadu_si128( ( ( const __m128i * )src ) + 6 ); + __m128i m7 = _mm_loadu_si128( ( ( const __m128i * )src ) + 7 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 0, m0 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 1, m1 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 2, m2 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 3, m3 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 4, m4 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 5, m5 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 6, m6 ); + _mm_storeu_si128( ( ( __m128i * )dst ) + 7, m7 ); +} + + +//--------------------------------------------------------------------- +// tiny memory copy with jump table optimized +//--------------------------------------------------------------------- +static INLINE void *memcpy_tiny( void *dst, const void *src, size_t size ) +{ + unsigned char *dd = ( (unsigned char *)dst ) + size; + const unsigned char *ss = ( (const unsigned char *)src ) + size; + + switch ( size ) + { + case 64: + memcpy_sse2_64( dd - 64, ss - 64 ); + case 0: + break; + + case 65: + memcpy_sse2_64( dd - 65, ss - 65 ); + case 1: + dd[-1] = ss[-1]; + break; + + case 66: + memcpy_sse2_64( dd - 66, ss - 66 ); + case 2: + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 67: + memcpy_sse2_64( dd - 67, ss - 67 ); + case 3: + *( (uint16_t *)( dd - 3 ) ) = *( (uint16_t *)( ss - 3 ) ); + dd[-1] = ss[-1]; + break; + + case 68: + memcpy_sse2_64( dd - 68, ss - 68 ); + case 4: + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 69: + memcpy_sse2_64( dd - 69, ss - 69 ); + case 5: + *( (uint32_t *)( dd - 5 ) ) = *( (uint32_t *)( ss - 5 ) ); + dd[-1] = ss[-1]; + break; + + case 70: + memcpy_sse2_64( dd - 70, ss - 70 ); + case 6: + *( (uint32_t *)( dd - 6 ) ) = *( (uint32_t *)( ss - 6 ) ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 71: + memcpy_sse2_64( dd - 71, ss - 71 ); + case 7: + *( (uint32_t *)( dd - 7 ) ) = *( (uint32_t *)( ss - 7 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 72: + memcpy_sse2_64( dd - 72, ss - 72 ); + case 8: + *( (uint64_t *)( dd - 8 ) ) = *( (uint64_t *)( ss - 8 ) ); + break; + + case 73: + memcpy_sse2_64( dd - 73, ss - 73 ); + case 9: + *( (uint64_t *)( dd - 9 ) ) = *( (uint64_t *)( ss - 9 ) ); + dd[-1] = ss[-1]; + break; + + case 74: + memcpy_sse2_64( dd - 74, ss - 74 ); + case 10: + *( (uint64_t *)( dd - 10 ) ) = *( (uint64_t *)( ss - 10 ) ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 75: + memcpy_sse2_64( dd - 75, ss - 75 ); + case 11: + *( (uint64_t *)( dd - 11 ) ) = *( (uint64_t *)( ss - 11 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 76: + memcpy_sse2_64( dd - 76, ss - 76 ); + case 12: + *( (uint64_t *)( dd - 12 ) ) = *( (uint64_t *)( ss - 12 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 77: + memcpy_sse2_64( dd - 77, ss - 77 ); + case 13: + *( (uint64_t *)( dd - 13 ) ) = *( (uint64_t *)( ss - 13 ) ); + *( (uint32_t *)( dd - 5 ) ) = *( (uint32_t *)( ss - 5 ) ); + dd[-1] = ss[-1]; + break; + + case 78: + memcpy_sse2_64( dd - 78, ss - 78 ); + case 14: + *( (uint64_t *)( dd - 14 ) ) = *( (uint64_t *)( ss - 14 ) ); + *( (uint64_t *)( dd - 8 ) ) = *( (uint64_t *)( ss - 8 ) ); + break; + + case 79: + memcpy_sse2_64( dd - 79, ss - 79 ); + case 15: + *( (uint64_t *)( dd - 15 ) ) = *( (uint64_t *)( ss - 15 ) ); + *( (uint64_t *)( dd - 8 ) ) = *( (uint64_t *)( ss - 8 ) ); + break; + + case 80: + memcpy_sse2_64( dd - 80, ss - 80 ); + case 16: + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 81: + memcpy_sse2_64( dd - 81, ss - 81 ); + case 17: + memcpy_sse2_16( dd - 17, ss - 17 ); + dd[-1] = ss[-1]; + break; + + case 82: + memcpy_sse2_64( dd - 82, ss - 82 ); + case 18: + memcpy_sse2_16( dd - 18, ss - 18 ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 83: + memcpy_sse2_64( dd - 83, ss - 83 ); + case 19: + memcpy_sse2_16( dd - 19, ss - 19 ); + *( (uint16_t *)( dd - 3 ) ) = *( (uint16_t *)( ss - 3 ) ); + dd[-1] = ss[-1]; + break; + + case 84: + memcpy_sse2_64( dd - 84, ss - 84 ); + case 20: + memcpy_sse2_16( dd - 20, ss - 20 ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 85: + memcpy_sse2_64( dd - 85, ss - 85 ); + case 21: + memcpy_sse2_16( dd - 21, ss - 21 ); + *( (uint32_t *)( dd - 5 ) ) = *( (uint32_t *)( ss - 5 ) ); + dd[-1] = ss[-1]; + break; + + case 86: + memcpy_sse2_64( dd - 86, ss - 86 ); + case 22: + memcpy_sse2_16( dd - 22, ss - 22 ); + *( (uint32_t *)( dd - 6 ) ) = *( (uint32_t *)( ss - 6 ) ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 87: + memcpy_sse2_64( dd - 87, ss - 87 ); + case 23: + memcpy_sse2_16( dd - 23, ss - 23 ); + *( (uint32_t *)( dd - 7 ) ) = *( (uint32_t *)( ss - 7 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 88: + memcpy_sse2_64( dd - 88, ss - 88 ); + case 24: + memcpy_sse2_16( dd - 24, ss - 24 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 89: + memcpy_sse2_64( dd - 89, ss - 89 ); + case 25: + memcpy_sse2_16( dd - 25, ss - 25 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 90: + memcpy_sse2_64( dd - 90, ss - 90 ); + case 26: + memcpy_sse2_16( dd - 26, ss - 26 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 91: + memcpy_sse2_64( dd - 91, ss - 91 ); + case 27: + memcpy_sse2_16( dd - 27, ss - 27 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 92: + memcpy_sse2_64( dd - 92, ss - 92 ); + case 28: + memcpy_sse2_16( dd - 28, ss - 28 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 93: + memcpy_sse2_64( dd - 93, ss - 93 ); + case 29: + memcpy_sse2_16( dd - 29, ss - 29 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 94: + memcpy_sse2_64( dd - 94, ss - 94 ); + case 30: + memcpy_sse2_16( dd - 30, ss - 30 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 95: + memcpy_sse2_64( dd - 95, ss - 95 ); + case 31: + memcpy_sse2_16( dd - 31, ss - 31 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 96: + memcpy_sse2_64( dd - 96, ss - 96 ); + case 32: + memcpy_sse2_32( dd - 32, ss - 32 ); + break; + + case 97: + memcpy_sse2_64( dd - 97, ss - 97 ); + case 33: + memcpy_sse2_32( dd - 33, ss - 33 ); + dd[-1] = ss[-1]; + break; + + case 98: + memcpy_sse2_64( dd - 98, ss - 98 ); + case 34: + memcpy_sse2_32( dd - 34, ss - 34 ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 99: + memcpy_sse2_64( dd - 99, ss - 99 ); + case 35: + memcpy_sse2_32( dd - 35, ss - 35 ); + *( (uint16_t *)( dd - 3 ) ) = *( (uint16_t *)( ss - 3 ) ); + dd[-1] = ss[-1]; + break; + + case 100: + memcpy_sse2_64( dd - 100, ss - 100 ); + case 36: + memcpy_sse2_32( dd - 36, ss - 36 ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 101: + memcpy_sse2_64( dd - 101, ss - 101 ); + case 37: + memcpy_sse2_32( dd - 37, ss - 37 ); + *( (uint32_t *)( dd - 5 ) ) = *( (uint32_t *)( ss - 5 ) ); + dd[-1] = ss[-1]; + break; + + case 102: + memcpy_sse2_64( dd - 102, ss - 102 ); + case 38: + memcpy_sse2_32( dd - 38, ss - 38 ); + *( (uint32_t *)( dd - 6 ) ) = *( (uint32_t *)( ss - 6 ) ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 103: + memcpy_sse2_64( dd - 103, ss - 103 ); + case 39: + memcpy_sse2_32( dd - 39, ss - 39 ); + *( (uint32_t *)( dd - 7 ) ) = *( (uint32_t *)( ss - 7 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 104: + memcpy_sse2_64( dd - 104, ss - 104 ); + case 40: + memcpy_sse2_32( dd - 40, ss - 40 ); + *( (uint64_t *)( dd - 8 ) ) = *( (uint64_t *)( ss - 8 ) ); + break; + + case 105: + memcpy_sse2_64( dd - 105, ss - 105 ); + case 41: + memcpy_sse2_32( dd - 41, ss - 41 ); + *( (uint64_t *)( dd - 9 ) ) = *( (uint64_t *)( ss - 9 ) ); + dd[-1] = ss[-1]; + break; + + case 106: + memcpy_sse2_64( dd - 106, ss - 106 ); + case 42: + memcpy_sse2_32( dd - 42, ss - 42 ); + *( (uint64_t *)( dd - 10 ) ) = *( (uint64_t *)( ss - 10 ) ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 107: + memcpy_sse2_64( dd - 107, ss - 107 ); + case 43: + memcpy_sse2_32( dd - 43, ss - 43 ); + *( (uint64_t *)( dd - 11 ) ) = *( (uint64_t *)( ss - 11 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 108: + memcpy_sse2_64( dd - 108, ss - 108 ); + case 44: + memcpy_sse2_32( dd - 44, ss - 44 ); + *( (uint64_t *)( dd - 12 ) ) = *( (uint64_t *)( ss - 12 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 109: + memcpy_sse2_64( dd - 109, ss - 109 ); + case 45: + memcpy_sse2_32( dd - 45, ss - 45 ); + *( (uint64_t *)( dd - 13 ) ) = *( (uint64_t *)( ss - 13 ) ); + *( (uint32_t *)( dd - 5 ) ) = *( (uint32_t *)( ss - 5 ) ); + dd[-1] = ss[-1]; + break; + + case 110: + memcpy_sse2_64( dd - 110, ss - 110 ); + case 46: + memcpy_sse2_32( dd - 46, ss - 46 ); + *( (uint64_t *)( dd - 14 ) ) = *( (uint64_t *)( ss - 14 ) ); + *( (uint64_t *)( dd - 8 ) ) = *( (uint64_t *)( ss - 8 ) ); + break; + + case 111: + memcpy_sse2_64( dd - 111, ss - 111 ); + case 47: + memcpy_sse2_32( dd - 47, ss - 47 ); + *( (uint64_t *)( dd - 15 ) ) = *( (uint64_t *)( ss - 15 ) ); + *( (uint64_t *)( dd - 8 ) ) = *( (uint64_t *)( ss - 8 ) ); + break; + + case 112: + memcpy_sse2_64( dd - 112, ss - 112 ); + case 48: + memcpy_sse2_32( dd - 48, ss - 48 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 113: + memcpy_sse2_64( dd - 113, ss - 113 ); + case 49: + memcpy_sse2_32( dd - 49, ss - 49 ); + memcpy_sse2_16( dd - 17, ss - 17 ); + dd[-1] = ss[-1]; + break; + + case 114: + memcpy_sse2_64( dd - 114, ss - 114 ); + case 50: + memcpy_sse2_32( dd - 50, ss - 50 ); + memcpy_sse2_16( dd - 18, ss - 18 ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 115: + memcpy_sse2_64( dd - 115, ss - 115 ); + case 51: + memcpy_sse2_32( dd - 51, ss - 51 ); + memcpy_sse2_16( dd - 19, ss - 19 ); + *( (uint16_t *)( dd - 3 ) ) = *( (uint16_t *)( ss - 3 ) ); + dd[-1] = ss[-1]; + break; + + case 116: + memcpy_sse2_64( dd - 116, ss - 116 ); + case 52: + memcpy_sse2_32( dd - 52, ss - 52 ); + memcpy_sse2_16( dd - 20, ss - 20 ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 117: + memcpy_sse2_64( dd - 117, ss - 117 ); + case 53: + memcpy_sse2_32( dd - 53, ss - 53 ); + memcpy_sse2_16( dd - 21, ss - 21 ); + *( (uint32_t *)( dd - 5 ) ) = *( (uint32_t *)( ss - 5 ) ); + dd[-1] = ss[-1]; + break; + + case 118: + memcpy_sse2_64( dd - 118, ss - 118 ); + case 54: + memcpy_sse2_32( dd - 54, ss - 54 ); + memcpy_sse2_16( dd - 22, ss - 22 ); + *( (uint32_t *)( dd - 6 ) ) = *( (uint32_t *)( ss - 6 ) ); + *( (uint16_t *)( dd - 2 ) ) = *( (uint16_t *)( ss - 2 ) ); + break; + + case 119: + memcpy_sse2_64( dd - 119, ss - 119 ); + case 55: + memcpy_sse2_32( dd - 55, ss - 55 ); + memcpy_sse2_16( dd - 23, ss - 23 ); + *( (uint32_t *)( dd - 7 ) ) = *( (uint32_t *)( ss - 7 ) ); + *( (uint32_t *)( dd - 4 ) ) = *( (uint32_t *)( ss - 4 ) ); + break; + + case 120: + memcpy_sse2_64( dd - 120, ss - 120 ); + case 56: + memcpy_sse2_32( dd - 56, ss - 56 ); + memcpy_sse2_16( dd - 24, ss - 24 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 121: + memcpy_sse2_64( dd - 121, ss - 121 ); + case 57: + memcpy_sse2_32( dd - 57, ss - 57 ); + memcpy_sse2_16( dd - 25, ss - 25 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 122: + memcpy_sse2_64( dd - 122, ss - 122 ); + case 58: + memcpy_sse2_32( dd - 58, ss - 58 ); + memcpy_sse2_16( dd - 26, ss - 26 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 123: + memcpy_sse2_64( dd - 123, ss - 123 ); + case 59: + memcpy_sse2_32( dd - 59, ss - 59 ); + memcpy_sse2_16( dd - 27, ss - 27 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 124: + memcpy_sse2_64( dd - 124, ss - 124 ); + case 60: + memcpy_sse2_32( dd - 60, ss - 60 ); + memcpy_sse2_16( dd - 28, ss - 28 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 125: + memcpy_sse2_64( dd - 125, ss - 125 ); + case 61: + memcpy_sse2_32( dd - 61, ss - 61 ); + memcpy_sse2_16( dd - 29, ss - 29 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 126: + memcpy_sse2_64( dd - 126, ss - 126 ); + case 62: + memcpy_sse2_32( dd - 62, ss - 62 ); + memcpy_sse2_16( dd - 30, ss - 30 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 127: + memcpy_sse2_64( dd - 127, ss - 127 ); + case 63: + memcpy_sse2_32( dd - 63, ss - 63 ); + memcpy_sse2_16( dd - 31, ss - 31 ); + memcpy_sse2_16( dd - 16, ss - 16 ); + break; + + case 128: + memcpy_sse2_128( dd - 128, ss - 128 ); + break; + } + + return dst; +} + + +//--------------------------------------------------------------------- +// main routine +//--------------------------------------------------------------------- +static void *memcpy_fast( void *destination, const void *source, size_t size ) +{ + unsigned char *dst = (unsigned char *)destination; + const unsigned char *src = (const unsigned char *)source; + static size_t cachesize = 0x200000; // L2-cache size + size_t padding; + + // small memory copy + if ( size <= 128 ) + { + return memcpy_tiny( dst, src, size ); + } + + // align destination to 16 bytes boundary + padding = ( 16 - ( ( (size_t)dst ) & 15 ) ) & 15; + + if ( padding > 0 ) + { + __m128i head = _mm_loadu_si128( ( const __m128i * )src ); + _mm_storeu_si128( ( __m128i * )dst, head ); + dst += padding; + src += padding; + size -= padding; + } + + // medium size copy + if ( size <= cachesize ) + { + __m128i c0, c1, c2, c3, c4, c5, c6, c7; + + for ( ; size >= 128; size -= 128 ) + { + c0 = _mm_loadu_si128( ( ( const __m128i * )src ) + 0 ); + c1 = _mm_loadu_si128( ( ( const __m128i * )src ) + 1 ); + c2 = _mm_loadu_si128( ( ( const __m128i * )src ) + 2 ); + c3 = _mm_loadu_si128( ( ( const __m128i * )src ) + 3 ); + c4 = _mm_loadu_si128( ( ( const __m128i * )src ) + 4 ); + c5 = _mm_loadu_si128( ( ( const __m128i * )src ) + 5 ); + c6 = _mm_loadu_si128( ( ( const __m128i * )src ) + 6 ); + c7 = _mm_loadu_si128( ( ( const __m128i * )src ) + 7 ); + _mm_prefetch( (const char *)( src + 256 ), _MM_HINT_NTA ); + src += 128; + _mm_store_si128( ( ( ( __m128i * )dst ) + 0 ), c0 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 1 ), c1 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 2 ), c2 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 3 ), c3 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 4 ), c4 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 5 ), c5 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 6 ), c6 ); + _mm_store_si128( ( ( ( __m128i * )dst ) + 7 ), c7 ); + dst += 128; + } + } + else + { // big memory copy + __m128i c0, c1, c2, c3, c4, c5, c6, c7; + + _mm_prefetch( (const char *)( src ), _MM_HINT_NTA ); + + if ( ( ( (size_t)src ) & 15 ) == 0 ) + { // source aligned + for ( ; size >= 128; size -= 128 ) + { + c0 = _mm_load_si128( ( ( const __m128i * )src ) + 0 ); + c1 = _mm_load_si128( ( ( const __m128i * )src ) + 1 ); + c2 = _mm_load_si128( ( ( const __m128i * )src ) + 2 ); + c3 = _mm_load_si128( ( ( const __m128i * )src ) + 3 ); + c4 = _mm_load_si128( ( ( const __m128i * )src ) + 4 ); + c5 = _mm_load_si128( ( ( const __m128i * )src ) + 5 ); + c6 = _mm_load_si128( ( ( const __m128i * )src ) + 6 ); + c7 = _mm_load_si128( ( ( const __m128i * )src ) + 7 ); + _mm_prefetch( (const char *)( src + 256 ), _MM_HINT_NTA ); + src += 128; + _mm_stream_si128( ( ( ( __m128i * )dst ) + 0 ), c0 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 1 ), c1 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 2 ), c2 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 3 ), c3 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 4 ), c4 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 5 ), c5 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 6 ), c6 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 7 ), c7 ); + dst += 128; + } + } + else + { // source unaligned + for ( ; size >= 128; size -= 128 ) + { + c0 = _mm_loadu_si128( ( ( const __m128i * )src ) + 0 ); + c1 = _mm_loadu_si128( ( ( const __m128i * )src ) + 1 ); + c2 = _mm_loadu_si128( ( ( const __m128i * )src ) + 2 ); + c3 = _mm_loadu_si128( ( ( const __m128i * )src ) + 3 ); + c4 = _mm_loadu_si128( ( ( const __m128i * )src ) + 4 ); + c5 = _mm_loadu_si128( ( ( const __m128i * )src ) + 5 ); + c6 = _mm_loadu_si128( ( ( const __m128i * )src ) + 6 ); + c7 = _mm_loadu_si128( ( ( const __m128i * )src ) + 7 ); + _mm_prefetch( (const char *)( src + 256 ), _MM_HINT_NTA ); + src += 128; + _mm_stream_si128( ( ( ( __m128i * )dst ) + 0 ), c0 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 1 ), c1 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 2 ), c2 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 3 ), c3 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 4 ), c4 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 5 ), c5 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 6 ), c6 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 7 ), c7 ); + dst += 128; + } + } + _mm_sfence(); + } + + memcpy_tiny( dst, src, size ); + + return destination; +} + + +#endif + + diff --git a/materialsystem/shaderapidx11/IndexBufferDx11.cpp b/materialsystem/shaderapidx11/IndexBufferDx11.cpp new file mode 100644 index 0000000..1a27597 --- /dev/null +++ b/materialsystem/shaderapidx11/IndexBufferDx11.cpp @@ -0,0 +1,458 @@ +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "IndexBufferDx11.h" +#include "shaderapidx9/locald3dtypes.h" +#include "shaderapidx11_global.h" +#include "shaderdevicedx11.h" +#include "shaderapi/ishaderutil.h" +#include "tier0/vprof.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// +// Dx11 implementation of an index buffer +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// globals +//----------------------------------------------------------------------------- + +// shove indices into this if you don't actually want indices +static unsigned int s_nScratchIndexBuffer = 0; + +#ifdef _DEBUG +int CIndexBufferDx11::s_nBufferCount = 0; +#endif + + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CIndexBufferDx11::CIndexBufferDx11( ShaderBufferType_t type, MaterialIndexFormat_t fmt, int nIndexCount, const char* pBudgetGroupName ) : + BaseClass( pBudgetGroupName ) +{ + // NOTE: MATERIAL_INDEX_FORMAT_UNKNOWN can't be dealt with under dx9 + // because format is bound at buffer creation time. What we'll do + // is just arbitrarily choose to use a 16-bit index buffer of the same size + if ( fmt == MATERIAL_INDEX_FORMAT_UNKNOWN ) + { + fmt = MATERIAL_INDEX_FORMAT_16BIT; + nIndexCount /= 2; + } + + //Assert( nIndexCount != 0 ); + Assert( IsDynamicBufferType( type ) || ( fmt != MATERIAL_INDEX_FORMAT_UNKNOWN ) ); + + m_pIndexMemory = NULL; + m_pIndexBuffer = NULL; + m_IndexFormat = fmt; + m_nIndexSize = SizeForIndex( fmt ); + m_nIndexCount = nIndexCount; + m_nBufferSize = nIndexCount * m_nIndexSize; + m_Position = 0; + m_bIsLocked = false; + m_bIsDynamic = IsDynamicBufferType( type ); + m_nIndicesLocked = 0; + m_bFlush = false; + +#ifdef _DEBUG + m_pShadowIndices = new unsigned short[m_nIndexCount]; + m_NumIndices = nIndexCount; +#endif + + // NOTE: This has to happen at the end since m_IndexFormat must be valid for IndexSize() to work + //if ( m_bIsDynamic ) + //{ + // m_IndexFormat = MATERIAL_INDEX_FORMAT_UNKNOWN; + // m_nIndexCount = 0; + //} +} + +CIndexBufferDx11::~CIndexBufferDx11() +{ +#ifdef _DEBUG + if ( m_pShadowIndices ) + { + delete[] m_pShadowIndices; + m_pShadowIndices = NULL; + } +#endif + Free(); +} + +bool CIndexBufferDx11::HasEnoughRoom( int nIndexCount ) const +{ + return ( GetRoomRemaining() - nIndexCount ) >= 0; +} + + +//----------------------------------------------------------------------------- +// Creates, destroys the index buffer +//----------------------------------------------------------------------------- +bool CIndexBufferDx11::Allocate() +{ + Assert( !m_pIndexBuffer ); + + if ( !m_bIsDynamic ) + { + m_pIndexMemory = (unsigned char *)malloc( m_nBufferSize ); + memset( m_pIndexMemory, 0, m_nBufferSize ); + } + else + { + m_pIndexMemory = NULL; + } + + m_Position = 0; + + //Log( "Creating D3D index buffer: size: %i\n", m_nBufferSize ); + + D3D11_BUFFER_DESC bd; + if ( m_bIsDynamic ) + { + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + } + else + { + bd.Usage = D3D11_USAGE_DEFAULT; + bd.CPUAccessFlags = 0; + } + + bd.ByteWidth = m_nBufferSize; + bd.BindFlags = D3D11_BIND_INDEX_BUFFER; + + bd.MiscFlags = 0; + + HRESULT hr = D3D11Device()->CreateBuffer( &bd, NULL, &m_pIndexBuffer ); + bool bOk = !FAILED( hr ) && ( m_pIndexBuffer != NULL ); + + if ( bOk ) + { + if ( !m_bIsDynamic ) + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); + } + else + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); + } +#ifdef _DEBUG + ++s_nBufferCount; +#endif + } + + return bOk; +} + +void CIndexBufferDx11::Free() +{ + if ( m_pIndexBuffer ) + { +#ifdef _DEBUG + --s_nBufferCount; +#endif + + m_pIndexBuffer->Release(); + m_pIndexBuffer = NULL; + + if ( !m_bIsDynamic ) + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, -m_nBufferSize ); + } + else + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, -m_nBufferSize ); + } + } + + if ( m_pIndexMemory ) + { + free( m_pIndexMemory ); + m_pIndexMemory = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Returns the buffer size (only valid for static index buffers) +//----------------------------------------------------------------------------- +int CIndexBufferDx11::IndexCount() const +{ + //Assert( !m_bIsDynamic ); + return m_nIndexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the buffer format (only valid for static index buffers) +//----------------------------------------------------------------------------- +MaterialIndexFormat_t CIndexBufferDx11::IndexFormat() const +{ + //Assert( !m_bIsDynamic ); + return m_IndexFormat; +} + + +//----------------------------------------------------------------------------- +// Returns true if the buffer is dynamic +//----------------------------------------------------------------------------- +bool CIndexBufferDx11::IsDynamic() const +{ + return m_bIsDynamic; +} + + +//----------------------------------------------------------------------------- +// Only used by dynamic buffers, indicates the next lock should perform a discard. +//----------------------------------------------------------------------------- +void CIndexBufferDx11::Flush() +{ + // This strange-looking line makes a flush only occur if the buffer is dynamic. + m_bFlush = m_bIsDynamic; +} + +int CIndexBufferDx11::SizeForIndex( MaterialIndexFormat_t fmt ) const +{ + switch ( fmt ) + { + default: + case MATERIAL_INDEX_FORMAT_UNKNOWN: + return 0; + case MATERIAL_INDEX_FORMAT_16BIT: + return 2; + case MATERIAL_INDEX_FORMAT_32BIT: + return 4; + } +} + +//----------------------------------------------------------------------------- +// Casts a dynamic buffer to be a particular index type +//----------------------------------------------------------------------------- +void CIndexBufferDx11::BeginCastBuffer( MaterialIndexFormat_t format ) +{ + Assert( format != MATERIAL_INDEX_FORMAT_UNKNOWN ); + Assert( m_bIsDynamic && ( m_IndexFormat == MATERIAL_INDEX_FORMAT_UNKNOWN || m_IndexFormat == format ) ); + if ( !m_bIsDynamic ) + return; + + m_IndexFormat = format; + m_nIndexSize = SizeForIndex( m_IndexFormat ); + m_nIndexCount = m_nBufferSize / IndexSize(); +} + +void CIndexBufferDx11::EndCastBuffer() +{ + Assert( m_bIsDynamic && m_IndexFormat != MATERIAL_INDEX_FORMAT_UNKNOWN ); + if ( !m_bIsDynamic ) + return; + m_IndexFormat = MATERIAL_INDEX_FORMAT_UNKNOWN; + m_nIndexCount = 0; + m_nIndexSize = 0; +} + + +//----------------------------------------------------------------------------- +// Returns the number of indices that can be written into the buffer +//----------------------------------------------------------------------------- +int CIndexBufferDx11::GetRoomRemaining() const +{ + return ( m_nBufferSize - m_Position ) / IndexSize(); +} + +bool CIndexBufferDx11::LockEx( int nFirstIndex, int nMaxIndexCount, IndexDesc_t &desc ) +{ + Assert( !m_bIsLocked && ( nMaxIndexCount <= m_nIndexCount ) ); + Assert( m_IndexFormat != MATERIAL_INDEX_FORMAT_UNKNOWN ); + + // FIXME: Why do we need to sync matrices now? + ShaderUtil()->SyncMatrices(); + g_ShaderMutex.Lock(); + + // This can happen if the buffer was locked but a type wasn't bound + if ( m_IndexFormat == MATERIAL_INDEX_FORMAT_UNKNOWN ) + goto indexBufferLockFailed; + + // Just give the app crap buffers to fill up while we're suppressed... + if ( g_pShaderDevice->IsDeactivated() || ( nMaxIndexCount == 0 ) ) + goto indexBufferLockFailed; + + // Did we ask for something too large? + if ( nMaxIndexCount > m_nIndexCount ) + { + Warning( "Too many indices for index buffer. . tell a programmer (%d>%d)\n", nMaxIndexCount, m_nIndexCount ); + //DebuggerBreak(); + goto indexBufferLockFailed; + } + + // We might not have a buffer owing to alt-tab type stuff + if ( !m_pIndexBuffer ) + { + if ( !Allocate() ) + goto indexBufferLockFailed; + } + + //Log( "Locking index buffer %p\n", m_pIndexBuffer ); + + if ( m_bIsDynamic ) + { + // Check to see if we have enough memory + int nMemoryRequired = nMaxIndexCount * IndexSize(); + bool bHasEnoughMemory = ( m_Position + nMemoryRequired <= m_nBufferSize ); + + D3D11_MAPPED_SUBRESOURCE lockedData; + HRESULT hr; + + D3D11_MAP map; + if ( !m_bFlush && bHasEnoughMemory ) + { + map = ( m_Position == 0 ) ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE; + } + else + { + map = D3D11_MAP_WRITE_DISCARD; + m_Position = 0; + m_bFlush = false; + } + + //goto indexBufferLockFailed; + hr = D3D11DeviceContext()->Map( m_pIndexBuffer, 0, map, 0, &lockedData ); + if ( FAILED( hr ) ) + { + Warning( "Failed to lock index buffer in CIndexBufferDx11::Lock\n" ); + goto indexBufferLockFailed; + } + //Log( "LOcking index buffer at %i\n", m_Position ); + desc.m_pIndices = (unsigned short *)( (unsigned char *)lockedData.pData + m_Position ); + desc.m_nIndexSize = IndexSize() >> 1; + desc.m_nOffset = m_Position; + desc.m_nFirstIndex = desc.m_nOffset / IndexSize(); +#ifdef _DEBUG + m_LockedStartIndex = desc.m_nFirstIndex; + m_LockedNumIndices = nMaxIndexCount; +#endif + m_bIsLocked = true; + return true; + } + else + { + // Static index buffer case + // Check to see if we have enough memory + int nOffset; + if ( nFirstIndex >= 0 ) + nOffset = nFirstIndex * IndexSize(); + else + nOffset = m_Position; + int nMemoryRequired = nMaxIndexCount * IndexSize(); + bool bHasEnoughMemory = ( nOffset + nMemoryRequired <= m_nBufferSize ); + + if ( !bHasEnoughMemory ) + { + goto indexBufferLockFailed; + } + + m_Position = nOffset; + + desc.m_pIndices = (unsigned short *)( m_pIndexMemory + nOffset ); + + desc.m_nIndexSize = IndexSize() >> 1; + desc.m_nOffset = nOffset; + desc.m_nFirstIndex = desc.m_nOffset / IndexSize(); + + m_nIndicesLocked = nMaxIndexCount; + m_bIsLocked = true; + return true; + } + + + +indexBufferLockFailed: + g_ShaderMutex.Unlock(); + + // Set up a bogus index descriptor + desc.m_pIndices = (unsigned short *)( &s_nScratchIndexBuffer ); + desc.m_nFirstIndex = 0; + desc.m_nIndexSize = 0; + desc.m_nOffset = 0; + return false; +} + + +//----------------------------------------------------------------------------- +// Locks, unlocks the mesh +//----------------------------------------------------------------------------- +bool CIndexBufferDx11::Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t &desc ) +{ + return LockEx( 0, nMaxIndexCount, desc ); +} + +void CIndexBufferDx11::Unlock( int nWrittenIndexCount, IndexDesc_t& desc ) +{ + //Log( "Unlocking index buffer %p\n", m_pIndexBuffer ); + Assert( nWrittenIndexCount <= m_nIndexCount ); + + //Log( "Wrote %i indices\n", nWrittenIndexCount ); + + // NOTE: This can happen if the lock occurs during alt-tab + // or if another application is initializing + if ( !m_bIsLocked ) + return; + + //Spew( nWrittenIndexCount, desc ); + if ( m_pIndexBuffer ) + { + if ( m_bIsDynamic ) + { + D3D11DeviceContext()->Unmap( m_pIndexBuffer, 0 ); + m_Position += nWrittenIndexCount * IndexSize(); + } + else + { + // Static vertex buffers + D3D11_BOX box; + box.back = 1; + box.front = 0; + box.bottom = 1; + box.top = 0; + box.left = m_Position; + box.right = box.left + ( m_nIndicesLocked * IndexSize() ); + D3D11DeviceContext()->UpdateSubresource( m_pIndexBuffer, 0, &box, m_pIndexMemory + m_Position, 0, 0 ); + m_Position += m_nIndicesLocked * IndexSize(); + } + } + + + +#ifdef _DEBUG + m_LockedStartIndex = 0; + m_LockedNumIndices = 0; +#endif + + //Log( "Unlock index buffer: just wrote %i indices\n", nWrittenIndexCount ); + + + m_bIsLocked = false; + g_ShaderMutex.Unlock(); +} + + +//----------------------------------------------------------------------------- +// Locks, unlocks an existing mesh +//----------------------------------------------------------------------------- +void CIndexBufferDx11::ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ) +{ + Assert( 0 ); +} + +void CIndexBufferDx11::ModifyEnd( IndexDesc_t& desc ) +{ + +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/IndexBufferDx11.h b/materialsystem/shaderapidx11/IndexBufferDx11.h new file mode 100644 index 0000000..0d857c5 --- /dev/null +++ b/materialsystem/shaderapidx11/IndexBufferDx11.h @@ -0,0 +1,119 @@ +#pragma once + +#include "shaderapidx9/meshbase.h" +#include "shaderapi/ishaderdevice.h" + +#include "Dx11Global.h" + +//----------------------------------------------------------------------------- +// Forward declaration +//----------------------------------------------------------------------------- +struct ID3D11Buffer; + +//----------------------------------------------------------------------------- +// Dx11 implementation of an index buffer +//----------------------------------------------------------------------------- +class CIndexBufferDx11 : public CIndexBufferBase +{ + typedef CIndexBufferBase BaseClass; + + // Methods of IIndexBuffer +public: + virtual int IndexCount() const; + virtual MaterialIndexFormat_t IndexFormat() const; + virtual int GetRoomRemaining() const; + virtual bool Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t& desc ); + virtual bool LockEx( int nFirstIndex, int nMaxIndex, IndexDesc_t &desc ); + virtual void Unlock( int nWrittenIndexCount, IndexDesc_t& desc ); + virtual void ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ); + virtual void ModifyEnd( IndexDesc_t& desc ); + virtual bool IsDynamic() const; + virtual void BeginCastBuffer( MaterialIndexFormat_t format ); + virtual void EndCastBuffer(); + bool HasEnoughRoom( int nVertCount ) const; + +#ifdef _DEBUG + void UpdateShadowIndices( unsigned short *pData ) + { + Assert( m_LockedStartIndex + m_LockedNumIndices <= m_NumIndices ); + memcpy( m_pShadowIndices + m_LockedStartIndex, pData, m_LockedNumIndices * IndexSize() ); + } + + unsigned short GetShadowIndex( int i ) + { + Assert( i >= 0 && i < (int)m_NumIndices ); + return m_pShadowIndices[i]; + } +#endif + + int IndexPosition() const + { + return m_Position; + } + + // Other public methods +public: + // constructor, destructor + CIndexBufferDx11( ShaderBufferType_t type, MaterialIndexFormat_t fmt, int nIndexCount, const char* pBudgetGroupName ); + virtual ~CIndexBufferDx11(); + + ID3D11Buffer* GetDx11Buffer() const; + MaterialIndexFormat_t GetIndexFormat() const; + + // Only used by dynamic buffers, indicates the next lock should perform a discard. + void Flush(); + + // Returns the size of the index in bytes + int IndexSize() const; + + int SizeForIndex( MaterialIndexFormat_t fmt ) const; + +protected: + // Creates, destroys the index buffer + bool Allocate(); + void Free(); + +#ifdef _DEBUG + unsigned short *m_pShadowIndices; + unsigned int m_NumIndices; + unsigned int m_LockedStartIndex; + unsigned int m_LockedNumIndices; +#endif + + // Used for static buffers to keep track of the memory + // and not throw it away when a section needs modification. + unsigned char *m_pIndexMemory; + int m_nIndicesLocked; + + ID3D11Buffer* m_pIndexBuffer; + MaterialIndexFormat_t m_IndexFormat; + int m_nIndexSize; + int m_nIndexCount; + int m_nBufferSize; + int m_Position; // Used only for dynamic buffers, indicates where it's safe to write (nooverwrite) + bool m_bIsLocked : 1; + bool m_bIsDynamic : 1; + bool m_bFlush : 1; // Used only for dynamic buffers, indicates to discard the next time + +#ifdef _DEBUG + static int s_nBufferCount; +#endif +}; + +//----------------------------------------------------------------------------- +// Returns the size of the index in bytes +//----------------------------------------------------------------------------- +inline int CIndexBufferDx11::IndexSize() const +{ + return m_nIndexSize; +} + +inline ID3D11Buffer* CIndexBufferDx11::GetDx11Buffer() const +{ + return m_pIndexBuffer; +} + +inline MaterialIndexFormat_t CIndexBufferDx11::GetIndexFormat() const +{ + return m_IndexFormat; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/ShaderConstantBufferDx11.cpp b/materialsystem/shaderapidx11/ShaderConstantBufferDx11.cpp new file mode 100644 index 0000000..b673720 --- /dev/null +++ b/materialsystem/shaderapidx11/ShaderConstantBufferDx11.cpp @@ -0,0 +1,106 @@ +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "ShaderConstantBufferDx11.h" +#include "Dx11Global.h" +#include "FastMemcpy.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +static FORCEINLINE void *memcpy_SSE_V2( void *pdst, const void *psrc, size_t size ) +{ + const char *dst = (const char *)pdst; + const char *src = (const char *)psrc; + + _mm_prefetch( src, _MM_HINT_NTA ); + + for ( ; size >= 16; size -= 16 ) + { + __m128i w0, w1, w2, w3, w4, w5, w6, w7; + w0 = _mm_load_si128( ( ( const __m128i * )src ) + 0 ); + w1 = _mm_load_si128( ( ( const __m128i * )src ) + 1 ); + w2 = _mm_load_si128( ( ( const __m128i * )src ) + 2 ); + w3 = _mm_load_si128( ( ( const __m128i * )src ) + 3 ); + w4 = _mm_load_si128( ( ( const __m128i * )src ) + 4 ); + w5 = _mm_load_si128( ( ( const __m128i * )src ) + 5 ); + w6 = _mm_load_si128( ( ( const __m128i * )src ) + 6 ); + w7 = _mm_load_si128( ( ( const __m128i * )src ) + 7 ); + _mm_prefetch( ( src + 128 ), _MM_HINT_NTA ); + src += 16; + _mm_stream_si128( ( ( ( __m128i * )dst ) + 0 ), w0 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 1 ), w1 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 2 ), w2 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 3 ), w3 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 4 ), w4 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 5 ), w5 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 6 ), w6 ); + _mm_stream_si128( ( ( ( __m128i * )dst ) + 7 ), w7 ); + dst += 16; + } + + return pdst; +} + +CShaderConstantBufferDx11::CShaderConstantBufferDx11() : + m_pCBuffer( NULL ), + m_nBufSize( 0 ), + m_bNeedsUpdate( false ), + m_bDynamic( false ), + m_pData( NULL ), + m_bLocked( false ) +{ +} + +void CShaderConstantBufferDx11::Create( size_t nBufferSize, bool bDynamic ) +{ + m_nBufSize = nBufferSize; + m_bDynamic = bDynamic; + + //Log( "Creating constant buffer of size %u\n", nBufferSize ); + + D3D11_BUFFER_DESC cbDesc; + cbDesc.ByteWidth = m_nBufSize; + cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + cbDesc.MiscFlags = 0; + cbDesc.StructureByteStride = 0; + if ( bDynamic ) + { + cbDesc.Usage = D3D11_USAGE_DYNAMIC; + cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + } + else + { + cbDesc.Usage = D3D11_USAGE_DEFAULT; + cbDesc.CPUAccessFlags = 0; + } + + // Fill the buffer with all zeros + m_pData = _aligned_malloc( nBufferSize, 16 ); + ZeroMemory( m_pData, nBufferSize ); + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = m_pData; + initialData.SysMemPitch = 0; + initialData.SysMemSlicePitch = 0; + + //Log( "Creating D3D constant buffer: size: %i\n", m_nBufSize ); + + HRESULT hr = D3D11Device()->CreateBuffer( &cbDesc, &initialData, &m_pCBuffer ); + if ( FAILED( hr ) ) + { + Warning( "Could not set constant buffer!" ); + //return NULL; + } +} + +void CShaderConstantBufferDx11::Destroy() +{ + if ( m_pCBuffer ) + m_pCBuffer->Release(); + + m_pCBuffer = NULL; + + if ( m_pData ) + _aligned_free( m_pData ); + m_pData = NULL; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/ShaderConstantBufferDx11.h b/materialsystem/shaderapidx11/ShaderConstantBufferDx11.h new file mode 100644 index 0000000..db2e109 --- /dev/null +++ b/materialsystem/shaderapidx11/ShaderConstantBufferDx11.h @@ -0,0 +1,138 @@ +#pragma once + +#include "shaderapi/ishaderconstantbuffer.h" +#include "../shaderapidx9/locald3dtypes.h" +#include "Dx11Global.h" +#include "tier0/vprof.h" + +class CShaderConstantBufferDx11 : public IShaderConstantBuffer +{ +public: + CShaderConstantBufferDx11(); + virtual void Create( size_t nBufferSize, bool bDynamic = true ); + virtual void Update( void *pNewData ); + virtual void Destroy(); + virtual bool NeedsUpdate() const; + virtual void UploadToGPU(); + virtual ConstantBufferHandle_t GetBuffer() const; + + void *GetData(); + + void *Lock(); + void Unlock(); + + void ForceUpdate(); + + ID3D11Buffer *GetD3DBuffer() const; + +private: + ID3D11Buffer* m_pCBuffer; + size_t m_nBufSize; + bool m_bNeedsUpdate; + bool m_bDynamic; + bool m_bLocked; + void *m_pData; +}; + +FORCEINLINE ID3D11Buffer *CShaderConstantBufferDx11::GetD3DBuffer() const +{ + return m_pCBuffer; +} + +FORCEINLINE bool CShaderConstantBufferDx11::NeedsUpdate() const +{ + return m_bNeedsUpdate; +} + +FORCEINLINE ConstantBufferHandle_t CShaderConstantBufferDx11::GetBuffer() const +{ + return (ConstantBufferHandle_t)m_pCBuffer; +} + +FORCEINLINE void *CShaderConstantBufferDx11::GetData() +{ + return m_pData; +} + +FORCEINLINE void CShaderConstantBufferDx11::ForceUpdate() +{ + m_bNeedsUpdate = true; + UploadToGPU(); +} + +FORCEINLINE void CShaderConstantBufferDx11::Update( void *pNewData ) +{ + if ( !pNewData ) + return; + + // If this new data is not the same as the data + // the GPU currently has, we need to update. + if ( memcmp( m_pData, pNewData, m_nBufSize ) ) + { + memcpy( m_pData, pNewData, m_nBufSize ); + m_bNeedsUpdate = true; + + UploadToGPU(); + } + +} + +FORCEINLINE void *CShaderConstantBufferDx11::Lock() +{ + if ( !m_bDynamic || m_bLocked || !m_pCBuffer ) + { + return NULL; + } + + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = D3D11DeviceContext()->Map( m_pCBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); + if ( FAILED( hr ) ) + { + return NULL; + } + + m_bLocked = true; + + return mapped.pData; +} + +FORCEINLINE void CShaderConstantBufferDx11::Unlock() +{ + if ( !m_bDynamic || !m_bLocked || !m_pCBuffer ) + { + return; + } + + m_bLocked = false; + + D3D11DeviceContext()->Unmap( m_pCBuffer, 0 ); +} + +FORCEINLINE void CShaderConstantBufferDx11::UploadToGPU() +{ + VPROF_BUDGET( "CShaderConstantBufferDx11::UploadToGPU()", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + if ( !m_pCBuffer || !m_bNeedsUpdate ) + return; + + if ( m_bDynamic ) + { + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = D3D11DeviceContext()->Map( m_pCBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); + if ( FAILED( hr ) ) + { + return; + } + //{ + //VPROF_BUDGET( "CShaderConstantBufferDx11::memcpy_SSE", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + memcpy( mapped.pData, m_pData, m_nBufSize ); + //} + D3D11DeviceContext()->Unmap( m_pCBuffer, 0 ); + } + else + { + D3D11DeviceContext()->UpdateSubresource( m_pCBuffer, 0, 0, m_pData, 0, 0 ); + } + + m_bNeedsUpdate = false; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/ShaderShadowDx11.h b/materialsystem/shaderapidx11/ShaderShadowDx11.h new file mode 100644 index 0000000..2b320ff --- /dev/null +++ b/materialsystem/shaderapidx11/ShaderShadowDx11.h @@ -0,0 +1,172 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef SHADERSHADOWDX11_H +#define SHADERSHADOWDX11_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderapi/ishadershadow.h" +#include "../shaderapidx9/locald3dtypes.h" +#include "shaderapidx11.h" +#include "StatesDx11.h" + +#define DEFAULT_SHADOW_STATE_ID -1 + +//----------------------------------------------------------------------------- +// The empty shader shadow +//----------------------------------------------------------------------------- +class CShaderShadowDx11 : public IShaderShadowDX11 +{ +public: + CShaderShadowDx11(); + virtual ~CShaderShadowDx11(); + + // Sets the default *shadow* state + void SetDefaultState(); + + // Methods related to depth buffering + void DepthFunc( ShaderDepthFunc_t depthFunc ); + void EnableDepthWrites( bool bEnable ); + void EnableDepthTest( bool bEnable ); + void EnablePolyOffset( PolygonOffsetMode_t nOffsetMode ); + + // Suppresses/activates color writing + void EnableColorWrites( bool bEnable ); + void EnableAlphaWrites( bool bEnable ); + + // Methods related to alpha blending + void EnableBlending( bool bEnable ); + void BlendFunc( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor ); + + // Alpha testing + void EnableAlphaTest( bool bEnable ); + void AlphaFunc( ShaderAlphaFunc_t alphaFunc, float alphaRef /* [0-1] */ ); + + // Wireframe/filled polygons + void PolyMode( ShaderPolyModeFace_t face, ShaderPolyMode_t polyMode ); + + // Back face culling + void EnableCulling( bool bEnable ); + + // constant color + transparency + void EnableConstantColor( bool bEnable ); + + // Indicates the vertex format for use with a vertex shader + // The flags to pass in here come from the VertexFormatFlags_t enum + // If pTexCoordDimensions is *not* specified, we assume all coordinates + // are 2-dimensional + void VertexShaderVertexFormat( unsigned int flags, + int numTexCoords, int* pTexCoordDimensions, + int userDataSize ); + + // Indicates we're going to light the model + void EnableLighting( bool bEnable ); + + // vertex blending + void EnableVertexBlend( bool bEnable ); + + // per texture unit stuff + void EnableTexture( Sampler_t stage, bool bEnable ); + + // GR - Separate alpha blending + void EnableBlendingSeparateAlpha( bool bEnable ); + void BlendFuncSeparateAlpha( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor ); + + // Sets the vertex and pixel shaders + void SetVertexShader( const char *pFileName, ShaderIndex_t vshIndex ); + void SetPixelShader( const char *pFileName, ShaderIndex_t pshIndex ); + + virtual void SetMorphFormat( MorphFormat_t flags ); + + virtual void EnableStencil( bool bEnable ); + virtual void StencilFunc( ShaderStencilFunc_t stencilFunc ); + virtual void StencilPassOp( ShaderStencilOp_t stencilOp ); + virtual void StencilFailOp( ShaderStencilOp_t stencilOp ); + virtual void StencilDepthFailOp( ShaderStencilOp_t stencilOp ); + virtual void StencilReference( int nReference ); + virtual void StencilMask( int nMask ); + virtual void StencilWriteMask( int nMask ); + + StateSnapshot_t FindOrCreateSnapshot(); + const StatesDx11::ShadowState *GetShadowState( StateSnapshot_t id ); + const StatesDx11::ShadowState *GetDefaultShadowState(); + + // Constant buffer enabling + virtual void SetVertexShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer ); + virtual void SetVertexShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer ); + virtual void SetGeometryShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer ); + virtual void SetGeometryShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer ); + virtual void SetPixelShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer ); + virtual void SetPixelShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer ); + + virtual void FogMode( ShaderFogMode_t fogMode ); + + // --------------------------------------------------- + // Below are unsupported by Dx11, only included to + // not break Dx9 compatibility. + // --------------------------------------------------- + + // Convert from linear to gamma color space on writes to frame buffer. + void EnableSRGBWrite( bool bEnable ); + void EnableSRGBRead( Sampler_t stage, bool bEnable ); + virtual void SetDiffuseMaterialSource( ShaderMaterialSource_t materialSource ); + void EnableTexGen( TextureStage_t stage, bool bEnable ); + void TexGen( TextureStage_t stage, ShaderTexGenParam_t param ); + // alternate method of specifying per-texture unit stuff, more flexible and more complicated + // Can be used to specify different operation per channel (alpha/color)... + void EnableCustomPixelPipe( bool bEnable ); + void CustomTextureStages( int stageCount ); + void CustomTextureOperation( TextureStage_t stage, ShaderTexChannel_t channel, + ShaderTexOp_t op, ShaderTexArg_t arg1, ShaderTexArg_t arg2 ); + void EnableTextureAlpha( TextureStage_t stage, bool bEnable ); + void EnableSpecular( bool bEnable ); + // A simpler method of dealing with alpha modulation + void EnableAlphaPipe( bool bEnable ); + void EnableConstantAlpha( bool bEnable ); + void EnableVertexAlpha( bool bEnable ); + // Alpha to coverage + void EnableAlphaToCoverage( bool bEnable ); + void SetShadowDepthFiltering( Sampler_t stage ); + void OverbrightValue( TextureStage_t stage, float value ); + virtual void DisableFogGammaCorrection( bool bDisable ); + // indicates what per-vertex data we're providing + void DrawFlags( unsigned int drawFlags ); + + // More alpha blending state + virtual void BlendOp(ShaderBlendOp_t blendOp); + virtual void BlendOpSeparateAlpha(ShaderBlendOp_t blendOp); + +private: + unsigned int FindOrCreateConstantBufferState( StatesDx11::ConstantBufferDesc &desc ); + unsigned int FindOrCreateDepthStencilState( StatesDx11::DepthStencilDesc &desc ); + unsigned int FindOrCreateBlendState( StatesDx11::BlendDesc &desc ); + unsigned int FindOrCreateRasterState( StatesDx11::RasterDesc &desc ); + +public: + StatesDx11::ShadowStateDesc m_ShadowState; + + CUtlVector m_ConstantBufferStates; + CUtlVector m_DepthStencilStates; + CUtlVector m_BlendStates; + CUtlVector m_RasterizerStates; + // Can have max value of StateSnapshot_t shadow states. + CUtlVector m_ShadowStates; + + StatesDx11::ShadowState m_DefaultShadowState; + StatesDx11::ConstantBufferDesc m_DefaultCBState; + StatesDx11::DepthStencilDesc m_DefaultDepthStencilState; + StatesDx11::BlendDesc m_DefaultBlendState; + StatesDx11::RasterDesc m_DefaultRasterState; +}; + +extern CShaderShadowDx11* g_pShaderShadowDx11; + +#endif // SHADERSHADOWDX11_H \ No newline at end of file diff --git a/materialsystem/shaderapidx11/StatesDx11.h b/materialsystem/shaderapidx11/StatesDx11.h new file mode 100644 index 0000000..e44c294 --- /dev/null +++ b/materialsystem/shaderapidx11/StatesDx11.h @@ -0,0 +1,531 @@ +#pragma once + +#include "shaderapi/ishaderdevice.h" +#include "shaderapi/ishadershadow.h" +#include "shaderapi/ishaderapi.h" +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/imorph.h" +#include + +#include + +#include "Dx11Global.h" + +class CShaderConstantBufferDx11; +class CTextureDx11; + +//----------------------------------------------------------------------------- +// DX11 enumerations that don't appear to exist +//----------------------------------------------------------------------------- +#define MAX_DX11_VIEWPORTS 16 +#define MAX_DX11_STREAMS 16 +#define MAX_DX11_CBUFFERS 15 +#define MAX_DX11_SAMPLERS 16 + +FORCEINLINE static D3D11_BLEND TranslateD3D11BlendFunc( ShaderBlendFactor_t blend ) +{ + switch ( blend ) + { + case SHADER_BLEND_ZERO: + return D3D11_BLEND_ZERO; + + case SHADER_BLEND_ONE: + return D3D11_BLEND_ONE; + + case SHADER_BLEND_DST_COLOR: + return D3D11_BLEND_DEST_COLOR; + + case SHADER_BLEND_ONE_MINUS_DST_COLOR: + return D3D11_BLEND_INV_DEST_COLOR; + + case SHADER_BLEND_SRC_ALPHA: + return D3D11_BLEND_SRC_ALPHA; + + case SHADER_BLEND_ONE_MINUS_SRC_ALPHA: + return D3D11_BLEND_INV_SRC_ALPHA; + + case SHADER_BLEND_DST_ALPHA: + return D3D11_BLEND_DEST_ALPHA; + + case SHADER_BLEND_ONE_MINUS_DST_ALPHA: + return D3D11_BLEND_INV_DEST_ALPHA; + + case SHADER_BLEND_SRC_COLOR: + return D3D11_BLEND_SRC_COLOR; + + case SHADER_BLEND_ONE_MINUS_SRC_COLOR: + return D3D11_BLEND_INV_SRC_COLOR; + + default: + // Impossible + return D3D11_BLEND_ZERO; + } +} + +enum DX11StateChangeFlags_t +{ + STATE_CHANGED_NONE = 0, + STATE_CHANGED_SAMPLERS = 1 << 0, + STATE_CHANGED_VERTEXSAMPLERS = 1 << 1, + STATE_CHANGED_VIEWPORTS = 1 << 2, + STATE_CHANGED_VERTEXBUFFER = 1 << 3, + STATE_CHANGED_INPUTLAYOUT = 1 << 4, + STATE_CHANGED_INDEXBUFFER = 1 << 5, + STATE_CHANGED_RENDERTARGET = 1 << 6, + STATE_CHANGED_DEPTHBUFFER = 1 << 7, + STATE_CHANGED_VERTEXSHADER = 1 << 8, + STATE_CHANGED_GEOMETRYSHADER = 1 << 9, + STATE_CHANGED_PIXELSHADER = 1 << 10, + STATE_CHANGED_TOPOLOGY = 1 << 11, + STATE_CHANGED_RASTERIZER = 1 << 12, + STATE_CHANGED_BLEND = 1 << 13, + STATE_CHANGED_DEPTHSTENCIL = 1 << 14, + STATE_CHANGED_VSCONSTANTBUFFERS = 1 << 15, + STATE_CHANGED_GSCONSTANTBUFFERS = 1 << 16, + STATE_CHANGED_PSCONSTANTBUFFERS = 1 << 17, + STATE_CHANGED_TEXTURES = 1 << 18, + STATE_CHANGED_VERTEXTEXTURES = 1 << 19, +}; + +namespace StatesDx11 +{ + // These states below describe the D3D pipeline state. + + // + // Things that are set once on SHADOW_STATE and don't + // change per-mesh or per-frame (in DYNAMIC_STATE) + // + + struct DepthStencilDesc : public D3D11_DEPTH_STENCIL_DESC + { + int StencilRef; + + ID3D11DepthStencilState *m_pD3DState; + + void SetDefault() + { + DepthEnable = TRUE; + DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D11_COMPARISON_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + const D3D11_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + + StencilRef = 0; + m_pD3DState = NULL; + } + + bool operator==( const DepthStencilDesc &other ) const + { + return memcmp( this, &other, sizeof( DepthStencilDesc ) - sizeof( m_pD3DState ) ) == 0; + } + }; + + struct BlendDesc : public D3D11_BLEND_DESC + { + float BlendColor[4]; + uint SampleMask; + + ID3D11BlendState *m_pD3DState; + + bool BlendEnabled() const + { + return (bool)RenderTarget[0].BlendEnable; + } + + void SetDefault() + { + m_pD3DState = NULL; + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D11_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE, + D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, + D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, + D3D11_COLOR_WRITE_ENABLE_ALL, + }; + for ( UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i ) + RenderTarget[i] = defaultRenderTargetBlendDesc; + + BlendColor[0] = BlendColor[1] = BlendColor[2] = BlendColor[3] = 1.0f; + SampleMask = 1; + } + + bool operator==( const BlendDesc &other ) const + { + return memcmp( this, &other, sizeof( BlendDesc ) - sizeof( m_pD3DState ) ) == 0; + } + }; + + struct RasterDesc : public D3D11_RASTERIZER_DESC + { + ID3D11RasterizerState *m_pD3DState; + + void SetDefault() + { + m_pD3DState = NULL; + FillMode = D3D11_FILL_SOLID; + CullMode = D3D11_CULL_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + ScissorEnable = FALSE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + } + + bool operator==( const RasterDesc &other ) const + { + return memcmp( this, &other, sizeof( RasterDesc ) - sizeof( m_pD3DState ) ) == 0; + } + }; + + struct ConstantBufferDesc + { + int m_MaxSlot; + ID3D11Buffer *m_ppBuffers[MAX_DX11_CBUFFERS]; + + bool operator==( const ConstantBufferDesc &other ) const + { + if ( m_MaxSlot != other.m_MaxSlot ) + { + return false; + } + + return memcmp( m_ppBuffers, other.m_ppBuffers, sizeof( m_ppBuffers ) ) == 0; + } + + void SetDefault() + { + m_MaxSlot = -1; + memset( m_ppBuffers, 0, sizeof( m_ppBuffers ) ); + } + }; + + struct ShadowStateDesc + { + BlendDesc blend; + DepthStencilDesc depthStencil; + RasterDesc rasterizer; + + ConstantBufferDesc vsConstantBuffers; + ConstantBufferDesc gsConstantBuffers; + ConstantBufferDesc psConstantBuffers; + + VertexShader_t vertexShader; + int staticVertexShaderIndex; + PixelShader_t pixelShader; + int staticPixelShaderIndex; + GeometryShader_t geometryShader; + int staticGeometryShaderIndex; + + // Vertex data used by this snapshot + // Note that the vertex format actually used will be the + // aggregate of the vertex formats used by all snapshots in a material + VertexFormat_t vertexFormat; + + // Morph data used by this snapshot + // Note that the morph format actually used will be the + // aggregate of the morph formats used by all snapshots in a material + MorphFormat_t morphFormat; + + // Set this to something other than SHADER_FOGMODE_DISABLED + // to override the scene fog color + ShaderFogMode_t fogMode; + bool disableFogGammaCorrection; + + bool Equals( const ShadowStateDesc &other ) const + { + if ( vertexShader != other.vertexShader || + staticVertexShaderIndex != other.staticVertexShaderIndex || + pixelShader != other.pixelShader || + staticPixelShaderIndex != other.staticPixelShaderIndex || + geometryShader != other.geometryShader || + staticGeometryShaderIndex != other.staticGeometryShaderIndex || + vertexFormat != other.vertexFormat || + morphFormat != other.morphFormat || + fogMode != other.fogMode || + disableFogGammaCorrection != other.disableFogGammaCorrection ) + { + return false; + } + + return ( blend == other.blend && + depthStencil == other.depthStencil && + rasterizer == other.rasterizer && + vsConstantBuffers == other.vsConstantBuffers && + gsConstantBuffers == other.gsConstantBuffers && + psConstantBuffers == other.psConstantBuffers ); + } + + // Sets the default shadow state + void SetDefault() + { + vsConstantBuffers.SetDefault(); + gsConstantBuffers.SetDefault(); + psConstantBuffers.SetDefault(); + + depthStencil.SetDefault(); + rasterizer.SetDefault(); + blend.SetDefault(); + + vertexShader = -1; + staticVertexShaderIndex = 0; + pixelShader = -1; + staticPixelShaderIndex = 0; + geometryShader = -1; + staticGeometryShaderIndex = 0; + + vertexFormat = VERTEX_FORMAT_UNKNOWN; + morphFormat = 0; + + fogMode = SHADER_FOGMODE_FOGCOLOR; + } + + ShadowStateDesc() + { + SetDefault(); + } + }; + + struct ShadowState + { + ShadowStateDesc desc; + + unsigned int m_iVSConstantBufferState; + unsigned int m_iPSConstantBufferState; + unsigned int m_iGSConstantBufferState; + + unsigned int m_iBlendState; + unsigned int m_iDepthStencilState; + unsigned int m_iRasterState; + + bool operator==( const ShadowState &other ) const + { + return desc.Equals( other.desc ); + } + + ShadowState() + { + m_iBlendState = 0; + m_iDepthStencilState = 0; + m_iRasterState = 0; + m_iVSConstantBufferState = 0; + m_iPSConstantBufferState = 0; + m_iGSConstantBufferState = 0; + } + }; + + // + // Things that can change per-mesh or per-frame (in DYNAMIC_STATE) + // + + struct IndexBufferState + { + ID3D11Buffer *m_pBuffer; + DXGI_FORMAT m_Format; + UINT m_nOffset; + + bool operator!=( const IndexBufferState &src ) const + { + return memcmp( this, &src, sizeof( IndexBufferState ) ) != 0; + } + }; + + struct InputLayoutState + { + VertexShaderHandle_t m_hVertexShader; + VertexFormat_t m_pVertexDecl[MAX_DX11_STREAMS]; + bool m_bStaticLit; + bool m_bUsingFlex; + bool m_bUsingMorph; + }; + + struct RenderTargetState + { + ShaderAPITextureHandle_t m_RenderTarget; + ShaderAPITextureHandle_t m_DepthTarget; + }; + + struct DynamicState + { + int m_nViewportCount; + D3D11_VIEWPORT m_pViewports[MAX_DX11_VIEWPORTS]; + + FLOAT m_ClearColor[4]; + + InputLayoutState m_InputLayout; + IndexBufferState m_IndexBuffer; + + int m_MaxVertexBuffer; + int m_PrevMaxVertexBuffer; + ID3D11Buffer *m_pVertexBuffer[MAX_DX11_STREAMS]; + UINT m_pVBStrides[MAX_DX11_STREAMS]; + UINT m_pVBOffsets[MAX_DX11_STREAMS]; + + D3D11_PRIMITIVE_TOPOLOGY m_Topology; + + ID3D11VertexShader *m_pVertexShader; + ID3D11GeometryShader *m_pGeometryShader; + ID3D11PixelShader *m_pPixelShader; + + ID3D11RenderTargetView *m_pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + ID3D11DepthStencilView *m_pDepthStencilView; + + int m_MaxVSSampler; + int m_MaxPSSampler; + int m_PrevMaxVSSampler; + int m_PrevMaxPSSampler; + ID3D11ShaderResourceView *m_ppVertexTextures[MAX_DX11_SAMPLERS]; + ID3D11SamplerState *m_ppVertexSamplers[MAX_DX11_SAMPLERS]; + ID3D11ShaderResourceView *m_ppTextures[MAX_DX11_SAMPLERS]; + ID3D11SamplerState *m_ppSamplers[MAX_DX11_SAMPLERS]; + + void Reset() + { + ZeroMemory( this, sizeof( DynamicState ) ); + // We always need viewports + m_nViewportCount = 1; + m_pViewports[0].Width = 640; + m_pViewports[0].Height = 480; + m_pViewports[0].MinDepth = 0; + m_pViewports[0].MaxDepth = 1; + m_MaxPSSampler = -1; + m_MaxVSSampler = -1; + m_PrevMaxPSSampler = -1; + m_PrevMaxVSSampler = -1; + m_MaxVertexBuffer = -1; + m_PrevMaxVertexBuffer = -1; + m_Topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + } + + DynamicState() + { + Reset(); + } + }; + + // These states describe the dynamic shader state. + // (the state of constants that we provide to shaders) + + struct MatrixItem_t + { + DirectX::XMMATRIX m_Matrix; + int m_Flags; + }; + + struct FogState + { + MaterialFogMode_t m_FogMode; + float m_flFogStart; + float m_flFogEnd; + float m_flFogZ; + float m_flFogMaxDensity; + float m_FogColor[3]; + + bool m_bFogChanged; + }; + + struct LightState + { + LightDesc_t m_Lights[MAX_NUM_LIGHTS]; + LightType_t m_LightType[MAX_NUM_LIGHTS]; + int m_NumLights; + bool m_bLightChanged; + + VectorAligned m_AmbientLightCube[6]; + bool m_bAmbientChanged; + }; + + struct BoneState + { + DirectX::XMFLOAT3X4A m_BoneMatrix[NUM_MODEL_TRANSFORMS]; + int m_MaxBoneLoaded; + int m_NumBones; + + bool m_bBonesChanged; + }; + + struct MorphState + { + int m_nFirstWeight; + int m_nCount; + MorphWeight_t m_pWeights[512]; + int m_nMaxWeightLoaded; + + bool m_bMorphChanged; + }; + + // State that is set through constant buffers and used + // by shaders. + struct ShaderState + { + FogState fog; + LightState light; + BoneState bone; + MorphState morph; + + Vector4D m_ToneMappingScale; + bool m_bToneMappingScaleChanged; + + CUtlStack m_MatrixStacks[NUM_MATRIX_MODES]; + bool m_ChangedMatrices[NUM_MATRIX_MODES]; + + void SetDefault() + { + ZeroMemory( this, sizeof( ShaderState ) ); + + m_ToneMappingScale.Init( 1, 1, 1, 1 ); + m_bToneMappingScaleChanged = true; + + fog.m_FogColor[0] = 1.0f; + fog.m_FogColor[1] = 1.0f; + fog.m_FogColor[2] = 1.0f; + fog.m_flFogMaxDensity = -1.0f; + fog.m_flFogZ = 0.0f; + fog.m_flFogEnd = -1; + fog.m_flFogStart = -1; + fog.m_FogMode = MATERIAL_FOG_NONE; + + memset( bone.m_BoneMatrix, 0, sizeof( bone.m_BoneMatrix ) ); + //for ( int i = 0; i < NUM_MODEL_TRANSFORMS; i++ ) + //{ + // bone.m_BoneMatrix[i] = DirectX::XMMatrixIdentity(); + // bone.m_BoneMatrix[i] = DirectX::XMMatrixTranspose( + // bone.m_BoneMatrix[i] + // ); + //} + bone.m_bBonesChanged = true; + + for ( int i = 0; i < MAX_NUM_LIGHTS; i++ ) + { + light.m_Lights[i].m_Type = MATERIAL_LIGHT_DISABLE; + } + light.m_bLightChanged = true; + light.m_bAmbientChanged = true; + + for ( int i = 0; i < NUM_MATRIX_MODES; i++ ) + { + m_MatrixStacks[i].Clear(); + m_MatrixStacks[i].Push(); + m_MatrixStacks[i].Top().m_Matrix = DirectX::XMMatrixIdentity(); + m_MatrixStacks[i].Top().m_Flags = 0;//( MATRIXDX11_DIRTY | MATRIXDX11_IDENTITY ); + m_ChangedMatrices[i] = true; + } + + morph.m_bMorphChanged = true; + } + + ShaderState() + { + SetDefault(); + } + }; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/TextureDx11.cpp b/materialsystem/shaderapidx11/TextureDx11.cpp new file mode 100644 index 0000000..bfbc29f --- /dev/null +++ b/materialsystem/shaderapidx11/TextureDx11.cpp @@ -0,0 +1,1126 @@ +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "TextureDx11.h" +#include "shaderapi/ishaderapi.h" +#include "shaderdevicedx11.h" +#include "shaderapidx11_global.h" +#include "shaderapi/ishaderutil.h" +#include "filesystem.h" +#include "bitmap/tgawriter.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +// Returns a matching ShaderResourceView format for the depth texture's format. +FORCEINLINE DXGI_FORMAT GetDepthSRVFormat( DXGI_FORMAT depthResourceFormat ) +{ + switch ( depthResourceFormat ) + { + case DXGI_FORMAT_R16_TYPELESS: + return DXGI_FORMAT_R16_UNORM; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_R32_FLOAT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + default: + return DXGI_FORMAT_UNKNOWN; + } +} + +// Returns a matching DepthStencilView format for the depth texture's format. +FORCEINLINE DXGI_FORMAT GetDepthStencilViewFormat( DXGI_FORMAT depthResourceFormat ) +{ + switch ( depthResourceFormat ) + { + case DXGI_FORMAT_R16_TYPELESS: + return DXGI_FORMAT_D16_UNORM; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_D32_FLOAT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + default: + return DXGI_FORMAT_UNKNOWN; + } +} + +// We will have to convert srcFormat into what this function +// returns for use in D3D11. +ImageFormat CTextureDx11::GetClosestSupportedImageFormatForD3D11( ImageFormat srcFormat ) +{ + switch ( srcFormat ) + { + case IMAGE_FORMAT_BGR888: + return IMAGE_FORMAT_BGRA8888; + + case IMAGE_FORMAT_RGB888: + return IMAGE_FORMAT_RGBA8888; + default: + return srcFormat; + } +} + +DXGI_FORMAT GetD3DFormat( ImageFormat format ) +{ + switch ( format ) + { + // These are not exact but have the same number + // of channels and bits-per-channel. + case IMAGE_FORMAT_I8: + return DXGI_FORMAT_R8_UNORM; + case IMAGE_FORMAT_IA88: + return DXGI_FORMAT_R8G8_UNORM; + case IMAGE_FORMAT_UV88: + return DXGI_FORMAT_R8G8_UNORM; + case IMAGE_FORMAT_UVWQ8888: + case IMAGE_FORMAT_UVLX8888: + return DXGI_FORMAT_R8G8B8A8_UNORM; + + // Depth buffer formats + case IMAGE_FORMAT_NV_DST24: + return DXGI_FORMAT_R24G8_TYPELESS; + case IMAGE_FORMAT_NV_DST16: + return DXGI_FORMAT_R16_TYPELESS; + + // These ones match D3D. + case IMAGE_FORMAT_A8: + return DXGI_FORMAT_A8_UNORM; + + case IMAGE_FORMAT_DXT1: + case IMAGE_FORMAT_DXT1_ONEBITALPHA: + return DXGI_FORMAT_BC1_UNORM; + //case IMAGE_FORMAT_DXT1_SRGB: + //case IMAGE_FORMAT_DXT1_ONEBITALPHA_SRGB: + return DXGI_FORMAT_BC1_UNORM_SRGB; + + case IMAGE_FORMAT_DXT3: + return DXGI_FORMAT_BC2_UNORM; + //case IMAGE_FORMAT_DXT3_SRGB: + return DXGI_FORMAT_BC2_UNORM_SRGB; + + case IMAGE_FORMAT_DXT5: + return DXGI_FORMAT_BC3_UNORM; + //case IMAGE_FORMAT_DXT5_SRGB: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + case IMAGE_FORMAT_BGRA4444: + return DXGI_FORMAT_B4G4R4A4_UNORM; + case IMAGE_FORMAT_BGRX5551: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case IMAGE_FORMAT_BGR565: + return DXGI_FORMAT_B5G6R5_UNORM; + + case IMAGE_FORMAT_BGRX8888: + return DXGI_FORMAT_B8G8R8X8_UNORM; + //case IMAGE_FORMAT_BGRX8888_SRGB: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + case IMAGE_FORMAT_ARGB8888: // unsupported? + return DXGI_FORMAT_R8G8B8A8_UNORM; + + case IMAGE_FORMAT_BGRA8888: + return DXGI_FORMAT_B8G8R8A8_UNORM; + //case IMAGE_FORMAT_BGRA8888_SRGB: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case IMAGE_FORMAT_RGBA16161616F: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case IMAGE_FORMAT_RGBA16161616: + return DXGI_FORMAT_R16G16B16A16_UNORM; + case IMAGE_FORMAT_R32F: + return DXGI_FORMAT_R32_FLOAT; + case IMAGE_FORMAT_RGBA32323232F: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + + case IMAGE_FORMAT_RGBA8888: + return DXGI_FORMAT_R8G8B8A8_UNORM; + //case IMAGE_FORMAT_RGBA8888_SRGB: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + default: + return DXGI_FORMAT_UNKNOWN; + } +} + +ImageFormat CTextureDx11::GetImageFormat( DXGI_FORMAT d3dFormat ) +{ + switch ( d3dFormat ) + { + case DXGI_FORMAT_UNKNOWN: + return IMAGE_FORMAT_UNKNOWN; + + // These are not exact but have the same number + // of channels and bits-per-channel. + case DXGI_FORMAT_R8_UNORM: + return IMAGE_FORMAT_I8; + case DXGI_FORMAT_R8G8_UNORM: + return IMAGE_FORMAT_IA88; + + case DXGI_FORMAT_R8G8B8A8_UNORM: + return IMAGE_FORMAT_RGBA8888; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + return IMAGE_FORMAT_RGBA8888;// _SRGB; + case DXGI_FORMAT_A8_UNORM: + return IMAGE_FORMAT_A8; + case DXGI_FORMAT_BC1_UNORM: + return IMAGE_FORMAT_DXT1; + case DXGI_FORMAT_BC1_UNORM_SRGB: + return IMAGE_FORMAT_DXT1;// _SRGB; + case DXGI_FORMAT_BC2_UNORM: + return IMAGE_FORMAT_DXT3; + case DXGI_FORMAT_BC2_UNORM_SRGB: + return IMAGE_FORMAT_DXT3;// _SRGB; + case DXGI_FORMAT_BC3_UNORM: + return IMAGE_FORMAT_DXT5; + case DXGI_FORMAT_BC3_UNORM_SRGB: + return IMAGE_FORMAT_DXT5;// _SRGB; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return IMAGE_FORMAT_BGRA4444; + case DXGI_FORMAT_B5G6R5_UNORM: + return IMAGE_FORMAT_BGR565; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return IMAGE_FORMAT_BGRX8888; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return IMAGE_FORMAT_BGRX8888;// _SRGB; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return IMAGE_FORMAT_BGRA8888; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + return IMAGE_FORMAT_BGRA8888;// _SRGB; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return IMAGE_FORMAT_RGBA16161616F; + case DXGI_FORMAT_R16G16B16A16_UNORM: + return IMAGE_FORMAT_RGBA16161616; + case DXGI_FORMAT_R32_FLOAT: + return IMAGE_FORMAT_R32F; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return IMAGE_FORMAT_RGBA32323232F; + + default: + return IMAGE_FORMAT_UNKNOWN; + } +} + +int CTextureDx11::CalcRamBytes() const +{ + int rWidth = m_nWidth; + int rHeight = m_nHeight; + int rDepth = m_Depth; + int nRamBytes = 0; + for ( int i = 0; i < m_NumLevels; i++ ) + { + nRamBytes += ImageLoader::GetMemRequired( rWidth, rHeight, rDepth, m_Format, false ); + if ( rWidth == 1 && rHeight == 1 && rDepth == 1 ) + { + break; + } + rDepth >>= 1; + rWidth >>= 1; + rHeight >>= 1; + if ( rWidth < 1 ) + { + rWidth = 1; + } + if ( rHeight < 1 ) + { + rHeight = 1; + } + if ( rDepth < 1 ) + { + rDepth = 1; + } + } + return nRamBytes; +} + +// Texture2D is used for regular 2D textures, cubemaps, and 2D texture arrays +// TODO: Support 1D and 3D textures? +ID3D11Resource *CTextureDx11::CreateD3DTexture( int width, int height, int nDepth, + ImageFormat dstFormat, int numLevels, int nCreationFlags ) +{ + if ( nDepth <= 0 ) + nDepth = 1; + + bool isCubeMap = ( nCreationFlags & TEXTURE_CREATE_CUBEMAP ) != 0; + if ( isCubeMap ) + nDepth = 6; + + bool bIsRenderTarget = ( nCreationFlags & TEXTURE_CREATE_RENDERTARGET ) != 0; + //bool bManaged = ( nCreationFlags & TEXTURE_CREATE_MANAGED ) != 0; + bool bIsDepthBuffer = ( nCreationFlags & TEXTURE_CREATE_DEPTHBUFFER ) != 0; + bool isDynamic = ( nCreationFlags & TEXTURE_CREATE_DYNAMIC ) != 0; + bool bAutoMipMap = ( nCreationFlags & TEXTURE_CREATE_AUTOMIPMAP ) != 0; + //bool bVertexTexture = ( nCreationFlags & TEXTURE_CREATE_VERTEXTEXTURE ) != 0; + //bool bAllowNonFilterable = ( nCreationFlags & TEXTURE_CREATE_UNFILTERABLE_OK ) != 0; + //bool bVolumeTexture = ( nDepth > 1 ); + //bool bIsFallback = ( nCreationFlags & TEXTURE_CREATE_FALLBACK ) != 0; + //bool bNoD3DBits = ( nCreationFlags & TEXTURE_CREATE_NOD3DMEMORY ) != 0; + + // NOTE: This function shouldn't be used for creating depth buffers! + //Assert( !bIsDepthBuffer ); + + dstFormat = GetClosestSupportedImageFormatForD3D11( dstFormat ); + m_Format = dstFormat; + DXGI_FORMAT d3dFormat = DXGI_FORMAT_UNKNOWN; + d3dFormat = GetD3DFormat( dstFormat ); + + if ( d3dFormat == DXGI_FORMAT_UNKNOWN ) + { + Warning( "ShaderAPIDX11::CreateD3DTexture: Invalid image format %i!\n", (int)dstFormat ); + Assert( 0 ); + return 0; + } + + m_D3DFormat = d3dFormat; + + D3D11_USAGE usage = D3D11_USAGE_DEFAULT; + if ( isDynamic ) + { + usage = D3D11_USAGE_DYNAMIC; + } + + UINT miscFlags = 0; + if ( bAutoMipMap ) + { + miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; + } + if ( isCubeMap ) + { + miscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; + } + + UINT bindFlags = D3D11_BIND_SHADER_RESOURCE; + if ( bIsRenderTarget ) + { + bindFlags |= D3D11_BIND_RENDER_TARGET; + } + if ( bIsDepthBuffer ) + { + bindFlags |= D3D11_BIND_DEPTH_STENCIL; + } + + UINT cpuAccessFlags = 0; + if ( isDynamic ) + { + cpuAccessFlags = D3D11_CPU_ACCESS_WRITE; + } + + ID3D11Resource *pBaseTexture = NULL; + HRESULT hr = S_OK; + + // TODO: Support 1D and 3D textures + // (2D textures are good for regular textures, cubemaps, and texture arrays) + D3D11_TEXTURE2D_DESC desc; + ZeroMemory( &desc, sizeof( D3D11_TEXTURE2D_DESC ) ); + desc.ArraySize = nDepth; + desc.Format = d3dFormat; + desc.Width = width; + desc.Height = height; + desc.MipLevels = numLevels; + desc.MiscFlags = miscFlags; + desc.BindFlags = bindFlags; + desc.CPUAccessFlags = cpuAccessFlags; + desc.Usage = usage; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + ID3D11Texture2D *pTex2D = NULL; + hr = D3D11Device()->CreateTexture2D( &desc, NULL, &pTex2D ); + pBaseTexture = pTex2D; + + if ( FAILED( hr ) ) + { + switch ( hr ) + { + case E_OUTOFMEMORY: + Warning( "TextureDx11::CreateD3DTexture: E_OUTOFMEMORY\n" ); + break; + default: + break; + } + return 0; + } + + //s_TextureCount++; + return pBaseTexture; +} + +void DestroyD3DTexture( ID3D11Resource *pD3DTex ) +{ + if ( pD3DTex ) + { + pD3DTex->Release(); + Assert( ref == 0 ); + //s_TextureCount--; + } +} + +//----------------------------------- +// Dx11 implementation of a texture +//----------------------------------- + +CTextureDx11::CTextureDx11() +{ + m_pLockedFace = NULL; + m_nLockedFaceSize = 0; + m_pLockedTexture = NULL; + m_LockedSubresource = 0; + m_bLocked = false; + m_nFlags = 0; + m_Count = 0; + m_CountIndex = 0; + m_nTimesBoundMax = 0; + m_nTimesBoundThisFrame = 0; + m_Anisotropy = 0; + m_Format = IMAGE_FORMAT_RGBA8888; + m_MinFilter = D3D11_FILTER_TYPE_LINEAR; + m_MagFilter = D3D11_FILTER_TYPE_LINEAR; + m_MipFilter = D3D11_FILTER_TYPE_POINT; + m_bIsAnisotropic = false; + m_UTexWrap = D3D11_TEXTURE_ADDRESS_CLAMP; + m_VTexWrap = D3D11_TEXTURE_ADDRESS_CLAMP; + m_WTexWrap = D3D11_TEXTURE_ADDRESS_CLAMP; + m_Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; + + m_pTexture = NULL; + m_ppTexture = NULL; + + m_pSamplerState = NULL; + + m_pView = NULL; + m_ppView = NULL; + m_pDepthStencilView = NULL; + m_pRenderTargetView = NULL; + + m_pRamImage = NULL; + m_ppRamImage = NULL; +} + +inline int CalcMipLevels( int w, int h ) +{ + return /*ceil( log2( max( w, h ) ) ) +*/ 1; // we dont support mips yet +} + +void CTextureDx11::SetupTexture2D( int width, int height, int depth, int count, int i, + int flags, int numCopies, int numMipLevels, ImageFormat dstImageFormat ) +{ + if ( dstImageFormat == IMAGE_FORMAT_I8 ) + { + //DebuggerBreak(); + } + //Log( "Making texture2D\n" ); + bool bIsRenderTarget = ( flags & TEXTURE_CREATE_RENDERTARGET ) != 0; + bool bIsDepthBuffer = ( flags & TEXTURE_CREATE_DEPTHBUFFER ) != 0; + + if ( bIsDepthBuffer ) + { + //Log( "Making depth buffer\n" ); + SetupDepthTexture( dstImageFormat, width, height, "depth", true ); + return; + } + else if ( bIsRenderTarget ) + { + //Log( "Making render target\n" ); + SetupBackBuffer( width, height, "rendertarget", NULL, dstImageFormat ); + return; + } + + //dstImageFormat = IMAGE_FORMAT_RGBA8888; + + //--------------------------------------------------------------------------------- + + if ( depth == 0 ) + depth = 1; + + bool bIsCubeMap = ( flags & TEXTURE_CREATE_CUBEMAP ) != 0; + if ( bIsCubeMap ) + depth = 6; + bool bIsDynamic = ( flags & TEXTURE_CREATE_DYNAMIC ) != 0; + //bool bAutoMipMap = ( flags & TEXTURE_CREATE_AUTOMIPMAP ) != 0; + bool bIsManaged = ( flags & TEXTURE_CREATE_MANAGED ) != 0; + + // Can't be both managed + dynamic. Dynamic is an optimization, but + // if it's not managed, then we gotta do special client-specific stuff + // So, managed wins out! + if ( bIsManaged ) + bIsDynamic = false; + + /*if ( bAutoMipMap && numMipLevels == 0 && !bIsDynamic ) + { + numMipLevels = CalcMipLevels( width, height ); + } + else if ( bIsDynamic )*/ + { + // Dynamic textures can't have mipmaps + numMipLevels = 1; + } + + m_iTextureType = TEXTURE_STANDARD; + m_iTextureDimensions = TEXTURE_2D; + + unsigned short usSetFlags = 0; + usSetFlags |= ( flags & TEXTURE_CREATE_VERTEXTEXTURE ) ? CTextureDx11::IS_VERTEX_TEXTURE : 0; + + m_nFlags = CTextureDx11::IS_ALLOCATED; + m_nWidth = width; + m_nHeight = height; + m_Depth = depth; + m_Count = count; + m_CountIndex = i; + m_CreationFlags = flags; + m_nFlags |= usSetFlags; + + m_NumLevels = numMipLevels; + + ID3D11Resource *pD3DTex; + + // Set the initial texture state + if ( numCopies <= 1 ) + { + m_NumCopies = 1; + pD3DTex = CreateD3DTexture( width, height, depth, dstImageFormat, numMipLevels, flags ); + SetTexture( pD3DTex ); + if ( bIsDynamic ) + { + int nRamBytes = CalcRamBytes(); + m_pRamImage = new unsigned char[nRamBytes]; + memset( m_pRamImage, 0, nRamBytes ); + } + } + else + { + m_NumCopies = numCopies; + m_ppTexture = new ID3D11Resource * [numCopies]; + if ( bIsDynamic ) + m_ppRamImage = new unsigned char * [numCopies]; + for ( int k = 0; k < numCopies; k++ ) + { + pD3DTex = CreateD3DTexture( width, height, depth, dstImageFormat, numMipLevels, flags ); + SetTexture( k, pD3DTex ); + if ( bIsDynamic ) + { + int nRamBytes = CalcRamBytes(); + m_ppRamImage[k] = new unsigned char[nRamBytes]; + memset( m_ppRamImage[k], 0, nRamBytes ); + } + } + } + m_CurrentCopy = 0; + + if ( m_NumCopies == 1 ) + pD3DTex = m_pTexture; + else + pD3DTex = m_ppTexture[m_CurrentCopy]; + + m_UTexWrap = D3D11_TEXTURE_ADDRESS_CLAMP; + m_VTexWrap = D3D11_TEXTURE_ADDRESS_CLAMP; + m_WTexWrap = D3D11_TEXTURE_ADDRESS_CLAMP; + + m_MipFilter = ( numMipLevels != 1 ) ? + D3D11_FILTER_TYPE_LINEAR : D3D11_FILTER_TYPE_POINT; + m_MinFilter = m_MagFilter = D3D11_FILTER_TYPE_LINEAR; + + m_SwitchNeeded = false; + + AdjustD3DFilter(); + MakeView(); +} + +void CTextureDx11::SetupDepthTexture( ImageFormat depthFormat, int width, int height, const char *pDebugName, bool bTexture ) +{ + m_nFlags = CTextureDx11::IS_ALLOCATED; + if ( bTexture ) + m_nFlags |= CTextureDx11::IS_DEPTH_STENCIL_TEXTURE; + else + m_nFlags |= CTextureDx11::IS_DEPTH_STENCIL; + + m_iTextureType = TEXTURE_DEPTHSTENCIL; + m_iTextureDimensions = TEXTURE_3D; + + m_nWidth = width; + m_nHeight = height; + m_Depth = 1; + m_Count = 1; + m_CountIndex = 0; + m_CreationFlags = TEXTURE_CREATE_DEPTHBUFFER; + m_MinFilter = D3D11_FILTER_TYPE_LINEAR; + m_MagFilter = D3D11_FILTER_TYPE_LINEAR; + m_MipFilter = D3D11_FILTER_TYPE_POINT; + m_NumLevels = 1; + m_NumCopies = 1; + m_CurrentCopy = 0; + + m_pTexture = CreateD3DTexture( + width, height, m_Depth, depthFormat, m_NumLevels, m_CreationFlags ); + AdjustD3DFilter(); + MakeDepthStencilView(); + if ( bTexture ) + { + MakeView(); + } +} + +void CTextureDx11::SetupBackBuffer( int width, int height, const char *pDebugName, + ID3D11Texture2D *pBackBuffer, ImageFormat format ) +{ + m_nFlags = CTextureDx11::IS_ALLOCATED; + + m_iTextureType = TEXTURE_RENDERTARGET; + m_iTextureDimensions = TEXTURE_2D; + + m_nWidth = width; + m_nHeight = height; + m_Depth = 1; + m_Count = 1; + m_CountIndex = 0; + m_CreationFlags = TEXTURE_CREATE_RENDERTARGET; + m_MinFilter = D3D11_FILTER_TYPE_LINEAR; + m_MagFilter = D3D11_FILTER_TYPE_LINEAR; + m_MipFilter = D3D11_FILTER_TYPE_POINT; + m_NumLevels = 1; + m_NumCopies = 1; + m_CurrentCopy = 0; + m_Format = GetClosestSupportedImageFormatForD3D11( format ); + m_D3DFormat = GetD3DFormat( m_Format ); + + if ( pBackBuffer ) + m_pTexture = pBackBuffer; + else + m_pTexture = CreateD3DTexture( width, height, m_Depth, format, m_NumLevels, m_CreationFlags ); + + AdjustD3DFilter(); + MakeRenderTargetView(); + MakeView(); +} + +void CTextureDx11::SetMinFilter( ShaderTexFilterMode_t texFilterMode ) +{ + switch ( texFilterMode ) + { + case SHADER_TEXFILTERMODE_LINEAR: + case SHADER_TEXFILTERMODE_LINEAR_MIPMAP_NEAREST: + m_MinFilter = D3D11_FILTER_TYPE_LINEAR; + m_MipFilter = D3D11_FILTER_TYPE_POINT; + m_bIsAnisotropic = false; + break; + case SHADER_TEXFILTERMODE_LINEAR_MIPMAP_LINEAR: + m_MinFilter = D3D11_FILTER_TYPE_LINEAR; + m_MipFilter = D3D11_FILTER_TYPE_LINEAR; + m_bIsAnisotropic = false; + break; + + case SHADER_TEXFILTERMODE_NEAREST: + case SHADER_TEXFILTERMODE_NEAREST_MIPMAP_NEAREST: + m_MinFilter = D3D11_FILTER_TYPE_POINT; + m_MipFilter = D3D11_FILTER_TYPE_POINT; + m_bIsAnisotropic = false; + break; + case SHADER_TEXFILTERMODE_NEAREST_MIPMAP_LINEAR: + m_MinFilter = D3D11_FILTER_TYPE_POINT; + m_MipFilter = D3D11_FILTER_TYPE_LINEAR; + m_bIsAnisotropic = false; + break; + + case SHADER_TEXFILTERMODE_ANISOTROPIC: + m_bIsAnisotropic = true; + break; + + } + + AdjustD3DFilter(); +} + +void CTextureDx11::SetMagFilter( ShaderTexFilterMode_t texFilterMode ) +{ + switch ( texFilterMode ) + { + case SHADER_TEXFILTERMODE_LINEAR: + m_MagFilter = D3D11_FILTER_TYPE_LINEAR; + break; + case SHADER_TEXFILTERMODE_NEAREST: + m_MagFilter = D3D11_FILTER_TYPE_POINT; + break; + } + + AdjustD3DFilter(); +} + +void CTextureDx11::SetWrap( ShaderTexCoordComponent_t coord, ShaderTexWrapMode_t wrapMode ) +{ + D3D11_TEXTURE_ADDRESS_MODE address; + switch ( wrapMode ) + { + case SHADER_TEXWRAPMODE_CLAMP: + address = D3D11_TEXTURE_ADDRESS_CLAMP; + break; + case SHADER_TEXWRAPMODE_REPEAT: + address = D3D11_TEXTURE_ADDRESS_WRAP; + break; + case SHADER_TEXWRAPMODE_BORDER: + address = D3D11_TEXTURE_ADDRESS_BORDER; + break; + default: + address = D3D11_TEXTURE_ADDRESS_CLAMP; + Warning( "CTextureDx11::SetWrap: unknown wrapMode %i\n", wrapMode ); + break; + } + + switch ( coord ) + { + case SHADER_TEXCOORD_S: + m_UTexWrap = address; + break; + case SHADER_TEXCOORD_T: + m_VTexWrap = address; + break; + case SHADER_TEXCOORD_U: + m_WTexWrap = address; + break; + default: + Warning( "CTextureDx11::SetWrap: unknown coord %i\n", coord ); + break; + } + + AdjustSamplerState(); +} + +void CTextureDx11::AdjustD3DFilter() +{ + // Set to anisotropic if the texture was already set to an anisotropic filter, + // or we are using at least bilinear filtering and have an anisotropic level > 1 + if ( m_bIsAnisotropic || + ( m_MinFilter == D3D11_FILTER_TYPE_LINEAR && m_MagFilter == D3D11_FILTER_TYPE_LINEAR && m_Anisotropy > 1 ) ) + { + m_Filter = D3D11_FILTER_ANISOTROPIC; + } + else + { + m_Filter = D3D11_ENCODE_BASIC_FILTER( m_MinFilter, m_MagFilter, m_MipFilter, + D3D11_FILTER_REDUCTION_TYPE_STANDARD ); + } + + AdjustSamplerState(); +} + +void CTextureDx11::SetAnisotropicLevel( int level ) +{ + m_Anisotropy = level; + AdjustD3DFilter(); +} + +void CTextureDx11::AdjustSamplerState() +{ + if ( m_pSamplerState ) + m_pSamplerState->Release(); + + m_pSamplerState = NULL; + D3D11_SAMPLER_DESC desc; + ZeroMemory( &desc, sizeof( D3D11_SAMPLER_DESC ) ); + desc.AddressU = m_UTexWrap; + desc.AddressV = m_VTexWrap; + desc.AddressW = m_WTexWrap; + desc.Filter = m_Filter; + desc.MaxAnisotropy = m_Anisotropy; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0; + desc.MaxLOD = D3D11_FLOAT32_MAX; + + HRESULT hr = D3D11Device()->CreateSamplerState( &desc, &m_pSamplerState ); + if ( FAILED( hr ) ) + { + Warning( "CTextureDx11: Couldn't create sampler state!\n" ); + } +} + +void CTextureDx11::MakeRenderTargetView() +{ + if ( m_iTextureType != TEXTURE_RENDERTARGET ) + { + return; + } + + D3D11_RENDER_TARGET_VIEW_DESC desc; + ZeroMemory( &desc, sizeof( D3D11_RENDER_TARGET_VIEW_DESC ) ); + desc.Format = m_D3DFormat; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + + if ( m_pRenderTargetView ) + { + m_pRenderTargetView->Release(); + Assert( ref == 0 ); + } + HRESULT hr = D3D11Device()->CreateRenderTargetView( m_pTexture, &desc, &m_pRenderTargetView ); + if ( FAILED( hr ) ) + { + Warning( "Failed to make D3D render target view!\n" ); + } +} + +void CTextureDx11::MakeDepthStencilView() +{ + if ( m_iTextureType != TEXTURE_DEPTHSTENCIL ) + { + return; + } + + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + ZeroMemory( &desc, sizeof( D3D11_DEPTH_STENCIL_VIEW_DESC ) ); + desc.Format = GetDepthStencilViewFormat( m_D3DFormat ); + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + desc.Flags = 0; + + if ( m_pDepthStencilView ) + { + m_pDepthStencilView->Release(); + Assert( ref == 0 ); + } + HRESULT hr = D3D11Device()->CreateDepthStencilView( m_pTexture, &desc, &m_pDepthStencilView ); + if ( FAILED( hr ) ) + { + Warning( "Failed to make D3D depth stencil view!\n" ); + } +} + +void CTextureDx11::MakeView() +{ + DXGI_FORMAT format; + if ( m_iTextureType == TEXTURE_DEPTHSTENCIL ) + { + format = GetDepthSRVFormat( m_D3DFormat ); + } + else + { + format = m_D3DFormat; + } + + D3D11_SRV_DIMENSION dim; + if ( m_Depth == 6 && ( ( m_CreationFlags & TEXTURE_CREATE_CUBEMAP ) != 0 ) ) + { + dim = D3D11_SRV_DIMENSION_TEXTURECUBE; + } + else if ( m_Depth > 1 ) + { + dim = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + } + else + { + dim = D3D11_SRV_DIMENSION_TEXTURE2D; + } + + CD3D11_SHADER_RESOURCE_VIEW_DESC desc( dim, format ); + + if ( m_NumCopies > 1 ) + { + if ( m_ppView ) + { + delete[] m_ppView; + } + m_ppView = new ID3D11ShaderResourceView * [m_NumCopies]; + for ( int copy = 0; copy < m_NumCopies; copy++ ) + { + HRESULT hr = D3D11Device()->CreateShaderResourceView( m_ppTexture[copy], &desc, &m_ppView[copy] ); + if ( FAILED( hr ) ) + { + Warning( "Unable to create shader resource view for texture copy %i!\n", copy ); + } + } + + } + else + { + if ( m_pView ) + { + m_pView->Release(); + } + m_pView = NULL; + + HRESULT hr = D3D11Device()->CreateShaderResourceView( m_pTexture, &desc, &m_pView ); + if ( FAILED( hr ) ) + { + Warning( "Unable to create D3D11 Texture view!\n" ); + } + } + +} + +static int s_CubemapBlits = 0; + +void CTextureDx11::BlitSurfaceBits( CTextureDx11::TextureLoadInfo_t &info, int xOffset, int yOffset, int srcStride ) +{ + if ( m_CreationFlags & TEXTURE_CREATE_DYNAMIC ) + { + // Dynamic textures need to be updated using Lock() and Unlock() + Warning( "TextureDX11: Tried to call BlitSurfaceBits() on a dynamic texture!\n" ); + return; + } + + int width = info.m_nWidth; + int height = info.m_nHeight; + if ( m_Format == IMAGE_FORMAT_DXT3 || //m_Format == IMAGE_FORMAT_DXT3_SRGB || + m_Format == IMAGE_FORMAT_DXT5 || //m_Format == IMAGE_FORMAT_DXT5_SRGB || + m_Format == IMAGE_FORMAT_DXT1 || //m_Format == IMAGE_FORMAT_DXT1_SRGB || + m_Format == IMAGE_FORMAT_DXT1_ONEBITALPHA )//|| m_Format == IMAGE_FORMAT_DXT1_ONEBITALPHA_SRGB ) + { + width = ALIGN_VALUE( width, 4 ); + height = ALIGN_VALUE( height, 4 ); + } + + CD3D11_BOX box; + box.left = xOffset; + box.right = xOffset + width; + box.top = yOffset; + box.bottom = yOffset + height; + box.front = info.m_nZOffset; + box.back = info.m_nZOffset + 1; + + int mem = ImageLoader::GetMemRequired( width, height, info.m_nZOffset, m_Format, false ); + unsigned char *pNewImage = new unsigned char[mem]; + int dstStride = ImageLoader::SizeInBytes( m_Format ); + int pitch = dstStride * width; + if ( m_Format == IMAGE_FORMAT_DXT3 || //m_Format == IMAGE_FORMAT_DXT3_SRGB || + m_Format == IMAGE_FORMAT_DXT5 )//|| m_Format == IMAGE_FORMAT_DXT5_SRGB ) + { + pitch = 16 * ( width / 4 ); + } + else if ( m_Format == IMAGE_FORMAT_DXT1 || //m_Format == IMAGE_FORMAT_DXT1_SRGB || + m_Format == IMAGE_FORMAT_DXT1_ONEBITALPHA )//|| m_Format == IMAGE_FORMAT_DXT1_ONEBITALPHA_SRGB ) + { + pitch = 8 * ( width / 4 ); + } + + bool ret = + ShaderUtil()->ConvertImageFormat( info.m_pSrcData, info.m_SrcFormat, pNewImage, m_Format, + width, height, srcStride ); + if ( !ret ) + { + Warning( "Couldn't convert texture for uploading to D3D!\n" ); + return; + } + +#if 0 + if ( m_CreationFlags & TEXTURE_CREATE_CUBEMAP ) + { + char cmfile[100]; + sprintf( cmfile, "C:\\Users\\Brian\\Desktop\\SourceDX11Debug\\cubemap-%i-face-%i.tga", s_CubemapBlits, info.m_CubeFaceID ); + TGAWriter::WriteTGAFile( cmfile, info.m_nWidth, info.m_nHeight, m_Format, pNewImage, dstStride * info.m_nWidth ); + + if ( info.m_CubeFaceID == 4 ) + { + s_CubemapBlits++; + } + } +#endif + + UINT subresource = D3D11CalcSubresource( info.m_nLevel, info.m_CubeFaceID, m_NumLevels ); + + D3D11DeviceContext()->UpdateSubresource( info.m_pTexture, subresource, &box, pNewImage, + pitch, 0 ); + + delete[] pNewImage; + + // If the texture was created with auto mipmap and we have just filled in the base mip, + // make D3D generate the remaining mips. If the texture was not created with auto mipmap, + // or we have just filled in a non-base mip, we assume the user is filling in the mips. + if ( ( ( m_CreationFlags & TEXTURE_CREATE_AUTOMIPMAP ) != 0 ) && m_NumLevels > 1 && info.m_nLevel == 0 ) + { + D3D11DeviceContext()->GenerateMips( info.m_pView ); + } +} + +void CTextureDx11::BlitTextureBits( CTextureDx11::TextureLoadInfo_t &info, int xOffset, int yOffset, int srcStride ) +{ + // TODO: Volume texture? + + //Assert( info.m_nZOffset == 0 ); + if ( info.m_nZOffset != 0 ) + { + return; + } + BlitSurfaceBits( info, xOffset, yOffset, srcStride ); +} + +void CTextureDx11::LoadTexImage( CTextureDx11::TextureLoadInfo_t &info, int xOffset, int yOffset, int srcStride ) +{ + MEM_ALLOC_CREDIT(); + + Assert( info.m_pSrcData ); + Assert( info.m_pTexture ); + + // Copy in the bits... + BlitTextureBits( info, xOffset, yOffset, srcStride ); +} + +void CTextureDx11::LoadTextureFromVTF(CTextureDx11::TextureLoadInfo_t& info, IVTFTexture* pVTF, int iVTFFrame) +{ + BlitTextureBits(info, 0, 0, 0); +} + +void CTextureDx11::Delete() +{ + int nDeallocated = 0; + + if ( m_NumCopies == 1 ) + { + if ( m_pView ) + { + m_pView->Release(); + Assert( refCount == 0 ); + m_pView = 0; + nDeallocated++; + } + + if ( m_pTexture ) + { + DestroyD3DTexture( m_pTexture ); + m_pTexture = 0; + nDeallocated = 1; + } + + if ( m_pRamImage ) + { + delete[] m_pRamImage; + m_pRamImage = NULL; + } + } + else + { + if ( m_ppView ) + { + for ( int i = 0; i < m_NumCopies; i++ ) + { + if ( m_ppView[i] ) + { + m_ppView[i]->Release(); + Assert( refCount == 0 ); + nDeallocated++; + } + } + + delete[] m_ppView; + m_ppView = NULL; + } + + if ( m_ppTexture ) + { + // Multiple copy texture + for ( int j = 0; j < m_NumCopies; j++ ) + { + if ( m_ppTexture[j] ) + { + DestroyD3DTexture( m_ppTexture[j] ); + m_ppTexture[j] = 0; + ++nDeallocated; + } + } + delete[] m_ppTexture; + m_ppTexture = NULL; + } + + if ( m_ppRamImage ) + { + delete[] m_ppRamImage; + m_ppRamImage = NULL; + } + } + + if ( m_iTextureType == TEXTURE_RENDERTARGET ) + { + if ( m_pRenderTargetView ) + { + m_pRenderTargetView->Release(); + Assert( refCount == 0 ); + m_pRenderTargetView = 0; + nDeallocated++; + } + } + else if ( m_iTextureType == TEXTURE_DEPTHSTENCIL ) + { + if ( m_pDepthStencilView ) + { + m_pDepthStencilView->Release(); + Assert( refCount == 0 ); + m_pDepthStencilView = 0; + nDeallocated++; + } + } + + if ( m_pSamplerState ) + { + m_pSamplerState->Release(); + m_pSamplerState = 0; + nDeallocated++; + } + + m_NumCopies = 0; + m_nFlags = 0; +} + +bool CTextureDx11::Lock( int copy, int level, int cubeFaceID, int xOffset, int yOffset, + int width, int height, bool bDiscard, CPixelWriter &writer ) +{ + Assert( !m_bLocked ); + Assert( level == 0 ); // dynamic textures can't have mipmaps + + if ( m_bLocked ) + { + return false; + } + + if ( m_NumCopies == 1 ) + { + m_pLockedTexture = m_pTexture; + m_pLockedFace = m_pRamImage; + } + else + { + m_pLockedTexture = m_ppTexture[copy]; + m_pLockedFace = m_ppRamImage[copy]; + } + + int bytesPerXel = ImageLoader::SizeInBytes( m_Format ); + int bytesPerRow = bytesPerXel * m_nWidth; + int bytesPerFace = bytesPerXel * m_nWidth * m_nHeight; + // Where do we want to start modifying? + int nMemOffset = bytesPerFace * cubeFaceID; + nMemOffset += yOffset * bytesPerRow; + nMemOffset += xOffset * bytesPerXel; + // Offset into the ram image + unsigned char *pModifyBegin = m_pLockedFace + nMemOffset; + + m_nLockedFaceSize = bytesPerFace; + + m_LockedSubresource = D3D11CalcSubresource( 0, cubeFaceID, 1 ); + + ZeroMemory( &m_MappedData, sizeof( D3D11_MAPPED_SUBRESOURCE ) ); + HRESULT hr = D3D11DeviceContext()->Map( m_pLockedTexture, m_LockedSubresource, D3D11_MAP_WRITE_DISCARD, 0, &m_MappedData ); + if ( FAILED( hr ) ) + { + return false; + } + + writer.SetPixelMemory( m_Format, pModifyBegin, bytesPerRow ); + + m_bLocked = true; + return true; +} + +void CTextureDx11::Unlock( int copy, int level, int cubeFaceID ) +{ + Assert( m_bLocked ); + if ( !m_bLocked ) + { + return; + } + + memcpy( m_MappedData.pData, m_pLockedFace, m_nLockedFaceSize ); + D3D11DeviceContext()->Unmap( m_pLockedTexture, m_LockedSubresource ); + + m_pLockedFace = NULL; + m_nLockedFaceSize = 0; + m_pLockedTexture = NULL; + m_LockedSubresource = 0; + + m_bLocked = false; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/TextureDx11.h b/materialsystem/shaderapidx11/TextureDx11.h new file mode 100644 index 0000000..85fc333 --- /dev/null +++ b/materialsystem/shaderapidx11/TextureDx11.h @@ -0,0 +1,308 @@ +#pragma once + +#include "platform.h" +#include "bitmap/imageformat.h" +#include "Dx11Global.h" +#include "shaderapi/shareddefs.h" +#include "tier0/dbg.h" +#include "shaderapi/ishaderapi.h" +#include +#include +#include +#include + +class CTextureDx11 +{ +public: + //----------------------------------------------------------------------------- + // Info for texture loading + //----------------------------------------------------------------------------- + struct TextureLoadInfo_t + { + ShaderAPITextureHandle_t m_TextureHandle; + int m_nCopy; + ID3D11Resource *m_pTexture; + ID3D11ShaderResourceView *m_pView; + int m_nLevel; + D3D11_TEXTURECUBE_FACE m_CubeFaceID; + int m_nWidth; + int m_nHeight; + int m_nZOffset; // What z-slice of the volume texture are we loading? + ImageFormat m_SrcFormat; + unsigned char *m_pSrcData; + }; + + enum + { + TEXTURE_1D = 1, + TEXTURE_2D, + TEXTURE_3D, + }; + + enum + { + TEXTURE_STANDARD, + TEXTURE_DEPTHSTENCIL, + TEXTURE_RENDERTARGET, + }; + + enum + { + IS_ALLOCATED = 1 << 0, + IS_DEPTH_STENCIL = 1 << 1, + IS_DEPTH_STENCIL_TEXTURE = 1 << 2, + IS_RENDERABLE = ( IS_DEPTH_STENCIL | IS_ALLOCATED ), + IS_VERTEX_TEXTURE = 1 << 3, + }; + + CTextureDx11(); + ID3D11Resource *GetTexture() const; + ID3D11Resource *GetTexture( int n ) const; + ID3D11ShaderResourceView *GetView( int n ) const; + ID3D11ShaderResourceView *GetView() const; + ID3D11DepthStencilView *GetDepthStencilView() const; + ID3D11RenderTargetView *GetRenderTargetView() const; + ID3D11Texture1D *GetTexture1D() const; + ID3D11Texture1D *GetTexture1D( int n ) const; + ID3D11Texture2D *GetTexture2D() const; + ID3D11Texture2D *GetTexture2D( int n ) const; + ID3D11Texture3D *GetTexture3D() const; + ID3D11Texture3D *GetTexture3D( int n ) const; + ID3D11SamplerState *GetSamplerState() const; + + void Delete(); + + void AdjustSamplerState(); + void MakeView(); + void MakeRenderTargetView(); + void MakeDepthStencilView(); + + void SetAnisotropicLevel( int level ); + void SetMinFilter( ShaderTexFilterMode_t texFilterMode ); + void SetMagFilter( ShaderTexFilterMode_t texFilterMode ); + void SetWrap( ShaderTexCoordComponent_t coord, ShaderTexWrapMode_t wrapMode ); + + void AdjustD3DFilter(); + + void SetupTexture2D( int width, int height, int depth, int count, int i, + int flags, int numCopies, + int numMipLevels, ImageFormat dstImageFormat ); + void SetupDepthTexture( ImageFormat renderFormat, int width, int height, + const char *pDebugName, bool bTexture ); + void SetupBackBuffer( int width, int height, const char *pDebugName, + ID3D11Texture2D *pBackBuffer = NULL, ImageFormat format = IMAGE_FORMAT_RGBA8888 ); + + bool Is1D() const; + bool Is2D() const; + bool Is3D() const; + + bool Lock( int copy, int level, int cubeFaceID, int xOffset, int yOffset, + int width, int height, bool bDiscard, CPixelWriter &writer ); + void Unlock( int copy, int level, int cubeFaceID ); + + void LoadTexImage( TextureLoadInfo_t &info, int xOffset = 0, int yOffset = 0, int srcStride = 0 ); + void LoadTextureFromVTF(TextureLoadInfo_t& info, IVTFTexture* pVTF, int iVTFFrame); + void BlitTextureBits( TextureLoadInfo_t &info, int xOffset, int yOffset, int srcStride ); + void BlitSurfaceBits( TextureLoadInfo_t &info, int xOffset, int yOffset, int srcStride ); + + void SetTexture( ID3D11Resource *tex ); + void SetTexture( int n, ID3D11Resource *tex ); + //void SetView( ID3D11ShaderResourceView *view ); + + int CalcRamBytes() const; + + static ImageFormat GetImageFormat( DXGI_FORMAT d3dFormat ); + + static ImageFormat GetClosestSupportedImageFormatForD3D11( ImageFormat srcFormat ); + +private: + ID3D11Resource *CreateD3DTexture( int width, int height, int nDepth, + ImageFormat dstFormat, int numLevels, int nCreationFlags ); + +private: + // Can either have a single texture or an array of texture copies + union + { + ID3D11Resource *m_pTexture; + ID3D11Resource **m_ppTexture; + }; + + // One sampler state + ID3D11SamplerState *m_pSamplerState; + + // Can either have a single view or array of views (for copies) + union + { + ID3D11ShaderResourceView *m_pView; + ID3D11ShaderResourceView **m_ppView; + }; + + // Can either have a depth stencil view (for depth buffers) or + // a render target view (for render targets/back buffer) + union + { + ID3D11DepthStencilView *m_pDepthStencilView; + ID3D11RenderTargetView *m_pRenderTargetView; + }; + + D3D11_TEXTURE_ADDRESS_MODE m_UTexWrap; + D3D11_TEXTURE_ADDRESS_MODE m_VTexWrap; + D3D11_TEXTURE_ADDRESS_MODE m_WTexWrap; + D3D11_FILTER m_Filter; + D3D11_FILTER_TYPE m_MinFilter; + D3D11_FILTER_TYPE m_MipFilter; + D3D11_FILTER_TYPE m_MagFilter; + int m_Anisotropy; + bool m_bIsAnisotropic; + +public: + unsigned char m_NumLevels; + unsigned char m_SwitchNeeded; + unsigned char m_NumCopies; + unsigned char m_CurrentCopy; + short m_Count; + short m_CountIndex; + short m_Depth; + int m_iTextureType; + int m_iTextureDimensions; + int m_nWidth; + int m_nHeight; + + ImageFormat m_Format; + DXGI_FORMAT m_D3DFormat; + int m_nSizeTexels; + int m_nSizeBytes; + int m_LastBoundFrame; + int m_nTimesBoundMax; + int m_nTimesBoundThisFrame; + unsigned short m_nFlags; + int m_CreationFlags; + + // + // The stuff below exists to emulate DX9's LockRect function, which + // allowed you to modify a portion of the texture without discarding the + // rest of the texture. + // + + // For locking textures + ID3D11Resource *m_pLockedTexture; + D3D11_MAPPED_SUBRESOURCE m_MappedData; + unsigned char *m_pLockedFace; + unsigned int m_nLockedFaceSize; + UINT m_LockedSubresource; + bool m_bLocked; + + // We store copies of dynamic textures in system memory to + // allow for quickly modifying regions of dynamic textures. + // (Used by lightmaps) + union + { + unsigned char *m_pRamImage; + unsigned char **m_ppRamImage; + }; + + +}; + +FORCEINLINE ID3D11Resource *CTextureDx11::GetTexture() const +{ + return m_pTexture; +} + +FORCEINLINE ID3D11Resource *CTextureDx11::GetTexture( int n ) const +{ + return m_ppTexture[n]; +} + +FORCEINLINE ID3D11Texture1D *CTextureDx11::GetTexture1D() const +{ + return (ID3D11Texture1D *)m_pTexture; +} + +FORCEINLINE ID3D11Texture1D *CTextureDx11::GetTexture1D( int n ) const +{ + Assert( Is2D() ); + return (ID3D11Texture1D *)m_ppTexture[n]; +} + +FORCEINLINE ID3D11Texture2D *CTextureDx11::GetTexture2D() const +{ + Assert( Is2D() ); + return (ID3D11Texture2D *)m_pTexture; +} + +FORCEINLINE ID3D11Texture2D *CTextureDx11::GetTexture2D( int n ) const +{ + Assert( Is2D() ); + return (ID3D11Texture2D *)m_ppTexture[n]; +} + +FORCEINLINE ID3D11Texture3D *CTextureDx11::GetTexture3D() const +{ + Assert( Is3D() ); + return (ID3D11Texture3D *)m_pTexture; +} + +FORCEINLINE ID3D11Texture3D *CTextureDx11::GetTexture3D( int n ) const +{ + Assert( Is3D() ); + return (ID3D11Texture3D *)m_ppTexture[n]; +} + +FORCEINLINE bool CTextureDx11::Is1D() const +{ + return m_iTextureDimensions == TEXTURE_1D; +} + +FORCEINLINE bool CTextureDx11::Is2D() const +{ + return m_iTextureDimensions == TEXTURE_2D; +} + +FORCEINLINE bool CTextureDx11::Is3D() const +{ + return m_iTextureDimensions == TEXTURE_3D; +} + +FORCEINLINE ID3D11ShaderResourceView *CTextureDx11::GetView() const +{ + if ( m_NumCopies > 1 ) + { + return GetView( m_CurrentCopy ); + } + + return m_pView; +} + +FORCEINLINE ID3D11ShaderResourceView *CTextureDx11::GetView( int n ) const +{ + Assert( m_NumCopies > 1 ); + return m_ppView[n]; +} + +FORCEINLINE ID3D11DepthStencilView *CTextureDx11::GetDepthStencilView() const +{ + Assert( m_iTextureType == TEXTURE_DEPTHSTENCIL ); + return m_pDepthStencilView; +} + +FORCEINLINE ID3D11RenderTargetView *CTextureDx11::GetRenderTargetView() const +{ + Assert( m_iTextureType == TEXTURE_RENDERTARGET ); + return m_pRenderTargetView; +} + +FORCEINLINE ID3D11SamplerState *CTextureDx11::GetSamplerState() const +{ + return m_pSamplerState; +} + +FORCEINLINE void CTextureDx11::SetTexture( ID3D11Resource *tex ) +{ + m_pTexture = tex; +} + +FORCEINLINE void CTextureDx11::SetTexture( int n, ID3D11Resource *tex ) +{ + m_ppTexture[n] = tex; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/VertexBufferDx11.cpp b/materialsystem/shaderapidx11/VertexBufferDx11.cpp new file mode 100644 index 0000000..6af4189 --- /dev/null +++ b/materialsystem/shaderapidx11/VertexBufferDx11.cpp @@ -0,0 +1,430 @@ +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "VertexBufferDx11.h" +#include "shaderapidx9/locald3dtypes.h" +#include "shaderapidx11_global.h" +#include "shaderdevicedx11.h" +#include "shaderapi/ishaderutil.h" +#include "tier0/vprof.h" +#include "tier0/dbg.h" +#include "materialsystem/ivballoctracker.h" +#include "tier2/tier2.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// +// Dx11 implementation of a vertex buffer +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// globals +//----------------------------------------------------------------------------- +#ifdef _DEBUG +int CVertexBufferDx11::s_nBufferCount = 0; +#endif + + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CVertexBufferDx11::CVertexBufferDx11( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char* pBudgetGroupName ) : + BaseClass( pBudgetGroupName ) +{ + Assert( nVertexCount != 0 ); + + m_pVertexMemory = NULL; + m_nVerticesLocked = 0; + m_pVertexBuffer = NULL; + m_VertexFormat = fmt; + m_nVertexCount = ( fmt == VERTEX_FORMAT_UNKNOWN ) ? 0 : nVertexCount; + m_VertexSize = VertexFormatSize( m_VertexFormat ); + m_nBufferSize = ( fmt == VERTEX_FORMAT_UNKNOWN ) ? nVertexCount : nVertexCount * VertexSize(); + m_Position = 0; + m_bIsLocked = false; + m_bIsDynamic = ( type == SHADER_BUFFER_TYPE_DYNAMIC ) || ( type == SHADER_BUFFER_TYPE_DYNAMIC_TEMP ); + m_bFlush = false; +} + +CVertexBufferDx11::~CVertexBufferDx11() +{ + Free(); +} + +bool CVertexBufferDx11::HasEnoughRoom( int nVertCount ) const +{ + return ( NextLockOffset() + ( nVertCount * m_VertexSize ) ) <= m_nBufferSize; +} + +//----------------------------------------------------------------------------- +// Creates, destroys the vertex buffer +//----------------------------------------------------------------------------- +bool CVertexBufferDx11::Allocate() +{ + Assert( !m_pVertexBuffer ); + + if ( !m_bIsDynamic ) + { + m_pVertexMemory = (unsigned char *)malloc( m_nBufferSize ); + memset( m_pVertexMemory, 0, m_nBufferSize ); + } + else + { + m_pVertexMemory = NULL; + } + + m_Position = 0; + + D3D11_BUFFER_DESC bd; + if ( m_bIsDynamic ) + { + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + } + else + { + bd.Usage = D3D11_USAGE_DEFAULT; + bd.CPUAccessFlags = 0; + } + + bd.ByteWidth = m_nBufferSize; + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.MiscFlags = 0; + + //Log( "Creating D3D vertex buffer: size: %i\n", m_nBufferSize ); + + //if ( m_nBufferSize <= 0 ) + //{ + // int *p = 0; + // *p = 1; + //} + + + HRESULT hr = D3D11Device()->CreateBuffer( &bd, NULL, &m_pVertexBuffer ); + bool bOk = !FAILED( hr ) && ( m_pVertexBuffer != 0 ); + + if ( bOk ) + { + // Track VB allocations + g_VBAllocTracker->CountVB( m_pVertexBuffer, m_bIsDynamic, m_nBufferSize, VertexSize(), GetVertexFormat() ); + + if ( !m_bIsDynamic ) + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); + } + else + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); + // Dynamic meshes should never be compressed (slows down writing to them) + Assert( CompressionType( GetVertexFormat() ) == VERTEX_COMPRESSION_NONE ); + } +#ifdef _DEBUG + ++s_nBufferCount; +#endif + } + + return bOk; +} + +void CVertexBufferDx11::Free() +{ + if ( m_pVertexBuffer ) + { +#ifdef _DEBUG + --s_nBufferCount; +#endif + + // Track VB allocations + g_VBAllocTracker->UnCountVB( m_pVertexBuffer ); + + m_pVertexBuffer->Release(); + m_pVertexBuffer = NULL; + + if ( !m_bIsDynamic ) + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, -m_nBufferSize ); + } + else + { + VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, + COUNTER_GROUP_TEXTURE_GLOBAL, -m_nBufferSize ); + } + } + + if ( m_pVertexMemory ) + { + free( m_pVertexMemory ); + m_pVertexMemory = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Vertex Buffer info +//----------------------------------------------------------------------------- +int CVertexBufferDx11::VertexCount() const +{ + //Assert( !m_bIsDynamic ); + return m_nVertexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the buffer format (only valid for static index buffers) +//----------------------------------------------------------------------------- +VertexFormat_t CVertexBufferDx11::GetVertexFormat() const +{ + //Assert( !m_bIsDynamic ); + return m_VertexFormat; +} + + +//----------------------------------------------------------------------------- +// Returns true if the buffer is dynamic +//----------------------------------------------------------------------------- +bool CVertexBufferDx11::IsDynamic() const +{ + return m_bIsDynamic; +} + + +//----------------------------------------------------------------------------- +// Only used by dynamic buffers, indicates the next lock should perform a discard. +//----------------------------------------------------------------------------- +void CVertexBufferDx11::Flush() +{ + // This strange-looking line makes a flush only occur if the buffer is dynamic. + m_bFlush = m_bIsDynamic; +} + + +//----------------------------------------------------------------------------- +// Casts a dynamic buffer to be a particular vertex type +//----------------------------------------------------------------------------- +void CVertexBufferDx11::BeginCastBuffer( VertexFormat_t format ) +{ + Assert( format != VERTEX_FORMAT_UNKNOWN ); + Assert( m_bIsDynamic && ( m_VertexFormat == VERTEX_FORMAT_UNKNOWN || m_VertexFormat == format ) ); + if ( !m_bIsDynamic ) + return; + + m_VertexFormat = format; + m_VertexSize = VertexFormatSize( m_VertexFormat ); + m_nVertexCount = m_nBufferSize / VertexSize(); +} + +void CVertexBufferDx11::EndCastBuffer() +{ + Assert( m_bIsDynamic && m_VertexFormat != 0 ); + if ( !m_bIsDynamic ) + return; + m_VertexFormat = 0; + m_nVertexCount = 0; + m_VertexSize = 0; +} + + +//----------------------------------------------------------------------------- +// Returns the number of indices that can be written into the buffer +//----------------------------------------------------------------------------- +int CVertexBufferDx11::GetRoomRemaining() const +{ + return ( m_nBufferSize - NextLockOffset() ) / VertexSize(); +} + + +//----------------------------------------------------------------------------- +// Lock, unlock +//----------------------------------------------------------------------------- +bool CVertexBufferDx11::Lock( int nMaxVertexCount, bool bAppend, VertexDesc_t& desc ) +{ + return LockEx( 0, nMaxVertexCount, desc ); +} + +bool CVertexBufferDx11::LockEx( int nFirstVertex, int nMaxVertexCount, VertexDesc_t &desc ) +{ + Assert( !m_bIsLocked && ( nMaxVertexCount <= m_nVertexCount ) ); + Assert( m_VertexFormat != 0 ); + + // FIXME: Why do we need to sync matrices now? + ShaderUtil()->SyncMatrices(); + //g_ShaderMutex.Lock(); + + // This can happen if the buffer was locked but a type wasn't bound + if ( m_VertexFormat == 0 ) + { + //Log( "No vertex format!\n" ); + goto vertexBufferLockFailed; + } + + + // Just give the app crap buffers to fill up while we're suppressed... + if ( g_pShaderDevice->IsDeactivated() || ( nMaxVertexCount == 0 ) ) + goto vertexBufferLockFailed; + + // Did we ask for something too large? + if ( nMaxVertexCount > m_nVertexCount ) + { + Warning( "Too many vertices for vertex buffer. . tell a programmer (%d>%d)\n", nMaxVertexCount, m_nVertexCount ); + goto vertexBufferLockFailed; + } + + // We might not have a buffer owing to alt-tab type stuff + if ( !m_pVertexBuffer ) + { + if ( !Allocate() ) + { + //Log( "Couldn't allocate vertex buffer\n" ); + goto vertexBufferLockFailed; + } + + } + + //Log( "Locking vertex buffer %p\n", m_pVertexBuffer ); + + // Check to see if we have enough memory + //int nMemoryRequired = nMaxVertexCount * VertexSize(); + + if ( m_bIsDynamic ) + { + D3D11_MAPPED_SUBRESOURCE lockedData; + HRESULT hr; + + D3D11_MAP map; + + bool bHasEnoughMemory = HasEnoughRoom( nMaxVertexCount ); + + // If we're not appending, no overwrite unless we don't have enough room + // If we're a static buffer, always discard if we're not appending + if ( !m_bFlush && bHasEnoughMemory ) + { + map = ( m_Position == 0 ) ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE; + } + else + { + map = D3D11_MAP_WRITE_DISCARD; + m_Position = 0; + m_bFlush = false; + } + + int nLockOffset = NextLockOffset(); + + //goto vertexBufferLockFailed; + hr = D3D11DeviceContext()->Map( m_pVertexBuffer, 0, map, 0, &lockedData ); + if ( FAILED( hr ) ) + { + Warning( "Failed to lock vertex buffer in CVertexBufferDx11::Lock\n" ); + goto vertexBufferLockFailed; + } + + ComputeVertexDescription( (unsigned char *)lockedData.pData + nLockOffset, m_VertexFormat, desc ); + desc.m_nFirstVertex = nLockOffset / VertexSize(); + desc.m_nOffset = nLockOffset; + m_bIsLocked = true; + return true; + } + else + { + // Static vertex buffers + + bool bHasEnoughMemory = ( nFirstVertex + nMaxVertexCount ) <= m_nVertexCount; + if ( !bHasEnoughMemory ) + { + goto vertexBufferLockFailed; + } + int nLockOffset; + if ( nFirstVertex >= 0 ) + nLockOffset = nFirstVertex * VertexSize(); + else + nLockOffset = m_Position; + m_Position = nLockOffset; + // Static vertex buffer case + ComputeVertexDescription( m_pVertexMemory + nLockOffset, m_VertexFormat, desc ); + desc.m_nFirstVertex = nFirstVertex; + desc.m_nOffset = nLockOffset; + m_nVerticesLocked = nMaxVertexCount; + m_bIsLocked = true; + return true; + } + + +vertexBufferLockFailed: + g_ShaderMutex.Unlock(); + + // Set up a bogus index descriptor + ComputeVertexDescription( 0, 0, desc ); + desc.m_nFirstVertex = 0; + desc.m_nOffset = 0; + return false; +} + +void CVertexBufferDx11::Unlock( int nWrittenVertexCount, VertexDesc_t& desc ) +{ + //Log( "Unlocking vertex buffer %p\n", m_pVertexBuffer ); + Assert( nWrittenVertexCount <= m_nVertexCount ); + + // NOTE: This can happen if the lock occurs during alt-tab + // or if another application is initializing + if ( !m_bIsLocked ) + return; + + if ( m_pVertexBuffer ) + { + if ( m_bIsDynamic ) + { + D3D11DeviceContext()->Unmap( m_pVertexBuffer, 0 ); + + int nLockOffset = NextLockOffset(); + int nBufferSize = nWrittenVertexCount * m_VertexSize; + + m_Position = nLockOffset + nBufferSize; + } + else + { + D3D11_BOX box; + box.back = 1; + box.front = 0; + box.bottom = 1; + box.top = 0; + box.left = m_Position; + box.right = box.left + ( m_nVerticesLocked * VertexSize() ); + D3D11DeviceContext()->UpdateSubresource( m_pVertexBuffer, 0, &box, m_pVertexMemory + m_Position, 0, 0 ); + + m_Position += m_nVerticesLocked * VertexSize(); + } + + } + + //Spew( nWrittenVertexCount, desc ); + + m_bIsLocked = false; + //g_ShaderMutex.Unlock(); +} + +unsigned char *CVertexBufferDx11::Modify( bool bReadOnly, int nFirstVertex, int nVertexCount ) +{ + if ( nVertexCount == 0 ) + return NULL; + + Assert( m_pVertexBuffer && !m_bIsDynamic ); + + if ( nFirstVertex + nVertexCount > m_nVertexCount ) + { + Assert( 0 ); + return NULL; + } + + unsigned char *pData = m_pVertexMemory + ( nFirstVertex * m_VertexSize ); + m_nVerticesLocked = nVertexCount; + + m_Position = nFirstVertex * m_VertexSize; + m_bIsLocked = true; + + return pData; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/VertexBufferDx11.h b/materialsystem/shaderapidx11/VertexBufferDx11.h new file mode 100644 index 0000000..cf25aed --- /dev/null +++ b/materialsystem/shaderapidx11/VertexBufferDx11.h @@ -0,0 +1,94 @@ +#pragma once + +#include "shaderapidx9/meshbase.h" +#include "shaderapi/ishaderdevice.h" + +//----------------------------------------------------------------------------- +// Forward declaration +//----------------------------------------------------------------------------- +struct ID3D11Buffer; + +//----------------------------------------------------------------------------- +// Dx11 implementation of a vertex buffer +//----------------------------------------------------------------------------- +class CVertexBufferDx11 : public CVertexBufferBase +{ + typedef CVertexBufferBase BaseClass; + + // Methods of IVertexBuffer +public: + virtual int VertexCount() const; + virtual VertexFormat_t GetVertexFormat() const; + unsigned char *Modify( bool bReadOnly, int nFirstVertex, int nVertexCount ); + virtual bool Lock( int nMaxVertexCount, bool bAppend, VertexDesc_t& desc ); + bool LockEx( int nFirstVertex, int nMaxVertexCount, VertexDesc_t &desc ); + virtual void Unlock( int nWrittenVertexCount, VertexDesc_t& desc ); + virtual bool IsDynamic() const; + virtual void BeginCastBuffer( VertexFormat_t format ); + virtual void EndCastBuffer(); + virtual int GetRoomRemaining() const; + bool HasEnoughRoom( int nVertCount ) const; + + int NextLockOffset() const + { + int nNextOffset = ( m_Position + m_VertexSize - 1 ) / m_VertexSize; + nNextOffset *= m_VertexSize; + return nNextOffset; + } + + // used to alter the characteristics after creation + // allows one dynamic vb to be shared for multiple formats + void ChangeConfiguration( int vertexSize, int totalSize, VertexFormat_t fmt ) + { + Assert( m_bIsDynamic && !m_bIsLocked && vertexSize ); + m_VertexSize = vertexSize; + m_nVertexCount = m_nBufferSize / vertexSize; + m_VertexFormat = fmt; + } + + // Other public methods +public: + // constructor, destructor + CVertexBufferDx11( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char* pBudgetGroupName ); + virtual ~CVertexBufferDx11(); + + ID3D11Buffer* GetDx11Buffer() const; + int VertexSize() const; + + // Only used by dynamic buffers, indicates the next lock should perform a discard. + void Flush(); + +protected: + // Creates, destroys the index buffer + bool Allocate(); + void Free(); + + unsigned char *m_pVertexMemory; + int m_nVerticesLocked; + ID3D11Buffer* m_pVertexBuffer; + VertexFormat_t m_VertexFormat; + int m_VertexSize; + int m_nVertexCount; + int m_nBufferSize; + int m_Position; + bool m_bIsLocked : 1; + bool m_bIsDynamic : 1; + bool m_bFlush : 1; // Used only for dynamic buffers, indicates to discard the next time + +#ifdef _DEBUG + static int s_nBufferCount; +#endif +}; + +//----------------------------------------------------------------------------- +// inline methods for CVertexBufferDx11 +//----------------------------------------------------------------------------- +inline ID3D11Buffer* CVertexBufferDx11::GetDx11Buffer() const +{ + return m_pVertexBuffer; +} + +inline int CVertexBufferDx11::VertexSize() const +{ + return m_VertexSize; +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/inputlayoutdx11.cpp b/materialsystem/shaderapidx11/inputlayoutdx11.cpp new file mode 100644 index 0000000..2af242c --- /dev/null +++ b/materialsystem/shaderapidx11/inputlayoutdx11.cpp @@ -0,0 +1,323 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include +#include +#undef GetCommandLine + +#include "inputlayoutdx11.h" +#include "materialsystem/imesh.h" +#include "shaderdevicedx11.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Standard input layouts +//----------------------------------------------------------------------------- +static const DXGI_FORMAT s_pSizeLookup[] = +{ + DXGI_FORMAT_UNKNOWN, // Should be unused... + DXGI_FORMAT_R32_FLOAT, // D3DDECLTYPE_FLOAT1 + DXGI_FORMAT_R32G32_FLOAT, // D3DDECLTYPE_FLOAT2, + DXGI_FORMAT_R32G32B32_FLOAT, // D3DDECLTYPE_FLOAT3, + DXGI_FORMAT_R32G32B32A32_FLOAT, // D3DDECLTYPE_FLOAT4 +}; + +struct FieldInfo_t +{ + const char *m_pSemanticString; + unsigned int m_nSemanticIndex; + uint64 m_nFormatMask; + int m_nFieldSize; +}; + +// +// Stream 0 -- Base mesh data +// + +static FieldInfo_t s_pFieldInfo[] = +{ + { "POSITION", 0, VERTEX_POSITION, sizeof( float32 ) * 3 }, + { "BLENDWEIGHT", 0, VERTEX_BONE_WEIGHT_MASK, 0 }, + { "BLENDINDICES", 0, VERTEX_BONE_INDEX, 4 }, + { "NORMAL", 0, VERTEX_NORMAL, sizeof( float32 ) * 3 }, + { "COLOR", 0, VERTEX_COLOR, 4 }, + { "SPECULAR", 0, VERTEX_SPECULAR, 4 }, + { "TEXCOORD", 0, VERTEX_TEXCOORD_MASK(0), 0 }, + { "TEXCOORD", 1, VERTEX_TEXCOORD_MASK(1), 0 }, + { "TEXCOORD", 2, VERTEX_TEXCOORD_MASK(2), 0 }, + { "TEXCOORD", 3, VERTEX_TEXCOORD_MASK(3), 0 }, + { "TEXCOORD", 4, VERTEX_TEXCOORD_MASK(4), 0 }, + { "TEXCOORD", 5, VERTEX_TEXCOORD_MASK(5), 0 }, + { "TEXCOORD", 6, VERTEX_TEXCOORD_MASK(6), 0 }, + { "TEXCOORD", 7, VERTEX_TEXCOORD_MASK(7), 0 }, + { "TANGENT", 0, VERTEX_TANGENT_S, sizeof( float32 ) * 3 }, + { "BINORMAL", 0, VERTEX_TANGENT_T, sizeof( float32 ) * 3 }, + { "USERDATA", 0, USER_DATA_SIZE_MASK, 0 }, + { NULL, 0, 0 }, +}; + +static D3D11_INPUT_ELEMENT_DESC s_pVertexDesc[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "BLENDWEIGHT", 0, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "SPECULAR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 1, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 2, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 3, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 4, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 5, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 6, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 7, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "USERDATA", 0, DXGI_FORMAT_UNKNOWN, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +}; + +static D3D11_INPUT_ELEMENT_DESC s_pFallbackVertexDesc[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 0, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "BLENDWEIGHT", 0, DXGI_FORMAT_R32G32_FLOAT, 15, 12, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UINT, 15, 20, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 24, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 15, 36, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "SPECULAR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 15, 40, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 15, 44, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 15, 52, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 15, 60, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 3, DXGI_FORMAT_R32G32_FLOAT, 15, 68, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 4, DXGI_FORMAT_R32G32_FLOAT, 15, 76, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 5, DXGI_FORMAT_R32G32_FLOAT, 15, 84, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 6, DXGI_FORMAT_R32G32_FLOAT, 15, 92, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 7, DXGI_FORMAT_R32G32_FLOAT, 15, 100, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 108, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 120, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "USERDATA", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 15, 132, D3D11_INPUT_PER_INSTANCE_DATA, UINT_MAX }, +}; + + +//----------------------------------------------------------------------------- +// Computes the required input desc based on the vertex format +//----------------------------------------------------------------------------- +static void PrintInputDesc( int nCount, const D3D11_INPUT_ELEMENT_DESC *pDecl ) +{ + for ( int i = 0; i < nCount; i++ ) + { + Msg( "%s (%d): Stream: %d, Offset: %d, Instanced? %c\n", + pDecl[i].SemanticName, + pDecl[i].SemanticIndex, + ( int )pDecl[i].InputSlot, + ( int )pDecl[i].AlignedByteOffset, + pDecl[i].InputSlotClass == D3D11_INPUT_PER_VERTEX_DATA ? 'n' : 'y' + ); + } +} + + +//----------------------------------------------------------------------------- +// Checks to see if a shader requires a particular field +//----------------------------------------------------------------------------- +static bool CheckShaderSignatureExpectations( ID3D11ShaderReflection* pReflection, const char* pSemantic, unsigned int nSemanticIndex ) +{ + D3D11_SHADER_DESC shaderDesc; + D3D11_SIGNATURE_PARAMETER_DESC paramDesc; + + Assert( pSemantic ); + Assert( pReflection ); + + pReflection->GetDesc( &shaderDesc ); + + for ( unsigned int k=0; k < shaderDesc.InputParameters; k++ ) + { + pReflection->GetInputParameterDesc( k, ¶mDesc ); + if ( ( nSemanticIndex == paramDesc.SemanticIndex ) && !Q_stricmp( pSemantic, paramDesc.SemanticName ) ) + return true; + } + + return false; +} + +void MakeFallbackInputElement( D3D11_INPUT_ELEMENT_DESC &desc, const char *pszSemanticName, DXGI_FORMAT format, int nOffset ) +{ + desc.SemanticName = pszSemanticName; + desc.SemanticIndex = 0; + desc.InputSlot = 15; + desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + desc.Format = format; + desc.AlignedByteOffset = nOffset; + desc.InstanceDataStepRate = UINT_MAX; +} + +void MakeInputElement( D3D11_INPUT_ELEMENT_DESC &desc, const char *pszSemanticName, DXGI_FORMAT format, int nSlot, int nOffset, int nSemanticIndex = 0 ) +{ + desc.SemanticName = pszSemanticName; + desc.SemanticIndex = nSemanticIndex; + desc.InputSlot = nSlot; + desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + desc.Format = format; + desc.AlignedByteOffset = nOffset; + desc.InstanceDataStepRate = 0; +} + +//----------------------------------------------------------------------------- +// Computes the required input desc based on the vertex format +//----------------------------------------------------------------------------- +static unsigned int ComputeInputDesc( VertexFormat_t fmt, bool bStaticLit, bool bUsingFlex, bool bUsingMorph, + D3D11_INPUT_ELEMENT_DESC *pDecl, ID3D11ShaderReflection* pReflection ) +{ + unsigned int nCount = 0; + int nOffset = 0; + + // Fix up the global table so we don't need special-case code + int nBoneCount = NumBoneWeights( fmt ); + s_pFieldInfo[1].m_nFieldSize = sizeof( float ) * nBoneCount; + s_pVertexDesc[1].Format = s_pSizeLookup[nBoneCount]; + + int nUserDataSize = UserDataSize( fmt ); + s_pFieldInfo[16].m_nFieldSize = sizeof( float ) * nUserDataSize; + s_pVertexDesc[16].Format = s_pSizeLookup[nUserDataSize]; + + // NOTE: Fix s_pFieldInfo, s_pVertexDesc, s_pFallbackVertexDesc if you add more fields + // As well as the fallback stream (stream #15) + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i ) + { + int nTexCoordCount = TexCoordSize( i, fmt ); + s_pFieldInfo[6 + i].m_nFieldSize = sizeof( float ) * nTexCoordCount; + s_pVertexDesc[6 + i].Format = s_pSizeLookup[nTexCoordCount]; + } + + // FIXME: Change this loop so CheckShaderSignatureExpectations is called once! + for ( int i = 0; s_pFieldInfo[i].m_pSemanticString; ++i ) + { + if ( fmt & s_pFieldInfo[i].m_nFormatMask ) + { + memcpy( &pDecl[nCount], &s_pVertexDesc[i], sizeof(D3D11_INPUT_ELEMENT_DESC) ); + pDecl[nCount].AlignedByteOffset = nOffset; + nOffset += s_pFieldInfo[i].m_nFieldSize; + ++nCount; + } + else if ( CheckShaderSignatureExpectations( pReflection, s_pFieldInfo[i].m_pSemanticString, s_pFieldInfo[i].m_nSemanticIndex ) ) + { + memcpy( &pDecl[nCount], &s_pFallbackVertexDesc[i], sizeof(D3D11_INPUT_ELEMENT_DESC) ); + ++nCount; + } + } + + nOffset = 0; + + // Static lighting goes in stream 1 + if ( bStaticLit ) + { + D3D11_INPUT_ELEMENT_DESC staticLitDesc; + MakeInputElement( staticLitDesc, "STATICLIGHTING", DXGI_FORMAT_B8G8R8A8_UNORM, 1, nOffset ); + pDecl[nCount++] = staticLitDesc; + } + else + { + // Don't have static lighting, but shader might expect the data + if ( CheckShaderSignatureExpectations( pReflection, "STATICLIGHTING", 0 ) ) + { + D3D11_INPUT_ELEMENT_DESC staticLitDesc; + MakeFallbackInputElement( staticLitDesc, "STATICLIGHTING", DXGI_FORMAT_B8G8R8A8_UNORM, nOffset ); + pDecl[nCount++] = staticLitDesc; + } + } + + nOffset = 0; + + // Flex data goes in stream 2 + if ( bUsingFlex ) + { + // Wrinkle is in .w + D3D11_INPUT_ELEMENT_DESC flexDeltaDesc; + MakeInputElement( flexDeltaDesc, "FLEXDELTA", DXGI_FORMAT_R32G32B32A32_FLOAT, 2, nOffset ); + pDecl[nCount++] = flexDeltaDesc; + + nOffset += sizeof( float32 ) * 4; + + D3D11_INPUT_ELEMENT_DESC flexNormalDesc; + MakeInputElement( flexNormalDesc, "FLEXNORMAL", DXGI_FORMAT_R32G32B32_FLOAT, 2, nOffset ); + pDecl[nCount++] = flexNormalDesc; + } + else + { + // Don't have flex, but shader might expect the data. + + if ( CheckShaderSignatureExpectations( pReflection, "FLEXDELTA", 0 ) ) + { + // Wrinkle is in .w + D3D11_INPUT_ELEMENT_DESC flexDeltaDesc; + MakeFallbackInputElement( flexDeltaDesc, "FLEXDELTA", DXGI_FORMAT_R32G32B32A32_FLOAT, nOffset ); + pDecl[nCount++] = flexDeltaDesc; + + nOffset += sizeof( float32 ) * 4; + } + + if ( CheckShaderSignatureExpectations( pReflection, "FLEXNORMAL", 0 ) ) + { + D3D11_INPUT_ELEMENT_DESC flexNormalDesc; + MakeFallbackInputElement( flexNormalDesc, "FLEXNORMAL", DXGI_FORMAT_R32G32B32A32_FLOAT, nOffset ); + pDecl[nCount++] = flexNormalDesc; + } + } + + nOffset = 0; + + // Vertex ID/morph data goes in stream 3 + if ( bUsingMorph ) + { + D3D11_INPUT_ELEMENT_DESC vertexIDDesc; + MakeInputElement( vertexIDDesc, "MORPHVERTEXID", DXGI_FORMAT_R32G32B32_FLOAT, 3, nOffset ); + pDecl[nCount++] = vertexIDDesc; + } + else + { + // Don't have vertex ID, but shader might expect the data + if ( CheckShaderSignatureExpectations( pReflection, "MORPHVERTEXID", 0 ) ) + { + D3D11_INPUT_ELEMENT_DESC vertexIDDesc; + MakeFallbackInputElement( vertexIDDesc, "MORPHVERTEXID", DXGI_FORMAT_R32G32B32_FLOAT, nOffset ); + pDecl[nCount++] = vertexIDDesc; + } + } + + // For debugging only... + PrintInputDesc( nCount, pDecl ); + + return nCount; +} + + +//----------------------------------------------------------------------------- +// Gets the input layout associated with a vertex format +//----------------------------------------------------------------------------- +ID3D11InputLayout *CreateInputLayout( VertexFormat_t fmt, bool bStaticLit, bool bUsingFlex, bool bUsingMorph, + ID3D11ShaderReflection* pReflection, const void *pByteCode, size_t nByteCodeLen ) +{ + D3D11_INPUT_ELEMENT_DESC pDecl[32]; + unsigned int nDeclCount = ComputeInputDesc( fmt, bStaticLit, bUsingFlex, bUsingMorph, pDecl, pReflection ); + + ID3D11InputLayout *pInputLayout; + HRESULT hr = D3D11Device()->CreateInputLayout( pDecl, nDeclCount, pByteCode, nByteCodeLen, &pInputLayout ); + if ( FAILED( hr ) ) + { + Warning( "CreateInputLayout::Unable to create input layout for format %X!\n", fmt ); + return NULL; + } + return pInputLayout; +} diff --git a/materialsystem/shaderapidx11/inputlayoutdx11.h b/materialsystem/shaderapidx11/inputlayoutdx11.h new file mode 100644 index 0000000..0e44ea3 --- /dev/null +++ b/materialsystem/shaderapidx11/inputlayoutdx11.h @@ -0,0 +1,35 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef INPUTLAYOUTDX11_H +#define INPUTLAYOUTDX11_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "materialsystem/IMaterial.h" + + +//----------------------------------------------------------------------------- +// Forward declaration +//----------------------------------------------------------------------------- +struct ID3D11InputLayout; +struct ID3D11ShaderReflection; + + +//----------------------------------------------------------------------------- +// Gets the input layout associated with a vertex format +// FIXME: Note that we'll need to change this from a VertexFormat_t +//----------------------------------------------------------------------------- +ID3D11InputLayout *CreateInputLayout( VertexFormat_t fmt, bool bStaticLit, bool bUsingFlex, bool bUsingMorph, + ID3D11ShaderReflection* pReflection, const void *pByteCode, size_t nByteCodeLen ); + + +#endif // INPUTLAYOUTDX11_H + diff --git a/materialsystem/shaderapidx11/meshdx11.cpp b/materialsystem/shaderapidx11/meshdx11.cpp new file mode 100644 index 0000000..bcfd613 --- /dev/null +++ b/materialsystem/shaderapidx11/meshdx11.cpp @@ -0,0 +1,4173 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include +#undef GetCommandLine + +#include "materialsystem/imesh.h" +#include "meshdx11.h" +#include "utlvector.h" +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/materialsystem_config.h" +#include "IHardwareConfigInternal.h" +#include "shaderapidx9/shaderapi_global.h" +#include "shaderapi/ishaderutil.h" +#include "shaderapi/ishaderapi.h" +#include "shaderdevicedx11.h" +#include "materialsystem/imesh.h" +#include "tier0/vprof.h" +#include "tier0/dbg.h" +#include "materialsystem/idebugtextureinfo.h" +#include "materialsystem/ivballoctracker.h" +#include "tier2/tier2.h" +#include "shaderapidx11.h" +#include "VertexBufferDx11.h" +#include "IndexBufferDx11.h" +#include "shaderapi/ishaderutil.h" + +#ifdef _DEBUG +//#define CHECK_INDICES +#endif + +//----------------------------------------------------------------------------- +// Important enumerations +//----------------------------------------------------------------------------- +enum +{ + VERTEX_BUFFER_SIZE = 65536, + MAX_QUAD_INDICES = 16384, +}; + + +// this is hooked into the engines convar +extern ConVar mat_debugalttab; + +CShaderAPIDx11 *ShaderAPI() +{ + return g_pShaderAPIDx11; +} + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +#define VERTEX_FORMAT_INVALID 0xFFFFFFFFFFFFFFFFull + +//------------------------------------------------------------------ +// +// Mesh rendering begins here. Here's the annoyingly complex +// process: +// +// Before the Draw() function below is called, the user should've +// binded an IMaterial to the Shader API using g_pShaderAPI->Bind(). +// +// So, the Shader API currently has a material to use. +// +// The user then calls the Draw() function below on the mesh they +// want to render. By default, firstIndex = -1 and numIndices = 0, +// causing the entire mesh to draw. The user can specify which +// which vertex indices on the mesh to draw. +// +// DrawInternal() is then called from Draw(), passing the list of +// primitives on the mesh to draw. Each primitive in the list is +// simply a first index and an index count. The primitive list is +// then stored statically on CMeshDx11, so we only have one list +// of primitives to render floating around. +// +// DrawInternal() then calls DrawMesh(), which binds the mesh's +// vertex buffer, index buffer, and primitive topology type to the. +// Shader API. Finally, we call DrawMesh() on the Shader API, +// passing our mesh pointer. +// +// Shader API's DrawMesh() will then store our mesh pointer, and +// call DrawMesh() on the currently bound material, which will do +// the work of setting the snapshot state, binding the constant +// buffers and shaders, and setting other dynamic states. +// +// Each pass of a material will call Shader API's RenderPass() +// function. In this function, Shader API calls RenderPass() on the +// mesh pointer that we gave it, which tells the Shader API to +// actually issue the queued up state changes to D3D, and actually +// draw the individual primitives. +// +//------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +// Helpers with meshdescs... +//----------------------------------------------------------------------------- +// FIXME: add compression-agnostic read-accessors (which decompress and return by value, checking desc.m_CompressionType) +inline DirectX::XMFLOAT3 &Position( MeshDesc_t const &desc, int vert ) +{ + return *( DirectX::XMFLOAT3 *)( (unsigned char *)desc.m_pPosition + vert * desc.m_VertexSize_Position ); +} + +inline float Wrinkle( MeshDesc_t const &desc, int vert ) +{ + return *(float *)( (unsigned char *)desc.m_pWrinkle + vert * desc.m_VertexSize_Wrinkle ); +} + +inline DirectX::XMFLOAT3 &BoneWeight( MeshDesc_t const &desc, int vert ) +{ + Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE ); + return *( DirectX::XMFLOAT3 *)( (unsigned char *)desc.m_pBoneWeight + vert * desc.m_VertexSize_BoneWeight ); +} + +inline unsigned char *BoneIndex( MeshDesc_t const &desc, int vert ) +{ + return desc.m_pBoneMatrixIndex + vert * desc.m_VertexSize_BoneMatrixIndex; +} + +inline DirectX::XMFLOAT3 &Normal( MeshDesc_t const &desc, int vert ) +{ + Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE ); + return *( DirectX::XMFLOAT3 *)( (unsigned char *)desc.m_pNormal + vert * desc.m_VertexSize_Normal ); +} + +inline unsigned char *Color( MeshDesc_t const &desc, int vert ) +{ + return desc.m_pColor + vert * desc.m_VertexSize_Color; +} + +inline DirectX::XMFLOAT2 &TexCoord( MeshDesc_t const &desc, int vert, int stage ) +{ + return *( DirectX::XMFLOAT2 *)( (unsigned char *)desc.m_pTexCoord[stage] + vert * desc.m_VertexSize_TexCoord[stage] ); +} + +inline DirectX::XMFLOAT3 &TangentS( MeshDesc_t const &desc, int vert ) +{ + return *( DirectX::XMFLOAT3 *)( (unsigned char *)desc.m_pTangentS + vert * desc.m_VertexSize_TangentS ); +} + +inline DirectX::XMFLOAT3 &TangentT( MeshDesc_t const &desc, int vert ) +{ + return *( DirectX::XMFLOAT3 *)( (unsigned char *)desc.m_pTangentT + vert * desc.m_VertexSize_TangentT ); +} + +//----------------------------------------------------------------------------- +// Base class for the different mesh types. +//----------------------------------------------------------------------------- +class CBaseMeshDX11 : public CMeshBase +{ +public: + // constructor, destructor + CBaseMeshDX11(); + virtual ~CBaseMeshDX11(); + + // FIXME: Make this work! Unsupported methods of IIndexBuffer + IVertexBuffer + virtual bool Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t &desc ) + { + Assert( 0 ); return false; + } + virtual void Unlock( int nWrittenIndexCount, IndexDesc_t &desc ) + { + Assert( 0 ); + } + virtual void ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t &desc ) + { + Assert( 0 ); + } + virtual void ModifyEnd( IndexDesc_t &desc ) + { + Assert( 0 ); + } + virtual void Spew( int nIndexCount, const IndexDesc_t &desc ) + { + Assert( 0 ); + } + virtual void ValidateData( int nIndexCount, const IndexDesc_t &desc ) + { + Assert( 0 ); + } + virtual bool Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc ) + { + Assert( 0 ); return false; + } + virtual void Unlock( int nVertexCount, VertexDesc_t &desc ) + { + Assert( 0 ); + } + virtual void Spew( int nVertexCount, const VertexDesc_t &desc ) + { + Assert( 0 ); + } + virtual void ValidateData( int nVertexCount, const VertexDesc_t &desc ) + { + Assert( 0 ); + } + + // Locks mesh for modifying + void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ); + void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ); + void ModifyEnd( MeshDesc_t &desc ); + + // Sets/gets the vertex format + virtual void SetVertexFormat( VertexFormat_t format ); + virtual VertexFormat_t GetVertexFormat() const; + + // Sets/gets the morph format + virtual void SetMorphFormat( MorphFormat_t format ); + virtual MorphFormat_t GetMorphFormat() const; + // Am I using morph data? + virtual bool IsUsingMorphData() const; + bool IsUsingVertexID() const + { + return g_pShaderAPIDx11->GetBoundMaterial()->IsUsingVertexID(); + } + + // Sets the material + virtual void SetMaterial( IMaterial *pMaterial ); + + // returns the # of vertices (static meshes only) + int VertexCount() const + { + return 0; + } + + void SetColorMesh( IMesh *pColorMesh, int nVertexOffsetInBytes ) + { + Assert( 0 ); + } + + void SetFlexMesh( IMesh *pMesh, int nVertexOffsetInBytes ) + { + Assert( pMesh == NULL && nVertexOffsetInBytes == 0 ); + } + + void DisableFlexMesh() + { + Assert( 0 ); + } + + void MarkAsDrawn() + { + } + + bool HasColorMesh() const + { + return false; + } + bool HasFlexMesh() const + { + return false; + } + + // Draws the mesh + void DrawMesh(); + + // Begins a pass + void BeginPass(); + + // Spews the mesh data + virtual void Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ); + + // Call this in debug mode to make sure our data is good. + virtual void ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ); + + void Draw( CPrimList *pLists, int nLists ); + + // Copy verts and/or indices to a mesh builder. This only works for temp meshes! + virtual void CopyToMeshBuilder( + int iStartVert, // Which vertices to copy. + int nVerts, + int iStartIndex, // Which indices to copy. + int nIndices, + int indexOffset, // This is added to each index. + CMeshBuilder &builder ); + + // returns the primitive type + virtual MaterialPrimitiveType_t GetPrimitiveType() const = 0; + + // Returns the number of indices in a mesh.. + virtual int IndexCount() const = 0; + + // FIXME: Make this work! + virtual MaterialIndexFormat_t IndexFormat() const + { + return MATERIAL_INDEX_FORMAT_16BIT; + } + + // NOTE: For dynamic index buffers only! + // Casts the memory of the dynamic index buffer to the appropriate type + virtual void BeginCastBuffer( MaterialIndexFormat_t format ) + { + Assert( 0 ); + } + virtual void BeginCastBuffer( VertexFormat_t format ) + { + Assert( 0 ); + } + virtual void EndCastBuffer() + { + Assert( 0 ); + } + virtual int GetRoomRemaining() const + { + Assert( 0 ); return 0; + } + + // returns a static vertex buffer... + virtual CVertexBufferDx11 *GetVertexBuffer() + { + return 0; + } + virtual CIndexBufferDx11 *GetIndexBuffer() + { + return 0; + } + + // Do I need to reset the vertex format? + virtual bool NeedsVertexFormatReset( VertexFormat_t fmt ) const; + + // Do I have enough room? + virtual bool HasEnoughRoom( int nVertexCount, int nIndexCount ) const; + + // Operation to do pre-lock + virtual void PreLock() + { + } + + virtual unsigned ComputeMemoryUsed(); + + bool m_bMeshLocked; + +protected: + bool DebugTrace() const; + + // The vertex format we're using... + VertexFormat_t m_VertexFormat; + + // The morph format we're using + MorphFormat_t m_MorphFormat; + +#ifdef _DEBUG + IMaterialInternal *m_pMaterial; + bool m_IsDrawing; +#endif +}; + +//----------------------------------------------------------------------------- +// Implementation of the mesh +//----------------------------------------------------------------------------- +class CMeshDX11 : public CBaseMeshDX11 +{ +public: + // constructor + CMeshDX11( const char *pTextureGroupName ); + virtual ~CMeshDX11(); + + // Locks/unlocks the mesh + void LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + + // Locks mesh for modifying + void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ); + void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ); + void ModifyEnd( MeshDesc_t &desc ); + + // returns the # of vertices (static meshes only) + int VertexCount() const; + + // returns the # of indices + virtual int IndexCount() const; + + // Sets up the vertex and index buffers + void UseIndexBuffer( CIndexBufferDx11 *pBuffer ); + void UseVertexBuffer( CVertexBufferDx11 *pBuffer ); + + // returns a static vertex buffer... + CVertexBufferDx11 *GetVertexBuffer() + { + return m_pVertexBuffer; + } + CIndexBufferDx11 *GetIndexBuffer() + { + return m_pIndexBuffer; + } + + void SetColorMesh( IMesh *pColorMesh, int nVertexOffsetInBytes ); + void SetFlexMesh( IMesh *pMesh, int nVertexOffsetInBytes ); + void DisableFlexMesh(); + + bool HasColorMesh() const; + bool HasFlexMesh() const; + + // Draws the mesh + void Draw( int nFirstIndex, int nIndexCount ); + void Draw( CPrimList *pLists, int nLists ); + void DrawInternal( CPrimList *pLists, int nLists ); + + // Draws a single pass + void RenderPass(); + + // Sets the primitive type + void SetPrimitiveType( MaterialPrimitiveType_t type ); + MaterialPrimitiveType_t GetPrimitiveType() const; + + bool IsDynamic() const + { + return false; + } + + void CheckIndices( CPrimList *pPrim, int numPrimitives ); + +protected: + // Sets the render state. + bool SetRenderState( int nFirstIndex, int nFirstVertexIdx, VertexFormat_t vertexFormat = VERTEX_FORMAT_INVALID ); + + // Is the vertex format valid? + bool IsValidVertexFormat( VertexFormat_t vertexFormat = VERTEX_FORMAT_INVALID ); + + // Locks/ unlocks the vertex buffer + bool Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc ); + void Unlock( int nVertexCount, VertexDesc_t &desc ); + + // Locks/unlocks the index buffer + // Pass in nFirstIndex=-1 to lock wherever the index buffer is. Pass in a value + // >= 0 to specify where to lock. + int Lock( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t &pIndices ); + void Unlock( int nIndexCount, IndexDesc_t &desc ); + + // computes how many primitives we've got + int NumPrimitives( int nVertexCount, int nIndexCount ) const; + + // The vertex and index buffers + CVertexBufferDx11 *m_pVertexBuffer; + CIndexBufferDx11 *m_pIndexBuffer; + + // The current color mesh (to be bound to stream 1) + // The vertex offset allows use of a global, shared color mesh VB + CMeshDX11 *m_pColorMesh; + int m_nColorMeshVertOffsetInBytes; + + CVertexBufferDx11 *m_pFlexVertexBuffer; + + bool m_bHasFlexVerts; + int m_nFlexVertOffsetInBytes; + int m_flexVertCount; + + // Primitive type + MaterialPrimitiveType_t m_Type; + + // Number of primitives + unsigned short m_NumVertices; + unsigned short m_NumIndices; + + // Is it locked? + bool m_IsVBLocked; + bool m_IsIBLocked; + + // Used in rendering sub-parts of the mesh + static CPrimList *s_pPrims; + static int s_nPrims; + static unsigned int s_FirstVertex; // Gets reset during CMeshDX8::DrawInternal + static unsigned int s_NumVertices; + int m_FirstIndex; + +#ifdef RECORDING + int m_LockVertexBufferSize; + void *m_LockVertexBuffer; +#endif + +#if defined( RECORDING ) || defined( CHECK_INDICES ) + void *m_LockIndexBuffer; + int m_LockIndexBufferSize; +#endif + const char *m_pTextureGroupName; + + friend class CMeshMgr; // MESHFIXME +}; + +//----------------------------------------------------------------------------- +// A little extra stuff for the dynamic version +//----------------------------------------------------------------------------- +class CDynamicMeshDX11 : public CMeshDX11 +{ +public: + // constructor, destructor + CDynamicMeshDX11(); + virtual ~CDynamicMeshDX11(); + + // Initializes the dynamic mesh + void Init( int nBufferId ); + + // Sets the vertex format + virtual void SetVertexFormat( VertexFormat_t format ); + + // Resets the state in case of a task switch + void Reset(); + + // Do I have enough room in the buffer? + bool HasEnoughRoom( int nVertexCount, int nIndexCount ) const; + + // returns the # of indices + int IndexCount() const; + + // Locks the mesh + void LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + + // Unlocks the mesh + void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + + // Override vertex + index buffer + void OverrideVertexBuffer( CVertexBufferDx11 *pStaticVertexBuffer ); + void OverrideIndexBuffer( CIndexBufferDx11 *pStaticIndexBuffer ); + + // Do I need to reset the vertex format? + bool NeedsVertexFormatReset( VertexFormat_t fmt ) const; + + // Draws it + void Draw( int nFirstIndex, int nIndexCount ); + void MarkAsDrawn() + { + m_HasDrawn = true; + } + // Simply draws what's been buffered up immediately, without state change + void DrawSinglePassImmediately(); + + // Operation to do pre-lock + void PreLock(); + + bool IsDynamic() const + { + return true; + } + +private: + // Resets buffering state + void ResetVertexAndIndexCounts(); + + // Buffer Id + int m_nBufferId; + + // total queued vertices + int m_TotalVertices; + int m_TotalIndices; + + // the first vertex and index since the last draw + int m_nFirstVertex; + int m_FirstIndex; + + // Have we drawn since the last lock? + bool m_HasDrawn; + + // Any overrides? + bool m_VertexOverride; + bool m_IndexOverride; +}; + + +//----------------------------------------------------------------------------- +// A mesh that stores temporary vertex data in the correct format (for modification) +//----------------------------------------------------------------------------- +class CTempMeshDX11 : public CBaseMeshDX11 +{ +public: + // constructor, destructor + CTempMeshDX11( bool isDynamic ); + virtual ~CTempMeshDX11(); + + // Sets the material + virtual void SetVertexFormat( VertexFormat_t format ); + + // Locks/unlocks the mesh + void LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + + // Locks mesh for modifying + virtual void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ); + virtual void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ); + virtual void ModifyEnd( MeshDesc_t &desc ); + + // Number of indices + vertices + int VertexCount() const; + virtual int IndexCount() const; + virtual bool IsDynamic() const; + + // Sets the primitive type + void SetPrimitiveType( MaterialPrimitiveType_t type ); + MaterialPrimitiveType_t GetPrimitiveType() const; + + // Begins a pass + void BeginPass(); + + // Draws a single pass + void RenderPass(); + + // Draws the entire beast + void Draw( int nFirstIndex, int nIndexCount ); + + virtual void CopyToMeshBuilder( + int iStartVert, // Which vertices to copy. + int nVerts, + int iStartIndex, // Which indices to copy. + int nIndices, + int indexOffset, // This is added to each index. + CMeshBuilder &builder ); +private: + // Selection mode + void TestSelection(); + void ClipTriangle( DirectX::XMVECTOR **ppVert, float zNear, DirectX::XMMATRIX &proj ); + + CDynamicMeshDX11 *GetDynamicMesh(); + + CUtlVector< unsigned char, CUtlMemoryAligned< unsigned char, 32 > > m_VertexData; + CUtlVector< unsigned short > m_IndexData; + + unsigned short m_VertexSize; + MaterialPrimitiveType_t m_Type; + int m_LockedVerts; + int m_LockedIndices; + bool m_IsDynamic; + + // Used in rendering sub-parts of the mesh + static unsigned int s_NumIndices; + static unsigned int s_FirstIndex; + +#ifdef _DEBUG + bool m_Locked; + bool m_InPass; +#endif +}; + + +//----------------------------------------------------------------------------- +// This is a version that buffers up vertex data so we can blast through it later +//----------------------------------------------------------------------------- +class CBufferedMeshDX11 : public CBaseMeshDX11 +{ +public: + // constructor, destructor + CBufferedMeshDX11(); + virtual ~CBufferedMeshDX11(); + + // checks to see if it was rendered.. + void ResetRendered(); + bool WasNotRendered() const; + + // Sets the mesh we're really going to draw into + void SetMesh( CBaseMeshDX11 *pMesh ); + const CBaseMeshDX11 *GetMesh() const + { + return m_pMesh; + } + +// Spews the mesh data + virtual void Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &spewDesc ); + + // Sets the vertex format + virtual void SetVertexFormat( VertexFormat_t format ); + virtual VertexFormat_t GetVertexFormat() const; + + // Sets the morph format + virtual void SetMorphFormat( MorphFormat_t format ); + + // Sets the material + void SetMaterial( IMaterial *pMaterial ); + + // returns the number of indices (should never be called!) + virtual int IndexCount() const + { + Assert( 0 ); return 0; + } + virtual MaterialIndexFormat_t IndexFormat() const + { + Assert( 0 ); return MATERIAL_INDEX_FORMAT_16BIT; + } + virtual bool IsDynamic() const + { + Assert( 0 ); return true; + } + virtual void BeginCastBuffer( MaterialIndexFormat_t format ) + { + Assert( 0 ); + } + virtual void EndCastBuffer() + { + Assert( 0 ); + } + virtual int GetRoomRemaining() const + { + Assert( 0 ); return 0; + } + + // Locks the mesh + void LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ); + + // Sets the primitive type + void SetPrimitiveType( MaterialPrimitiveType_t type ); + MaterialPrimitiveType_t GetPrimitiveType() const; + + void ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &spewDesc ); + + // Draws it + void Draw( int nFirstIndex, int nIndexCount ); + + // Renders a pass + void RenderPass(); + + // Flushes queued data + void Flush(); + + void SetFlexMesh( IMesh *pMesh, int nVertexOffsetInBytes ); + +private: + // The actual mesh we need to render.... + CBaseMeshDX11 *m_pMesh; + + // The index of the last vertex (for tristrip fixup) + unsigned short m_LastIndex; + + // Extra padding indices for tristrips + unsigned short m_ExtraIndices; + + // Am I currently flushing? + bool m_IsFlushing; + + // has the dynamic mesh been rendered? + bool m_WasRendered; + + // Do I need to flush? + bool m_FlushNeeded; + +#ifdef DEBUG_BUFFERED_MESHES + // for debugging only + bool m_BufferedStateSet; + BufferedState_t m_BufferedState; +#endif +}; + +//----------------------------------------------------------------------------- +// Implementation of the mesh manager +//----------------------------------------------------------------------------- +class CMeshMgr : public IMeshMgrDx11 +{ +public: + // constructor, destructor + CMeshMgr(); + virtual ~CMeshMgr(); + + // Initialize, shutdown + void Init(); + void Shutdown(); + + // Task switch... + void ReleaseBuffers(); + void RestoreBuffers(); + + // Releases all dynamic vertex buffers + void DestroyVertexBuffers(); + + // Flushes the dynamic mesh + void Flush(); + + // Flushes the vertex buffers + void DiscardVertexBuffers(); + + // Creates, destroys static meshes + IMesh *CreateStaticMesh( VertexFormat_t vertexFormat, const char *pTextureBudgetGroup, IMaterial *pMaterial = NULL ); + void DestroyStaticMesh( IMesh *pMesh ); + + // Gets at the dynamic mesh (spoofs it though) + IMesh *GetDynamicMesh( IMaterial *pMaterial, VertexFormat_t vertexFormat, int nHWSkinBoneCount, bool buffered, + IMesh *pVertexOverride, IMesh *pIndexOverride ); + + // ----------------------------------------------------------- + // ------------ New Vertex/Index Buffer interface ---------------------------- + // Do we need support for bForceTempMesh and bSoftwareVertexShader? + // I don't think we use bSoftwareVertexShader anymore. .need to look into bForceTempMesh. + IVertexBuffer *CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup ) + { + Assert( 0 ); + return NULL; + } + IIndexBuffer *CreateIndexBuffer( ShaderBufferType_t bufferType, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup ) + { + Assert( 0 ); + return NULL; + } + void DestroyVertexBuffer( IVertexBuffer * ) + { + Assert( 0 ); + } + void DestroyIndexBuffer( IIndexBuffer * ) + { + Assert( 0 ); + } + // Do we need to specify the stream here in the case of locking multiple dynamic VBs on different streams? + IVertexBuffer *GetDynamicVertexBuffer( int streamID, VertexFormat_t vertexFormat, bool bBuffered = true ); + IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true ); + void BindVertexBuffer( int streamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 ) + { + Assert( 0 ); + } + void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ) + { + Assert( 0 ); + } + void Draw( MaterialPrimitiveType_t primitiveType, int nFirstIndex, int nIndexCount ) + { + Assert( 0 ); + } + // ------------ End ---------------------------- + void RenderPassWithVertexAndIndexBuffers( void ); + + VertexFormat_t GetCurrentVertexFormat( void ) const + { + return m_CurrentVertexFormat; + } + + // Gets at the *actual* dynamic mesh + IMesh *GetActualDynamicMesh( VertexFormat_t vertexFormat ); + IMesh *GetFlexMesh(); + + // Computes vertex format from a list of ingredients + VertexFormat_t ComputeVertexFormat( unsigned int flags, + int numTexCoords, int *pTexCoordDimensions, int numBoneWeights, + int userDataSize ) const; + + // Use fat vertices (for tools) + virtual void UseFatVertices( bool bUseFat ); + + // Returns the number of vertices we can render using the dynamic mesh + virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ); + virtual int GetMaxVerticesToRender( IMaterial *pMaterial ); + virtual int GetMaxIndicesToRender(); + + // Returns a vertex buffer appropriate for the flags + CVertexBufferDx11 *FindOrCreateVertexBuffer( int nDynamicBufferId, VertexFormat_t fmt ); + CIndexBufferDx11 *GetDynamicIndexBuffer(); + + // Is the mesh dynamic? + bool IsDynamicMesh( IMesh *pMesh ) const; + bool IsBufferedDynamicMesh( IMesh *pMesh ) const; + + // Is the vertex buffer dynamic? + bool IsDynamicVertexBuffer( IVertexBuffer *pVertexBuffer ) const; + + // Is the index buffer dynamic? + bool IsDynamicIndexBuffer( IIndexBuffer *pIndexBuffer ) const; + + // Returns the vertex size + int VertexFormatSize( VertexFormat_t vertexFormat ) const + { + return CVertexBufferBase::VertexFormatSize( vertexFormat ); + } + + CVertexBufferDx11 *GetVertexIDBuffer(); + + // Computes the vertex buffer pointers + void ComputeVertexDescription( unsigned char *pBuffer, + VertexFormat_t vertexFormat, MeshDesc_t &desc ) const; + + IVertexBuffer *GetDynamicVertexBuffer( IMaterial *pMaterial, bool buffered = true ); + IIndexBuffer *GetDynamicIndexBuffer( IMaterial *pMaterial, bool buffered = true ); + virtual void MarkUnusedVertexFields( unsigned int nFlags, int nTexCoordCount, bool *pUnusedTexCoords ); + + int UnusedVertexFields() const + { + return m_nUnusedVertexFields; + } + int UnusedTextureCoords() const + { + return m_nUnusedTextureCoords; + } + + virtual int BufferCount() const + { + return 0; + } + +private: + void CreateVertexIDBuffer(); + void DestroyVertexIDBuffer(); + void FillVertexIDBuffer( CVertexBufferDx11 *pVertexIDBuffer, int nCount ); + + bool SetRenderState( int nVertexOffsetInBytes, int nFirstVertexIdx, VertexFormat_t vertexFormat, int nVertexStride ); + + struct VertexBufferLookup_t + { + CVertexBufferDx11 *m_pBuffer; + int m_VertexSize; + VertexFormat_t m_VertexFormat; + }; + + void CopyStaticMeshIndexBufferToTempMeshIndexBuffer( CTempMeshDX11 *pDstIndexMesh, CMeshDX11 *pSrcIndexMesh ); + + // Cleans up the class + void CleanUp(); + + // The dynamic index buffer + CIndexBufferDx11 *m_pDynamicIndexBuffer; + + // A static vertexID buffer + CVertexBufferDx11 *m_pVertexIDBuffer; + + // The dynamic vertex buffers + CUtlVector< VertexBufferLookup_t > m_DynamicVertexBuffers; + + // The buffered mesh + CBufferedMeshDX11 m_BufferedMesh; + + // The current dynamic mesh + CDynamicMeshDX11 m_DynamicMesh; + CDynamicMeshDX11 m_DynamicFlexMesh; + + // The current dynamic vertex buffer + CVertexBufferDx11 m_DynamicVertexBuffer; + + // The current dynamic index buffer + CIndexBufferDx11 m_DynamicIndexBuffer; + + // The dynamic mesh temp version (for shaders that modify vertex data) + CTempMeshDX11 m_DynamicTempMesh; + + // Am I buffering or not? + bool m_BufferedMode; + + // Using fat vertices? + bool m_bUseFatVertices; + + CVertexBufferDx11 *m_pCurrentVertexBuffer; + VertexFormat_t m_CurrentVertexFormat; + int m_pVertexBufferOffset[MAX_DX11_STREAMS]; + int m_pCurrentVertexStride[MAX_DX11_STREAMS]; + int m_pFirstVertex[MAX_DX11_STREAMS]; + int m_pVertexCount[MAX_DX11_STREAMS]; + CIndexBufferBase *m_pCurrentIndexBuffer; + int m_nIndexBufferOffset; + MaterialPrimitiveType_t m_PrimitiveType; + int m_nFirstIndex; + int m_nNumIndices; + + unsigned int m_nUnusedVertexFields; + unsigned int m_nUnusedTextureCoords; +}; + +//----------------------------------------------------------------------------- +// Singleton Dx11 Mesh manager +//----------------------------------------------------------------------------- +static CMeshMgr g_MeshMgr; +IMeshMgrDx11 *MeshMgr() +{ + return &g_MeshMgr; +} + +static CIndexBufferDx11 *g_pLastIndex = NULL; +static CVertexBufferDx11 *g_pLastVertex = NULL; +static CMeshDX11 *g_pLastColorMesh = NULL; + +//----------------------------------------------------------------------------- +// +// Base mesh +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- + +CBaseMeshDX11::CBaseMeshDX11() : m_VertexFormat( 0 ) +{ + m_bMeshLocked = false; +#ifdef _DEBUG + m_IsDrawing = false; + m_pMaterial = 0; +#endif +} + +CBaseMeshDX11::~CBaseMeshDX11() +{ +} + + +//----------------------------------------------------------------------------- +// For debugging... +//----------------------------------------------------------------------------- +bool CBaseMeshDX11::DebugTrace() const +{ +//#ifdef _DEBUG + if (g_pShaderAPIDx11->GetBoundMaterial()) + return g_pShaderAPIDx11->GetBoundMaterial()->PerformDebugTrace(); +//#endif + + return false; +} + +void CBaseMeshDX11::SetMaterial( IMaterial *pMaterial ) +{ +#ifdef _DEBUG + m_pMaterial = static_cast( pMaterial ); +#endif +} + + +//----------------------------------------------------------------------------- +// Sets, gets the vertex format +//----------------------------------------------------------------------------- +void CBaseMeshDX11::SetVertexFormat( VertexFormat_t format ) +{ + m_VertexFormat = format; +} + +VertexFormat_t CBaseMeshDX11::GetVertexFormat() const +{ + return m_VertexFormat; +} + + +//----------------------------------------------------------------------------- +// Sets/gets the morph format +//----------------------------------------------------------------------------- +void CBaseMeshDX11::SetMorphFormat( MorphFormat_t format ) +{ + m_MorphFormat = format; +} + +MorphFormat_t CBaseMeshDX11::GetMorphFormat() const +{ + return m_MorphFormat; +} + + +//----------------------------------------------------------------------------- +// Am I using morph data? +//----------------------------------------------------------------------------- +bool CBaseMeshDX11::IsUsingMorphData() const +{ + LOCK_SHADERAPI(); + // We're not using a morph unless the bound morph is a superset of what the rendermesh needs + MorphFormat_t morphFormat = GetMorphFormat(); + if ( !morphFormat ) + return false; + + return ( ( morphFormat & ShaderUtil()->GetBoundMorphFormat() ) == morphFormat ); +} + +//----------------------------------------------------------------------------- +// Do I need to reset the vertex format? +//----------------------------------------------------------------------------- +bool CBaseMeshDX11::NeedsVertexFormatReset( VertexFormat_t fmt ) const +{ + return m_VertexFormat != fmt; +} + + +//----------------------------------------------------------------------------- +// Do I have enough room? +//----------------------------------------------------------------------------- +bool CBaseMeshDX11::HasEnoughRoom( int nVertexCount, int nIndexCount ) const +{ + // by default, we do + return true; +} + +//----------------------------------------------------------------------------- +// Estimate the memory used +//----------------------------------------------------------------------------- +unsigned CBaseMeshDX11::ComputeMemoryUsed() +{ + unsigned size = 0; + + if (GetVertexBuffer()) + { + size += GetVertexBuffer()->VertexCount() * GetVertexBuffer()->VertexSize(); + } + + if (GetIndexBuffer()) + { + size += GetIndexBuffer()->IndexCount() * GetIndexBuffer()->IndexSize(); + } + + return size; +} + + +//----------------------------------------------------------------------------- +// Locks mesh for modifying +//----------------------------------------------------------------------------- +void CBaseMeshDX11::ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) +{ + LOCK_SHADERAPI(); + // for the time being, disallow for most cases + Assert( 0 ); +} + +void CBaseMeshDX11::ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) +{ + LOCK_SHADERAPI(); + // for the time being, disallow for most cases + Assert( 0 ); +} + +void CBaseMeshDX11::ModifyEnd( MeshDesc_t &desc ) +{ + LOCK_SHADERAPI(); + // for the time being, disallow for most cases + Assert( 0 ); +} + + +//----------------------------------------------------------------------------- +// Begins a pass +//----------------------------------------------------------------------------- +void CBaseMeshDX11::BeginPass() +{ + LOCK_SHADERAPI(); +} + + +//----------------------------------------------------------------------------- +// Sets the render state and gets the drawing going +//----------------------------------------------------------------------------- +inline void CBaseMeshDX11::DrawMesh() +{ +#ifdef _DEBUG + // Make sure we're not drawing... + Assert( !m_IsDrawing ); + m_IsDrawing = true; +#endif + + // This is going to cause RenderPass to get called a bunch + g_pShaderAPIDx11->DrawMesh( this ); + +#ifdef _DEBUG + m_IsDrawing = false; +#endif +} + + +//----------------------------------------------------------------------------- +// Spews the mesh data +//----------------------------------------------------------------------------- +void CBaseMeshDX11::Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &spewDesc ) +{ + LOCK_SHADERAPI(); + // This has regressed. + int i; + + + // FIXME: just fall back to the base class (CVertexBufferBase) version of this function! + + +#ifdef _DEBUG + if ( m_pMaterial ) + { + Plat_DebugString( (const char *)m_pMaterial->GetName() ); + Plat_DebugString( "\n" ); + } +#endif // _DEBUG + + // This is needed so buffering can just use this + VertexFormat_t fmt = m_VertexFormat; + + // Set up the vertex descriptor + MeshDesc_t desc = spewDesc; + + char tempbuf[256]; + char *temp = tempbuf; + sprintf( tempbuf, "\nVerts: (Vertex Format %x)\n", (unsigned int)fmt ); + Plat_DebugString( tempbuf ); + + CVertexBufferBase::PrintVertexFormat( fmt ); + + int numBoneWeights = NumBoneWeights( fmt ); + for ( i = 0; i < nVertexCount; ++i ) + { + temp += sprintf( temp, "[%4d] ", i + desc.m_nFirstVertex ); + if ( fmt & VERTEX_POSITION ) + { + DirectX::XMFLOAT3 &pos = Position( desc, i ); + temp += sprintf( temp, "P %8.2f %8.2f %8.2f ", + pos.x, pos.y, pos.z ); + } + + if ( fmt & VERTEX_WRINKLE ) + { + float flWrinkle = Wrinkle( desc, i ); + temp += sprintf( temp, "Wr %8.2f ", flWrinkle ); + } + + if ( numBoneWeights > 0 ) + { + temp += sprintf( temp, "BW " ); + DirectX::XMFLOAT3 pWeight = BoneWeight( desc, i ); + for ( int j = 0; j < numBoneWeights; ++j ) + { + float weight = (*(float*)&(&pWeight)[j]); // evil casting + temp += sprintf( temp, "%1.2f ", weight); + } + } + if ( fmt & VERTEX_BONE_INDEX ) + { + unsigned char *pIndex = BoneIndex( desc, i ); + temp += sprintf( temp, "BI %d %d %d %d ", (int)pIndex[0], (int)pIndex[1], (int)pIndex[2], (int)pIndex[3] ); + Assert( pIndex[0] >= 0 && pIndex[0] < 16 ); + Assert( pIndex[1] >= 0 && pIndex[1] < 16 ); + Assert( pIndex[2] >= 0 && pIndex[2] < 16 ); + Assert( pIndex[3] >= 0 && pIndex[3] < 16 ); + } + + if ( fmt & VERTEX_NORMAL ) + { + DirectX::XMFLOAT3 &normal = Normal( desc, i ); + temp += sprintf( temp, "N %1.2f %1.2f %1.2f ", + normal.x, normal.y, normal.z ); + } + + if ( fmt & VERTEX_COLOR ) + { + unsigned char *pColor = Color( desc, i ); + temp += sprintf( temp, "C b %3d g %3d r %3d a %3d ", + pColor[0], pColor[1], pColor[2], pColor[3] ); + } + + for ( int j = 0; j < VERTEX_MAX_TEXTURE_COORDINATES; ++j ) + { + if ( TexCoordSize( j, fmt ) > 0 ) + { + DirectX::XMFLOAT2 &texcoord = TexCoord( desc, i, j ); + temp += sprintf( temp, "T%d %.2f %.2f ", j, texcoord.x, texcoord.y ); + } + } + + if ( fmt & VERTEX_TANGENT_S ) + { + DirectX::XMFLOAT3 &tangentS = TangentS( desc, i ); + temp += sprintf( temp, "S %1.2f %1.2f %1.2f ", + tangentS.x, tangentS.y, tangentS.z ); + } + + if ( fmt & VERTEX_TANGENT_T ) + { + DirectX::XMFLOAT3 &tangentT = TangentT( desc, i ); + temp += sprintf( temp, "T %1.2f %1.2f %1.2f ", + tangentT.x, tangentT.y, tangentT.z ); + } + + sprintf( temp, "\n" ); + Plat_DebugString( tempbuf ); + temp = tempbuf; + } + + sprintf( tempbuf, "\nIndices: %d\n", nIndexCount ); + Plat_DebugString( tempbuf ); + for ( i = 0; i < nIndexCount; ++i ) + { + temp += sprintf( temp, "%d ", (int)desc.m_pIndices[i] ); + if ( ( i & 0x0F ) == 0x0F ) + { + sprintf( temp, "\n" ); + Plat_DebugString( tempbuf ); + tempbuf[0] = '\0'; + temp = tempbuf; + } + } + sprintf( temp, "\n" ); + Plat_DebugString( tempbuf ); +} + +void CBaseMeshDX11::ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &spewDesc ) +{ + LOCK_SHADERAPI(); +} + +void CBaseMeshDX11::Draw( CPrimList *pLists, int nLists ) +{ + LOCK_SHADERAPI(); + Assert( !"CBaseMeshDX11::Draw(CPrimList, int): should never get here." ); +} + + +// Copy verts and/or indices to a mesh builder. This only works for temp meshes! +void CBaseMeshDX11::CopyToMeshBuilder( + int iStartVert, // Which vertices to copy. + int nVerts, + int iStartIndex, // Which indices to copy. + int nIndices, + int indexOffset, // This is added to each index. + CMeshBuilder &builder ) +{ + LOCK_SHADERAPI(); + Assert( false ); + Warning( "CopyToMeshBuilder called on something other than a temp mesh.\n" ); +} + +//----------------------------------------------------------------------------- +// +// static mesh +// +//----------------------------------------------------------------------------- + +CPrimList *CMeshDX11::s_pPrims; +int CMeshDX11::s_nPrims; +unsigned int CMeshDX11::s_FirstVertex; +unsigned int CMeshDX11::s_NumVertices; + +//----------------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------------- +CMeshDX11::CMeshDX11( const char *pTextureGroupName ) : m_NumVertices( 0 ), m_NumIndices( 0 ), m_pVertexBuffer( 0 ), +m_pColorMesh( 0 ), m_nColorMeshVertOffsetInBytes( 0 ), +m_pIndexBuffer( 0 ), m_Type( MATERIAL_TRIANGLES ), m_IsVBLocked( false ), +m_IsIBLocked( false ) +{ + m_pTextureGroupName = pTextureGroupName; + + m_bHasFlexVerts = false; + m_pFlexVertexBuffer = NULL; + m_nFlexVertOffsetInBytes = 0; +} + +CMeshDX11::~CMeshDX11() +{ + // Don't release the vertex buffer + if ( !g_MeshMgr.IsDynamicMesh( this ) ) + { + if ( m_pVertexBuffer ) + { + g_pShaderDevice->DestroyVertexBuffer( m_pVertexBuffer ); + } + if ( m_pIndexBuffer ) + { + g_pShaderDevice->DestroyIndexBuffer( m_pIndexBuffer ); + } + } +} + +void CMeshDX11::SetFlexMesh( IMesh *pMesh, int nVertexOffsetInBytes ) +{ + if ( !ShaderUtil()->OnSetFlexMesh( this, pMesh, nVertexOffsetInBytes ) ) + return; + + LOCK_SHADERAPI(); + m_nFlexVertOffsetInBytes = nVertexOffsetInBytes; // Offset into dynamic mesh (in bytes) + + if ( pMesh ) + { + m_flexVertCount = pMesh->VertexCount(); + pMesh->MarkAsDrawn(); + + CBaseMeshDX11 *pBaseMesh = static_cast( pMesh ); + m_pFlexVertexBuffer = pBaseMesh->GetVertexBuffer(); + + m_bHasFlexVerts = true; + } + else + { + m_flexVertCount = 0; + m_pFlexVertexBuffer = NULL; + m_bHasFlexVerts = false; + } +} + +void CMeshDX11::DisableFlexMesh() +{ + CMeshDX11::SetFlexMesh( NULL, 0 ); +} + +bool CMeshDX11::HasFlexMesh() const +{ + LOCK_SHADERAPI(); + return m_bHasFlexVerts; +} + +void CMeshDX11::SetColorMesh( IMesh *pColorMesh, int nVertexOffsetInBytes ) +{ + if ( !ShaderUtil()->OnSetColorMesh( this, pColorMesh, nVertexOffsetInBytes ) ) + return; + + LOCK_SHADERAPI(); + m_pColorMesh = (CMeshDX11 *)pColorMesh; // dangerous conversion! garymcthack + m_nColorMeshVertOffsetInBytes = nVertexOffsetInBytes; + Assert( m_pColorMesh || ( nVertexOffsetInBytes == 0 ) ); + +#ifdef _DEBUG + if ( pColorMesh ) + { + int nVertexCount = VertexCount(); + int numVertsColorMesh = m_pColorMesh->VertexCount(); + Assert( numVertsColorMesh >= nVertexCount ); + } +#endif +} + +bool CMeshDX11::HasColorMesh() const +{ + LOCK_SHADERAPI(); + return ( m_pColorMesh != NULL ); +} + +bool CMeshDX11::Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc ) +{ + Assert( !m_IsVBLocked ); + + //Log( "MeshDx11::Lock(): nVertexCount = %i, bAppend = %i\n", nVertexCount, (int)bAppend ); + + if ( g_pShaderDeviceDx11->IsDeactivated() || ( nVertexCount == 0 ) ) + { + //Log( "Deactivated or no verts\n" ); + // Set up the vertex descriptor + CVertexBufferBase::ComputeVertexDescription( 0, 0, desc ); + desc.m_nFirstVertex = 0; + return false; + } + + // Static vertex buffer case + if ( !m_pVertexBuffer ) + { + //int size = MeshMgr()->VertexFormatSize(m_VertexFormat); + m_pVertexBuffer = static_cast( + g_pShaderDeviceDx11->CreateVertexBuffer( ShaderBufferType_t::SHADER_BUFFER_TYPE_STATIC, + m_VertexFormat, nVertexCount, m_pTextureGroupName ) ); + } + + // Lock it baby + int nMaxVerts, nMaxIndices; + // DX11FIXME + g_MeshMgr.GetMaxToRender( this, false, &nMaxVerts, &nMaxIndices ); + if ( !g_pHardwareConfig->SupportsStreamOffset() ) + { + // Without stream offset, we can't use VBs greater than 65535 verts (due to our using 16-bit indices) + Assert( nVertexCount <= nMaxVerts ); + } + + bool ret = m_pVertexBuffer->Lock( nVertexCount, bAppend, desc ); + if ( !ret ) + { + //Log( "Couldn't lock vertex buffer\n" ); + if ( nVertexCount > nMaxVerts ) + { + Assert( 0 ); + Error( "Too many verts for a dynamic vertex buffer (%d>%d) Tell a programmer to up VERTEX_BUFFER_SIZE.\n", + (int)nVertexCount, (int)nMaxVerts ); + } + return false; + } + + m_IsVBLocked = true; + return true; +} + +void CMeshDX11::Unlock( int nVertexCount, VertexDesc_t &desc ) +{ + // NOTE: This can happen if another application finishes + // initializing during the construction of a mesh + if ( !m_IsVBLocked ) + return; + +#ifdef CHECK_INDICES + m_pIndexBuffer->UpdateShadowIndices( (unsigned short *)m_LockIndexBuffer ); +#endif // CHECK_INDICES + + Assert( m_pVertexBuffer ); + m_pVertexBuffer->Unlock( nVertexCount, desc ); + m_IsVBLocked = false; +} + +//----------------------------------------------------------------------------- +// Locks/unlocks the index buffer +//----------------------------------------------------------------------------- +int CMeshDX11::Lock( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t &desc ) +{ + Assert( !m_IsIBLocked ); + + // Static index buffer case + if ( !m_pIndexBuffer ) + { + m_pIndexBuffer = static_cast( + g_pShaderDeviceDx11->CreateIndexBuffer( SHADER_BUFFER_TYPE_STATIC, + MATERIAL_INDEX_FORMAT_16BIT, + nIndexCount, m_pTextureGroupName ) ); + } + + bool ret = m_pIndexBuffer->LockEx( nFirstIndex, nIndexCount, desc ); + if ( !ret ) + { + return desc.m_nFirstIndex; + } + +#if defined( RECORDING ) || defined( CHECK_INDICES ) + m_LockIndexBufferSize = nIndexCount * 2; + m_LockIndexBuffer = desc.m_pIndices; +#endif + + m_IsIBLocked = true; + return desc.m_nFirstIndex; +} + +void CMeshDX11::Unlock( int nIndexCount, IndexDesc_t &desc ) +{ + // NOTE: This can happen if another application finishes + // initializing during the construction of a mesh + if ( !m_IsIBLocked ) + return; + + Assert( m_pIndexBuffer ); + + // Unlock, and indicate how many vertices we actually used + m_pIndexBuffer->Unlock( nIndexCount, desc ); + m_IsIBLocked = false; +} + +void CMeshDX11::LockMesh( int numVerts, int numIndices, MeshDesc_t &desc ) +{ + ShaderUtil()->SyncMatrices(); + + g_ShaderMutex.Lock(); + VPROF( "CMeshDx11::LockMesh" ); + //Log( "Locking vertex buffer\n" ); + // Lock vertex buffer + Lock( numVerts, false, *static_cast( &desc ) ); + if ( m_Type != MATERIAL_POINTS ) + { + // Lock index buffer + //Log( "Locking index buffer\n" ); + Lock( false, -1, numIndices, *static_cast( &desc ) ); + } + + m_bMeshLocked = true; +} + +void CMeshDX11::UnlockMesh( int numVerts, int numIndices, MeshDesc_t &desc ) +{ + VPROF( "CMeshDx11::UnlockMesh" ); + + Assert( m_bMeshLocked ); + + Unlock( numVerts, *static_cast( &desc ) ); + if ( m_Type != MATERIAL_POINTS ) + { + Unlock( numIndices, *static_cast( &desc ) ); + } + + // The actual # we wrote + m_NumVertices = numVerts; + m_NumIndices = numIndices; + + m_bMeshLocked = false; + g_ShaderMutex.Unlock(); +} + +void CMeshDX11::ModifyBeginEx( bool bReadOnly, int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t &desc ) +{ + VPROF( "CMeshDX11::ModifyBegin" ); + + // Just give the app crap buffers to fill up while we're suppressed... + + Assert( m_pVertexBuffer ); + + // Lock it baby + unsigned char *pVertexMemory = m_pVertexBuffer->Modify( bReadOnly, firstVertex, numVerts ); + if ( pVertexMemory ) + { + m_IsVBLocked = true; + g_MeshMgr.ComputeVertexDescription( pVertexMemory, m_VertexFormat, desc ); + } + + desc.m_nFirstVertex = firstVertex; + + Lock( bReadOnly, firstIndex, numIndices, *static_cast( &desc ) ); +} + +void CMeshDX11::ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t &desc ) +{ + ModifyBeginEx( false, firstVertex, numVerts, firstIndex, numIndices, desc ); +} + +void CMeshDX11::ModifyEnd( MeshDesc_t &desc ) +{ + VPROF( "CMeshDx11::ModifyEnd" ); + Unlock( 0, *static_cast( &desc ) ); + Unlock( 0, *static_cast( &desc ) ); +} + +//----------------------------------------------------------------------------- +// returns the # of vertices (static meshes only) +//----------------------------------------------------------------------------- +int CMeshDX11::VertexCount() const +{ + return m_pVertexBuffer ? m_pVertexBuffer->VertexCount() : 0; +} + +//----------------------------------------------------------------------------- +// returns the # of indices +//----------------------------------------------------------------------------- +int CMeshDX11::IndexCount() const +{ + return m_pIndexBuffer ? m_pIndexBuffer->IndexCount() : 0; +} + +//----------------------------------------------------------------------------- +// Sets up the vertex and index buffers +//----------------------------------------------------------------------------- +void CMeshDX11::UseIndexBuffer( CIndexBufferDx11 *pBuffer ) +{ + m_pIndexBuffer = pBuffer; +} + +void CMeshDX11::UseVertexBuffer( CVertexBufferDx11 *pBuffer ) +{ + m_pVertexBuffer = pBuffer; +} + +//----------------------------------------------------------------------------- +// Sets the primitive type +//----------------------------------------------------------------------------- +void CMeshDX11::SetPrimitiveType( MaterialPrimitiveType_t type ) +{ + Assert( IsX360() || ( type != MATERIAL_INSTANCED_QUADS ) ); + if ( !ShaderUtil()->OnSetPrimitiveType( this, type ) ) + { + return; + } + + LOCK_SHADERAPI(); + m_Type = type; +} + +MaterialPrimitiveType_t CMeshDX11::GetPrimitiveType() const +{ + return m_Type; +} + +int CMeshDX11::NumPrimitives( int nVertexCount, int nIndexCount ) const +{ + switch ( m_Type ) + { + case MATERIAL_POINTS: + // D3D11_PRIMITIVE_TOPOLOGY_POINTLIST + return nVertexCount; + + case MATERIAL_LINES: + // D3D11_PRIMITIVE_TOPOLOGY_LINELIST + return nIndexCount / 2; + + case MATERIAL_TRIANGLES: + // D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST + return nIndexCount / 3; + + case MATERIAL_TRIANGLE_STRIP: + // D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP + return nIndexCount - 2; + + default: + // Invalid type! + Assert( 0 ); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// Helpers to count texture coordinates +//----------------------------------------------------------------------------- +static int NumTextureCoordinates( VertexFormat_t vertexFormat ) +{ + int nTexCoordCount = 0; + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i ) + { + if ( TexCoordSize( i, vertexFormat ) == 0 ) + continue; + ++nTexCoordCount; + } + return nTexCoordCount; +} + +//----------------------------------------------------------------------------- +// Checks if it's a valid format +//----------------------------------------------------------------------------- +#ifdef _DEBUG +static void OutputVertexFormat( VertexFormat_t format ) +{ + // FIXME: this is a duplicate of the function in meshdx8.cpp + VertexCompressionType_t compressionType = CompressionType( format ); + + if ( format & VERTEX_POSITION ) + { + Warning( "VERTEX_POSITION|" ); + } + if ( format & VERTEX_NORMAL ) + { + if ( compressionType == VERTEX_COMPRESSION_ON ) + Warning( "VERTEX_NORMAL[COMPRESSED]|" ); + else + Warning( "VERTEX_NORMAL|" ); + } + if ( format & VERTEX_COLOR ) + { + Warning( "VERTEX_COLOR|" ); + } + if ( format & VERTEX_SPECULAR ) + { + Warning( "VERTEX_SPECULAR|" ); + } + if ( format & VERTEX_TANGENT_S ) + { + Warning( "VERTEX_TANGENT_S|" ); + } + if ( format & VERTEX_TANGENT_T ) + { + Warning( "VERTEX_TANGENT_T|" ); + } + if ( format & VERTEX_BONE_INDEX ) + { + Warning( "VERTEX_BONE_INDEX|" ); + } + if ( format & VERTEX_FORMAT_VERTEX_SHADER ) + { + Warning( "VERTEX_FORMAT_VERTEX_SHADER|" ); + } + Warning( "\nBone weights: %d (%s)\n", NumBoneWeights( format ), + ( CompressionType( format ) == VERTEX_COMPRESSION_ON ? "compressed" : "uncompressed" ) ); + Warning( "user data size: %d (%s)\n", UserDataSize( format ), + ( CompressionType( format ) == VERTEX_COMPRESSION_ON ? "compressed" : "uncompressed" ) ); + Warning( "num tex coords: %d\n", NumTextureCoordinates( format ) ); + // NOTE: This doesn't print texcoord sizes. +} +#endif + +bool CMeshDX11::IsValidVertexFormat( VertexFormat_t vertexFormat ) +{ + // FIXME: Make this a debug-only check on say 6th July 2007 (after a week or so's testing) + // (i.e. avoid the 360 release build perf. hit for when we ship) + bool bCheckCompression = ( m_VertexFormat & VERTEX_FORMAT_COMPRESSED ) && + ( ( vertexFormat == VERTEX_FORMAT_INVALID ) || ( ( vertexFormat & VERTEX_FORMAT_COMPRESSED ) == 0 ) ); + + if ( bCheckCompression || IsPC() || IsDebug() ) + { + IMaterialInternal *pMaterial = g_pShaderAPIDx11->GetBoundMaterial(); + Assert( pMaterial ); + + // the material format should match the vertex usage, unless another format is passed in + if ( vertexFormat == VERTEX_FORMAT_INVALID ) + { + vertexFormat = pMaterial->GetVertexUsage() & ~( VERTEX_FORMAT_VERTEX_SHADER | VERTEX_FORMAT_USE_EXACT_FORMAT ); + + // Blat out unused fields + vertexFormat &= ~g_MeshMgr.UnusedVertexFields(); + int nUnusedTextureCoords = g_MeshMgr.UnusedTextureCoords(); + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i ) + { + if ( nUnusedTextureCoords & ( 1 << i ) ) + { + vertexFormat &= ~VERTEX_TEXCOORD_MASK( i ); + } + } + } + else + { + vertexFormat &= ~( VERTEX_FORMAT_VERTEX_SHADER | VERTEX_FORMAT_USE_EXACT_FORMAT ); + } + + bool bIsValid = ( ( VERTEX_FORMAT_FIELD_MASK & vertexFormat ) & ( VERTEX_FORMAT_FIELD_MASK & ~m_VertexFormat ) ) == 0; + + if ( m_VertexFormat & VERTEX_FORMAT_COMPRESSED ) + { + // We shouldn't get compressed verts if this material doesn't support them! + if ( ( vertexFormat & VERTEX_FORMAT_COMPRESSED ) == 0 ) + { + static int numWarnings = 0; + if ( numWarnings++ == 0 ) + { + // NOTE: ComputeVertexFormat() will make sure no materials support VERTEX_FORMAT_COMPRESSED + // if vertex compression is disabled in the config + if ( g_pHardwareConfig->SupportsCompressedVertices() == VERTEX_COMPRESSION_NONE ) + Warning( "ERROR: Compressed vertices in use but vertex compression is disabled (or not supported on this hardware)!\n" ); + else + Warning( "ERROR: Compressed vertices in use but material does not support them!\n" ); + } + Assert( 0 ); + bIsValid = false; + } + } + + bIsValid = bIsValid && UserDataSize( m_VertexFormat ) >= UserDataSize( vertexFormat ); + + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; i++ ) + { + if ( TexCoordSize( i, m_VertexFormat ) < TexCoordSize( i, vertexFormat ) ) + { + bIsValid = false; + } + } + + // NOTE: It can totally be valid to have more weights than the current number of bones. + // The -1 here is because if we have N bones, we can have only (N-1) weights, + // since the Nth is implied (the weights sum to 1). + int nWeightCount = NumBoneWeights( m_VertexFormat ); + bIsValid = bIsValid && ( nWeightCount >= ( g_pShaderAPI->GetCurrentNumBones() - 1 ) ); + +#ifdef _DEBUG + if ( !bIsValid ) + { + Warning( "Material Format:" ); + if ( g_pShaderAPI->GetCurrentNumBones() > 0 ) + { + vertexFormat |= VERTEX_BONE_INDEX; + vertexFormat &= ~VERTEX_BONE_WEIGHT_MASK; + vertexFormat |= VERTEX_BONEWEIGHT( 2 ); + } + + OutputVertexFormat( vertexFormat ); + Warning( "Mesh Format:" ); + OutputVertexFormat( m_VertexFormat ); + } +#endif + return bIsValid; + } + + return true; +} + +bool CMeshDX11::SetRenderState( int nFirstIndex, int nFirstVertexIdx, VertexFormat_t vertexFormat ) +{ + // Can't set the state if we're deactivated + if ( g_pShaderDeviceDx11->IsDeactivated() ) + { + //ResetMeshRenderState(); + return false; + } + + //g_LastVertexFormat = vertexFormat; + + // Bind the mesh's buffers + g_pShaderAPIDx11->SetTopology( m_Type ); + + Assert( m_pVertexBuffer ); + g_pShaderAPIDx11->BindVertexBuffer( 0, GetVertexBuffer(), -1, nFirstVertexIdx, m_NumVertices, GetVertexFormat() ); + + // Bind separate color vertex buffer + if ( HasColorMesh() ) + { + g_pShaderAPIDx11->BindVertexBuffer( 1, m_pColorMesh->GetVertexBuffer(), + m_nColorMeshVertOffsetInBytes, + -1, m_NumVertices, + m_pColorMesh->GetVertexBuffer()->GetVertexFormat() ); + } + + // Bind flex vertex buffer + if ( HasFlexMesh() ) + { + g_pShaderAPIDx11->BindVertexBuffer( 2, m_pFlexVertexBuffer, m_nFlexVertOffsetInBytes, -1, + m_flexVertCount, m_pFlexVertexBuffer->GetVertexFormat() ); + } + + // Bind vertex ID buffer + bool bUsingVertexId = IsUsingVertexID(); + if ( bUsingVertexId ) + { + g_pShaderAPIDx11->BindVertexBuffer( 3, g_MeshMgr.GetVertexIDBuffer(), 0, 0, 0, GetVertexFormat() ); + } + + Assert( m_pIndexBuffer ); + g_pShaderAPIDx11->BindIndexBuffer( GetIndexBuffer(), nFirstIndex * GetIndexBuffer()->IndexSize() ); + + g_pLastIndex = GetIndexBuffer(); + g_pLastVertex = GetVertexBuffer(); + + + return true; +} + +//----------------------------------------------------------------------------- +// Draws the static mesh +//----------------------------------------------------------------------------- +void CMeshDX11::Draw( int nFirstIndex, int nIndexCount ) +{ + if ( !ShaderUtil()->OnDrawMesh( this, nFirstIndex, nIndexCount ) ) + { + MarkAsDrawn(); + return; + } + + CPrimList primList; + if ( nFirstIndex == -1 || nIndexCount == 0 ) + { + primList.m_FirstIndex = 0; + primList.m_NumIndices = m_NumIndices; + } + else + { + primList.m_FirstIndex = nFirstIndex; + primList.m_NumIndices = nIndexCount; + } + DrawInternal( &primList, 1 ); +} + +void CMeshDX11::Draw( CPrimList *pLists, int nLists ) +{ + if ( !ShaderUtil()->OnDrawMesh( this, pLists, nLists ) ) + { + MarkAsDrawn(); + return; + } + + DrawInternal( pLists, nLists ); +} + + +void CMeshDX11::DrawInternal( CPrimList *pLists, int nLists ) +{ + // Make sure there's something to draw.. + int i; + for ( i = 0; i < nLists; i++ ) + { + if ( pLists[i].m_NumIndices > 0 ) + break; + } + if ( i == nLists ) + return; + + // can't do these in selection mode! + Assert( !ShaderAPI()->IsInSelectionMode() ); + + if ( !SetRenderState( 0, 0 ) ) + return; + + s_pPrims = pLists; + s_nPrims = nLists; + +#ifdef _DEBUG + for ( i = 0; i < nLists; ++i ) + { + Assert( pLists[i].m_NumIndices > 0 ); + } +#endif + + s_FirstVertex = 0; + s_NumVertices = m_pVertexBuffer->VertexCount(); + + DrawMesh(); +} + +#ifdef CHECK_INDICES +void CMeshDX11::CheckIndices( CPrimList *pPrim, int numPrimitives ) +{ + // g_pLastVertex - this is the current vertex buffer + // g_pLastColorMesh - this is the current color mesh, if there is one. + // g_pLastIndex - this is the current index buffer. + // vertoffset : m_FirstIndex + if ( m_Type == MATERIAL_TRIANGLES || m_Type == MATERIAL_TRIANGLE_STRIP ) + { + Assert( pPrim->m_FirstIndex >= 0 && pPrim->m_FirstIndex < g_pLastIndex->IndexCount() ); + int i; + for ( i = 0; i < 2; i++ ) + { + CVertexBufferDx11 *pMesh; + if ( i == 0 ) + { + pMesh = g_pLastVertex; + Assert( pMesh ); + } + else + { + if ( !g_pLastColorMesh ) + { + continue; + } + pMesh = g_pLastColorMesh->m_pVertexBuffer; + if ( !pMesh ) + { + continue; + } + } + Assert( s_FirstVertex >= 0 && + (int)( s_FirstVertex + m_FirstIndex ) < pMesh->VertexCount() ); + int nIndexCount = 0; + if ( m_Type == MATERIAL_TRIANGLES ) + { + nIndexCount = numPrimitives * 3; + } + else if ( m_Type == MATERIAL_TRIANGLE_STRIP ) + { + nIndexCount = numPrimitives + 2; + } + else + { + Assert( 0 ); + } + int j; + for ( j = 0; j < nIndexCount; j++ ) + { + int index = g_pLastIndex->GetShadowIndex( j + pPrim->m_FirstIndex ); + Assert( index >= (int)s_FirstVertex ); + Assert( index < (int)( s_FirstVertex + s_NumVertices ) ); + } + } + } +} +#endif // CHECK_INDICES + +// Draws the specified primitives on the mesh +void CMeshDX11::RenderPass() +{ + if ( !s_pPrims ) + { + Warning( "CMeshDx11::RenderPass(): s_pPrims is NULL!\n" ); + return; + } + + if ( m_Type == MATERIAL_HETEROGENOUS ) + { + Warning( "CMeshDx11::RenderPass() m_Type is MATERIAL_HETEROGENOUS\n" ); + return; + } + + // make sure the vertex format is a superset of the current material's + // vertex format... + //if ( !IsValidVertexFormat( g_LastVertexFormat ) ) + //{ + // Warning( "Material %s does not support vertex format used by the mesh (maybe missing fields or mismatched vertex compression?), mesh will not be rendered. Grab a programmer!\n", + // ShaderAPI()->GetBoundMaterial()->GetName() ); + // return; + //} + + // Set the state and transform + g_pShaderAPIDx11->IssueStateChanges(); + + // Now draw our primitives + for ( int i = 0; i < s_nPrims; i++ ) + { + CPrimList *pPrim = &s_pPrims[i]; + if ( pPrim->m_NumIndices == 0 ) + return; + + if ( ( m_Type == MATERIAL_POINTS ) || ( m_Type == MATERIAL_INSTANCED_QUADS ) ) + { + // (For point/instanced-quad lists, we don't actually fill in indices, but we treat it as + // though there are indices for the list up until here). + g_pShaderAPIDx11->DrawNotIndexed( s_FirstVertex, pPrim->m_NumIndices ); + } + else + { +#ifdef CHECK_INDICES + int numPrimitives = NumPrimitives( s_NumVertices, pPrim->m_NumIndices ); + CheckIndices( pPrim, numPrimitives ); +#endif // CHECK_INDICES + g_pShaderAPIDx11->DrawIndexed( pPrim->m_FirstIndex, pPrim->m_NumIndices, 0 ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Dynamic mesh implementation +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CDynamicMeshDX11::CDynamicMeshDX11() : CMeshDX11( "CDynamicMeshDX11" ) +{ + m_nBufferId = 0; + ResetVertexAndIndexCounts(); +} + +CDynamicMeshDX11::~CDynamicMeshDX11() +{ +} + + +//----------------------------------------------------------------------------- +// Initializes the dynamic mesh +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::Init( int nBufferId ) +{ + m_nBufferId = nBufferId; +} + +//----------------------------------------------------------------------------- +// Resets buffering state +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::ResetVertexAndIndexCounts() +{ + m_TotalVertices = m_TotalIndices = 0; + m_FirstIndex = m_nFirstVertex = -1; + m_HasDrawn = false; +} + +//----------------------------------------------------------------------------- +// Resets the state in case of a task switch +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::Reset() +{ + m_VertexFormat = 0; + m_pVertexBuffer = 0; + m_pIndexBuffer = 0; + ResetVertexAndIndexCounts(); + + // Force the render state to be updated next time + //ResetMeshRenderState(); +} + +//----------------------------------------------------------------------------- +// Sets the vertex format associated with the dynamic mesh +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::SetVertexFormat( VertexFormat_t format ) +{ + if ( g_pShaderDeviceDx11->IsDeactivated() ) + return; + + if ( CompressionType( format ) != VERTEX_COMPRESSION_NONE ) + { + // UNDONE: support compressed dynamic meshes if needed (pro: less VB memory, con: CMeshBuilder gets slower) + Warning( "ERROR: dynamic meshes cannot use compressed vertices!\n" ); + Assert( 0 ); + format &= ~VERTEX_FORMAT_COMPRESSED; + } + + if ( ( format != m_VertexFormat ) || m_VertexOverride || m_IndexOverride ) + { + m_VertexFormat = format; + UseVertexBuffer( g_MeshMgr.FindOrCreateVertexBuffer( m_nBufferId, format ) ); + + if ( m_nBufferId == 0 ) + { + UseIndexBuffer( g_MeshMgr.GetDynamicIndexBuffer() ); + } + + m_VertexOverride = m_IndexOverride = false; + } +} + +void CDynamicMeshDX11::OverrideVertexBuffer( CVertexBufferDx11 *pVertexBuffer ) +{ + UseVertexBuffer( pVertexBuffer ); + m_VertexOverride = true; +} + +void CDynamicMeshDX11::OverrideIndexBuffer( CIndexBufferDx11 *pIndexBuffer ) +{ + UseIndexBuffer( pIndexBuffer ); + m_IndexOverride = true; +} + + +//----------------------------------------------------------------------------- +// Do I need to reset the vertex format? +//----------------------------------------------------------------------------- +bool CDynamicMeshDX11::NeedsVertexFormatReset( VertexFormat_t fmt ) const +{ + //Log( "Does CDynamicMeshDx11 need format reset? %i %i %i != %i\n", m_VertexOverride, m_IndexOverride, m_VertexFormat, fmt ); + return m_VertexOverride || m_IndexOverride || ( m_VertexFormat != fmt ); +} + +//----------------------------------------------------------------------------- +// Locks/unlocks the entire mesh +//----------------------------------------------------------------------------- +bool CDynamicMeshDX11::HasEnoughRoom( int nVertexCount, int nIndexCount ) const +{ + if ( g_pShaderDeviceDx11->IsDeactivated() ) + return false; + + // We need space in both the vertex and index buffer + return m_pVertexBuffer->HasEnoughRoom( nVertexCount ) && + m_pIndexBuffer->HasEnoughRoom( nIndexCount ); +} + +//----------------------------------------------------------------------------- +// returns the number of indices in the mesh +//----------------------------------------------------------------------------- +int CDynamicMeshDX11::IndexCount() const +{ + return m_TotalIndices; +} + +//----------------------------------------------------------------------------- +// Operation to do pre-lock (only called for buffered meshes) +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::PreLock() +{ + if ( m_HasDrawn ) + { + // Start again then + ResetVertexAndIndexCounts(); + } +} + + +//----------------------------------------------------------------------------- +// Locks/unlocks the entire mesh +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) +{ + ShaderUtil()->SyncMatrices(); + + g_ShaderMutex.Lock(); + + // Yes, this may well also be called from BufferedMesh but that's ok + PreLock(); + + if ( m_VertexOverride ) + { + nVertexCount = 0; + } + + if ( m_IndexOverride ) + { + nIndexCount = 0; + } + + Lock( nVertexCount, false, *static_cast( &desc ) ); + if ( m_nFirstVertex < 0 ) + { + m_nFirstVertex = desc.m_nFirstVertex; + } + + // When we're using a static index buffer or a flex mesh, the indices assume vertices start at 0 + if ( m_IndexOverride || HasFlexMesh() ) + { + desc.m_nFirstVertex -= m_nFirstVertex; + } + + // Don't add indices for points; DrawIndexedPrimitive not supported for them. + if ( m_Type != MATERIAL_POINTS ) + { + int nFirstIndex = Lock( false, -1, nIndexCount, *static_cast( &desc ) ); + if ( m_FirstIndex < 0 ) + { + m_FirstIndex = nFirstIndex; + } + } + //else + //{ + // desc.m_pIndices = (unsigned short *)( &g_nScratchIndexBuffer ); + // desc.m_nIndexSize = 0; + //} + + m_bMeshLocked = true; +} + +//----------------------------------------------------------------------------- +// Unlocks the mesh +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) +{ + m_TotalVertices += nVertexCount; + m_TotalIndices += nIndexCount; + + if ( DebugTrace() ) + { + Spew( nVertexCount, nIndexCount, desc ); + } + + CMeshDX11::UnlockMesh( nVertexCount, nIndexCount, desc ); + + // This is handled in the CMeshDX8::UnlockMesh above. + //CBaseMeshDX8::m_bMeshLocked = false; +} + +//----------------------------------------------------------------------------- +// Draws it +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::Draw( int nFirstIndex, int nIndexCount ) +{ + //return; + if ( !ShaderUtil()->OnDrawMesh( this, nFirstIndex, nIndexCount ) ) + { + MarkAsDrawn(); + return; + } + + VPROF( "CDynamicMeshDX11::Draw" ); + + m_HasDrawn = true; + + if ( m_IndexOverride || m_VertexOverride || + ( ( m_TotalVertices > 0 ) && ( m_TotalIndices > 0 || m_Type == MATERIAL_POINTS || m_Type == MATERIAL_INSTANCED_QUADS ) ) ) + { + Assert( !m_IsDrawing ); + + // only have a non-zero first vertex when we are using static indices + int nFirstVertex = m_VertexOverride ? 0 : m_nFirstVertex; + int actualFirstVertex = m_IndexOverride || HasFlexMesh() ? nFirstVertex : 0; + int baseIndex = m_IndexOverride ? 0 : m_FirstIndex; + + // Overriding with the dynamic index buffer, preserve state! + if ( m_IndexOverride && m_pIndexBuffer == g_MeshMgr.GetDynamicIndexBuffer() ) + { + baseIndex = m_FirstIndex; + } + + VertexFormat_t fmt = m_VertexOverride ? GetVertexFormat() : VERTEX_FORMAT_INVALID; + if ( !SetRenderState( 0, actualFirstVertex, fmt ) ) + return; + + // Draws a portion of the mesh + int numVertices = m_VertexOverride ? m_pVertexBuffer->VertexCount() : m_TotalVertices; + if ( ( nFirstIndex != -1 ) && ( nIndexCount != 0 ) ) + { + nFirstIndex += baseIndex; + } + else + { + // by default we draw the whole thing + nFirstIndex = baseIndex; + if ( m_IndexOverride ) + { + nIndexCount = m_pIndexBuffer->IndexCount(); + Assert( nIndexCount != 0 ); + } + else + { + nIndexCount = m_TotalIndices; + // Fake out the index count if we're drawing points/instanced-quads + if ( ( m_Type == MATERIAL_POINTS ) || ( m_Type == MATERIAL_INSTANCED_QUADS ) ) + { + nIndexCount = m_TotalVertices; + } + Assert( nIndexCount != 0 ); + } + } + + // Fix up nFirstVertex to indicate the first vertex used in the data + if ( !HasFlexMesh() ) + { + actualFirstVertex = nFirstVertex - actualFirstVertex; + } + + s_FirstVertex = actualFirstVertex; + s_NumVertices = numVertices; + + // Build a primlist with 1 element.. + CPrimList prim; + prim.m_FirstIndex = nFirstIndex; + prim.m_NumIndices = nIndexCount; + Assert( nIndexCount != 0 ); + s_pPrims = &prim; + s_nPrims = 1; + + DrawMesh(); + + s_pPrims = NULL; + } +} + +//----------------------------------------------------------------------------- +// This is useful when we need to dynamically modify data; just set the +// render state and draw the pass immediately +//----------------------------------------------------------------------------- +void CDynamicMeshDX11::DrawSinglePassImmediately() +{ + if ( ( m_TotalVertices > 0 ) || ( m_TotalIndices > 0 ) ) + { + Assert( !m_IsDrawing ); + + // Set the render state + if ( SetRenderState( 0, 0 ) ) + { + s_FirstVertex = m_nFirstVertex; + s_NumVertices = m_TotalVertices; + + // Make a temporary PrimList to hold the indices. + CPrimList prim( m_FirstIndex, m_TotalIndices ); + Assert( m_TotalIndices != 0 ); + s_pPrims = &prim; + s_nPrims = 1; + + // Render it + RenderPass(); + } + + // We're done with our data + ResetVertexAndIndexCounts(); + } +} + +//----------------------------------------------------------------------------- +// +// A mesh that stores temporary vertex data in the correct format (for modification) +// +//----------------------------------------------------------------------------- +// Used in rendering sub-parts of the mesh +unsigned int CTempMeshDX11::s_NumIndices; +unsigned int CTempMeshDX11::s_FirstIndex; + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CTempMeshDX11::CTempMeshDX11( bool isDynamic ) : m_VertexSize( 0xFFFF ), m_IsDynamic( isDynamic ) +{ +#ifdef _DEBUG + m_Locked = false; + m_InPass = false; +#endif +} + +CTempMeshDX11::~CTempMeshDX11() +{ +} + +//----------------------------------------------------------------------------- +// Is the temp mesh dynamic? +//----------------------------------------------------------------------------- +bool CTempMeshDX11::IsDynamic() const +{ + return m_IsDynamic; +} + + +//----------------------------------------------------------------------------- +// Sets the vertex format +//----------------------------------------------------------------------------- +void CTempMeshDX11::SetVertexFormat( VertexFormat_t format ) +{ + CBaseMeshDX11::SetVertexFormat( format ); + m_VertexSize = g_MeshMgr.VertexFormatSize( format ); +} + +//----------------------------------------------------------------------------- +// returns the # of vertices (static meshes only) +//----------------------------------------------------------------------------- +int CTempMeshDX11::VertexCount() const +{ + return m_VertexSize ? m_VertexData.Count() / m_VertexSize : 0; +} + +//----------------------------------------------------------------------------- +// returns the # of indices +//----------------------------------------------------------------------------- +int CTempMeshDX11::IndexCount() const +{ + return m_IndexData.Count(); +} + +void CTempMeshDX11::ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) +{ + Assert( !m_Locked ); + + m_LockedVerts = nVertexCount; + m_LockedIndices = nIndexCount; + + if ( nVertexCount > 0 ) + { + int vertexByteOffset = m_VertexSize * nFirstVertex; + + // Lock it baby + unsigned char *pVertexMemory = &m_VertexData[vertexByteOffset]; + + // Compute the vertex index.. + desc.m_nFirstVertex = vertexByteOffset / m_VertexSize; + + // Set up the mesh descriptor + g_MeshMgr.ComputeVertexDescription( pVertexMemory, m_VertexFormat, desc ); + } + else + { + desc.m_nFirstVertex = 0; + // Set up the mesh descriptor + g_MeshMgr.ComputeVertexDescription( 0, 0, desc ); + } + + if ( m_Type != MATERIAL_POINTS && nIndexCount > 0 ) + { + desc.m_pIndices = &m_IndexData[nFirstIndex]; + desc.m_nIndexSize = 1; + } + //else + //{ + // desc.m_pIndices = (unsigned short *)( &g_nScratchIndexBuffer ); + // desc.m_nIndexSize = 0; + //} + +#ifdef _DEBUG + m_Locked = true; +#endif +} + +void CTempMeshDX11::ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) +{ + ModifyBeginEx( false, nFirstVertex, nVertexCount, nFirstIndex, nIndexCount, desc ); +} + +void CTempMeshDX11::ModifyEnd( MeshDesc_t &desc ) +{ +#ifdef _DEBUG + Assert( m_Locked ); + m_Locked = false; +#endif +} + +//----------------------------------------------------------------------------- +// Locks/unlocks the mesh +//----------------------------------------------------------------------------- +void CTempMeshDX11::LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) +{ + ShaderUtil()->SyncMatrices(); + + g_ShaderMutex.Lock(); + + Assert( !m_Locked ); + + m_LockedVerts = nVertexCount; + m_LockedIndices = nIndexCount; + + if ( nVertexCount > 0 ) + { + int vertexByteOffset = m_VertexData.AddMultipleToTail( m_VertexSize * nVertexCount ); + + // Lock it baby + unsigned char *pVertexMemory = &m_VertexData[vertexByteOffset]; + + // Compute the vertex index.. + desc.m_nFirstVertex = vertexByteOffset / m_VertexSize; + + // Set up the mesh descriptor + g_MeshMgr.ComputeVertexDescription( pVertexMemory, m_VertexFormat, desc ); + } + else + { + desc.m_nFirstVertex = 0; + // Set up the mesh descriptor + g_MeshMgr.ComputeVertexDescription( 0, 0, desc ); + } + + if ( m_Type != MATERIAL_POINTS && nIndexCount > 0 ) + { + int nFirstIndex = m_IndexData.AddMultipleToTail( nIndexCount ); + desc.m_pIndices = &m_IndexData[nFirstIndex]; + desc.m_nIndexSize = 1; + } + //else + //{ + // desc.m_pIndices = (unsigned short *)( &g_nScratchIndexBuffer ); + // desc.m_nIndexSize = 0; + //} + +#ifdef _DEBUG + m_Locked = true; +#endif + + m_bMeshLocked = true; +} + +void CTempMeshDX11::UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) +{ + Assert( m_Locked ); + + // Remove unused vertices and indices + int verticesToRemove = m_LockedVerts - nVertexCount; + if ( verticesToRemove != 0 ) + { + m_VertexData.RemoveMultiple( m_VertexData.Count() - verticesToRemove, verticesToRemove ); + } + + int indicesToRemove = m_LockedIndices - nIndexCount; + if ( indicesToRemove != 0 ) + { + m_IndexData.RemoveMultiple( m_IndexData.Count() - indicesToRemove, indicesToRemove ); + } + +#ifdef _DEBUG + m_Locked = false; +#endif + + m_bMeshLocked = false; + + g_ShaderMutex.Unlock(); +} + +//----------------------------------------------------------------------------- +// Sets the primitive type +//----------------------------------------------------------------------------- +void CTempMeshDX11::SetPrimitiveType( MaterialPrimitiveType_t type ) +{ + // FIXME: Support MATERIAL_INSTANCED_QUADS for CTempMeshDX8 (X360 only) + Assert( ( type != MATERIAL_INSTANCED_QUADS ) /* || IsX360() */ ); + m_Type = type; +} + +MaterialPrimitiveType_t CTempMeshDX11::GetPrimitiveType() const +{ + return m_Type; +} + +//----------------------------------------------------------------------------- +// Gets the dynamic mesh +//----------------------------------------------------------------------------- +CDynamicMeshDX11 *CTempMeshDX11::GetDynamicMesh() +{ + return static_cast( g_MeshMgr.GetActualDynamicMesh( m_VertexFormat ) ); +} + +//----------------------------------------------------------------------------- +// Draws the entire mesh +//----------------------------------------------------------------------------- +void CTempMeshDX11::Draw( int nFirstIndex, int nIndexCount ) +{ + if ( !ShaderUtil()->OnDrawMesh( this, nFirstIndex, nIndexCount ) ) + { + MarkAsDrawn(); + return; + } + + if ( m_VertexData.Count() > 0 ) + { + if ( !g_pShaderDeviceDx11->IsDeactivated() ) + { +#ifdef DRAW_SELECTION + if ( !g_bDrawSelection && !ShaderAPI()->IsInSelectionMode() ) +#else + if ( !ShaderAPI()->IsInSelectionMode() ) +#endif + { + s_FirstIndex = nFirstIndex; + s_NumIndices = nIndexCount; + + DrawMesh(); + + // This assertion fails if a BeginPass() call was not matched by + // a RenderPass() call + Assert( !m_InPass ); + } + else + { + TestSelection(); + } + } + + // Clear out the data if this temp mesh is a dynamic one... + if ( m_IsDynamic ) + { + m_VertexData.RemoveAll(); + m_IndexData.RemoveAll(); + } + } +} + +void CTempMeshDX11::CopyToMeshBuilder( + int iStartVert, // Which vertices to copy. + int nVerts, + int iStartIndex, // Which indices to copy. + int nIndices, + int indexOffset, // This is added to each index. + CMeshBuilder &builder ) +{ + int startOffset = iStartVert * m_VertexSize; + int endOffset = ( iStartVert + nVerts ) * m_VertexSize; + Assert( startOffset >= 0 && startOffset <= m_VertexData.Count() ); + Assert( endOffset >= 0 && endOffset <= m_VertexData.Count() && endOffset >= startOffset ); + if ( endOffset > startOffset ) + { + // FIXME: make this a method of CMeshBuilder (so the 'Position' pointer accessor can be removed) + // make sure it takes a VertexFormat_t parameter for src/dest match validation + memcpy( (void *)builder.Position(), &m_VertexData[startOffset], endOffset - startOffset ); + builder.AdvanceVertices( nVerts ); + } + + for ( int i = 0; i < nIndices; ++i ) + { + builder.Index( m_IndexData[iStartIndex + i] + indexOffset ); + builder.AdvanceIndex(); + } +} + +//----------------------------------------------------------------------------- +// Selection mode helper functions +//----------------------------------------------------------------------------- +static void ComputeModelToView( DirectX::XMMATRIX &modelToView ) +{ + // Get the modelview matrix... + DirectX::XMMATRIX world, view; + ShaderAPI()->GetMatrix( MATERIAL_MODEL, world ); + ShaderAPI()->GetMatrix( MATERIAL_VIEW, view ); + modelToView = DirectX::XMMatrixMultiply( world, view ); +} + +static float ComputeCullFactor() +{ + D3D11_CULL_MODE cullMode = ShaderAPI()->GetCullMode(); + + float cullFactor; + switch ( cullMode ) + { + case D3D11_CULL_BACK: + cullFactor = -1.0f; + break; + + case D3D11_CULL_FRONT: + cullFactor = 1.0f; + break; + + default: + cullFactor = 0.0f; + break; + }; + + return cullFactor; +} + +//----------------------------------------------------------------------------- +// Clip to viewport +//----------------------------------------------------------------------------- +static int g_NumClipVerts; +static DirectX::XMVECTOR g_ClipVerts[16]; + +static float XMVec3Component( const DirectX::XMVECTOR &flt3, int cmp ) +{ + switch ( cmp ) + { + case 0: + return DirectX::XMVectorGetX( flt3 ); + case 1: + return DirectX::XMVectorGetY( flt3 ); + case 2: + return DirectX::XMVectorGetZ( flt3 ); + default: + return DirectX::XMVectorGetX( flt3 ); + } +} + +static void XMVec3SetComponent( DirectX::XMVECTOR &flt3, int cmp, float val ) +{ + switch ( cmp ) + { + case 0: + flt3 = DirectX::XMVectorSetX( flt3, val ); + case 1: + flt3 = DirectX::XMVectorSetY( flt3, val ); + case 2: + flt3 = DirectX::XMVectorSetZ( flt3, val ); + default: + Assert( 0 ); + } +} + +static bool PointInsidePlane( DirectX::XMVECTOR *pVert, int normalInd, float val, bool nearClip ) +{ + if ( ( val > 0 ) || nearClip ) + return ( val - XMVec3Component( *pVert, normalInd ) >= 0 ); + else + return ( XMVec3Component( *pVert, normalInd ) - val >= 0 ); +} + +static void IntersectPlane( DirectX::XMVECTOR *pStart, DirectX::XMVECTOR *pEnd, + int normalInd, float val, DirectX::XMVECTOR *pOutVert ) +{ + DirectX::XMVECTOR dir; + dir = DirectX::XMVectorSubtract( *pEnd, *pStart ); + Assert( XMVec3Component( dir, normalInd ) != 0.0f ); + float t = ( val - XMVec3Component( *pStart, normalInd ) ) / XMVec3Component( dir, normalInd ); + XMVec3SetComponent( *pOutVert, 0, XMVec3Component( *pStart, 0 ) + XMVec3Component( dir, 0 ) * t ); + XMVec3SetComponent( *pOutVert, 1, XMVec3Component( *pStart, 1 ) + XMVec3Component( dir, 1 ) * t ); + XMVec3SetComponent( *pOutVert, 2, XMVec3Component( *pStart, 2 ) + XMVec3Component( dir, 2 ) * t ); + + // Avoid any precision problems. + XMVec3SetComponent( *pOutVert, normalInd, val ); +} + +static int ClipTriangleAgainstPlane( DirectX::XMVECTOR **ppVert, int nVertexCount, + DirectX::XMVECTOR **ppOutVert, int normalInd, float val, bool nearClip = false ) +{ + // Ye Olde Sutherland-Hodgman clipping algorithm + int numOutVerts = 0; + DirectX::XMVECTOR *pStart = ppVert[nVertexCount - 1]; + bool startInside = PointInsidePlane( pStart, normalInd, val, nearClip ); + for ( int i = 0; i < nVertexCount; ++i ) + { + DirectX::XMVECTOR *pEnd = ppVert[i]; + bool endInside = PointInsidePlane( pEnd, normalInd, val, nearClip ); + if ( endInside ) + { + if ( !startInside ) + { + IntersectPlane( pStart, pEnd, normalInd, val, &g_ClipVerts[g_NumClipVerts] ); + ppOutVert[numOutVerts++] = &g_ClipVerts[g_NumClipVerts++]; + } + ppOutVert[numOutVerts++] = pEnd; + } + else + { + if ( startInside ) + { + IntersectPlane( pStart, pEnd, normalInd, val, &g_ClipVerts[g_NumClipVerts] ); + ppOutVert[numOutVerts++] = &g_ClipVerts[g_NumClipVerts++]; + } + } + pStart = pEnd; + startInside = endInside; + } + + return numOutVerts; +} + +void CTempMeshDX11::ClipTriangle( DirectX::XMVECTOR **ppVert, float zNear, DirectX::XMMATRIX &projection ) +{ + int i; + int nVertexCount = 3; + DirectX::XMVECTOR *ppClipVert1[10]; + DirectX::XMVECTOR *ppClipVert2[10]; + + g_NumClipVerts = 0; + + // Clip against the near plane in view space to prevent negative w. + // Clip against each plane + nVertexCount = ClipTriangleAgainstPlane( ppVert, nVertexCount, ppClipVert1, 2, zNear, true ); + if ( nVertexCount < 3 ) + return; + + // Sucks that I have to do this, but I have to clip near plane in view space + // Clipping in projection space is screwy when w < 0 + // Transform the clipped points into projection space + Assert( g_NumClipVerts <= 2 ); + for ( i = 0; i < nVertexCount; ++i ) + { + if ( ppClipVert1[i] == &g_ClipVerts[0] ) + { + g_ClipVerts[0] = DirectX::XMVector3TransformCoord( *ppClipVert1[i], projection ); + } + else if ( ppClipVert1[i] == &g_ClipVerts[1] ) + { + g_ClipVerts[1] = DirectX::XMVector3TransformCoord( *ppClipVert1[i], projection ); + } + else + { + g_ClipVerts[g_NumClipVerts] = DirectX::XMVector3TransformCoord( *ppClipVert1[i], projection ); + ppClipVert1[i] = &g_ClipVerts[g_NumClipVerts]; + ++g_NumClipVerts; + } + } + + nVertexCount = ClipTriangleAgainstPlane( ppClipVert1, nVertexCount, ppClipVert2, 2, 1.0f ); + if ( nVertexCount < 3 ) + return; + + nVertexCount = ClipTriangleAgainstPlane( ppClipVert2, nVertexCount, ppClipVert1, 0, 1.0f ); + if ( nVertexCount < 3 ) + return; + + nVertexCount = ClipTriangleAgainstPlane( ppClipVert1, nVertexCount, ppClipVert2, 0, -1.0f ); + if ( nVertexCount < 3 ) + return; + + nVertexCount = ClipTriangleAgainstPlane( ppClipVert2, nVertexCount, ppClipVert1, 1, 1.0f ); + if ( nVertexCount < 3 ) + return; + + nVertexCount = ClipTriangleAgainstPlane( ppClipVert1, nVertexCount, ppClipVert2, 1, -1.0f ); + if ( nVertexCount < 3 ) + return; + +#ifdef DRAW_SELECTION + if ( 1 || g_bDrawSelection ) + { + srand( *(int *)( &ppClipVert2[0]->x ) ); + unsigned char r = (unsigned char)( rand() * 191.0f / RAND_MAX ) + 64; + unsigned char g = (unsigned char)( rand() * 191.0f / RAND_MAX ) + 64; + unsigned char b = (unsigned char)( rand() * 191.0f / RAND_MAX ) + 64; + + ShaderAPI()->SetupSelectionModeVisualizationState(); + + CMeshBuilder *pMeshBuilder = ShaderAPI()->GetVertexModifyBuilder(); + IMesh *pMesh = GetDynamicMesh(); + pMeshBuilder->Begin( pMesh, MATERIAL_POLYGON, nVertexCount ); + + for ( i = 0; i < nVertexCount; ++i ) + { + pMeshBuilder->Position3fv( *ppClipVert2[i] ); + pMeshBuilder->Color3ub( r, g, b ); + pMeshBuilder->AdvanceVertex(); + } + + pMeshBuilder->End(); + pMesh->Draw(); + + pMeshBuilder->Begin( pMesh, MATERIAL_LINE_LOOP, nVertexCount ); + + for ( i = 0; i < nVertexCount; ++i ) + { + pMeshBuilder->Position3fv( *ppClipVert2[i] ); + pMeshBuilder->Color3ub( 255, 255, 255 ); + pMeshBuilder->AdvanceVertex(); + } + + pMeshBuilder->End(); + pMesh->Draw(); + } +#endif + + // Compute closest and furthest verts + float minz = XMVec3Component( *ppClipVert2[0], 2 ); + float maxz = minz; + for ( i = 1; i < nVertexCount; ++i ) + { + if ( XMVec3Component( *ppClipVert2[i], 2 ) < minz ) + minz = XMVec3Component( *ppClipVert2[i], 2 ); + else if ( XMVec3Component( *ppClipVert2[i], 2 ) > maxz ) + maxz = XMVec3Component( *ppClipVert2[i], 2 ); + } + + ShaderAPI()->RegisterSelectionHit( minz, maxz ); +} + +//----------------------------------------------------------------------------- +// Selection mode +//----------------------------------------------------------------------------- +void CTempMeshDX11::TestSelection() +{ + // Note that this doesn't take into account any vertex modification + // done in a vertex shader. Also it doesn't take into account any clipping + // done in hardware + + // Blow off points and lines; they don't matter + if ( ( m_Type != MATERIAL_TRIANGLES ) && ( m_Type != MATERIAL_TRIANGLE_STRIP ) ) + return; + + DirectX::XMMATRIX modelToView, projection; + ComputeModelToView( modelToView ); + ShaderAPI()->GetMatrix( MATERIAL_PROJECTION, projection ); + float zNear = 0.1f;// -projection.m[3][2] / projection.m[2][2]; // FIXME + + //DirectX::XMMatrix + + DirectX::XMVECTOR *pPos[3]; + DirectX::XMVECTOR edge[2]; + DirectX::XMVECTOR normal; + + int numTriangles; + if ( m_Type == MATERIAL_TRIANGLES ) + numTriangles = m_IndexData.Count() / 3; + else + numTriangles = m_IndexData.Count() - 2; + + float cullFactor = ComputeCullFactor(); + + // Makes the lovely loop simpler + if ( m_Type == MATERIAL_TRIANGLE_STRIP ) + cullFactor *= -1.0f; + + // We'll need some temporary memory to tell us if we're transformed the vert + int nVertexCount = m_VertexData.Count() / m_VertexSize; + static CUtlVector< unsigned char > transformedVert; + int transformedVertSize = ( nVertexCount + 7 ) >> 3; + transformedVert.RemoveAll(); + transformedVert.EnsureCapacity( transformedVertSize ); + transformedVert.AddMultipleToTail( transformedVertSize ); + memset( transformedVert.Base(), 0, transformedVertSize ); + + int indexPos; + for ( int i = 0; i < numTriangles; ++i ) + { + // Get the three indices + if ( m_Type == MATERIAL_TRIANGLES ) + { + indexPos = i * 3; + } + else + { + Assert( m_Type == MATERIAL_TRIANGLE_STRIP ); + cullFactor *= -1.0f; + indexPos = i; + } + + // BAH. Gotta clip to the near clip plane in view space to prevent + // negative w coords; negative coords throw off the projection-space clipper. + + // Get the three positions in view space + int inFrontIdx = -1; + for ( int j = 0; j < 3; ++j ) + { + int index = m_IndexData[indexPos]; + DirectX::XMVECTOR *pPosition = ( DirectX::XMVECTOR *)&m_VertexData[index * m_VertexSize]; + if ( ( transformedVert[index >> 3] & ( 1 << ( index & 0x7 ) ) ) == 0 ) + { + *pPosition = DirectX::XMVector3TransformCoord( *pPosition, modelToView ); + //D3DXVec3TransformCoord( pPosition, pPosition, &modelToView ); + transformedVert[index >> 3] |= ( 1 << ( index & 0x7 ) ); + } + + pPos[j] = pPosition; + if ( XMVec3Component( *pPos[j], 2 ) < 0.0f ) + inFrontIdx = j; + ++indexPos; + } + + // all points are behind the camera + if ( inFrontIdx < 0 ) + continue; + + // backface cull.... + edge[0] = DirectX::XMVectorSubtract( *pPos[1], *pPos[0] ); + //D3DXVec3Subtract( &edge[0], pPos[1], pPos[0] ); + edge[1] = DirectX::XMVectorSubtract( *pPos[2], *pPos[0] ); + //D3DXVec3Subtract( &edge[1], pPos[2], pPos[0] ); + normal = DirectX::XMVector3Cross( edge[0], edge[1] ); + //D3DXVec3Cross( &normal, &edge[0], &edge[1] ); + float dot = DirectX::XMVectorGetX( DirectX::XMVector3Dot( normal, *pPos[inFrontIdx] ) ); + //float dot = D3DXVec3Dot( &normal, pPos[inFrontIdx] ); + if ( dot * cullFactor > 0.0f ) + continue; + + // Clip to viewport + ClipTriangle( pPos, zNear, projection ); + } +} + +//----------------------------------------------------------------------------- +// Begins a render pass +//----------------------------------------------------------------------------- +void CTempMeshDX11::BeginPass() +{ + Assert( !m_InPass ); + +#ifdef _DEBUG + m_InPass = true; +#endif + + CMeshBuilder *pMeshBuilder = ShaderAPI()->GetVertexModifyBuilder(); + + CDynamicMeshDX11 *pMesh = GetDynamicMesh(); + + int nIndexCount; + int nFirstIndex; + if ( ( s_FirstIndex == -1 ) && ( s_NumIndices == 0 ) ) + { + nIndexCount = m_IndexData.Count(); + nFirstIndex = 0; + } + else + { + nIndexCount = s_NumIndices; + nFirstIndex = s_FirstIndex; + } + + int i; + int nVertexCount = m_VertexData.Count() / m_VertexSize; + pMeshBuilder->Begin( pMesh, m_Type, nVertexCount, nIndexCount ); + + // Copy in the vertex data... + // Note that since we pad the vertices, it's faster for us to simply + // copy the fields we're using... + Assert( pMeshBuilder->BaseVertexData() ); + memcpy( pMeshBuilder->BaseVertexData(), m_VertexData.Base(), m_VertexData.Count() ); + pMeshBuilder->AdvanceVertices( m_VertexData.Count() / m_VertexSize ); + + for ( i = 0; i < nIndexCount; ++i ) + { + pMeshBuilder->Index( m_IndexData[nFirstIndex + i] ); + pMeshBuilder->AdvanceIndex(); + } + + // NOTE: The client is expected to modify the data after this call is made + pMeshBuilder->Reset(); +} + +//----------------------------------------------------------------------------- +// Draws a single pass +//----------------------------------------------------------------------------- +void CTempMeshDX11::RenderPass() +{ + Assert( m_InPass ); + +#ifdef _DEBUG + m_InPass = false; +#endif + + // Have the shader API modify the vertex data as it needs + // This vertex data is modified based on state set by the material + //ShaderAPI()->ModifyVertexData(); + + // Done building the mesh + ShaderAPI()->GetVertexModifyBuilder()->End(); + + // Have the dynamic mesh render a single pass... + GetDynamicMesh()->DrawSinglePassImmediately(); +} + +//----------------------------------------------------------------------------- +// +// Buffered mesh implementation +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- + +CBufferedMeshDX11::CBufferedMeshDX11() : m_IsFlushing( false ), m_WasRendered( true ) +{ + m_pMesh = NULL; +#ifdef DEBUG_BUFFERED_STATE + m_BufferedStateSet = false; +#endif +} + +CBufferedMeshDX11::~CBufferedMeshDX11() +{ +} + + +//----------------------------------------------------------------------------- +// Sets the mesh +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::SetMesh( CBaseMeshDX11 *pMesh ) +{ + if ( m_pMesh != pMesh ) + { + ShaderAPI()->FlushBufferedPrimitives(); + m_pMesh = pMesh; + } +} + + +//----------------------------------------------------------------------------- +// Spews the mesh data +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &spewDesc ) +{ + if ( m_pMesh ) + { + m_pMesh->Spew( nVertexCount, nIndexCount, spewDesc ); + } +} + + +//----------------------------------------------------------------------------- +// Sets the material +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::SetVertexFormat( VertexFormat_t format ) +{ + Assert( m_pMesh ); + bool bReset = m_pMesh->NeedsVertexFormatReset( format ); + if ( bReset ) + { + ShaderAPI()->FlushBufferedPrimitives(); + m_pMesh->SetVertexFormat( format ); + } +} + +void CBufferedMeshDX11::SetMorphFormat( MorphFormat_t format ) +{ + Assert( m_pMesh ); + m_pMesh->SetMorphFormat( format ); +} + +VertexFormat_t CBufferedMeshDX11::GetVertexFormat() const +{ + Assert( m_pMesh ); + return m_pMesh->GetVertexFormat(); +} + +void CBufferedMeshDX11::SetMaterial( IMaterial *pMaterial ) +{ +#if _DEBUG + Assert( m_pMesh ); + m_pMesh->SetMaterial( pMaterial ); +#endif +} + +void CBufferedMeshDX11::ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &spewDesc ) +{ +#if _DEBUG + Assert( m_pMesh ); + m_pMesh->ValidateData( nVertexCount, nIndexCount, spewDesc ); +#endif +} + + +//----------------------------------------------------------------------------- +// Sets the flex mesh to render with this mesh +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::SetFlexMesh( IMesh *pMesh, int nVertexOffsetInBytes ) +{ + // FIXME: Probably are situations where we don't need to flush, + // but this is going to look different in a very short while, so I'm not going to bother + ShaderAPI()->FlushBufferedPrimitives(); + m_pMesh->SetFlexMesh( pMesh, nVertexOffsetInBytes ); +} + + +//----------------------------------------------------------------------------- +// checks to see if it was rendered.. +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::ResetRendered() +{ + m_WasRendered = false; +} + +bool CBufferedMeshDX11::WasNotRendered() const +{ + return !m_WasRendered; +} + +//----------------------------------------------------------------------------- +// "Draws" it +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::Draw( int nFirstIndex, int nIndexCount ) +{ + if ( !ShaderUtil()->OnDrawMesh( this, nFirstIndex, nIndexCount ) ) + { + m_WasRendered = true; + MarkAsDrawn(); + return; + } + + Assert( !m_IsFlushing && !m_WasRendered ); + + // Gotta draw all of the buffered mesh + Assert( ( nFirstIndex == -1 ) && ( nIndexCount == 0 ) ); + + // No need to draw it more than once... + m_WasRendered = true; + + // We've got something to flush + m_FlushNeeded = true; + + // Less than 0 indices indicates we were using a standard buffer + if ( m_pMesh->HasFlexMesh() || !ShaderUtil()->GetConfig().bBufferPrimitives ) + { + ShaderAPI()->FlushBufferedPrimitives(); + } +} + + +//----------------------------------------------------------------------------- +// Sets the primitive mode +//----------------------------------------------------------------------------- + +void CBufferedMeshDX11::SetPrimitiveType( MaterialPrimitiveType_t type ) +{ + Assert( IsX360() || ( type != MATERIAL_INSTANCED_QUADS ) ); + Assert( type != MATERIAL_HETEROGENOUS ); + + if ( type != GetPrimitiveType() ) + { + ShaderAPI()->FlushBufferedPrimitives(); + m_pMesh->SetPrimitiveType( type ); + } +} + +MaterialPrimitiveType_t CBufferedMeshDX11::GetPrimitiveType() const +{ + return m_pMesh->GetPrimitiveType(); +} + +//----------------------------------------------------------------------------- +// Locks/unlocks the entire mesh +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) +{ + ShaderUtil()->SyncMatrices(); + + Assert( m_pMesh ); + Assert( m_WasRendered ); + + // Do some pre-lock processing + m_pMesh->PreLock(); + + // for tristrips, gotta make degenerate ones... + m_ExtraIndices = 0; + bool tristripFixup = ( m_pMesh->IndexCount() != 0 ) && + ( m_pMesh->GetPrimitiveType() == MATERIAL_TRIANGLE_STRIP ); + if ( tristripFixup ) + { + m_ExtraIndices = ( m_pMesh->IndexCount() & 0x1 ) != 0 ? 3 : 2; + nIndexCount += m_ExtraIndices; + } + + // Flush if we gotta + if ( !m_pMesh->HasEnoughRoom( nVertexCount, nIndexCount ) ) + { + ShaderAPI()->FlushBufferedPrimitives(); + } + + m_pMesh->LockMesh( nVertexCount, nIndexCount, desc ); + +// This is taken care of in the function above. +// CBaseMeshDX8::m_bMeshLocked = true; + + // Deal with fixing up the tristrip.. + if ( tristripFixup && desc.m_nIndexSize ) + { + char buf[32]; + if ( DebugTrace() ) + { + if ( m_ExtraIndices == 3 ) + sprintf( buf, "Link Index: %d %d\n", m_LastIndex, m_LastIndex ); + else + sprintf( buf, "Link Index: %d\n", m_LastIndex ); + Plat_DebugString( buf ); + } + *desc.m_pIndices++ = m_LastIndex; + if ( m_ExtraIndices == 3 ) + { + *desc.m_pIndices++ = m_LastIndex; + } + + // Leave room for the last padding index + ++desc.m_pIndices; + } + + m_WasRendered = false; + +#ifdef DEBUG_BUFFERED_MESHES + if ( m_BufferedStateSet ) + { + BufferedState_t compare; + ShaderAPI()->GetBufferedState( compare ); + Assert( !memcmp( &compare, &m_BufferedState, sizeof( compare ) ) ); + } + else + { + ShaderAPI()->GetBufferedState( m_BufferedState ); + m_BufferedStateSet = true; + } +#endif +} + + +//----------------------------------------------------------------------------- +// Locks/unlocks the entire mesh +//----------------------------------------------------------------------------- +void CBufferedMeshDX11::UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) +{ + Assert( m_pMesh ); + + // Gotta fix up the first index to batch strips reasonably + if ( ( m_pMesh->GetPrimitiveType() == MATERIAL_TRIANGLE_STRIP ) && desc.m_nIndexSize ) + { + if ( m_ExtraIndices > 0 ) + { + *( desc.m_pIndices - 1 ) = *desc.m_pIndices; + + if ( DebugTrace() ) + { + char buf[32]; + sprintf( buf, "Link Index: %d\n", *desc.m_pIndices ); + Plat_DebugString( buf ); + } + } + + // Remember the last index for next time + m_LastIndex = desc.m_pIndices[nIndexCount - 1]; + + nIndexCount += m_ExtraIndices; + } + + m_pMesh->UnlockMesh( nVertexCount, nIndexCount, desc ); + +// This is taken care of in the function above. +// CBaseMeshDX8::m_bMeshLocked = false; +} + +//----------------------------------------------------------------------------- +// Renders a pass +//----------------------------------------------------------------------------- + +void CBufferedMeshDX11::RenderPass() +{ + // this should never be called! + Assert( 0 ); +} + +//----------------------------------------------------------------------------- +// Flushes queued data +//----------------------------------------------------------------------------- + +void CBufferedMeshDX11::Flush() +{ + //return; + + // If you are hitting this assert you are causing a flush between a + // meshbuilder begin/end and you are more than likely losing rendering data. + AssertOnce( !m_bMeshLocked ); + + if ( m_pMesh && !m_IsFlushing && m_FlushNeeded ) + { + VPROF( "CBufferedMeshDX11::Flush" ); + +#ifdef DEBUG_BUFFERED_MESHES + if ( m_BufferedStateSet ) + { + BufferedState_t compare; + ShaderAPI()->GetBufferedState( compare ); + Assert( !memcmp( &compare, &m_BufferedState, sizeof( compare ) ) ); + m_BufferedStateSet = false; + } +#endif + + m_IsFlushing = true; + + // Actually draws the data using the mesh's material + static_cast( m_pMesh )->Draw(); + + m_IsFlushing = false; + m_FlushNeeded = false; + + m_pMesh->SetFlexMesh( NULL, 0 ); + } +} + +//----------------------------------------------------------------------------- +// +// Mesh manager implementation +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +CMeshMgr::CMeshMgr() : + m_pDynamicIndexBuffer( 0 ), + m_DynamicTempMesh( true ), + m_pVertexIDBuffer( 0 ), + m_pCurrentVertexBuffer( NULL ), + m_CurrentVertexFormat( 0 ), + m_pCurrentIndexBuffer( NULL ), + m_DynamicIndexBuffer( SHADER_BUFFER_TYPE_DYNAMIC, MATERIAL_INDEX_FORMAT_16BIT, INDEX_BUFFER_SIZE, "dynamic" ), + m_DynamicVertexBuffer( SHADER_BUFFER_TYPE_DYNAMIC, VERTEX_FORMAT_UNKNOWN, DYNAMIC_VERTEX_BUFFER_MEMORY, "dynamic" ) +{ + m_bUseFatVertices = false; + m_nIndexBufferOffset = 0; + memset( m_pVertexBufferOffset, 0, sizeof( m_pVertexBufferOffset ) ); + memset( m_pCurrentVertexStride, 0, sizeof( m_pCurrentVertexStride ) ); + memset( m_pFirstVertex, 0, sizeof( m_pFirstVertex ) ); + memset( m_pVertexCount, 0, sizeof( m_pVertexCount ) ); + m_nUnusedVertexFields = 0; + m_nUnusedTextureCoords = 0; +} + +CMeshMgr::~CMeshMgr() +{ +} + +//----------------------------------------------------------------------------- +// Initialize, shutdown +//----------------------------------------------------------------------------- +void CMeshMgr::Init() +{ + m_DynamicMesh.Init( 0 ); + m_DynamicFlexMesh.Init( 1 ); + + // The dynamic index buffer + //m_pDynamicIndexBuffer = new CIndexBuffer( Dx9Device(), INDEX_BUFFER_SIZE, ShaderAPI()->UsingSoftwareVertexProcessing(), true ); + m_pDynamicIndexBuffer = static_cast( + g_pShaderDeviceDx11->CreateIndexBuffer( SHADER_BUFFER_TYPE_DYNAMIC, MATERIAL_INDEX_FORMAT_16BIT, INDEX_BUFFER_SIZE, "dynamic" ) ); + //Log( "Dynamic ib index size: %i\n", m_pDynamicIndexBuffer->IndexSize() ); + + // If we're running in vs3.0, allocate a vertexID buffer + CreateVertexIDBuffer(); + + m_BufferedMode = !IsX360(); +} + +void CMeshMgr::Shutdown() +{ + CleanUp(); +} + +void CMeshMgr::CreateVertexIDBuffer() +{ + DestroyVertexIDBuffer(); + + // Track mesh allocations + g_VBAllocTracker->TrackMeshAllocations( "CreateVertexIDBuffer" ); + if ( g_pHardwareConfig->HasFastVertexTextures() ) + { + m_pVertexIDBuffer = static_cast( + g_pShaderDeviceDx11->CreateVertexBuffer( SHADER_BUFFER_TYPE_DYNAMIC, VERTEX_USERDATA_SIZE( 1 ), VERTEX_BUFFER_SIZE, + TEXTURE_GROUP_STATIC_VERTEX_BUFFER_OTHER ) ); + FillVertexIDBuffer( m_pVertexIDBuffer, VERTEX_BUFFER_SIZE ); + } + g_VBAllocTracker->TrackMeshAllocations( NULL ); +} + +void CMeshMgr::DestroyVertexIDBuffer() +{ + if ( m_pVertexIDBuffer ) + { + g_pShaderDeviceDx11->DestroyVertexBuffer( m_pVertexIDBuffer ); + m_pVertexIDBuffer = NULL; + } +} + +CVertexBufferDx11 *CMeshMgr::GetVertexIDBuffer() +{ + return m_pVertexIDBuffer; +} + +//----------------------------------------------------------------------------- +// Fills a vertexID buffer +//----------------------------------------------------------------------------- +void CMeshMgr::FillVertexIDBuffer( CVertexBufferDx11 *pVertexIDBuffer, int nCount ) +{ + if ( IsX360() ) + return; + + // Fill the buffer with the values 0->(nCount-1) + int nBaseVertexIndex = 0; + VertexDesc_t desc; + bool ret = pVertexIDBuffer->Lock( nCount, nBaseVertexIndex, desc ); + if ( ret ) + { + for ( int i = 0; i < nCount; ++i ) + { + *desc.m_pUserData++ = (float)i; + } + } + + pVertexIDBuffer->Unlock( nCount, desc ); +} + +//----------------------------------------------------------------------------- +// Task switch... +//----------------------------------------------------------------------------- +void CMeshMgr::ReleaseBuffers() +{ + if ( IsPC() && mat_debugalttab.GetBool() ) + { + Warning( "mat_debugalttab: CMeshMgr::ReleaseBuffers\n" ); + } + + CleanUp(); + m_DynamicMesh.Reset(); + m_DynamicFlexMesh.Reset(); +} + +void CMeshMgr::RestoreBuffers() +{ + if ( IsPC() && mat_debugalttab.GetBool() ) + { + Warning( "mat_debugalttab: CMeshMgr::RestoreBuffers\n" ); + } + Init(); +} + +//----------------------------------------------------------------------------- +// Cleans up vertex and index buffers +//----------------------------------------------------------------------------- +void CMeshMgr::CleanUp() +{ + if ( m_pDynamicIndexBuffer ) + { + delete m_pDynamicIndexBuffer; + m_pDynamicIndexBuffer = 0; + } + + DestroyVertexBuffers(); + + // If we're running in vs3.0, allocate a vertexID buffer + DestroyVertexIDBuffer(); +} + +//----------------------------------------------------------------------------- +// Unused vertex fields +//----------------------------------------------------------------------------- +void CMeshMgr::MarkUnusedVertexFields( unsigned int nFlags, int nTexCoordCount, bool *pUnusedTexCoords ) +{ + m_nUnusedVertexFields = nFlags; + m_nUnusedTextureCoords = 0; + for ( int i = 0; i < nTexCoordCount; ++i ) + { + if ( pUnusedTexCoords[i] ) + { + m_nUnusedTextureCoords |= ( 1 << i ); + } + } +} + +//----------------------------------------------------------------------------- +// Is the mesh dynamic? +//----------------------------------------------------------------------------- +bool CMeshMgr::IsDynamicMesh( IMesh *pMesh ) const +{ + return ( pMesh == &m_DynamicMesh ) || ( pMesh == &m_DynamicFlexMesh ); +} + +bool CMeshMgr::IsBufferedDynamicMesh( IMesh *pMesh ) const +{ + return ( pMesh == &m_BufferedMesh ); +} + +bool CMeshMgr::IsDynamicVertexBuffer( IVertexBuffer *pVertexBuffer ) const +{ + return ( pVertexBuffer == &m_DynamicVertexBuffer ); +} + +bool CMeshMgr::IsDynamicIndexBuffer( IIndexBuffer *pIndexBuffer ) const +{ + return ( pIndexBuffer == &m_DynamicIndexBuffer ); +} + +//----------------------------------------------------------------------------- +// Discards the dynamic vertex and index buffer +//----------------------------------------------------------------------------- +void CMeshMgr::DiscardVertexBuffers() +{ + VPROF_BUDGET( "CMeshMgr::DiscardVertexBuffers", VPROF_BUDGETGROUP_SWAP_BUFFERS ); + // This shouldn't be necessary, but it seems to be on GeForce 2 + // It helps when running WC and the engine simultaneously. + //ResetMeshRenderState(); + + // Flush all dynamic vertex and index buffers the next time + // Lock() is called on them. + if ( !g_pShaderDeviceDx11->IsDeactivated() ) + { + for ( int i = m_DynamicVertexBuffers.Count(); --i >= 0; ) + { + m_DynamicVertexBuffers[i].m_pBuffer->Flush(); + } + m_pDynamicIndexBuffer->Flush(); + } +} + +//----------------------------------------------------------------------------- +// Releases all dynamic vertex buffers +//----------------------------------------------------------------------------- +void CMeshMgr::DestroyVertexBuffers() +{ + + for ( int i = m_DynamicVertexBuffers.Count(); --i >= 0; ) + { + if ( m_DynamicVertexBuffers[i].m_pBuffer ) + { + // This will also unbind it + g_pShaderDeviceDx11->DestroyVertexBuffer( m_DynamicVertexBuffers[i].m_pBuffer ); + } + } + + m_DynamicVertexBuffers.RemoveAll(); + m_DynamicMesh.Reset(); + m_DynamicFlexMesh.Reset(); +} + + +//----------------------------------------------------------------------------- +// Flushes the dynamic mesh +//----------------------------------------------------------------------------- +void CMeshMgr::Flush() +{ + if ( IsPC() ) + { + m_BufferedMesh.Flush(); + } +} + +//----------------------------------------------------------------------------- +// Creates, destroys static meshes +//----------------------------------------------------------------------------- +IMesh *CMeshMgr::CreateStaticMesh( VertexFormat_t format, const char *pTextureBudgetGroup, IMaterial *pMaterial ) +{ + // FIXME: Use a fixed-size allocator + CMeshDX11 *pNewMesh = new CMeshDX11( pTextureBudgetGroup ); + pNewMesh->SetVertexFormat( format ); + if ( pMaterial != NULL ) + { + pNewMesh->SetMorphFormat( pMaterial->GetMorphFormat() ); + pNewMesh->SetMaterial( pMaterial ); + } + return pNewMesh; +} + +void CMeshMgr::DestroyStaticMesh( IMesh *pMesh ) +{ + // Don't destroy the dynamic mesh! + Assert( !IsDynamicMesh( pMesh ) ); + CBaseMeshDX11 *pMeshImp = static_cast( pMesh ); + if ( pMeshImp ) + { + delete pMeshImp; + } +} + +//----------------------------------------------------------------------------- +// Copy a static mesh index buffer to a dynamic mesh index buffer +//----------------------------------------------------------------------------- +void CMeshMgr::CopyStaticMeshIndexBufferToTempMeshIndexBuffer( CTempMeshDX11 *pDstIndexMesh, + CMeshDX11 *pSrcIndexMesh ) +{ + Assert( !pSrcIndexMesh->IsDynamic() ); + int nIndexCount = pSrcIndexMesh->IndexCount(); + + CMeshBuilder dstMeshBuilder; + dstMeshBuilder.Begin( pDstIndexMesh, pSrcIndexMesh->GetPrimitiveType(), 0, nIndexCount ); + CIndexBufferDx11 *srcIndexBuffer = pSrcIndexMesh->GetIndexBuffer(); + IndexDesc_t desc; + bool ret = srcIndexBuffer->Lock( nIndexCount, false, desc ); + if ( ret ) + { + int i; + for ( i = 0; i < nIndexCount; i++ ) + { + dstMeshBuilder.Index( desc.m_pIndices[i] ); + dstMeshBuilder.AdvanceIndex(); + } + } + + srcIndexBuffer->Unlock( 0, desc ); + dstMeshBuilder.End(); +} + +//----------------------------------------------------------------------------- +// Gets at the *real* dynamic mesh +//----------------------------------------------------------------------------- +IMesh *CMeshMgr::GetActualDynamicMesh( VertexFormat_t format ) +{ + m_DynamicMesh.SetVertexFormat( format ); + return &m_DynamicMesh; +} + +IMesh *CMeshMgr::GetFlexMesh() +{ + if ( g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_b() ) + { + // FIXME: Kinda ugly size.. 28 bytes + m_DynamicFlexMesh.SetVertexFormat( VERTEX_POSITION | VERTEX_NORMAL | VERTEX_WRINKLE | VERTEX_FORMAT_USE_EXACT_FORMAT ); + } + else + { + // Same size as a pair of float3s (24 bytes) + m_DynamicFlexMesh.SetVertexFormat( VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_USE_EXACT_FORMAT ); + } + return &m_DynamicFlexMesh; +} + +//----------------------------------------------------------------------------- +// Gets at the dynamic mesh +//----------------------------------------------------------------------------- +IMesh *CMeshMgr::GetDynamicMesh( IMaterial *pMaterial, VertexFormat_t vertexFormat, int nHWSkinBoneCount, + bool buffered, IMesh *pVertexOverride, IMesh *pIndexOverride ) +{ + if ( !( ( pMaterial == NULL ) || ( (IMaterialInternal *)pMaterial )->IsRealTimeVersion() ) ) + { + //DebuggerBreak(); + } + + if ( IsX360() ) + { + buffered = false; + } + + // Can't be buffered if we're overriding the buffers + if ( pVertexOverride || pIndexOverride ) + { + buffered = false; + } + + // When going from buffered to unbuffered mode, need to flush.. + if ( ( m_BufferedMode != buffered ) && m_BufferedMode ) + { + m_BufferedMesh.SetMesh( 0 ); + } + m_BufferedMode = buffered; + + IMaterialInternal *pMatInternal = static_cast( pMaterial ); + + bool needTempMesh = ShaderAPI()->IsInSelectionMode(); + +#ifdef DRAW_SELECTION + if ( g_bDrawSelection ) + { + needTempMesh = true; + } +#endif + + CBaseMeshDX11 *pMesh; + + if ( needTempMesh ) + { + // These haven't been implemented yet for temp meshes! + // I'm not a hundred percent sure how to implement them; it would + // involve a lock and a copy at least, which would stall the entire + // rendering pipeline. + Assert( !pVertexOverride ); + + if ( pIndexOverride ) + { + CopyStaticMeshIndexBufferToTempMeshIndexBuffer( &m_DynamicTempMesh, + (CMeshDX11 *)pIndexOverride ); + } + pMesh = &m_DynamicTempMesh; + } + else + { + pMesh = &m_DynamicMesh; + } + + if ( m_BufferedMode ) + { + Assert( !m_BufferedMesh.WasNotRendered() ); + m_BufferedMesh.SetMesh( pMesh ); + pMesh = &m_BufferedMesh; + } + + if ( !pVertexOverride ) + { + // Remove VERTEX_FORMAT_COMPRESSED from the material's format (dynamic meshes don't + // support compression, and all materials should support uncompressed verts too) + VertexFormat_t materialFormat = pMatInternal->GetVertexFormat() & ~VERTEX_FORMAT_COMPRESSED; + VertexFormat_t fmt = ( vertexFormat != 0 ) ? vertexFormat : materialFormat; + if ( vertexFormat != 0 ) + { + int nVertexFormatBoneWeights = NumBoneWeights( vertexFormat ); + if ( nHWSkinBoneCount < nVertexFormatBoneWeights ) + { + nHWSkinBoneCount = nVertexFormatBoneWeights; + } + } + + // Force the requested number of bone weights + fmt &= ~VERTEX_BONE_WEIGHT_MASK; + if ( nHWSkinBoneCount > 0 ) + { + fmt |= VERTEX_BONEWEIGHT( 2 ); + fmt |= VERTEX_BONE_INDEX; + } + + pMesh->SetVertexFormat( fmt ); + } + else + { + CBaseMeshDX11 *pDX8Mesh = static_cast( pVertexOverride ); + pMesh->SetVertexFormat( pDX8Mesh->GetVertexFormat() ); + } + pMesh->SetMorphFormat( pMatInternal->GetMorphFormat() ); + pMesh->SetMaterial( pMatInternal ); + + // Note this works because we're guaranteed to not be using a buffered mesh + // when we have overrides on + // FIXME: Make work for temp meshes + if ( pMesh == &m_DynamicMesh ) + { + CBaseMeshDX11 *pBaseVertex = static_cast( pVertexOverride ); + if ( pBaseVertex ) + { + m_DynamicMesh.OverrideVertexBuffer( pBaseVertex->GetVertexBuffer() ); + } + + CBaseMeshDX11 *pBaseIndex = static_cast( pIndexOverride ); + if ( pBaseIndex ) + { + m_DynamicMesh.OverrideIndexBuffer( pBaseIndex->GetIndexBuffer() ); + } + } + + return pMesh; +} + + +//----------------------------------------------------------------------------- +// Used to construct vertex data +//----------------------------------------------------------------------------- +void CMeshMgr::ComputeVertexDescription( unsigned char *pBuffer, + VertexFormat_t vertexFormat, MeshDesc_t &desc ) const +{ + ComputeVertexDesc( pBuffer, vertexFormat, (VertexDesc_t &)desc ); +} + +//----------------------------------------------------------------------------- +// Computes the vertex format +//----------------------------------------------------------------------------- +VertexFormat_t CMeshMgr::ComputeVertexFormat( unsigned int flags, + int nTexCoordArraySize, int *pTexCoordDimensions, int numBoneWeights, + int userDataSize ) const +{ + // Construct a bitfield that makes sense and is unique from the standard FVF formats + VertexFormat_t fmt = flags & ~VERTEX_FORMAT_USE_EXACT_FORMAT; + + if ( g_pHardwareConfig->SupportsCompressedVertices() == VERTEX_COMPRESSION_NONE ) + { + // Vertex compression is disabled - make sure all materials + // say "No!" to compressed verts ( tested in IsValidVertexFormat() ) + fmt &= ~VERTEX_FORMAT_COMPRESSED; + } + + // This'll take 3 bits at most + Assert( numBoneWeights <= 4 ); + + if ( numBoneWeights > 0 ) + { + fmt |= VERTEX_BONEWEIGHT( 2 ); // Always exactly two weights + } + + // Size is measured in # of floats + Assert( userDataSize <= 4 ); + fmt |= VERTEX_USERDATA_SIZE( userDataSize ); + + // NOTE: If pTexCoordDimensions isn't specified, then nTexCoordArraySize + // is interpreted as meaning that we have n 2D texcoords in the first N texcoord slots + nTexCoordArraySize = min( nTexCoordArraySize, VERTEX_MAX_TEXTURE_COORDINATES ); + for ( int i = 0; i < nTexCoordArraySize; ++i ) + { + if ( pTexCoordDimensions ) + { + Assert( pTexCoordDimensions[i] >= 0 && pTexCoordDimensions[i] <= 4 ); + fmt |= VERTEX_TEXCOORD_SIZE( (TextureStage_t)i, pTexCoordDimensions[i] ); + } + else + { + fmt |= VERTEX_TEXCOORD_SIZE( (TextureStage_t)i, 2 ); + } + } + + return fmt; +} + +//----------------------------------------------------------------------------- +// Use fat vertices (for tools) +//----------------------------------------------------------------------------- +void CMeshMgr::UseFatVertices( bool bUseFat ) +{ + m_bUseFatVertices = bUseFat; +} + +//----------------------------------------------------------------------------- +// Returns the number of vertices we can render using the dynamic mesh +//----------------------------------------------------------------------------- +void CMeshMgr::GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) +{ + CBaseMeshDX11 *pBaseMesh = static_cast( pMesh ); + if ( !pBaseMesh ) + { + *pMaxVerts = 0; + *pMaxIndices = m_pDynamicIndexBuffer->IndexCount(); + return; + } + + if ( IsBufferedDynamicMesh( pMesh ) ) + { + pBaseMesh = ( CBaseMeshDX11 * )static_cast( pBaseMesh )->GetMesh(); + pMesh = pBaseMesh; + } + + // Static mesh? Max you can use is 65535 + if ( !IsDynamicMesh( pMesh ) ) + { + *pMaxVerts = VERTEX_BUFFER_SIZE; + *pMaxIndices = 65535; + return; + } + + CVertexBufferDx11 *pVertexBuffer = pBaseMesh->GetVertexBuffer(); + CIndexBufferDx11 *pIndexBuffer = pBaseMesh->GetIndexBuffer(); + + if ( !pVertexBuffer ) + { + *pMaxVerts = 0; + *pMaxIndices = 0; + return; + } + + if ( !bMaxUntilFlush ) + { + *pMaxVerts = ShaderAPI()->GetCurrentDynamicVBSize() / pVertexBuffer->VertexSize(); + if ( *pMaxVerts > VERTEX_BUFFER_SIZE) + { + *pMaxVerts = VERTEX_BUFFER_SIZE; + } + *pMaxIndices = pIndexBuffer ? pIndexBuffer->IndexCount() : 0; + return; + } + + *pMaxVerts = pVertexBuffer->GetRoomRemaining(); + *pMaxIndices = pIndexBuffer ? pIndexBuffer->IndexCount() - pIndexBuffer->IndexPosition() : 0; + if ( *pMaxVerts == 0 ) + { + *pMaxVerts = ShaderAPI()->GetCurrentDynamicVBSize() / pVertexBuffer->VertexSize(); + } + if ( *pMaxVerts > VERTEX_BUFFER_SIZE) + { + *pMaxVerts = VERTEX_BUFFER_SIZE; + } + if ( *pMaxIndices == 0 ) + { + *pMaxIndices = pIndexBuffer ? pIndexBuffer->IndexCount() : 0; + } +} + +int CMeshMgr::GetMaxVerticesToRender( IMaterial *pMaterial ) +{ + //if ( !( ( pMaterial == NULL ) || ( (IMaterialInternal *)pMaterial )->IsRealTimeVersion() ) ) + //{ + // DebuggerBreak(); + //}// + + // Be conservative, assume no compression (in here, we don't know if the caller will used a compressed VB or not) + // FIXME: allow the caller to specify which compression type should be used to compute size from the vertex format + // (this can vary between multiple VBs/Meshes using the same material) + VertexFormat_t fmt = pMaterial->GetVertexFormat() & ~VERTEX_FORMAT_COMPRESSED; + int nMaxVerts = ShaderAPI()->GetCurrentDynamicVBSize() / VertexFormatSize( fmt ); + if ( nMaxVerts > VERTEX_BUFFER_SIZE) + { + nMaxVerts = VERTEX_BUFFER_SIZE; + } + return nMaxVerts; +} + +int CMeshMgr::GetMaxIndicesToRender() +{ + return INDEX_BUFFER_SIZE; +} + +//----------------------------------------------------------------------------- +// Returns a vertex buffer appropriate for the flags +//----------------------------------------------------------------------------- +CVertexBufferDx11 *CMeshMgr::FindOrCreateVertexBuffer( int nDynamicBufferId, VertexFormat_t vertexFormat ) +{ + int vertexSize = VertexFormatSize( vertexFormat ); + + while ( m_DynamicVertexBuffers.Count() <= nDynamicBufferId ) + { + // Track VB allocations (override any prior allocator string set higher up on the callstack) + g_VBAllocTracker->TrackMeshAllocations( NULL ); + g_VBAllocTracker->TrackMeshAllocations( "CMeshMgr::FindOrCreateVertexBuffer (dynamic VB)" ); + + // create the single 1MB dynamic vb that will be shared amongst all consumers + // the correct thing is to use the largest expected vertex format size of max elements, but this + // creates an undesirably large buffer - instead create the buffer we want, and fix consumers that bork + // NOTE: GetCurrentDynamicVBSize returns a smaller value during level transitions + int nBufferMemory = ShaderAPI()->GetCurrentDynamicVBSize(); + int nIndex = m_DynamicVertexBuffers.AddToTail(); + m_DynamicVertexBuffers[nIndex].m_VertexSize = vertexSize; + m_DynamicVertexBuffers[nIndex].m_VertexFormat = vertexFormat; + m_DynamicVertexBuffers[nIndex].m_pBuffer = static_cast( + g_pShaderDeviceDx11->CreateVertexBuffer( SHADER_BUFFER_TYPE_DYNAMIC, vertexFormat, nBufferMemory / vertexSize, "dynamicvb" ) ); + + g_VBAllocTracker->TrackMeshAllocations( NULL ); + } + + if ( m_DynamicVertexBuffers[nDynamicBufferId].m_VertexSize != vertexSize || + m_DynamicVertexBuffers[nDynamicBufferId].m_VertexFormat != vertexFormat ) + { + // provide caller with dynamic vb in expected format + // NOTE: GetCurrentDynamicVBSize returns a smaller value during level transitions + int nBufferMemory = ShaderAPI()->GetCurrentDynamicVBSize(); + m_DynamicVertexBuffers[nDynamicBufferId].m_VertexSize = vertexSize; + m_DynamicVertexBuffers[nDynamicBufferId].m_VertexFormat = vertexFormat; + m_DynamicVertexBuffers[nDynamicBufferId].m_pBuffer->ChangeConfiguration( vertexSize, nBufferMemory, vertexFormat ); + + // size changed means stream stride needs update + // mark cached stream state as invalid to reset stream + //if ( nDynamicBufferId == 0 ) + //{ + // g_pLastVertex = NULL; + //} + } + + return m_DynamicVertexBuffers[nDynamicBufferId].m_pBuffer; +} + +CIndexBufferDx11 *CMeshMgr::GetDynamicIndexBuffer() +{ + return m_pDynamicIndexBuffer; +} + +IVertexBuffer *CMeshMgr::GetDynamicVertexBuffer( IMaterial *pMaterial, bool buffered ) +{ + Assert( 0 ); + return NULL; +// return ( IMeshDX8 * )GetDynamicMesh( pMaterial, buffered, NULL, NULL ); +} + +IIndexBuffer *CMeshMgr::GetDynamicIndexBuffer( IMaterial *pMaterial, bool buffered ) +{ + Assert( 0 ); + return NULL; +// return ( IMeshDX8 * )GetDynamicMesh( pMaterial, buffered, NULL, NULL ); +} + +// Do we need to specify the stream here in the case of locking multiple dynamic VBs on different streams? +IVertexBuffer *CMeshMgr::GetDynamicVertexBuffer( int streamID, VertexFormat_t vertexFormat, bool bBuffered ) +{ + if ( IsX360() ) + { + bBuffered = false; + } + + if ( CompressionType( vertexFormat ) != VERTEX_COMPRESSION_NONE ) + { + // UNDONE: support compressed dynamic meshes if needed (pro: less VB memory, con: time spent compressing) + //DebuggerBreak(); + return NULL; + } + + // MESHFIXME +#if 0 + if ( ( m_BufferedMode != bBuffered ) && m_BufferedMode ) + { + m_BufferedIndexBuffer.SetIndexBuffer( NULL ); + } +#endif + + m_BufferedMode = bBuffered; + Assert( !m_BufferedMode ); // MESHFIXME: don't deal with buffered VBs yet. + + bool needTempMesh = ShaderAPI()->IsInSelectionMode(); + +#ifdef DRAW_SELECTION + if ( g_bDrawSelection ) + { + needTempMesh = true; + } +#endif + + Assert( !needTempMesh ); // MESHFIXME: don't support temp meshes here yet. + + CVertexBufferDx11 *pVertexBuffer; + + if ( needTempMesh ) + { + Assert( 0 ); // MESHFIXME: don't do this yet. +// pVertexBuffer = &m_DynamicTempVertexBuffer; + pVertexBuffer = NULL; + } + else + { + pVertexBuffer = &m_DynamicVertexBuffer; + } + + if ( m_BufferedMode ) + { + Assert( 0 ); // don't support this yet. +#if 0 + Assert( !m_BufferedMesh.WasNotRendered() ); + m_BufferedMesh.SetMesh( pMesh ); + pMesh = &m_BufferedMesh; +#endif + } + + return pVertexBuffer; +} + +IIndexBuffer *CMeshMgr::GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered ) +{ + if ( IsX360() ) + { + bBuffered = false; + } + + m_BufferedMode = bBuffered; + + Assert( !m_BufferedMode ); + +#ifdef _DEBUG + bool needTempMesh = +#endif + ShaderAPI()->IsInSelectionMode(); + +#ifdef DRAW_SELECTION + if ( g_bDrawSelection ) + { + needTempMesh = true; + } +#endif + + Assert( !needTempMesh ); // don't handle this yet. MESHFIXME + + CIndexBufferBase *pIndexBuffer = &m_DynamicIndexBuffer; + return pIndexBuffer; +} + +void CMeshMgr::RenderPassWithVertexAndIndexBuffers() +{ + +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/meshdx11.h b/materialsystem/shaderapidx11/meshdx11.h new file mode 100644 index 0000000..0282585 --- /dev/null +++ b/materialsystem/shaderapidx11/meshdx11.h @@ -0,0 +1,100 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + + +#ifndef MESHDX11_H +#define MESHDX11_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderapidx9/meshbase.h" +#include "shaderapi/ishaderdevice.h" + +abstract_class IMeshMgrDx11 +{ +public: + // Initialize, shutdown + virtual void Init() = 0; + virtual void Shutdown() = 0; + + // Task switch... + virtual void ReleaseBuffers() = 0; + virtual void RestoreBuffers() = 0; + + // Releases all dynamic vertex buffers + virtual void DestroyVertexBuffers() = 0; + + // Flushes the dynamic mesh. Should be called when state changes + virtual void Flush() = 0; + + // Discards the dynamic vertex and index buffer + virtual void DiscardVertexBuffers() = 0; + + // Creates, destroys static meshes + virtual IMesh *CreateStaticMesh( VertexFormat_t vertexFormat, const char *pTextureBudgetGroup, IMaterial *pMaterial = NULL ) = 0; + virtual void DestroyStaticMesh( IMesh *pMesh ) = 0; + + // Gets at the dynamic mesh + virtual IMesh *GetDynamicMesh( IMaterial *pMaterial, VertexFormat_t vertexFormat, int nHWSkinBoneCount, bool buffered = true, + IMesh *pVertexOverride = 0, IMesh *pIndexOverride = 0 ) = 0; + + // ------------ New Vertex/Index Buffer interface ---------------------------- + // Do we need support for bForceTempMesh and bSoftwareVertexShader? + // I don't think we use bSoftwareVertexShader anymore. .need to look into bForceTempMesh. + virtual IVertexBuffer *CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup ) = 0; + virtual IIndexBuffer *CreateIndexBuffer( ShaderBufferType_t indexBufferType, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup ) = 0; + virtual void DestroyVertexBuffer( IVertexBuffer * ) = 0; + virtual void DestroyIndexBuffer( IIndexBuffer * ) = 0; + // Do we need to specify the stream here in the case of locking multiple dynamic VBs on different streams? + virtual IVertexBuffer *GetDynamicVertexBuffer( int streamID, VertexFormat_t vertexFormat, bool bBuffered = true ) = 0; + virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true ) = 0; + virtual void BindVertexBuffer( int streamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 ) = 0; + virtual void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ) = 0; + virtual void Draw( MaterialPrimitiveType_t primitiveType, int nFirstIndex, int nIndexCount ) = 0; + // ------------ End ---------------------------- + virtual VertexFormat_t GetCurrentVertexFormat( void ) const = 0; + virtual void RenderPassWithVertexAndIndexBuffers( void ) = 0; + + // Computes the vertex format + virtual VertexFormat_t ComputeVertexFormat( unsigned int flags, + int numTexCoords, int *pTexCoordDimensions, int numBoneWeights, + int userDataSize ) const = 0; + + // Returns the number of buffers... + virtual int BufferCount() const = 0; + + // Use fat vertices (for tools) + virtual void UseFatVertices( bool bUseFat ) = 0; + + // Returns the number of vertices + indices we can render using the dynamic mesh + // Passing true in the second parameter will return the max # of vertices + indices + // we can use before a flush is provoked and may return different values + // if called multiple times in succession. + // Passing false into the second parameter will return + // the maximum possible vertices + indices that can be rendered in a single batch + virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) = 0; + + // Returns the max number of vertices we can render for a given material + virtual int GetMaxVerticesToRender( IMaterial *pMaterial ) = 0; + virtual int GetMaxIndicesToRender() = 0; + virtual IMesh *GetFlexMesh() = 0; + + virtual void ComputeVertexDescription( unsigned char *pBuffer, VertexFormat_t vertexFormat, MeshDesc_t &desc ) const = 0; + + virtual IVertexBuffer *GetDynamicVertexBuffer( IMaterial *pMaterial, bool buffered = true ) = 0; + virtual IIndexBuffer *GetDynamicIndexBuffer( IMaterial *pMaterial, bool buffered = true ) = 0; + + virtual void MarkUnusedVertexFields( unsigned int nFlags, int nTexCoordCount, bool *pUnusedTexCoords ) = 0; +}; + +IMeshMgrDx11 *MeshMgr(); + +#endif // MESHDX11_H + diff --git a/materialsystem/shaderapidx11/shaderapidx11.cpp b/materialsystem/shaderapidx11/shaderapidx11.cpp new file mode 100644 index 0000000..ed895a9 --- /dev/null +++ b/materialsystem/shaderapidx11/shaderapidx11.cpp @@ -0,0 +1,3965 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: ShaderAPIDx11 implementation +// +// $NoKeywords: $ +// +//===========================================================================// + +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "shaderapidx11.h" +#include "shaderapidx9/shaderapibase.h" +#include "shaderapi/ishaderutil.h" +#include "shaderapi/commandbuffer.h" +#include "materialsystem/idebugtextureinfo.h" +#include "materialsystem/materialsystem_config.h" +#include "materialsystem/imorph.h" +#include "meshdx11.h" +#include "shadershadowdx11.h" +#include "shaderdevicedx11.h" +#include "shaderapidx11_global.h" +#include "imaterialinternal.h" +#include "ShaderConstantBufferDx11.h" +#include "vertexshaderdx11.h" +#include "VertexBufferDx11.h" +#include "IndexBufferDx11.h" +#include "materialsystem/IShader.h" +#include "../stdshaders/cpp_shader_constant_register_map.h" +#include "Dx11Global.h" +#include "ITextureInternal.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +template +FORCEINLINE static void XMSetComponent4( T &vec, int comp, float val ) +{ + switch ( comp ) + { + case 0: + vec.x = val; + break; + case 1: + vec.y = val; + break; + case 2: + vec.z = val; + break; + case 3: + vec.w = val; + break; + } +} + +//------------------------------------------------------------------- +// Common constant buffers, grouped by frequency of update. +// NOTE: These need to match the cbuffers in common_cbuffers_fxc.h!!! +//------------------------------------------------------------------- + +// In order of most frequent to least frequent... + +// NOTE: ShaderAPI is not responsible for constant buffers +// that change every material/draw call/shader, but the shader +// class itself. + +ALIGN16 struct DX11LightInfo_t +{ + DirectX::XMFLOAT4 color; + DirectX::XMFLOAT4 dir; + DirectX::XMFLOAT4 pos; + DirectX::XMFLOAT4 spotParams; + DirectX::XMFLOAT4 atten; +}; + +// Constants that can be expected to change for each model. +ALIGN16 struct PerModel_CBuffer_t +{ + DirectX::XMMATRIX cModelMatrix; // If using skinning, same as cModel[0] + // Four lights x 5 constants each = 20 constants + DX11LightInfo_t cLightInfo[4]; + DirectX::XMINT4 cLightCount; + DirectX::XMFLOAT3A cAmbientCube[6]; +}; + +// These were split from per-model because they are big + +ALIGN16 struct Skinning_CBuffer_t +{ + DirectX::XMFLOAT3X4A cModel[53]; +}; + +ALIGN16 struct Flex_CBuffer_t +{ + DirectX::XMFLOAT4 cFlexWeights[512]; +}; + +// Constants that can be expected to change each frame. +// TODO: Can we save a constant by having the vertex shader +// extract the eye position from the viewmatrix? +ALIGN16 struct PerFrame_CBuffer_t +{ + DirectX::XMMATRIX cViewMatrix; + DirectX::XMFLOAT4 cEyePos; + DirectX::XMFLOAT4 cTonemappingScale; + DirectX::XMFLOAT4 cFlashlightPos; +}; + +// Constants that don't change per-material, per-model, or per-frame. +// These are expected to be changed whenever and apply to all materials. +// TODO: Figure out how often these flashlight parameters change, +// particularly cFlashlightWorldToTexture. +ALIGN16 struct PerScene_CBuffer_t +{ + DirectX::XMMATRIX cProjMatrix; + DirectX::XMMATRIX cFlashlightWorldToTexture; + DirectX::XMFLOAT4 cFlashlightScreenScale; + DirectX::XMFLOAT4 cFlashlightColor; + DirectX::XMFLOAT4 cFlashlightAttenuationFactors; + DirectX::XMFLOAT4 cShadowTweaks; + DirectX::XMFLOAT4 cConstants; + // Only cFlexScale.x is used + // It is a binary value used to switch on/off the addition of the flex delta stream + DirectX::XMFLOAT4 cFlexScale; + // NOTE: Fog has moved to per-material constants, defined and requested by each shader. +}; + +enum +{ + MATRIXDX11_DIRTY, + MATRIXDX11_IDENTITY, +}; + +//----------------------------------------------------------------------------- +// +// Shader API Dx11 +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Class Factory +//----------------------------------------------------------------------------- +static CShaderAPIDx11 s_ShaderAPIDx11; +CShaderAPIDx11 *g_pShaderAPIDx11 = &s_ShaderAPIDx11; + +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderAPIDx11, IShaderAPI, + SHADERAPI_INTERFACE_VERSION, s_ShaderAPIDx11 ) + + EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderAPIDx11, IDebugTextureInfo, + DEBUG_TEXTURE_INFO_VERSION, s_ShaderAPIDx11 ) + + //----------------------------------------------------------------------------- + // Constructor, destructor + //----------------------------------------------------------------------------- + CShaderAPIDx11::CShaderAPIDx11() : + m_Textures( 32 ), + m_SelectionMinZ( FLT_MAX ), + m_SelectionMaxZ( FLT_MIN ), + m_pSelectionBuffer( 0 ), + m_pSelectionBufferEnd( 0 ), + m_nDynamicVBSize( DYNAMIC_VERTEX_BUFFER_MEMORY ), + m_TexAnisotropy( 0 ) +{ + m_ModifyTextureHandle = INVALID_SHADERAPI_TEXTURE_HANDLE; + m_ModifyTextureLockedLevel = -1; + m_ModifyTextureLockedFace = -1; + m_bResettingRenderState = false; + m_ShadowState = NULL; + m_ShaderState = StatesDx11::ShaderState(); + m_DynamicState = StatesDx11::DynamicState(); + m_StateChangeFlags = STATE_CHANGED_NONE; + m_bSelectionMode = false; + m_bFlashlightStateChanged = false; + m_pFlashlightDepthTexture = NULL; + + m_CurrentSnapshot = DEFAULT_SHADOW_STATE_ID; + + memset( IntRenderingParameters, 0, sizeof( IntRenderingParameters ) ); + memset( FloatRenderingParameters, 0, sizeof( FloatRenderingParameters ) ); + memset( VectorRenderingParameters, 0, sizeof( VectorRenderingParameters ) ); +} + +CShaderAPIDx11::~CShaderAPIDx11() +{ +} + +void CShaderAPIDx11::UpdateConstantBuffer( ConstantBufferHandle_t cbuffer, void *pNewData ) +{ + g_pShaderDeviceDx11->UpdateConstantBuffer( cbuffer, pNewData ); +} + +ConstantBufferHandle_t CShaderAPIDx11::GetInternalConstantBuffer( int type ) +{ + switch ( type ) + { + case SHADER_CONSTANTBUFFER_PERFRAME: + return m_hPerFrameConstants; + case SHADER_CONSTANTBUFFER_PERMODEL: + return m_hPerModelConstants; + case SHADER_CONSTANTBUFFER_PERSCENE: + return m_hPerSceneConstants; + case SHADER_CONSTANTBUFFER_SKINNING: + return m_hSkinningConstants; + //case SHADER_CONSTANTBUFFER_FLEX: + // return m_hFlexConstants; + default: + return CONSTANT_BUFFER_HANDLE_INVALID; + } +} + +//----------------------------------------------------------------------------- +// Resets the render state +//----------------------------------------------------------------------------- +void CShaderAPIDx11::ResetRenderState( bool bFullReset ) +{ + m_StateChangeFlags = STATE_CHANGED_NONE; + m_ShadowState = NULL; + m_CurrentSnapshot = DEFAULT_SHADOW_STATE_ID; + m_DynamicState.Reset(); + m_DynamicState.m_pDepthStencilView = GetTexture( m_hDepthBuffer ).GetDepthStencilView(); + + m_ShaderState.SetDefault(); + m_pCurMatrixItem = &m_ShaderState.m_MatrixStacks[0].Top(); + + IssueStateChanges( bFullReset ); +} + +void CShaderAPIDx11::SetRenderTargetEx( int nRenderTargetID, ShaderAPITextureHandle_t colorTextureHandle, ShaderAPITextureHandle_t depthTextureHandle ) +{ + // GR - need to flush batched geometry + FlushBufferedPrimitives(); + + if ( colorTextureHandle == SHADER_RENDERTARGET_BACKBUFFER ) + { + colorTextureHandle = m_hBackBuffer; + } + else if ( colorTextureHandle == SHADER_RENDERTARGET_NONE ) + { + colorTextureHandle = INVALID_SHADERAPI_TEXTURE_HANDLE; + } + + if ( depthTextureHandle == SHADER_RENDERTARGET_DEPTHBUFFER ) + { + depthTextureHandle = m_hDepthBuffer; + } + else if ( depthTextureHandle == SHADER_RENDERTARGET_NONE ) + { + depthTextureHandle = INVALID_SHADERAPI_TEXTURE_HANDLE; + } + + if ( colorTextureHandle != INVALID_SHADERAPI_TEXTURE_HANDLE ) + { + CTextureDx11 *pRT = &GetTexture( colorTextureHandle ); + m_DynamicState.m_pRenderTargetViews[nRenderTargetID] = pRT->GetRenderTargetView(); + SetStateFlag( STATE_CHANGED_RENDERTARGET ); + } + else + { + m_DynamicState.m_pRenderTargetViews[nRenderTargetID] = NULL; + } + + if ( depthTextureHandle != INVALID_SHADERAPI_TEXTURE_HANDLE ) + { + CTextureDx11 *pDT = &GetTexture( depthTextureHandle ); + m_DynamicState.m_pDepthStencilView = pDT->GetDepthStencilView(); + SetStateFlag( STATE_CHANGED_DEPTHBUFFER ); + } + else + { + m_DynamicState.m_pDepthStencilView = NULL; + } +} + +//----------------------------------------------------------------------------- +// Issues state changes to D3D for states that have been modified +//----------------------------------------------------------------------------- +void CShaderAPIDx11::IssueStateChanges( bool bForce ) +{ + // Don't bother committing anything if we're deactivated + if ( g_pShaderDeviceDx11->IsDeactivated() ) + return; + + m_ShadowState = g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot ); + //const StatesDx11::ShadowState *shadow = m_ShadowState; + StatesDx11::DynamicState &dynamic = m_DynamicState; + + DoIssueShaderState( bForce ); + + if ( bForce || IsStateSet( STATE_CHANGED_RENDERTARGET ) || + IsStateSet( STATE_CHANGED_DEPTHBUFFER ) ) + { + DoIssueRenderTargets(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_VIEWPORTS ) ) + { + DoIssueViewports(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_INPUTLAYOUT ) ) + { + DoIssueInputLayout(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_VERTEXBUFFER ) ) + { + DoIssueVertexBuffer(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_INDEXBUFFER ) ) + { + DoIssueIndexBuffer(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_TOPOLOGY ) ) + { + DoIssueTopology(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_VERTEXSHADER ) ) + { + DoIssueVertexShader(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_GEOMETRYSHADER ) ) + { + DoIssueGeometryShader(); + } + + if ( bForce || IsStateSet( STATE_CHANGED_PIXELSHADER ) ) + { + DoIssuePixelShader(); + } + + DoIssueConstantBuffers( bForce ); + + bool bPixel = bForce || IsStateSet( STATE_CHANGED_SAMPLERS ); + bool bVertex = bForce || IsStateSet( STATE_CHANGED_VERTEXSAMPLERS ); + if ( bPixel || bVertex ) + { + DoIssueSampler( bPixel, bVertex ); + dynamic.m_PrevMaxPSSampler = dynamic.m_MaxPSSampler; + dynamic.m_PrevMaxVSSampler = dynamic.m_MaxVSSampler; + } + + bPixel = bForce || IsStateSet( STATE_CHANGED_TEXTURES ); + bVertex = bForce || IsStateSet( STATE_CHANGED_VERTEXTEXTURES ); + if ( bPixel || bVertex ) + { + DoIssueTexture( bPixel, bVertex ); + } + + if ( bForce || + IsStateSet( STATE_CHANGED_DEPTHSTENCIL ) ) + { + DoIssueDepthStencilState(); + } + + if ( bForce || + IsStateSet( STATE_CHANGED_BLEND ) ) + { + DoIssueBlendState(); + } + + if ( bForce || + IsStateSet( STATE_CHANGED_RASTERIZER ) ) + { + DoIssueRasterState(); + } + + m_StateChangeFlags = STATE_CHANGED_NONE; + + m_ShadowState = NULL; +} + +//------------------------------ +// Issue state changes +//------------------------------ + +FORCEINLINE static void OutputMatrixRow( const DirectX::XMFLOAT4X4 &mat, int r ) +{ + Log( "\t%f\t%f\t%f\t%f\n", mat.m[r][0], mat.m[r][1], mat.m[r][2], mat.m[r][3] ); +} + +FORCEINLINE static void OutputMatrix( const DirectX::XMFLOAT4X4 &mat, const char *pszMatName ) +{ + Log( "DX11 %s Matrix:\n", pszMatName ); + + for ( int i = 0; i < 4; i++ ) + { + OutputMatrixRow( mat, i ); + } +} + +int CShaderAPIDx11::ComputeNumLights() const +{ + int numLights = 0; + for ( int i = 0; i < MAX_NUM_LIGHTS; i++ ) + { + if ( m_ShaderState.light.m_Lights[i].m_Type != MATERIAL_LIGHT_DISABLE ) + numLights++; + } + return numLights; +} + +void CShaderAPIDx11::SortLights( int *index ) +{ + m_ShaderState.light.m_NumLights = 0; + for ( int i = 0; i < MAX_NUM_LIGHTS; i++ ) + { + const LightDesc_t &light = m_ShaderState.light.m_Lights[i]; + LightType_t type = light.m_Type; + int j = m_ShaderState.light.m_NumLights; + if ( type != MATERIAL_LIGHT_DISABLE ) + { + while ( --j >= 0 ) + { + if ( m_ShaderState.light.m_LightType[j] <= type ) + break; + + // shift... + m_ShaderState.light.m_LightType[j + 1] = m_ShaderState.light.m_LightType[j]; + if ( index ) + index[j + 1] = index[j]; + } + ++j; + + m_ShaderState.light.m_LightType[j] = type; + if ( index ) + index[j] = i; + ++m_ShaderState.light.m_NumLights; + } + } +} + +FORCEINLINE static float ShadowAttenFromState( FlashlightState_t const &state ) +{ + // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + return state.m_flShadowAtten * 0.1f; // magic number + + return state.m_flShadowAtten; +} + +FORCEINLINE static float ShadowFilterFromState( FlashlightState_t const &state ) +{ + return state.m_flShadowFilterSize / state.m_flShadowMapResolution; +} + +FORCEINLINE static void HashShadow2DJitter( const float fJitterSeed, float *fU, float *fV ) +{ + const int nTexRes = 32; + int nSeed = fmod( fJitterSeed, 1.0f ) * nTexRes * nTexRes; + + int nRow = nSeed / nTexRes; + int nCol = nSeed % nTexRes; + + // Div and mod to get an individual texel in the fTexRes x fTexRes grid + *fU = nRow / (float)nTexRes; // Row + *fV = nCol / (float)nTexRes; // Column +} + +void CShaderAPIDx11::DoIssueShaderState( bool bForce ) +{ + // + // Transforms + // + + bool bViewChanged = m_ShaderState.m_ChangedMatrices[MATERIAL_VIEW]; + bool bProjChanged = m_ShaderState.m_ChangedMatrices[MATERIAL_PROJECTION]; + bool bModelChanged = m_ShaderState.m_ChangedMatrices[MATERIAL_MODEL]; + + PerFrame_CBuffer_t *pPerFrameConstants; + PerModel_CBuffer_t *pPerModelConstants; + PerScene_CBuffer_t *pPerSceneConstants; + //{ + //VPROF_BUDGET( "GetCBufferPointers", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + // To avoid an extra memcmp + memcpy... + pPerFrameConstants = (PerFrame_CBuffer_t *) + ( (CShaderConstantBufferDx11 *)m_hPerFrameConstants )->GetData(); + pPerModelConstants = (PerModel_CBuffer_t *) + ( (CShaderConstantBufferDx11 *)m_hPerModelConstants )->GetData(); + pPerSceneConstants = (PerScene_CBuffer_t *) + ( (CShaderConstantBufferDx11 *)m_hPerSceneConstants )->GetData(); +//} + + + bool bPerFrameChanged = false; + bool bPerModelChanged = false; + bool bPerSceneChanged = false; + + if ( bForce || bViewChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueViewMatrix", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + +#ifdef _DEBUG + const DirectX::XMMATRIX view = GetMatrix( MATERIAL_VIEW ); +#else + const DirectX::XMMATRIX &view = GetMatrix( MATERIAL_VIEW ); +#endif + // Row-major -> column-major + pPerFrameConstants->cViewMatrix = DirectX::XMMatrixTranspose( view ); + + // Store new view position. + DirectX::XMFLOAT4X4 flt4x4view; + DirectX::XMStoreFloat4x4( &flt4x4view, DirectX::XMMatrixInverse( NULL, view ) ); + pPerFrameConstants->cEyePos.x = flt4x4view.m[3][0]; + pPerFrameConstants->cEyePos.y = flt4x4view.m[3][1]; + pPerFrameConstants->cEyePos.z = flt4x4view.m[3][2]; + + m_ShaderState.m_ChangedMatrices[MATERIAL_VIEW] = false; + + bPerFrameChanged = true; + } + + if ( bForce || bModelChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueModelMatrix", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + +#ifdef _DEBUG + const DirectX::XMMATRIX model = GetMatrix( MATERIAL_MODEL ); +#else + const DirectX::XMMATRIX &model = GetMatrix( MATERIAL_MODEL ); +#endif + // Row-major -> column-major + pPerModelConstants->cModelMatrix = DirectX::XMMatrixTranspose( model ); + + m_ShaderState.m_ChangedMatrices[MATERIAL_MODEL] = false; + + bPerModelChanged = true; + } + + if ( bForce || bProjChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueProjMatrix", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + +#ifdef _DEBUG + const DirectX::XMMATRIX proj = GetMatrix( MATERIAL_PROJECTION ); +#else + const DirectX::XMMATRIX &proj = GetMatrix( MATERIAL_PROJECTION ); +#endif + // Row-major -> column-major + pPerSceneConstants->cProjMatrix = DirectX::XMMatrixTranspose( proj ); + + m_ShaderState.m_ChangedMatrices[MATERIAL_PROJECTION] = false; + + bPerSceneChanged = true; + } + + // + // Lighting + // + + if ( bForce || m_ShaderState.light.m_bLightChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueLightState", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + int lightIndex[MAX_NUM_LIGHTS]; + memset( lightIndex, 0, sizeof( lightIndex ) ); + SortLights( lightIndex ); + + pPerModelConstants->cLightCount.x = m_ShaderState.light.m_NumLights; + + //if ( m_ShaderState.light.m_NumLights == 0 ) + //{ + // memset( &pPerModelConstants->cLightEnabled, 0, sizeof( DirectX::XMINT4 ) ); + //} + + for ( int i = 0; i < m_ShaderState.light.m_NumLights; i++ ) + { + const LightDesc_t &light = m_ShaderState.light.m_Lights[lightIndex[i]]; + //XMSetComponent4( pPerModelConstants->cLightEnabled, i, light.m_Type != MATERIAL_LIGHT_DISABLE ); + + // The first one is the light color ( and light type code ) + float w = ( light.m_Type == MATERIAL_LIGHT_DIRECTIONAL ) ? 1.0f : 0.0f; + pPerModelConstants->cLightInfo[i].color = + DirectX::XMFLOAT4( light.m_Color.x, light.m_Color.y, light.m_Color.z, w ); + + // The next constant holds the light direction ( and light type code ) + w = ( light.m_Type == MATERIAL_LIGHT_SPOT ) ? 1.0f : 0.0f; + pPerModelConstants->cLightInfo[i].dir = + DirectX::XMFLOAT4( light.m_Direction.x, light.m_Direction.y, light.m_Direction.z, w ); + + // The next constant holds the light position + pPerModelConstants->cLightInfo[i].pos = + DirectX::XMFLOAT4( light.m_Position.x, light.m_Position.y, light.m_Position.z, 1.0f ); + + // The next constant holds exponent, stopdot, stopdot2, 1 / (stopdot - stopdot2) + if ( light.m_Type == MATERIAL_LIGHT_SPOT ) + { + float stopdot = cos( light.m_Theta * 0.5f ); + float stopdot2 = cos( light.m_Phi * 0.5f ); + float oodot = ( stopdot > stopdot2 ) ? 1.0f / ( stopdot - stopdot2 ) : 0.0f; + pPerModelConstants->cLightInfo[i].spotParams = + DirectX::XMFLOAT4( light.m_Falloff, stopdot, stopdot2, oodot ); + } + else + { + pPerModelConstants->cLightInfo[i].spotParams = + DirectX::XMFLOAT4( 0, 1, 1, 1 ); + } + + // The last constant holds atten0, atten1, atten2 + pPerModelConstants->cLightInfo[i].atten = + DirectX::XMFLOAT4( light.m_Attenuation0, light.m_Attenuation1, light.m_Attenuation2, 0.0f ); + } + m_ShaderState.light.m_bLightChanged = false; + + bPerModelChanged = true; + } + + if ( bForce || m_ShaderState.light.m_bAmbientChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueAmbientState", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + memcpy( pPerModelConstants->cAmbientCube, m_ShaderState.light.m_AmbientLightCube, sizeof( DirectX::XMFLOAT3A ) * 6 ); + m_ShaderState.light.m_bAmbientChanged = false; + bPerModelChanged = true; + } + + // + // Skinning + // + + if ( bForce || m_ShaderState.bone.m_bBonesChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueBoneState", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + // Since skinning is in it's own constant buffer and we are updating the whole + // thing if bones have changed, be more efficient and lock the buffer to + // avoid an extra memcpy. + + Skinning_CBuffer_t *pSkinningConstants = (Skinning_CBuffer_t *) + ( (CShaderConstantBufferDx11 *)m_hSkinningConstants )->Lock(); + + // Load the model matrix from the matrix stack into the + // first bone matrix. + DirectX::XMMATRIX model = GetMatrix( MATERIAL_MODEL ); + // This is stored row-major, needs to be column-major in shader. + // 3x4 in DirectXMath becomes 4x3 in HLSL shader + DirectX::XMStoreFloat3x4A( m_ShaderState.bone.m_BoneMatrix, model ); + m_ShaderState.bone.m_MaxBoneLoaded++; + int matricesLoaded = max( 1, m_ShaderState.bone.m_MaxBoneLoaded ); + m_ShaderState.bone.m_MaxBoneLoaded = 0; + + // Copy bone matrices into cModel constant + memcpy( pSkinningConstants->cModel, m_ShaderState.bone.m_BoneMatrix, + sizeof( DirectX::XMFLOAT3X4A ) * matricesLoaded ); + + m_ShaderState.bone.m_bBonesChanged = false; + + ( (CShaderConstantBufferDx11 *)m_hSkinningConstants )->Unlock(); + } + + // + // Morphing + // + if ( bForce || m_ShaderState.morph.m_bMorphChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueMorphState", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + // Since flex is in it's own constant buffer and we are updating the whole + // thing if flex has changed, be more efficient and lock the buffer to + // avoid an extra memcpy. + + //Flex_CBuffer_t *pFlexConstants = (Flex_CBuffer_t *) + // ( (CShaderConstantBufferDx11 *)m_hFlexConstants )->Lock(); + + //memcpy( pFlexConstants->cFlexWeights, m_ShaderState.morph.m_pWeights, + // sizeof( MorphWeight_t ) * m_ShaderState.morph.m_nMaxWeightLoaded ); + //m_ShaderState.morph.m_nMaxWeightLoaded = 0; + //pPerModelConstants->cFlexScale = DirectX::XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ); + //m_ShaderState.morph.m_bMorphChanged = false; + + //bPerModelChanged = true; + + //( (CShaderConstantBufferDx11 *)m_hFlexConstants )->Unlock(); + } + + // + // Flashlight + // + if ( m_bFlashlightStateChanged ) + { + //VPROF_BUDGET( "CShaderAPIDx11::IssueFlashLightState", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + float flFlashlightScale = 0.25f; + if ( !g_pHardwareConfig->GetHDREnabled() ) + { + // Non-HDR path requires 2.0 flashlight + flFlashlightScale = 2.0f; + } + // DX10 requires some hackery due to sRGB/blend ordering change from DX9 + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + { + flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800 + } + float const *pFlashlightColor = m_FlashlightState.m_Color; + float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], + flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] }; + vPsConst[3] = 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term + pPerSceneConstants->cFlashlightColor = DirectX::XMFLOAT4( vPsConst ); + DirectX::XMFLOAT4X4 flashlightWorldToTexture4x4 = DirectX::XMFLOAT4X4( m_FlashlightWorldToTexture.Base() ); + pPerSceneConstants->cFlashlightWorldToTexture = DirectX::XMLoadFloat4x4( &flashlightWorldToTexture4x4 ); + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = { 1280.0f / 32.0f, 720.0f / 32.0f, 0, 0 }; + int nWidth, nHeight; + GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float)nWidth / 32.0f; + vScreenScale[1] = (float)nHeight / 32.0f; + pPerSceneConstants->cFlashlightScreenScale = DirectX::XMFLOAT4( vScreenScale ); + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = m_FlashlightState.m_flShadowFilterSize / m_FlashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( m_FlashlightState ); + HashShadow2DJitter( m_FlashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pPerSceneConstants->cShadowTweaks = DirectX::XMFLOAT4( tweaks ); + pPerFrameConstants->cFlashlightPos = DirectX::XMFLOAT4( m_FlashlightState.m_vecLightOrigin[0], + m_FlashlightState.m_vecLightOrigin[1], + m_FlashlightState.m_vecLightOrigin[2], + 1.0f ); + pPerSceneConstants->cFlashlightAttenuationFactors = DirectX::XMFLOAT4( + m_FlashlightState.m_fConstantAtten, + m_FlashlightState.m_fLinearAtten, + m_FlashlightState.m_fQuadraticAtten, + m_FlashlightState.m_FarZ + ); + + bPerSceneChanged = true; + bPerFrameChanged = true; + + m_bFlashlightStateChanged = false; + } + + if ( bForce || m_ShaderState.m_bToneMappingScaleChanged ) + { + pPerFrameConstants->cTonemappingScale = DirectX::XMFLOAT4( m_ShaderState.m_ToneMappingScale.Base() ); + m_ShaderState.m_bToneMappingScaleChanged = false; + } + + //{ + //VPROF_BUDGET( "ForceUpdate constants", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + // + // Supply the new constants. + // + if ( bPerModelChanged ) + ( (CShaderConstantBufferDx11 *)m_hPerModelConstants )->ForceUpdate(); + if ( bPerFrameChanged ) + ( (CShaderConstantBufferDx11 *)m_hPerFrameConstants )->ForceUpdate(); + if ( bPerSceneChanged ) + ( (CShaderConstantBufferDx11 *)m_hPerSceneConstants )->ForceUpdate(); +//} + +} + +void CShaderAPIDx11::DoIssueVertexShader() +{ + D3D11DeviceContext()->VSSetShader( m_DynamicState.m_pVertexShader, NULL, 0 ); +} + +void CShaderAPIDx11::DoIssuePixelShader() +{ + D3D11DeviceContext()->PSSetShader( m_DynamicState.m_pPixelShader, NULL, 0 ); +} + +void CShaderAPIDx11::DoIssueGeometryShader() +{ + D3D11DeviceContext()->GSSetShader( m_DynamicState.m_pGeometryShader, NULL, 0 ); +} + +bool CShaderAPIDx11::DoIssueConstantBuffers( bool bForce ) +{ + const StatesDx11::ShadowState *shadow = m_ShadowState; + + if ( bForce || IsStateSet( STATE_CHANGED_VSCONSTANTBUFFERS ) ) + { + D3D11DeviceContext()->VSSetConstantBuffers( 0, shadow->desc.vsConstantBuffers.m_MaxSlot + 1, + shadow->desc.vsConstantBuffers.m_ppBuffers ); + } + + if ( bForce || IsStateSet( STATE_CHANGED_GSCONSTANTBUFFERS ) ) + { + D3D11DeviceContext()->GSSetConstantBuffers( 0, shadow->desc.gsConstantBuffers.m_MaxSlot + 1, + shadow->desc.gsConstantBuffers.m_ppBuffers ); + } + + if ( bForce || IsStateSet( STATE_CHANGED_PSCONSTANTBUFFERS ) ) + { + D3D11DeviceContext()->PSSetConstantBuffers( 0, shadow->desc.psConstantBuffers.m_MaxSlot + 1, + shadow->desc.psConstantBuffers.m_ppBuffers ); + } + + return true; +} + +void CShaderAPIDx11::DoIssueSampler( bool bPixel, bool bVertex ) +{ + if ( bPixel ) + { + int nSamplers = m_DynamicState.m_MaxPSSampler + 1; + D3D11DeviceContext()->PSSetSamplers( 0, nSamplers, m_DynamicState.m_ppSamplers ); + } + + if ( bVertex ) + { + int nSamplers = m_DynamicState.m_MaxVSSampler + 1; + D3D11DeviceContext()->VSSetSamplers( 0, nSamplers, m_DynamicState.m_ppVertexSamplers ); + } +} + +void CShaderAPIDx11::DoIssueTexture( bool bPixel, bool bVertex ) +{ + if ( bPixel ) + { + int nSamplers = m_DynamicState.m_MaxPSSampler + 1; + D3D11DeviceContext()->PSSetShaderResources( 0, nSamplers, m_DynamicState.m_ppTextures ); + } + + if ( bVertex ) + { + int nSamplers = m_DynamicState.m_MaxVSSampler + 1; + D3D11DeviceContext()->VSSetShaderResources( 0, nSamplers, m_DynamicState.m_ppVertexTextures ); + } +} + +void CShaderAPIDx11::DoIssueRasterState() +{ + D3D11DeviceContext()->RSSetState( m_ShadowState->desc.rasterizer.m_pD3DState ); +} + +void CShaderAPIDx11::DoIssueBlendState() +{ + D3D11DeviceContext()->OMSetBlendState( m_ShadowState->desc.blend.m_pD3DState, + m_ShadowState->desc.blend.BlendColor, + m_ShadowState->desc.blend.SampleMask ); +} + +void CShaderAPIDx11::DoIssueDepthStencilState() +{ + D3D11DeviceContext()->OMSetDepthStencilState( m_ShadowState->desc.depthStencil.m_pD3DState, + m_ShadowState->desc.depthStencil.StencilRef ); +} + +bool CShaderAPIDx11::DoIssueVertexBuffer() +{ + D3D11DeviceContext()->IASetVertexBuffers( 0, m_DynamicState.m_MaxVertexBuffer + 1, m_DynamicState.m_pVertexBuffer, + m_DynamicState.m_pVBStrides, m_DynamicState.m_pVBOffsets ); + m_DynamicState.m_PrevMaxVertexBuffer = m_DynamicState.m_MaxVertexBuffer; + m_DynamicState.m_MaxVertexBuffer = -1; + return true; +} + +void CShaderAPIDx11::DoIssueIndexBuffer() +{ + StatesDx11::DynamicState &dynamic = m_DynamicState; + D3D11DeviceContext()->IASetIndexBuffer( dynamic.m_IndexBuffer.m_pBuffer, + dynamic.m_IndexBuffer.m_Format, + dynamic.m_IndexBuffer.m_nOffset ); +} + +void CShaderAPIDx11::DoIssueInputLayout() +{ + StatesDx11::DynamicState &dynamic = m_DynamicState; + + ID3D11InputLayout *pInputLayout = g_pShaderDeviceDx11->GetInputLayout( + dynamic.m_InputLayout.m_hVertexShader, + dynamic.m_InputLayout.m_pVertexDecl[0], dynamic.m_InputLayout.m_bStaticLit, + dynamic.m_InputLayout.m_bUsingFlex, dynamic.m_InputLayout.m_bUsingMorph ); + + D3D11DeviceContext()->IASetInputLayout( pInputLayout ); +} + +void CShaderAPIDx11::DoIssueTopology() +{ + D3D11DeviceContext()->IASetPrimitiveTopology( m_DynamicState.m_Topology ); +} + +void CShaderAPIDx11::DoIssueViewports() +{ + D3D11DeviceContext()->RSSetViewports( m_DynamicState.m_nViewportCount, + m_DynamicState.m_pViewports ); +} + +void CShaderAPIDx11::DoIssueRenderTargets() +{ + int nCount = 0; + ID3D11RenderTargetView *rt; + for ( ; nCount < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; nCount++ ) + { + rt = m_DynamicState.m_pRenderTargetViews[nCount]; + if ( rt == NULL ) + break; + } + + if ( nCount > 0 ) + { + D3D11DeviceContext()->OMSetRenderTargets( nCount, m_DynamicState.m_pRenderTargetViews, NULL ); + } + else + { + // push the back buffer + rt = GetTexture( m_hBackBuffer ).GetRenderTargetView(); + D3D11DeviceContext()->OMSetRenderTargets( 1, &rt, m_DynamicState.m_pDepthStencilView ); + } +} + +//-------------------------------------------------------------------// + +//----------------------------------------------------------------------------- +// Methods of IShaderDynamicAPI +//----------------------------------------------------------------------------- +void CShaderAPIDx11::GetBackBufferDimensions( int &nWidth, int &nHeight ) const +{ + g_pShaderDeviceDx11->GetBackBufferDimensions( nWidth, nHeight ); +} + +//----------------------------------------------------------------------------- +// Viewport-related methods +//----------------------------------------------------------------------------- +void CShaderAPIDx11::SetViewports( int nCount, const ShaderViewport_t *pViewports ) +{ + nCount = min( nCount, MAX_DX11_VIEWPORTS ); + m_DynamicState.m_nViewportCount = nCount; + + for ( int i = 0; i < nCount; ++i ) + { + Assert( pViewports[i].m_nVersion == SHADER_VIEWPORT_VERSION ); + + D3D11_VIEWPORT &viewport = m_DynamicState.m_pViewports[i]; + viewport.TopLeftX = pViewports[i].m_nTopLeftX; + viewport.TopLeftY = pViewports[i].m_nTopLeftY; + viewport.Width = pViewports[i].m_nWidth; + viewport.Height = pViewports[i].m_nHeight; + viewport.MinDepth = pViewports[i].m_flMinZ; + viewport.MaxDepth = pViewports[i].m_flMaxZ; + } + + SetStateFlag( STATE_CHANGED_VIEWPORTS ); +} + +int CShaderAPIDx11::GetViewports( ShaderViewport_t *pViewports, int nMax ) const +{ + int nCount = m_DynamicState.m_nViewportCount; + if ( pViewports && nMax ) + { + nCount = min( nCount, nMax ); + for ( int i = 0; i < nCount; i++ ) + { + const D3D11_VIEWPORT &vp = m_DynamicState.m_pViewports[i]; + pViewports[i].m_nVersion = SHADER_VIEWPORT_VERSION; + pViewports[i].m_nTopLeftX = vp.TopLeftX; + pViewports[i].m_nTopLeftY = vp.TopLeftY; + pViewports[i].m_nWidth = vp.Width; + pViewports[i].m_nHeight = vp.Height; + pViewports[i].m_flMaxZ = vp.MaxDepth; + pViewports[i].m_flMinZ = vp.MinDepth; + } + } + return nCount; +} + +//----------------------------------------------------------------------------- +// Methods related to clearing buffers +//----------------------------------------------------------------------------- +void CShaderAPIDx11::ClearColor3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + m_DynamicState.m_ClearColor[0] = r / 255.0f; + m_DynamicState.m_ClearColor[1] = g / 255.0f; + m_DynamicState.m_ClearColor[2] = b / 255.0f; + m_DynamicState.m_ClearColor[3] = 1.0f; +} + +void CShaderAPIDx11::ClearColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + m_DynamicState.m_ClearColor[0] = r / 255.0f; + m_DynamicState.m_ClearColor[1] = g / 255.0f; + m_DynamicState.m_ClearColor[2] = b / 255.0f; + m_DynamicState.m_ClearColor[3] = a / 255.0f; +} + +void CShaderAPIDx11::ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil, int renderTargetWidth, int renderTargetHeight ) +{ + // NOTE: State change commit isn't necessary since clearing doesn't use state + // IssueStateChanges(); + + // State changed... need to flush the dynamic buffer + FlushBufferedPrimitives(); + + // FIXME: This implementation is totally bust0red [doesn't guarantee exact color specified] + if ( bClearColor && D3D11DeviceContext() ) + { + ID3D11RenderTargetView* rt; + for ( int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++ ) + { + rt = m_DynamicState.m_pRenderTargetViews[i]; + if ( rt == NULL ) + break; + + D3D11DeviceContext()->ClearRenderTargetView( rt, m_DynamicState.m_ClearColor ); + } + + // finally, free the back buffer + rt = GetTexture( m_hBackBuffer ).GetRenderTargetView(); + D3D11DeviceContext()->ClearRenderTargetView( rt, m_DynamicState.m_ClearColor ); + } + + if ( bClearDepth && D3D11DeviceContext() && m_DynamicState.m_pDepthStencilView ) + { + UINT clearFlags = 0; + if ( bClearDepth ) + { + clearFlags |= D3D11_CLEAR_DEPTH; + } + if ( bClearStencil ) + { + clearFlags |= D3D11_CLEAR_STENCIL; + } + D3D11DeviceContext()->ClearDepthStencilView( m_DynamicState.m_pDepthStencilView, clearFlags, 1.0f, 0 ); + } +} + +//----------------------------------------------------------------------------- +// Methods related to binding shaders +//----------------------------------------------------------------------------- +void CShaderAPIDx11::BindVertexShader( VertexShaderHandle_t hVertexShader ) +{ + ID3D11VertexShader *pVertexShader = g_pShaderDeviceDx11->GetVertexShader( hVertexShader ); + if ( m_DynamicState.m_pVertexShader != pVertexShader ) + { + SetStateFlag( STATE_CHANGED_VERTEXSHADER ); + } + if ( m_DynamicState.m_InputLayout.m_hVertexShader != hVertexShader ) + { + SetStateFlag( STATE_CHANGED_INPUTLAYOUT ); + } + m_DynamicState.m_pVertexShader = pVertexShader; + m_DynamicState.m_InputLayout.m_hVertexShader = hVertexShader; +} + +void CShaderAPIDx11::BindGeometryShader( GeometryShaderHandle_t hGeometryShader ) +{ + ID3D11GeometryShader *pGeometryShader = g_pShaderDeviceDx11->GetGeometryShader( hGeometryShader ); + if ( m_DynamicState.m_pGeometryShader != pGeometryShader ) + { + SetStateFlag( STATE_CHANGED_GEOMETRYSHADER ); + } + m_DynamicState.m_pGeometryShader = pGeometryShader; +} + +void CShaderAPIDx11::BindPixelShader( PixelShaderHandle_t hPixelShader ) +{ + ID3D11PixelShader *pPixelShader = g_pShaderDeviceDx11->GetPixelShader( hPixelShader ); + if ( m_DynamicState.m_pPixelShader != pPixelShader ) + { + SetStateFlag( STATE_CHANGED_PIXELSHADER ); + } + m_DynamicState.m_pPixelShader = pPixelShader; +} + +void CShaderAPIDx11::BindVertexBuffer( int nStreamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, + int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions ) +{ + StatesDx11::DynamicState &dynamic = m_DynamicState; + + // FIXME: What to do about repetitions? + CVertexBufferDx11 *pVertexBufferDx11 = static_cast( pVertexBuffer ); + + + ID3D11Buffer *pBuffer = NULL; + UINT stride = 0; + if ( pVertexBufferDx11 ) + { + pBuffer = pVertexBufferDx11->GetDx11Buffer(); + stride = pVertexBufferDx11->VertexSize(); + } + + // Offset can be provided by first index + if ( nOffsetInBytes < 0 ) + { + nOffsetInBytes = nFirstVertex * stride; + } + + UINT offset = nOffsetInBytes; + + if ( pBuffer != dynamic.m_pVertexBuffer[nStreamID] ) + { + dynamic.m_pVertexBuffer[nStreamID] = pBuffer; + SetStateFlag( STATE_CHANGED_VERTEXBUFFER ); + } + + if ( stride != dynamic.m_pVBStrides[nStreamID] ) + { + dynamic.m_pVBStrides[nStreamID] = stride; + SetStateFlag( STATE_CHANGED_VERTEXBUFFER ); + } + + if ( offset != dynamic.m_pVBOffsets[nStreamID] ) + { + dynamic.m_pVBOffsets[nStreamID] = offset; + SetStateFlag( STATE_CHANGED_VERTEXBUFFER ); + } + + if ( nStreamID > dynamic.m_MaxVertexBuffer ) + { + dynamic.m_MaxVertexBuffer = nStreamID; + if ( dynamic.m_MaxVertexBuffer > dynamic.m_PrevMaxVertexBuffer ) + { + SetStateFlag( STATE_CHANGED_VERTEXBUFFER ); + } + } + + if ( dynamic.m_InputLayout.m_pVertexDecl[nStreamID] != fmt ) + { + m_DynamicState.m_InputLayout.m_pVertexDecl[nStreamID] = fmt; + SetStateFlag( STATE_CHANGED_INPUTLAYOUT ); + } + +} + +void CShaderAPIDx11::SetUsingExtraVertexBuffers( bool bStaticLit, bool bUsingFlex, bool bUsingMorph ) +{ + if ( m_DynamicState.m_InputLayout.m_bStaticLit != bStaticLit || + m_DynamicState.m_InputLayout.m_bUsingFlex != bUsingFlex || + m_DynamicState.m_InputLayout.m_bUsingMorph != bUsingMorph ) + { + SetStateFlag( STATE_CHANGED_INPUTLAYOUT ); + } + + m_DynamicState.m_InputLayout.m_bStaticLit = bStaticLit; + m_DynamicState.m_InputLayout.m_bUsingFlex = bUsingFlex; + m_DynamicState.m_InputLayout.m_bUsingMorph = bUsingMorph; +} + +void CShaderAPIDx11::BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ) +{ + CIndexBufferDx11 *pIndexBufferDx11 = static_cast( pIndexBuffer ); + + ID3D11Buffer *pBuffer = NULL; + DXGI_FORMAT fmt = DXGI_FORMAT_R16_UINT; + UINT offset = nOffsetInBytes; + if ( pIndexBufferDx11 ) + { + pBuffer = pIndexBufferDx11->GetDx11Buffer(); + fmt = ( pIndexBufferDx11->GetIndexFormat() == MATERIAL_INDEX_FORMAT_16BIT ) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + } + + if ( pBuffer != m_DynamicState.m_IndexBuffer.m_pBuffer || + fmt != m_DynamicState.m_IndexBuffer.m_Format || + offset != m_DynamicState.m_IndexBuffer.m_nOffset) + { + SetStateFlag( STATE_CHANGED_INDEXBUFFER ); + } + + m_DynamicState.m_IndexBuffer.m_pBuffer = pBuffer; + m_DynamicState.m_IndexBuffer.m_Format = fmt; + m_DynamicState.m_IndexBuffer.m_nOffset = offset; +} + +//----------------------------------------------------------------------------- +// Unbinds resources because they are about to be deleted +//----------------------------------------------------------------------------- +void CShaderAPIDx11::Unbind( VertexShaderHandle_t hShader ) +{ + ID3D11VertexShader *pShader = g_pShaderDeviceDx11->GetVertexShader( hShader ); + Assert( pShader ); + if ( m_DynamicState.m_pVertexShader == pShader ) + { + BindVertexShader( VERTEX_SHADER_HANDLE_INVALID ); + } +} + +void CShaderAPIDx11::Unbind( GeometryShaderHandle_t hShader ) +{ + ID3D11GeometryShader *pShader = g_pShaderDeviceDx11->GetGeometryShader( hShader ); + Assert( pShader ); + if ( m_DynamicState.m_pGeometryShader == pShader ) + { + BindGeometryShader( GEOMETRY_SHADER_HANDLE_INVALID ); + } +} + +void CShaderAPIDx11::Unbind( PixelShaderHandle_t hShader ) +{ + ID3D11PixelShader *pShader = g_pShaderDeviceDx11->GetPixelShader( hShader ); + Assert( pShader ); + if ( m_DynamicState.m_pPixelShader == pShader ) + { + BindPixelShader( PIXEL_SHADER_HANDLE_INVALID ); + } +} + +void CShaderAPIDx11::UnbindVertexBuffer( ID3D11Buffer *pBuffer ) +{ + Assert( pBuffer ); + + for ( int i = 0; i < MAX_DX11_STREAMS; ++i ) + { + if ( m_DynamicState.m_pVertexBuffer[i] == pBuffer ) + { + BindVertexBuffer( i, NULL, 0, 0, 0, VERTEX_POSITION, 0 ); + } + } +} + +void CShaderAPIDx11::UnbindIndexBuffer( ID3D11Buffer *pBuffer ) +{ + Assert( pBuffer ); + + if ( m_DynamicState.m_IndexBuffer.m_pBuffer == pBuffer ) + { + BindIndexBuffer( NULL, 0 ); + } +} + +//----------------------------------------------------------------------------- +// Sets the topology state +//----------------------------------------------------------------------------- +void CShaderAPIDx11::SetTopology( MaterialPrimitiveType_t topology ) +{ + D3D11_PRIMITIVE_TOPOLOGY d3dTopology; + switch ( topology ) + { + case MATERIAL_POINTS: + d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + break; + + case MATERIAL_LINES: + d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + break; + + case MATERIAL_TRIANGLES: + d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + + case MATERIAL_TRIANGLE_STRIP: + d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + break; + + case MATERIAL_LINE_STRIP: + d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + + default: + case MATERIAL_LINE_LOOP: + case MATERIAL_POLYGON: + case MATERIAL_QUADS: + Assert( 0 ); + d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + break; + } + + ////Log( "Set topology to %i\n", d3dTopology ); + if ( d3dTopology != m_DynamicState.m_Topology ) + { + FlushBufferedPrimitives(); + SetStateFlag( STATE_CHANGED_TOPOLOGY ); + } + m_DynamicState.m_Topology = d3dTopology; +} + +//----------------------------------------------------------------------------- +// Mesh/Material rendering +//----------------------------------------------------------------------------- +void CShaderAPIDx11::DrawMesh( IMesh *pMesh ) +{ + VPROF( "CShaderAPIDx11::DrawMesh" ); + if ( ShaderUtil()->GetConfig().m_bSuppressRendering ) + return; + + //Log( "CShaderAPIDx11::DrawMesh %p\n", pMesh ); + + m_pMesh = static_cast( pMesh ); + if ( !m_pMesh || !m_pMaterial ) + { + Warning( "Tried to render mesh with NULL mesh or NULL material!\n" ); + return; + } + SetUsingExtraVertexBuffers( m_pMesh->HasColorMesh(), m_pMesh->HasFlexMesh(), m_pMaterial->IsUsingVertexID() ); + m_pMaterial->DrawMesh( CompressionType( pMesh->GetVertexFormat() ) ); + m_pMesh = NULL; +} + +static int s_nPassesRendered = 0; + +// Begins a rendering pass that uses a state snapshot +void CShaderAPIDx11::BeginPass( StateSnapshot_t snapshot ) +{ + // Apply the snapshot state + //if ( snapshot != -1 ) + UseSnapshot( snapshot ); +} + +// Renders a single pass of a material +void CShaderAPIDx11::RenderPass( int nPass, int nPassCount ) +{ + if ( g_pShaderDeviceDx11->IsDeactivated() ) + return; + + //IssueStateChanges(); + + // Now actually render + + if ( m_pMesh ) + { + m_pMesh->RenderPass(); + } + else + { + Assert( 0 ); + RenderPassWithVertexAndIndexBuffers(); + } + + //m_CurrentSnapshot = -1; +} + +void CShaderAPIDx11::RenderPassWithVertexAndIndexBuffers() +{ + if ( m_DynamicState.m_Topology == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST ) + { + Assert( 0 ); + } + else + { + //DrawIndexed(m_State.dynamic.m_IndexBuffer.) + } +} + +// Draws primitives +void CShaderAPIDx11::Draw( MaterialPrimitiveType_t primitiveType, int nFirstIndex, int nIndexCount ) +{ + //Log( "ShaderAPIDx11: Draw\n" ); + + SetTopology( primitiveType ); + + IssueStateChanges(); + + // FIXME: How do I set the base vertex location!? + DrawIndexed( nFirstIndex, nIndexCount, 0 ); +} + +void CShaderAPIDx11::DrawIndexed( int nFirstIndex, int nIndexCount, int nBaseVertexLocation ) +{ + //Assert( m_State.dynamic.m_pVertexShader != NULL ); + D3D11DeviceContext()->DrawIndexed( (UINT)nIndexCount, (UINT)nFirstIndex, (UINT)nBaseVertexLocation ); + //g_pShaderDeviceDx11->Present(); + //Log( "Presented" ); + //Log( "\n" ); +} + +void CShaderAPIDx11::DrawNotIndexed( int nFirstVertex, int nVertCount ) +{ + D3D11DeviceContext()->Draw( (UINT)nVertCount, (UINT)nFirstVertex ); +} + +//-----------------------------------------------------------------------------// + +bool CShaderAPIDx11::OnDeviceInit() +{ + // Initialize the mesh manager + MeshMgr()->Init(); + + int w, h; + g_pShaderDeviceDx11->GetBackBufferDimensions( w, h ); + + { + LOCK_SHADERAPI(); + // Create a the back buffer view + // UNDONE: Should texture creation and access be moved to ShaderDeviceDx11? + ID3D11Texture2D *pBackBuffer; + DXGI_SWAP_CHAIN_DESC swapChainDesc; + D3D11SwapChain()->GetDesc( &swapChainDesc ); + HRESULT hr = D3D11SwapChain()->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID *)&pBackBuffer ); + if ( FAILED( hr ) ) + return FALSE; + m_hBackBuffer = CreateTextureHandle(); + CTextureDx11 *pTex = &GetTexture( m_hBackBuffer ); + pTex->SetupBackBuffer( w, h, "dx11BackBuffer", pBackBuffer, pTex->GetImageFormat( swapChainDesc.BufferDesc.Format ) ); + } + + // Create the depth buffer + m_hDepthBuffer = CreateDepthTexture( IMAGE_FORMAT_NV_DST24, w, h, "dx11DepthBuffer", true ); + + m_hPerFrameConstants = g_pShaderDeviceDx11->CreateConstantBuffer( sizeof( PerFrame_CBuffer_t ) ); + m_hPerModelConstants = g_pShaderDeviceDx11->CreateConstantBuffer( sizeof( PerModel_CBuffer_t ) ); + m_hPerSceneConstants = g_pShaderDeviceDx11->CreateConstantBuffer( sizeof( PerScene_CBuffer_t ) ); + m_hSkinningConstants = g_pShaderDeviceDx11->CreateConstantBuffer( sizeof( Skinning_CBuffer_t ) ); + m_hFlexConstants = g_pShaderDeviceDx11->CreateConstantBuffer( sizeof( Flex_CBuffer_t ) ); + + // Write some constants that don't change + PerScene_CBuffer_t *pPerScene = (PerScene_CBuffer_t *)( (CShaderConstantBufferDx11 *)m_hPerSceneConstants )->GetData(); + // [ gamma, overbright, 1/3, 1/overbright] + pPerScene->cConstants.x = 1.0f / 2.2f; + pPerScene->cConstants.y = OVERBRIGHT; + pPerScene->cConstants.z = 1.0f / 3.0f; + pPerScene->cConstants.w = 1.0f / OVERBRIGHT; + pPerScene->cFlexScale.x = 1.0f; + pPerScene->cFlexScale.y = 1.0f; + pPerScene->cFlexScale.z = 0.0f; + pPerScene->cFlexScale.w = 0.0f; + + ( (CShaderConstantBufferDx11 *)m_hPerSceneConstants )->ForceUpdate(); + + ResetRenderState( true ); + + return true; +} + +void CShaderAPIDx11::OnDeviceShutdown() +{ + for ( int i = 0; i < m_Textures.Count(); i++ ) + { + CTextureDx11 *pTex = &m_Textures[i]; + pTex->Delete(); + } + m_Textures.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// +// Abandon all hope below this point +// +//----------------------------------------------------------------------------- + +bool CShaderAPIDx11::DoRenderTargetsNeedSeparateDepthBuffer() const +{ + return false; +} + +// Can we download textures? +bool CShaderAPIDx11::CanDownloadTextures() const +{ + if ( IsDeactivated() ) + return false; + + return true; +} + +// Used to clear the transition table when we know it's become invalid. +void CShaderAPIDx11::ClearSnapshots() +{ + LOCK_SHADERAPI(); + FlushBufferedPrimitives(); + g_pShaderShadowDx11->m_ShadowStates.RemoveAll(); + ResetRenderState( true ); +} + +// Sets the default *dynamic* state +void CShaderAPIDx11::SetDefaultState() +{ + m_DynamicState.m_MaxPSSampler = -1; + m_DynamicState.m_MaxVSSampler = -1; + + m_DynamicState.m_pVertexShader = 0; + m_DynamicState.m_pGeometryShader = 0; + m_DynamicState.m_pPixelShader = 0; +} + +// Returns the snapshot id for the current shadow state +StateSnapshot_t CShaderAPIDx11::TakeSnapshot() +{ + return g_pShaderShadowDx11->FindOrCreateSnapshot(); +} + +void CShaderAPIDx11::OverrideAlphaWriteEnable(bool bOverrideEnable, bool bAlphaWriteEnable) +{ + LOCK_SHADERAPI(); + // NOT IMPLEMENTED +} + +void CShaderAPIDx11::OverrideColorWriteEnable(bool bOverrideEnable, bool bColorWriteEnable) +{ + LOCK_SHADERAPI(); + // NOT IMPLEMENTED +} + +// Returns true if the state snapshot is transparent +bool CShaderAPIDx11::IsTranslucent( StateSnapshot_t id ) const +{ + LOCK_SHADERAPI(); + return g_pShaderShadowDx11->GetShadowState( id )->desc.blend.BlendEnabled(); +} + +bool CShaderAPIDx11::IsAlphaTested( StateSnapshot_t id ) const +{ + LOCK_SHADERAPI(); + return false; + //return g_pShaderShadowDx11->GetShadowState( id )->desc.bEnableAlphaTest; +} + +bool CShaderAPIDx11::IsDepthWriteEnabled( StateSnapshot_t id ) const +{ + LOCK_SHADERAPI(); + return g_pShaderShadowDx11->GetShadowState( id )->desc.depthStencil.DepthWriteMask != 0; +} + +bool CShaderAPIDx11::UsesVertexAndPixelShaders( StateSnapshot_t id ) const +{ + // It has to in DX11 + return true; +} + +//----------------------------------------------------------------------------- +// Gets the bound morph's vertex format; returns 0 if no morph is bound +//----------------------------------------------------------------------------- +MorphFormat_t CShaderAPIDx11::GetBoundMorphFormat() +{ + return ShaderUtil()->GetBoundMorphFormat(); +} + +//----------------------------------------------------------------------------- +// What fields in the morph do we actually use? +//----------------------------------------------------------------------------- +MorphFormat_t CShaderAPIDx11::ComputeMorphFormat( int numSnapshots, StateSnapshot_t *pIds ) const +{ + LOCK_SHADERAPI(); + MorphFormat_t format = 0; + for ( int i = 0; i < numSnapshots; ++i ) + { + MorphFormat_t fmt = g_pShaderShadowDx11->GetShadowState( pIds[i] )->desc.morphFormat; + format |= VertexFlags( fmt ); + } + return format; +} + +// Gets the vertex format for a set of snapshot ids +VertexFormat_t CShaderAPIDx11::ComputeVertexFormat( int numSnapshots, StateSnapshot_t *pIds ) const +{ + LOCK_SHADERAPI(); + VertexFormat_t fmt = ComputeVertexUsage( numSnapshots, pIds ); + return fmt; +} + +// Gets the vertex format for a set of snapshot ids +VertexFormat_t CShaderAPIDx11::ComputeVertexUsage( int num, StateSnapshot_t *pIds ) const +{ + LOCK_SHADERAPI(); + if ( num == 0 ) + return 0; + + // We don't have to all sorts of crazy stuff if there's only one snapshot + if ( num == 1 ) + { + const StatesDx11::ShadowState *state = g_pShaderShadowDx11->GetShadowState( pIds[0] ); + return (VertexFormat_t)( state->desc.vertexFormat ); + } + + Assert( pIds ); + + // Aggregating vertex formats is a little tricky; + // For example, what do we do when two passes want user data? + // Can we assume they are the same? For now, I'm going to + // just print a warning in debug. + + VertexCompressionType_t compression = VERTEX_COMPRESSION_INVALID; + int userDataSize = 0; + int numBones = 0; + int texCoordSize[VERTEX_MAX_TEXTURE_COORDINATES] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int flags = 0; + + for ( int i = num; --i >= 0; ) + { + //Log( "Applying vertex format from snapshot num %i, %i\n", i, pIds[i] ); + const StatesDx11::ShadowState *state = g_pShaderShadowDx11->GetShadowState( pIds[i] ); + VertexFormat_t fmt = state->desc.vertexFormat; + flags |= VertexFlags( fmt ); + + VertexCompressionType_t newCompression = CompressionType( fmt ); + if ( ( compression != newCompression ) && ( compression != VERTEX_COMPRESSION_INVALID ) ) + { + Warning( "Encountered a material with two passes that specify different vertex compression types!\n" ); + compression = VERTEX_COMPRESSION_NONE; // Be safe, disable compression + } + + int newNumBones = NumBoneWeights( fmt ); + if ( ( numBones != newNumBones ) && ( newNumBones != 0 ) ) + { + if ( numBones != 0 ) + { + Warning( "Encountered a material with two passes that use different numbers of bones!\n" ); + } + numBones = newNumBones; + } + + int newUserSize = UserDataSize( fmt ); + if ( ( userDataSize != newUserSize ) && ( newUserSize != 0 ) ) + { + if ( userDataSize != 0 ) + { + Warning( "Encountered a material with two passes that use different user data sizes!\n" ); + } + userDataSize = newUserSize; + } + + for ( int j = 0; j < VERTEX_MAX_TEXTURE_COORDINATES; ++j ) + { + int newSize = TexCoordSize( (TextureStage_t)j, fmt ); + if ( ( texCoordSize[j] != newSize ) && ( newSize != 0 ) ) + { + if ( texCoordSize[j] != 0 ) + { + Warning( "Encountered a material with two passes that use different texture coord sizes!\n" ); + } + if ( texCoordSize[j] < newSize ) + { + texCoordSize[j] = newSize; + } + } + } + } + + return MeshMgr()->ComputeVertexFormat( flags, VERTEX_MAX_TEXTURE_COORDINATES, + texCoordSize, numBones, userDataSize ); +} + +// Uses a state snapshot +void CShaderAPIDx11::UseSnapshot( StateSnapshot_t snapshot ) +{ + const StatesDx11::ShadowState *curr = g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot ); + const StatesDx11::ShadowState *entry = g_pShaderShadowDx11->GetShadowState( snapshot ); + + if ( entry->m_iBlendState != curr->m_iBlendState ) + { + SetStateFlag( STATE_CHANGED_BLEND ); + } + + if ( entry->m_iDepthStencilState != curr->m_iDepthStencilState ) + { + SetStateFlag( STATE_CHANGED_DEPTHSTENCIL ); + } + + if ( entry->m_iRasterState != curr->m_iRasterState ) + { + SetStateFlag( STATE_CHANGED_RASTERIZER ); + } + + if ( entry->m_iVSConstantBufferState != curr->m_iVSConstantBufferState ) + { + SetStateFlag( STATE_CHANGED_VSCONSTANTBUFFERS ); + } + + if ( entry->m_iGSConstantBufferState != curr->m_iGSConstantBufferState ) + { + SetStateFlag( STATE_CHANGED_GSCONSTANTBUFFERS ); + } + + if ( entry->m_iPSConstantBufferState != curr->m_iPSConstantBufferState ) + { + SetStateFlag( STATE_CHANGED_PSCONSTANTBUFFERS ); + } + + m_CurrentSnapshot = snapshot; +} + +// Sets the color to modulate by +void CShaderAPIDx11::Color3f( float r, float g, float b ) +{ +} + +void CShaderAPIDx11::Color3fv( float const *pColor ) +{ +} + +void CShaderAPIDx11::Color4f( float r, float g, float b, float a ) +{ +} + +void CShaderAPIDx11::Color4fv( float const *pColor ) +{ +} + +// Faster versions of color +void CShaderAPIDx11::Color3ub( unsigned char r, unsigned char g, unsigned char b ) +{ +} + +void CShaderAPIDx11::Color3ubv( unsigned char const *rgb ) +{ +} + +void CShaderAPIDx11::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ +} + +void CShaderAPIDx11::Color4ubv( unsigned char const *rgba ) +{ +} + +void CShaderAPIDx11::GetStandardTextureDimensions( int *pWidth, int *pHeight, StandardTextureId_t id ) +{ + ShaderUtil()->GetStandardTextureDimensions( pWidth, pHeight, id ); +} + +// Binds a particular material to render with +void CShaderAPIDx11::Bind( IMaterial *pMaterial ) +{ + LOCK_SHADERAPI(); + + IMaterialInternal *pMatInt = static_cast( pMaterial ); + + bool bMaterialChanged; + if ( m_pMaterial && pMatInt && m_pMaterial->InMaterialPage() && pMatInt->InMaterialPage() ) + { + bMaterialChanged = ( m_pMaterial->GetMaterialPage() != pMatInt->GetMaterialPage() ); + } + else + { + bMaterialChanged = ( m_pMaterial != pMatInt ) || ( m_pMaterial && m_pMaterial->InMaterialPage() ) || ( pMatInt && pMatInt->InMaterialPage() ); + } + + if ( bMaterialChanged ) + { + FlushBufferedPrimitives(); + m_pMaterial = pMatInt; + } +} + +IMaterialInternal *CShaderAPIDx11::GetBoundMaterial() const +{ + return m_pMaterial; +} + +// Cull mode +void CShaderAPIDx11::CullMode( MaterialCullMode_t cullMode ) +{ + // This has to be set in shadow state + Assert( 0 ); +} + +D3D11_CULL_MODE CShaderAPIDx11::GetCullMode() const +{ + return g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot )->desc.rasterizer.CullMode; +} + +void CShaderAPIDx11::ForceDepthFuncEquals( bool bEnable ) +{ +} + +// Forces Z buffering on or off +void CShaderAPIDx11::OverrideDepthEnable( bool bEnable, bool bDepthEnable ) +{ +} + +//legacy fast clipping linkage +void CShaderAPIDx11::SetHeightClipZ( float z ) +{ +} + +void CShaderAPIDx11::SetHeightClipMode( enum MaterialHeightClipMode_t heightClipMode ) +{ +} + +// Sets the lights +void CShaderAPIDx11::SetLight( int lightNum, const LightDesc_t &desc ) +{ + LOCK_SHADERAPI(); + + //if ( ) + //{ + + FlushBufferedPrimitives(); + if ( !m_ShaderState.light.m_bLightChanged && FastMemCompare( &desc, &m_ShaderState.light.m_Lights[lightNum], sizeof( LightDesc_t ) ) ) + { + m_ShaderState.light.m_bLightChanged = true; + } + m_ShaderState.light.m_Lights[lightNum] = desc; + m_ShaderState.light.m_NumLights = ComputeNumLights(); + //m_ShaderState.light.m_bLightChanged = true; + //SortLights(); + //if ( lightNum == 2 && desc.m_Type != MATERIAL_LIGHT_DISABLE) + // DebuggerBreak(); + //m_ShaderState.light.m_bLightChanged = true; +//} +} + +void CShaderAPIDx11::SetAmbientLightCube( Vector4D cube[6] ) +{ + LOCK_SHADERAPI(); + + if ( !m_ShaderState.light.m_bAmbientChanged && FastMemCompare( m_ShaderState.light.m_AmbientLightCube, cube, sizeof( VectorAligned ) * 6 ) ) + { + m_ShaderState.light.m_bAmbientChanged = true; + } + memcpy( m_ShaderState.light.m_AmbientLightCube, cube, 6 * sizeof( VectorAligned ) ); +} + +// Get lights +int CShaderAPIDx11::GetMaxLights( void ) const +{ + return HardwareConfig()->MaxNumLights(); +} + +const LightDesc_t &CShaderAPIDx11::GetLight( int lightNum ) const +{ + return m_ShaderState.light.m_Lights[lightNum]; +} + +int CShaderAPIDx11::GetCurrentLightCombo( void ) const +{ + // UNUSED + return 0; +} + +void CShaderAPIDx11::DisableAllLocalLights() +{ + LOCK_SHADERAPI(); + bool bFlushed = false; + for ( int lightNum = 0; lightNum < MAX_NUM_LIGHTS; lightNum++ ) + { + if ( m_ShaderState.light.m_Lights[lightNum].m_Type != MATERIAL_LIGHT_DISABLE ) + { + if ( !bFlushed ) + { + FlushBufferedPrimitives(); + bFlushed = true; + } + m_ShaderState.light.m_Lights[lightNum].m_Type = MATERIAL_LIGHT_DISABLE; + m_ShaderState.light.m_bLightChanged = true; + } + } + m_ShaderState.light.m_NumLights = 0; +} + +float CShaderAPIDx11::GetAmbientLightCubeLuminance( void ) +{ + Vector4DAligned vLuminance( 0.3f, 0.59f, 0.11f, 0.0f ); + float fLuminance = 0.0f; + + for ( int i = 0; i < 6; i++ ) + { + fLuminance += vLuminance.Dot( m_ShaderState.light.m_AmbientLightCube[i].Base() ); + } + + return fLuminance / 6.0f; +} + +void CShaderAPIDx11::SetSkinningMatrices() +{ +} + +float CShaderAPIDx11::GetLightMapScaleFactor() const +{ + switch ( HardwareConfig()->GetHDRType() ) + { + + case HDR_TYPE_FLOAT: + return 1.0; + break; + + case HDR_TYPE_INTEGER: + return 16.0; + + case HDR_TYPE_NONE: + default: + return GammaToLinearFullRange( 2.0 ); // light map scale + } +} + +// Gets the lightmap dimensions +void CShaderAPIDx11::GetLightmapDimensions( int *w, int *h ) +{ + g_pShaderUtil->GetLightmapDimensions( w, h ); +} + +// Flushes any primitives that are buffered +void CShaderAPIDx11::FlushBufferedPrimitives() +{ + if ( ShaderUtil() ) + { + if ( !ShaderUtil()->OnFlushBufferedPrimitives() ) + { + return; + } + } + + LOCK_SHADERAPI(); + // This shouldn't happen in the inner rendering loop! + //Assert( m_pMesh == 0 ); + + // NOTE: We've gotta store off the matrix mode because + // it'll get reset by the default state application caused by the flush + MaterialMatrixMode_t oldMatMode = m_MatrixMode; + + MeshMgr()->Flush(); + + m_MatrixMode = oldMatMode; +} + +// Creates/destroys Mesh +IMesh *CShaderAPIDx11::CreateStaticMesh( VertexFormat_t fmt, const char *pTextureBudgetGroup, IMaterial *pMaterial ) +{ + return MeshMgr()->CreateStaticMesh( fmt, pTextureBudgetGroup, pMaterial ); +} + +void CShaderAPIDx11::DestroyStaticMesh( IMesh *mesh ) +{ + MeshMgr()->DestroyStaticMesh( mesh ); +} + +// Gets the dynamic mesh; note that you've got to render the mesh +// before calling this function a second time. Clients should *not* +// call DestroyStaticMesh on the mesh returned by this call. +IMesh *CShaderAPIDx11::GetDynamicMesh( IMaterial *pMaterial, int nHWSkinBoneCount, bool buffered, IMesh *pVertexOverride, IMesh *pIndexOverride ) +{ + return MeshMgr()->GetDynamicMesh( pMaterial, 0, nHWSkinBoneCount, buffered, pVertexOverride, pIndexOverride ); +} + +IMesh *CShaderAPIDx11::GetDynamicMeshEx( IMaterial *pMaterial, VertexFormat_t fmt, int nHWSkinBoneCount, bool buffered, IMesh *pVertexOverride, IMesh *pIndexOverride ) +{ + return MeshMgr()->GetDynamicMesh( pMaterial, fmt, nHWSkinBoneCount, buffered, pVertexOverride, pIndexOverride ); +} + +IVertexBuffer *CShaderAPIDx11::GetDynamicVertexBuffer( IMaterial *pMaterial, bool buffered ) +{ + return MeshMgr()->GetDynamicVertexBuffer( pMaterial, buffered ); +} + +IIndexBuffer *CShaderAPIDx11::GetDynamicIndexBuffer( IMaterial *pMaterial, bool buffered ) +{ + return MeshMgr()->GetDynamicIndexBuffer( pMaterial, buffered ); +} + +IMesh *CShaderAPIDx11::GetFlexMesh() +{ + return MeshMgr()->GetFlexMesh(); +} + +bool CShaderAPIDx11::IsDeactivated() const +{ + return g_pShaderDeviceDx11->IsDeactivated(); +} + +// stuff related to matrix stacks +// +// Note Dx11 doesn't have a matrix stack, you just supply +// the matrices to the shader in a constant buffer, so we will +// not break compatibility with Dx9 and just emulate the behavior. + +bool CShaderAPIDx11::MatrixIsChanging() +{ + if ( IsDeactivated() ) + { + return false; + } + + if ( m_MatrixMode == MATERIAL_MODEL || m_MatrixMode == MATERIAL_VIEW || m_MatrixMode == MATERIAL_PROJECTION ) + { + FlushBufferedPrimitives(); + } + + return true; +} + +void CShaderAPIDx11::HandleMatrixModified() +{ + m_ShaderState.m_ChangedMatrices[m_MatrixMode] = true; + if ( m_MatrixMode == MATERIAL_MODEL ) + { + // The model matrix is also the first bone matrix + m_ShaderState.bone.m_bBonesChanged = true; + } +} + +static DirectX::XMMATRIX s_DXMatIdent = DirectX::XMMatrixIdentity(); + +DirectX::XMMATRIX &CShaderAPIDx11::GetMatrix( MaterialMatrixMode_t mode ) +{ + CUtlStack &curStack = m_ShaderState.m_MatrixStacks[mode]; + if ( !curStack.Count() ) + { + return s_DXMatIdent; + } + + return m_ShaderState.m_MatrixStacks[mode].Top().m_Matrix; +} + +DirectX::XMMATRIX &CShaderAPIDx11::GetCurrentMatrix() +{ + return m_pCurMatrixItem->m_Matrix; +} + +DirectX::XMMATRIX CShaderAPIDx11::GetMatrixCopy( MaterialMatrixMode_t mode ) const +{ + const CUtlStack &curStack = m_ShaderState.m_MatrixStacks[mode]; + if ( !curStack.Count() ) + { + return DirectX::XMMatrixIdentity(); + } + + return m_ShaderState.m_MatrixStacks[mode].Top().m_Matrix; +} + +DirectX::XMMATRIX CShaderAPIDx11::GetCurrentMatrixCopy() const +{ + return m_pCurMatrixItem->m_Matrix; +} + +void CShaderAPIDx11::MatrixMode( MaterialMatrixMode_t matrixMode ) +{ + Assert( m_ShaderState.m_MatrixStacks[matrixMode].Count() ); + m_MatrixMode = matrixMode; + m_pCurMatrixItem = &m_ShaderState.m_MatrixStacks[matrixMode].Top(); +} + +void CShaderAPIDx11::PushMatrix() +{ + // Does nothing in Dx11 + //GetCurrentMatrix() = DirectX::XMMatrixTranspose( GetCurrentMatrix() ); + + CUtlStack &curStack = m_ShaderState.m_MatrixStacks[m_MatrixMode]; + Assert( curStack.Count() ); + int iNew = m_ShaderState.m_MatrixStacks[m_MatrixMode].Push(); + curStack[iNew] = curStack[iNew - 1]; + m_pCurMatrixItem = &m_ShaderState.m_MatrixStacks[m_MatrixMode].Top(); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::PopMatrix() +{ + MatrixIsChanging(); + + Assert( m_ShaderState.m_MatrixStacks[m_MatrixMode].Count() > 1 ); + m_ShaderState.m_MatrixStacks[m_MatrixMode].Pop(); + m_pCurMatrixItem = &m_ShaderState.m_MatrixStacks[m_MatrixMode].Top(); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::LoadMatrix( float *m ) +{ + MatrixIsChanging(); + + DirectX::XMFLOAT4X4 flt4x4( m ); + GetCurrentMatrix() = DirectX::XMLoadFloat4x4( &flt4x4 ); + HandleMatrixModified(); +} + +void CShaderAPIDx11::LoadBoneMatrix( int boneIndex, const float *m ) +{ + // NOTE: Bone matrices are column major, and HLSL is column-major, + // so we don't have to transpose anything. + + m_ShaderState.bone.m_BoneMatrix[boneIndex] = DirectX::XMFLOAT3X4A( m ); + m_ShaderState.bone.m_bBonesChanged = true; + if ( boneIndex > m_ShaderState.bone.m_MaxBoneLoaded ) + { + m_ShaderState.bone.m_MaxBoneLoaded = boneIndex; + } + if ( boneIndex == 0 ) + { + // We have to transpose here because when loading + // the model matrix into the shader it gets transposed again. + MatrixMode( MATERIAL_MODEL ); + VMatrix boneMatrix; + boneMatrix.Init( *(matrix3x4_t *)m ); + MatrixTranspose( boneMatrix, boneMatrix ); + LoadMatrix( boneMatrix.Base() ); + } +} + +void CShaderAPIDx11::MultMatrix( float *m ) +{ + MatrixIsChanging(); + DirectX::XMFLOAT4X4 flt4x4( m ); + GetCurrentMatrix() = DirectX::XMMatrixMultiply( + GetCurrentMatrix(), DirectX::XMLoadFloat4x4( &flt4x4 ) ); + HandleMatrixModified(); +} + +void CShaderAPIDx11::MultMatrixLocal( float *m ) +{ + MatrixIsChanging(); + // DX11FIXME: Local multiply + DirectX::XMFLOAT4X4 flt4x4( m ); + GetCurrentMatrix() = DirectX::XMMatrixMultiply( + DirectX::XMLoadFloat4x4( &flt4x4 ), GetCurrentMatrix() ); + HandleMatrixModified(); +} + +void CShaderAPIDx11::GetMatrix( MaterialMatrixMode_t matrixMode, float *dst ) +{ + DirectX::XMFLOAT4X4 flt4x4; + DirectX::XMStoreFloat4x4( &flt4x4, GetMatrix( matrixMode ) ); + memcpy( dst, &flt4x4, sizeof( DirectX::XMFLOAT4X4 ) ); +} + +void CShaderAPIDx11::GetMatrix( MaterialMatrixMode_t matrixMode, DirectX::XMMATRIX &mat ) +{ + mat = GetMatrix( matrixMode ); +} + +void CShaderAPIDx11::LoadIdentity( void ) +{ + MatrixIsChanging(); + m_pCurMatrixItem->m_Matrix = DirectX::XMMatrixIdentity(); + HandleMatrixModified(); +} + +void CShaderAPIDx11::LoadCameraToWorld( void ) +{ + MatrixIsChanging(); + + DirectX::XMMATRIX inv; + inv = DirectX::XMMatrixInverse( NULL, GetMatrix( MATERIAL_VIEW ) ); + + DirectX::XMFLOAT4X4 flt4x4inv; + DirectX::XMStoreFloat4x4( &flt4x4inv, inv ); + + // Kill translation + flt4x4inv.m[3][0] = flt4x4inv.m[3][1] = flt4x4inv.m[3][2] = 0.0f; + inv = DirectX::XMLoadFloat4x4( &flt4x4inv ); + + m_pCurMatrixItem->m_Matrix = inv; + + HandleMatrixModified(); +} + +// Get the current camera position in world space. +void CShaderAPIDx11::GetWorldSpaceCameraPosition( float *pPos ) const +{ + DirectX::XMFLOAT4X4 flt4x4; + const DirectX::XMMATRIX &view = GetMatrixCopy( MATERIAL_VIEW ); + DirectX::XMStoreFloat4x4( &flt4x4, view ); + memcpy( pPos, &flt4x4, sizeof( DirectX::XMFLOAT4X4 ) ); +} + +void CShaderAPIDx11::Ortho( double left, double top, double right, double bottom, double zNear, double zFar ) +{ + MatrixIsChanging(); + + DirectX::XMMATRIX mat = DirectX::XMMatrixOrthographicOffCenterRH( left, right, bottom, top, zNear, zFar ); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( mat, GetCurrentMatrix() ); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::PerspectiveX( double fovx, double aspect, double zNear, double zFar ) +{ + MatrixIsChanging(); + + float width = 2 * zNear * tan( fovx * M_PI / 360.0 ); + float height = width / aspect; + DirectX::XMMATRIX mat; + mat = DirectX::XMMatrixPerspectiveRH( width, height, zNear, zFar ); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( mat, GetCurrentMatrix() ); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::PerspectiveOffCenterX( double fovx, double aspect, double zNear, double zFar, double bottom, double top, double left, double right ) +{ + MatrixIsChanging(); + + float width = 2 * zNear * tan( fovx * M_PI / 360.0 ); + float height = width / aspect; + + // bottom, top, left, right are 0..1 so convert to -1..1 + float flFrontPlaneLeft = -( width / 2.0f ) * ( 1.0f - left ) + left * ( width / 2.0f ); + float flFrontPlaneRight = -( width / 2.0f ) * ( 1.0f - right ) + right * ( width / 2.0f ); + float flFrontPlaneBottom = -( height / 2.0f ) * ( 1.0f - bottom ) + bottom * ( height / 2.0f ); + float flFrontPlaneTop = -( height / 2.0f ) * ( 1.0f - top ) + top * ( height / 2.0f ); + + DirectX::XMMATRIX mat; + mat = DirectX::XMMatrixPerspectiveOffCenterRH( flFrontPlaneLeft, flFrontPlaneRight, flFrontPlaneBottom, + flFrontPlaneTop, zNear, zFar ); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( mat, GetCurrentMatrix() ); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::PickMatrix( int x, int y, int width, int height ) +{ + MatrixIsChanging(); + + ShaderViewport_t viewport; + GetViewports( &viewport, 1 ); + + int vx = viewport.m_nTopLeftX; + int vy = viewport.m_nTopLeftX; + int vwidth = viewport.m_nWidth; + int vheight = viewport.m_nHeight; + + // Compute the location of the pick region in projection space... + float px = 2.0 * (float)( x - vx ) / (float)vwidth - 1; + float py = 2.0 * (float)( y - vy ) / (float)vheight - 1; + float pw = 2.0 * (float)width / (float)vwidth; + float ph = 2.0 * (float)height / (float)vheight; + + // we need to translate (px, py) to the origin + // and scale so (pw,ph) -> (2, 2) + DirectX::XMMATRIX mat; + mat = DirectX::XMMatrixTranslation( -2.0f * py / ph, -2.0f * px / pw, 0.0f ); + mat = DirectX::XMMatrixMultiply( mat, DirectX::XMMatrixScaling( 2.0f / pw, 2.0f / ph, 1.0f ) ); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( mat, GetCurrentMatrix() ); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::Rotate( float angle, float x, float y, float z ) +{ + MatrixIsChanging(); + + DirectX::XMVECTOR axis; + axis = DirectX::XMVectorSet( x, y, z, 0 ); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( DirectX::XMMatrixRotationAxis( axis, M_PI * angle / 180.0f ), GetCurrentMatrix() ); + + HandleMatrixModified(); +} + +void CShaderAPIDx11::Translate( float x, float y, float z ) +{ + MatrixIsChanging(); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( DirectX::XMMatrixTranslation( x, y, z ), GetCurrentMatrix() ); + HandleMatrixModified(); +} + +void CShaderAPIDx11::Scale( float x, float y, float z ) +{ + MatrixIsChanging(); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( DirectX::XMMatrixScaling( x, y, z ), GetCurrentMatrix() ); + HandleMatrixModified(); +} + +void CShaderAPIDx11::ScaleXY( float x, float y ) +{ + MatrixIsChanging(); + + // DX11FIXME: Local multiply + GetCurrentMatrix() = DirectX::XMMatrixMultiply( DirectX::XMMatrixScaling( x, y, 1.0f ), GetCurrentMatrix() ); + HandleMatrixModified(); +} + +// Fog methods... +void CShaderAPIDx11::FogMode( MaterialFogMode_t fogMode ) +{ + if ( fogMode != m_ShaderState.fog.m_FogMode ) + { + m_ShaderState.fog.m_FogMode = fogMode; + m_ShaderState.fog.m_bFogChanged = true; + } +} + +void CShaderAPIDx11::FogStart( float fStart ) +{ + if ( fStart != m_ShaderState.fog.m_flFogStart ) + { + m_ShaderState.fog.m_flFogStart = fStart; + m_ShaderState.fog.m_bFogChanged = true; + } +} + +void CShaderAPIDx11::FogEnd( float fEnd ) +{ + if ( m_ShaderState.fog.m_flFogEnd != fEnd ) + { + m_ShaderState.fog.m_flFogStart = fEnd; + m_ShaderState.fog.m_bFogChanged = true; + } +} + +void CShaderAPIDx11::SetFogZ( float fogZ ) +{ + if ( m_ShaderState.fog.m_flFogZ != fogZ ) + { + m_ShaderState.fog.m_flFogZ = fogZ; + m_ShaderState.fog.m_bFogChanged = true; + } +} + +void CShaderAPIDx11::FogMaxDensity( float flMaxDensity ) +{ + if ( m_ShaderState.fog.m_flFogMaxDensity != flMaxDensity ) + { + m_ShaderState.fog.m_flFogMaxDensity = flMaxDensity; + m_ShaderState.fog.m_bFogChanged = true; + } +} + +void CShaderAPIDx11::GetFogDistances( float *fStart, float *fEnd, float *fFogZ ) +{ + *fStart = m_ShaderState.fog.m_flFogStart; + *fEnd = m_ShaderState.fog.m_flFogEnd; + *fFogZ = m_ShaderState.fog.m_flFogZ; +} + +void CShaderAPIDx11::SceneFogColor3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + m_ShaderState.fog.m_FogColor[0] = r / 255.0f; + m_ShaderState.fog.m_FogColor[1] = g / 255.0f; + m_ShaderState.fog.m_FogColor[2] = b / 255.0f; + m_ShaderState.fog.m_bFogChanged = true; +} + +void CShaderAPIDx11::SceneFogMode( MaterialFogMode_t fogMode ) +{ + if ( fogMode != m_ShaderState.fog.m_FogMode ) + { + m_ShaderState.fog.m_FogMode = fogMode; + m_ShaderState.fog.m_bFogChanged = true; + } +} + +void CShaderAPIDx11::GetSceneFogColor( unsigned char *rgb ) +{ + rgb[0] = (unsigned char)( m_ShaderState.fog.m_FogColor[0] * 255 ); + rgb[1] = (unsigned char)( m_ShaderState.fog.m_FogColor[1] * 255 ); + rgb[2] = (unsigned char)( m_ShaderState.fog.m_FogColor[2] * 255 ); +} + +// Sigh... I don't understand why there's two different fog settings +MaterialFogMode_t CShaderAPIDx11::GetSceneFogMode() +{ + return m_ShaderState.fog.m_FogMode; +} + +int CShaderAPIDx11::GetPixelFogCombo() +{ + if ( m_ShaderState.fog.m_FogMode != MATERIAL_FOG_NONE ) + return m_ShaderState.fog.m_FogMode - 1; + else + return MATERIAL_FOG_NONE; +} + +void CShaderAPIDx11::FogColor3f( float r, float g, float b ) +{ +} + +void CShaderAPIDx11::FogColor3fv( float const *rgb ) +{ +} + +void CShaderAPIDx11::FogColor3ub( unsigned char r, unsigned char g, unsigned char b ) +{ +} + +void CShaderAPIDx11::FogColor3ubv( unsigned char const *rgb ) +{ +} + +void CShaderAPIDx11::GetFogColor( float *rgb ) +{ + //const StatesDx11::ShadowState *state = g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot ); +} + +void CShaderAPIDx11::GetFogParamsAndColor( float *fogParams, float *rgba ) +{ + const StatesDx11::ShadowState *state = g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot ); + + // Compute fog parameters + + if ( GetSceneFogMode() != MATERIAL_FOG_NONE && state->desc.fogMode != SHADER_FOGMODE_DISABLED ) + { + float fStart = m_ShaderState.fog.m_flFogStart; + float fEnd = m_ShaderState.fog.m_flFogEnd; + + fogParams[0] = fStart * 2; // fog begin distance + fogParams[1] = fEnd * 1.5f; // fog end distance (fully fogged) + fogParams[2] = clamp( m_ShaderState.fog.m_flFogMaxDensity, 0.0f, 1.0f ); // Max fog factor + fogParams[3] = m_ShaderState.fog.m_flFogZ; // water height + } + else + { + //emulating MATERIAL_FOG_NONE by setting the parameters so that CalcRangeFog() always returns 0. Gets rid of a dynamic combo across the ps2x set. + fogParams[0] = 1.0f; // begin + fogParams[1] = 1.0f; // end + fogParams[2] = 0.0f; // Max fog density + fogParams[3] = 0.0f; // water height + + rgba[0] = 0.0f; + rgba[1] = 0.0f; + rgba[2] = 0.0f; + rgba[3] = 0.0f; + + return; + } + + // Compute fog color + + ShaderFogMode_t fogMode = state->desc.fogMode; + bool bDisableFogGammaCorrection = state->desc.disableFogGammaCorrection; + bool bShouldGammaCorrect = true; // By default, we'll gamma correct. + unsigned char rgb[3] = { 0 }; + + switch ( fogMode ) + { + case SHADER_FOGMODE_BLACK: // Additive decals + bShouldGammaCorrect = false; + break; + case SHADER_FOGMODE_OO_OVERBRIGHT: + case SHADER_FOGMODE_GREY: // Mod2x decals + rgb[0] = rgb[1] = rgb[2] = 128; + break; + case SHADER_FOGMODE_WHITE: // Multiplicative decals + rgb[0] = rgb[1] = rgb[2] = 255; + bShouldGammaCorrect = false; + break; + case SHADER_FOGMODE_FOGCOLOR: + GetSceneFogColor( rgb ); // Scene fog color + break; + NO_DEFAULT + } + + rgba[0] = rgb[0] / 255.0f; + rgba[1] = rgb[1] / 255.0f; + rgba[2] = rgb[2] / 255.0f; + rgba[3] = 1.0f; + + bShouldGammaCorrect &= !bDisableFogGammaCorrection; + if ( bShouldGammaCorrect ) + { + GammaCorrectFogColor( rgba ); + } +} + +void CShaderAPIDx11::GammaCorrectFogColor( float *rgb ) +{ + bool bLinearSpace = g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT; + + bool bScaleFogByToneMappingScale = false;//g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER; + + float fr = rgb[0]; + float fg = rgb[1]; + float fb = rgb[2]; + if ( bLinearSpace ) + { + fr = GammaToLinear( fr ); + fg = GammaToLinear( fg ); + fb = GammaToLinear( fb ); + if ( bScaleFogByToneMappingScale ) + { + fr *= m_ShaderState.m_ToneMappingScale.x; // + fg *= m_ShaderState.m_ToneMappingScale.x; // Linear + fb *= m_ShaderState.m_ToneMappingScale.x; // + } + } + + else if ( bScaleFogByToneMappingScale ) + { + fr *= m_ShaderState.m_ToneMappingScale.w; // + fg *= m_ShaderState.m_ToneMappingScale.w; // Gamma + fb *= m_ShaderState.m_ToneMappingScale.w; // + } + + fr = min( fr, 1.0f ); + fg = min( fg, 1.0f ); + fb = min( fb, 1.0f ); + + rgb[0] = fr; + rgb[1] = fg; + rgb[2] = fb; +} + +// KMS +MaterialFogMode_t CShaderAPIDx11::GetCurrentFogType( void ) const +{ + return m_ShaderState.fog.m_FogMode; +} + +// Sets the *dynamic* vertex and pixel shaders +void CShaderAPIDx11::SetVertexShaderIndex( ShaderIndex_t vshIndex ) +{ + ShaderManager()->SetVertexShaderIndex( vshIndex ); + ShaderManager()->SetVertexShader( g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot )->desc.vertexShader ); +} + +void CShaderAPIDx11::SetPixelShaderIndex( ShaderIndex_t pshIndex ) +{ + ShaderManager()->SetPixelShaderIndex( pshIndex ); + ShaderManager()->SetPixelShader( g_pShaderShadowDx11->GetShadowState( m_CurrentSnapshot )->desc.pixelShader ); +} + +// Returns the nearest supported format +ImageFormat CShaderAPIDx11::GetNearestSupportedFormat( ImageFormat fmt, bool bFilteringRequired /* = true */ ) const +{ + return CTextureDx11::GetClosestSupportedImageFormatForD3D11( fmt ); +} + +ImageFormat CShaderAPIDx11::GetNearestRenderTargetFormat( ImageFormat fmt ) const +{ + return CTextureDx11::GetClosestSupportedImageFormatForD3D11( fmt ); +} + +// Sets the texture state +void CShaderAPIDx11::BindTexture( Sampler_t stage, ShaderAPITextureHandle_t textureHandle ) +{ + CTextureDx11 *pTex = &GetTexture( textureHandle ); + + if ( !pTex ) + return; + + StatesDx11::DynamicState &dynamic = m_DynamicState; + + ID3D11ShaderResourceView *pView = pTex->GetView(); + ID3D11SamplerState *pSampler = pTex->GetSamplerState(); + + if ( pView != dynamic.m_ppTextures[stage] ) + { + dynamic.m_ppTextures[stage] = pView; + + SetStateFlag( STATE_CHANGED_TEXTURES ); + } + + if ( pSampler != dynamic.m_ppSamplers[stage] ) + { + dynamic.m_ppSamplers[stage] = pSampler; + + SetStateFlag( STATE_CHANGED_SAMPLERS ); + } + + if ( stage > dynamic.m_MaxPSSampler ) + { + dynamic.m_MaxPSSampler = stage; + + if ( dynamic.m_MaxPSSampler > dynamic.m_PrevMaxPSSampler ) + { + SetStateFlag( STATE_CHANGED_SAMPLERS | STATE_CHANGED_TEXTURES ); + } + } +} + +void CShaderAPIDx11::UnbindTexture( ShaderAPITextureHandle_t textureHandle ) +{ + + CTextureDx11 *pTex = &GetTexture( textureHandle ); + + // Unbind the sampler + + int iSampler = -1; + for ( int i = 0; i < m_DynamicState.m_MaxPSSampler + 1; i++ ) + { + if ( m_DynamicState.m_ppTextures[i] == pTex->GetView() ) + { + iSampler = i; + break; + } + } + + if ( iSampler == -1 ) + return; + + m_DynamicState.m_ppSamplers[iSampler] = NULL; + m_DynamicState.m_ppTextures[iSampler] = NULL; + + int maxSampler = -1; + for ( int i = 0; i < MAX_DX11_SAMPLERS; i++ ) + { + if ( m_DynamicState.m_ppTextures[i] != NULL ) + { + maxSampler = i; + } + } + + m_DynamicState.m_MaxPSSampler = maxSampler; + + SetStateFlag( STATE_CHANGED_SAMPLERS | STATE_CHANGED_TEXTURES ); + +} + +// Indicates we're going to be modifying this texture +// TexImage2D, TexSubImage2D, TexWrap, TexMinFilter, and TexMagFilter +// all use the texture specified by this function. +void CShaderAPIDx11::ModifyTexture( ShaderAPITextureHandle_t textureHandle ) +{ + LOCK_SHADERAPI(); + + // Can't do this if we're locked! + Assert( m_ModifyTextureLockedLevel < 0 ); + + m_ModifyTextureHandle = textureHandle; + + // If we've got a multi-copy texture, we need to up the current copy count + CTextureDx11 &tex = GetTexture( textureHandle ); + if ( tex.m_NumCopies > 1 ) + { + // Each time we modify a texture, we'll want to switch texture + // as soon as a TexImage2D call is made... + tex.m_SwitchNeeded = true; + } +} + +void CShaderAPIDx11::AdvanceCurrentTextureCopy( ShaderAPITextureHandle_t texture ) +{ + // May need to switch textures.... + CTextureDx11 &tex = GetTexture( texture ); + if ( tex.m_NumCopies > 1 ) + { + if ( ++tex.m_CurrentCopy >= tex.m_NumCopies ) + tex.m_CurrentCopy = 0; + + // When the current copy changes, we need to make sure this texture + // isn't bound to any stages any more; thereby guaranteeing the new + // copy will be re-bound. + UnbindTexture( texture ); + } +} + +//----------------------------------------------------------------------------- +// Texture image upload +// +// level: mipmap level we are writing to +// cubeFace: face of the cubemap/array texture we are writing to +// dstFormat: unused +// zOffset: not sure +// width: image width +// height image height +// srcFormat: format of the source image data +// bSrcIsTiled: is the source image a tiled image +// imageData: pointer to the beginning of the source image data +//----------------------------------------------------------------------------- +void CShaderAPIDx11::TexImage2D( int level, int cubeFace, ImageFormat dstFormat, int zOffset, int width, int height, + ImageFormat srcFormat, bool bSrcIsTiled, void *imageData ) +{ + LOCK_SHADERAPI(); + Assert( imageData ); + ShaderAPITextureHandle_t hModifyTexture = m_ModifyTextureHandle; + if ( !m_Textures.IsValidIndex( hModifyTexture ) ) + { + Log( "Invalid modify texture handle!\n" ); + return; + + } + + //if ( zOffset != 0 ) + //DebuggerBreak(); + + + Assert( ( width <= g_pHardwareConfig->Caps().m_MaxTextureWidth ) && + ( height <= g_pHardwareConfig->Caps().m_MaxTextureHeight ) ); + + // Blow off mip levels if we don't support mipmapping + if ( !g_pHardwareConfig->SupportsMipmapping() && ( level > 0 ) ) + { + Log( "Trying to image mip but we don't support mips!\n" ); + return; + } + + // This test here just makes sure we don't try to download mipmap levels + // if we weren't able to create them in the first place + CTextureDx11 &tex = GetTexture( hModifyTexture ); + if ( level >= tex.m_NumLevels ) + { + Log( "level >= tex.m_NumLevels\n" ); + return; + } + + // May need to switch textures.... + if ( tex.m_SwitchNeeded ) + { + AdvanceCurrentTextureCopy( hModifyTexture ); + tex.m_SwitchNeeded = false; + } + + CTextureDx11::TextureLoadInfo_t info; + info.m_TextureHandle = hModifyTexture; + info.m_pTexture = GetD3DTexture( hModifyTexture ); + info.m_pView = tex.GetView(); + info.m_nLevel = level; + info.m_nCopy = tex.m_CurrentCopy; + info.m_CubeFaceID = (D3D11_TEXTURECUBE_FACE)cubeFace; + info.m_nWidth = width; + info.m_nHeight = height; + info.m_nZOffset = zOffset; + info.m_SrcFormat = srcFormat; + info.m_pSrcData = (unsigned char *)imageData; + tex.LoadTexImage( info ); +} + +void CShaderAPIDx11::TexSubImage2D( int level, int cubeFace, int xOffset, int yOffset, int zOffset, int width, int height, + ImageFormat srcFormat, int srcStride, bool bSrcIsTiled, void *imageData ) +{ + //Log( "TexSubImage2D!\n" ); + + LOCK_SHADERAPI(); + Assert( imageData ); + ShaderAPITextureHandle_t hModifyTexture = m_ModifyTextureHandle; + if ( !m_Textures.IsValidIndex( hModifyTexture ) ) + { + Log( "Invalid modify texture handle!\n" ); + return; + + } + + //if ( zOffset != 0 ) + //DebuggerBreak(); + + // Blow off mip levels if we don't support mipmapping + if ( !g_pHardwareConfig->SupportsMipmapping() && ( level > 0 ) ) + { + Log( "Trying to image mip but we don't support mips!\n" ); + return; + } + + CTextureDx11 &tex = GetTexture( hModifyTexture ); + + // NOTE: This can only be done with procedural textures if this method is + // being used to download the entire texture, cause last frame's partial update + // may be in a completely different texture! Sadly, I don't have all of the + // information I need, but I can at least check a couple things.... +#ifdef _DEBUG + if ( tex.m_NumCopies > 1 ) + { + Assert( ( xOffset == 0 ) && ( yOffset == 0 ) ); + } +#endif + + // This test here just makes sure we don't try to download mipmap levels + // if we weren't able to create them in the first place + if ( level >= tex.m_NumLevels ) + { + Log( "level >= tex.m_NumLevels\n" ); + return; + } + + // May need to switch textures.... + if ( tex.m_SwitchNeeded ) + { + AdvanceCurrentTextureCopy( hModifyTexture ); + tex.m_SwitchNeeded = false; + } + + CTextureDx11::TextureLoadInfo_t info; + info.m_TextureHandle = hModifyTexture; + info.m_pTexture = GetD3DTexture( hModifyTexture ); + info.m_pView = tex.GetView(); + info.m_nLevel = level; + info.m_nCopy = tex.m_CurrentCopy; + info.m_CubeFaceID = (D3D11_TEXTURECUBE_FACE)cubeFace; + info.m_nWidth = width; + info.m_nHeight = height; + info.m_nZOffset = zOffset; + info.m_SrcFormat = srcFormat; + info.m_pSrcData = (unsigned char *)imageData; + tex.LoadTexImage( info, xOffset, yOffset, srcStride ); +} + +void CShaderAPIDx11::TexImageFromVTF(IVTFTexture* pVTF, int iVTFFrame) +{ + TexImage2D(0, 0, pVTF->Format(), 0, pVTF->Width(), pVTF->Height(), pVTF->Format(), false, pVTF->ImageData(iVTFFrame, 0, 0)); +} + +bool CShaderAPIDx11::TexLock( int level, int cubeFaceID, int xOffset, int yOffset, + int width, int height, CPixelWriter &writer ) +{ + LOCK_SHADERAPI(); + + Assert( m_ModifyTextureHandle > 0 ); + + ShaderAPITextureHandle_t hTexture = m_ModifyTextureHandle; + if ( !m_Textures.IsValidIndex( hTexture ) ) + return false; + + // Blow off mip levels if we don't support mipmapping + if ( !g_pHardwareConfig->SupportsMipmapping() && ( level > 0 ) ) + return false; + + // This test here just makes sure we don't try to download mipmap levels + // if we weren't able to create them in the first place + CTextureDx11 &tex = GetTexture( hTexture ); + if ( level >= tex.m_NumLevels ) + { + return false; + } + + // May need to switch textures.... + if ( tex.m_SwitchNeeded ) + { + AdvanceCurrentTextureCopy( hTexture ); + tex.m_SwitchNeeded = false; + } + + bool ret = tex.Lock( tex.m_CurrentCopy, level, cubeFaceID, xOffset, yOffset, + width, height, false, writer ); + if ( ret ) + { + m_ModifyTextureLockedLevel = level; + m_ModifyTextureLockedFace = cubeFaceID; + } + + return ret; +} + +void CShaderAPIDx11::TexUnlock() +{ + LOCK_SHADERAPI(); + + if ( m_ModifyTextureLockedLevel >= 0 ) + { + CTextureDx11 &tex = GetTexture( m_ModifyTextureHandle ); + tex.Unlock( tex.m_CurrentCopy, m_ModifyTextureLockedLevel, + m_ModifyTextureLockedFace ); + + m_ModifyTextureLockedLevel = -1; + } +} + +// These are bound to the texture, not the texture environment +void CShaderAPIDx11::TexMinFilter( ShaderTexFilterMode_t texFilterMode ) +{ + LOCK_SHADERAPI(); + + ShaderAPITextureHandle_t hModifyTexture = m_ModifyTextureHandle; + if ( hModifyTexture == INVALID_SHADERAPI_TEXTURE_HANDLE ) + return; + + GetTexture( hModifyTexture ).SetMinFilter( texFilterMode ); +} + +void CShaderAPIDx11::TexMagFilter( ShaderTexFilterMode_t texFilterMode ) +{ + LOCK_SHADERAPI(); + + ShaderAPITextureHandle_t hModifyTexture = m_ModifyTextureHandle; + if ( hModifyTexture == INVALID_SHADERAPI_TEXTURE_HANDLE ) + return; + + GetTexture( hModifyTexture ).SetMagFilter( texFilterMode ); +} + +void CShaderAPIDx11::TexWrap( ShaderTexCoordComponent_t coord, ShaderTexWrapMode_t wrapMode ) +{ + LOCK_SHADERAPI(); + + ShaderAPITextureHandle_t hModifyTexture = m_ModifyTextureHandle; + if ( hModifyTexture == INVALID_SHADERAPI_TEXTURE_HANDLE ) + return; + + GetTexture( hModifyTexture ).SetWrap( coord, wrapMode ); +} + +ShaderAPITextureHandle_t CShaderAPIDx11::CreateTexture( + int width, + int height, + int depth, + ImageFormat dstImageFormat, + int numMipLevels, + int numCopies, + int flags, + const char *pDebugName, + const char *pTextureGroupName ) +{ + Log( "Create Texture with format: %s\n", ImageLoader::GetName( dstImageFormat ) ); + ShaderAPITextureHandle_t handle; + CreateTextures( &handle, 1, width, height, depth, dstImageFormat, numMipLevels, numCopies, flags, pDebugName, pTextureGroupName ); + return handle; +} + +void CShaderAPIDx11::CreateTextureHandles( ShaderAPITextureHandle_t *handles, int count ) +{ + if ( count <= 0 ) + return; + + MEM_ALLOC_CREDIT(); + + int idxCreating = 0; + ShaderAPITextureHandle_t hTexture; + for ( hTexture = 0; hTexture < m_Textures.Count(); hTexture++ ) + { + if ( !( m_Textures[hTexture].m_nFlags & CTextureDx11::IS_ALLOCATED ) ) + { + handles[idxCreating++] = hTexture; + if ( idxCreating >= count ) + return; + } + } + + while ( idxCreating < count ) + handles[idxCreating++] = m_Textures.AddToTail(); +} + +void CShaderAPIDx11::CreateTextures( + ShaderAPITextureHandle_t *pHandles, + int count, + int width, + int height, + int depth, + ImageFormat dstImageFormat, + int numMipLevels, + int numCopies, + int flags, + const char *pDebugName, + const char *pTextureGroupName ) +{ + LOCK_SHADERAPI(); + // Create a set of texture handles + CreateTextureHandles( pHandles, count ); + CTextureDx11 **arrTxp = new CTextureDx11 * [count]; + + Log( "Creating Textures with format: %s\n", ImageLoader::GetName( dstImageFormat ) ); + + for ( int idxFrame = 0; idxFrame < count; ++idxFrame ) + { + arrTxp[idxFrame] = &GetTexture( pHandles[idxFrame] ); + CTextureDx11 *pTexture = arrTxp[idxFrame]; + pTexture->SetupTexture2D( width, height, depth, count, idxFrame, flags, + numCopies, numMipLevels, dstImageFormat ); + pTexture->SetAnisotropicLevel( m_TexAnisotropy ); + + } + + delete[] arrTxp; +} + +CTextureDx11 &CShaderAPIDx11::GetTexture( ShaderAPITextureHandle_t handle ) +{ + return m_Textures[handle]; +} + +ShaderAPITextureHandle_t CShaderAPIDx11::CreateTextureHandle() +{ + ShaderAPITextureHandle_t handle; + CreateTextureHandles( &handle, 1 ); + return handle; +} + +ShaderAPITextureHandle_t CShaderAPIDx11::CreateDepthTexture( ImageFormat renderFormat, int width, int height, const char *pDebugName, bool bTexture ) +{ + LOCK_SHADERAPI(); + + ShaderAPITextureHandle_t i = CreateTextureHandle(); + CTextureDx11 *pTexture = &GetTexture( i ); + pTexture->SetupDepthTexture( renderFormat, width, height, pDebugName, bTexture ); + + return i; +} + +void CShaderAPIDx11::DeleteTexture( ShaderAPITextureHandle_t textureHandle ) +{ + LOCK_SHADERAPI(); + + if ( !TextureIsAllocated( textureHandle ) ) + { + // already deallocated + return; + } + + // Unbind it! + + // Delete it baby + GetTexture( textureHandle ).Delete(); +} + +bool CShaderAPIDx11::IsTexture( ShaderAPITextureHandle_t textureHandle ) +{ + LOCK_SHADERAPI(); + + if ( !TextureIsAllocated( textureHandle ) ) + return false; + + if ( GetTexture( textureHandle ).m_nFlags & CTextureDx11::IS_DEPTH_STENCIL ) + { + return GetTexture( textureHandle ).GetDepthStencilView() != 0; + } + else if ( ( GetTexture( textureHandle ).m_NumCopies == 1 && GetTexture( textureHandle ).GetTexture() != 0 ) || + ( GetTexture( textureHandle ).m_NumCopies > 1 && GetTexture( textureHandle ).GetTexture( 0 ) != 0 ) ) + { + return true; + } + + return false; +} + +void CShaderAPIDx11::SetAnisotropicLevel( int nAnisotropyLevel ) +{ + LOCK_SHADERAPI(); + + // NOTE: This must be called before the rest of the code in this function so + // anisotropic can be set per-texture to force it on! This will also avoid + // a possible infinite loop that existed before. + g_pShaderUtil->NoteAnisotropicLevel( nAnisotropyLevel ); + + // Never set this to 1. In the case we want it set to 1, we will use this to override + // aniso per-texture, so set it to something reasonable + if ( nAnisotropyLevel > g_pHardwareConfig->Caps().m_nMaxAnisotropy || nAnisotropyLevel <= 1 ) + { + // Set it to 1/4 the max but between 2-8 + nAnisotropyLevel = max( 2, min( 8, ( g_pHardwareConfig->Caps().m_nMaxAnisotropy / 4 ) ) ); + } + + m_TexAnisotropy = nAnisotropyLevel; + + // Set the D3D max aninsotropy state for all samplers + for ( ShaderAPITextureHandle_t handle = 0; + handle < m_Textures.Count(); + handle++ ) + { + CTextureDx11 &tex = GetTexture( handle ); + tex.SetAnisotropicLevel( m_TexAnisotropy ); + } +} + +bool CShaderAPIDx11::IsTextureResident( ShaderAPITextureHandle_t textureHandle ) +{ + return true; +} + +// stuff that isn't to be used from within a shader +void CShaderAPIDx11::ClearBuffersObeyStencil(bool bClearColor, bool bClearDepth) +{ + ClearBuffersObeyStencilEx(bClearColor, bClearColor, bClearDepth); +} + +// stuff that isn't to be used from within a shader +void CShaderAPIDx11::ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ) +{ + LOCK_SHADERAPI(); + + if ( !bClearColor && !bClearDepth ) + return; + + FlushBufferedPrimitives(); + + ShaderUtil()->DrawClearBufferQuad( m_DynamicState.m_ClearColor[0] * 255, + m_DynamicState.m_ClearColor[1] * 255, + m_DynamicState.m_ClearColor[2] * 255, + m_DynamicState.m_ClearColor[3] * 255, + bClearColor, bClearAlpha, bClearDepth ); + + FlushBufferedPrimitives(); +} + +void CShaderAPIDx11::PerformFullScreenStencilOperation( void ) +{ +} + +void CShaderAPIDx11::ReadPixels( int x, int y, int width, int height, unsigned char *data, ImageFormat dstFormat ) +{ +} + +void CShaderAPIDx11::ReadPixels( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *data, ImageFormat dstFormat, int nDstStride ) +{ +} + +void CShaderAPIDx11::FlushHardware() +{ +} + +// Set the number of bone weights +void CShaderAPIDx11::SetNumBoneWeights( int numBones ) +{ + LOCK_SHADERAPI(); + if ( m_ShaderState.bone.m_NumBones != numBones ) + { + FlushBufferedPrimitives(); + m_ShaderState.bone.m_NumBones = numBones; + m_ShaderState.bone.m_bBonesChanged = true; + } +} + +//----------------------------------------------------------------------------- +// Selection mode methods +//----------------------------------------------------------------------------- +int CShaderAPIDx11::SelectionMode( bool selectionMode ) +{ + LOCK_SHADERAPI(); + int numHits = m_NumHits; + if ( m_InSelectionMode ) + { + WriteHitRecord(); + } + m_InSelectionMode = selectionMode; + m_pCurrSelectionRecord = m_pSelectionBuffer; + m_NumHits = 0; + return numHits; +} + +bool CShaderAPIDx11::IsInSelectionMode() const +{ + return m_InSelectionMode; +} + +void CShaderAPIDx11::SelectionBuffer( unsigned int *pBuffer, int size ) +{ + LOCK_SHADERAPI(); + Assert( !m_InSelectionMode ); + Assert( pBuffer && size ); + m_pSelectionBufferEnd = pBuffer + size; + m_pSelectionBuffer = pBuffer; + m_pCurrSelectionRecord = pBuffer; +} + +void CShaderAPIDx11::ClearSelectionNames() +{ + LOCK_SHADERAPI(); + if ( m_InSelectionMode ) + { + WriteHitRecord(); + } + m_SelectionNames.Clear(); +} + +void CShaderAPIDx11::LoadSelectionName( int name ) +{ + LOCK_SHADERAPI(); + if ( m_InSelectionMode ) + { + WriteHitRecord(); + Assert( m_SelectionNames.Count() > 0 ); + m_SelectionNames.Top() = name; + } +} + +void CShaderAPIDx11::PushSelectionName( int name ) +{ + LOCK_SHADERAPI(); + if ( m_InSelectionMode ) + { + WriteHitRecord(); + m_SelectionNames.Push( name ); + } +} + +void CShaderAPIDx11::PopSelectionName() +{ + LOCK_SHADERAPI(); + if ( m_InSelectionMode ) + { + WriteHitRecord(); + m_SelectionNames.Pop(); + } +} + +void CShaderAPIDx11::WriteHitRecord() +{ + FlushBufferedPrimitives(); + + if ( m_SelectionNames.Count() && ( m_SelectionMinZ != FLT_MAX ) ) + { + Assert( m_pCurrSelectionRecord + m_SelectionNames.Count() + 3 < m_pSelectionBufferEnd ); + *m_pCurrSelectionRecord++ = m_SelectionNames.Count(); + *m_pCurrSelectionRecord++ = (int)( (double)m_SelectionMinZ * (double)0xFFFFFFFF ); + *m_pCurrSelectionRecord++ = (int)( (double)m_SelectionMaxZ * (double)0xFFFFFFFF ); + for ( int i = 0; i < m_SelectionNames.Count(); ++i ) + { + *m_pCurrSelectionRecord++ = m_SelectionNames[i]; + } + + ++m_NumHits; + } + + m_SelectionMinZ = FLT_MAX; + m_SelectionMaxZ = FLT_MIN; +} + +// We hit somefin in selection mode +void CShaderAPIDx11::RegisterSelectionHit( float minz, float maxz ) +{ + if ( minz < 0 ) + minz = 0; + if ( maxz > 1 ) + maxz = 1; + if ( m_SelectionMinZ > minz ) + m_SelectionMinZ = minz; + if ( m_SelectionMaxZ < maxz ) + m_SelectionMaxZ = maxz; +} + + +// Use this to get the mesh builder that allows us to modify vertex data +CMeshBuilder *CShaderAPIDx11::GetVertexModifyBuilder() +{ + return &m_ModifyBuilder; +} + +// Board-independent calls, here to unify how shaders set state +// Implementations should chain back to IShaderUtil->BindTexture(), etc. + +void CShaderAPIDx11::CopyRenderTargetToScratchTexture(ShaderAPITextureHandle_t srcRt, ShaderAPITextureHandle_t dstTex, Rect_t* pSrcRect, Rect_t* pDstRect) +{ +} + +//------------------------------------------------------------------------- +// Allows locking and unlocking of very specific surface types. pOutBits and pOutPitch will not be touched if +// the lock fails. +//------------------------------------------------------------------------- +void CShaderAPIDx11::LockRect(void** pOutBits, int* pOutPitch, ShaderAPITextureHandle_t texHandle, int mipmap, int x, int y, int w, int h, bool bWrite, bool bRead) +{ +} + +void CShaderAPIDx11::UnlockRect(ShaderAPITextureHandle_t texHandle, int mipmap) +{ +} + +// Use this to begin and end the frame +void CShaderAPIDx11::BeginFrame() +{ +} + +void CShaderAPIDx11::EndFrame() +{ +} + +// returns the current time in seconds.... +double CShaderAPIDx11::CurrentTime() const +{ + return Sys_FloatTime(); +} + +void CShaderAPIDx11::ForceHardwareSync( void ) +{ +} + +void CShaderAPIDx11::SetClipPlane( int index, const float *pPlane ) +{ +} + +void CShaderAPIDx11::EnableClipPlane( int index, bool bEnable ) +{ +} + +void CShaderAPIDx11::SetFastClipPlane( const float *pPlane ) +{ +} + +void CShaderAPIDx11::EnableFastClip( bool bEnable ) +{ +} + +int CShaderAPIDx11::GetCurrentNumBones( void ) const +{ + return m_ShaderState.bone.m_NumBones; +} + +// Is hardware morphing enabled? +bool CShaderAPIDx11::IsHWMorphingEnabled() const +{ + return false; +} + +int CShaderAPIDx11::MapLightComboToPSLightCombo( int nLightCombo ) const +{ + return 0; +} + +void CShaderAPIDx11::RecordString( const char *pStr ) +{ +} + +void CShaderAPIDx11::DestroyVertexBuffers( bool bExitingLevel ) +{ + LOCK_SHADERAPI(); + MeshMgr()->DestroyVertexBuffers(); + // After a map is shut down, we switch to using smaller dynamic VBs + // (VGUI shouldn't need much), so that we have more memory free during map loading + m_nDynamicVBSize = bExitingLevel ? DYNAMIC_VERTEX_BUFFER_MEMORY_SMALL : DYNAMIC_VERTEX_BUFFER_MEMORY; +} + +int CShaderAPIDx11::GetCurrentDynamicVBSize( void ) +{ + return m_nDynamicVBSize; +} + +void CShaderAPIDx11::EvictManagedResources() +{ +} + +void CShaderAPIDx11::ReleaseShaderObjects() +{ +} + +void CShaderAPIDx11::RestoreShaderObjects() +{ +} + +void CShaderAPIDx11::SyncToken( const char *pToken ) +{ +} + +// Rendering parameters + +void CShaderAPIDx11::SetFloatRenderingParameter( int parm_number, float value ) +{ + LOCK_SHADERAPI(); + if ( parm_number < ARRAYSIZE( FloatRenderingParameters ) ) + FloatRenderingParameters[parm_number] = value; +} + +void CShaderAPIDx11::SetIntRenderingParameter( int parm_number, int value ) +{ + LOCK_SHADERAPI(); + if ( parm_number < ARRAYSIZE( IntRenderingParameters ) ) + IntRenderingParameters[parm_number] = value; +} + +void CShaderAPIDx11::SetVectorRenderingParameter( int parm_number, Vector const &value ) +{ + LOCK_SHADERAPI(); + if ( parm_number < ARRAYSIZE( VectorRenderingParameters ) ) + VectorRenderingParameters[parm_number] = value; +} + +float CShaderAPIDx11::GetFloatRenderingParameter( int parm_number ) const +{ + LOCK_SHADERAPI(); + if ( parm_number < ARRAYSIZE( FloatRenderingParameters ) ) + return FloatRenderingParameters[parm_number]; + else + return 0.0; +} + +int CShaderAPIDx11::GetIntRenderingParameter( int parm_number ) const +{ + LOCK_SHADERAPI(); + if ( parm_number < ARRAYSIZE( IntRenderingParameters ) ) + return IntRenderingParameters[parm_number]; + else + return 0; +} + +Vector CShaderAPIDx11::GetVectorRenderingParameter( int parm_number ) const +{ + LOCK_SHADERAPI(); + if ( parm_number < ARRAYSIZE( VectorRenderingParameters ) ) + return VectorRenderingParameters[parm_number]; + else + return Vector( 0, 0, 0 ); +} + +// Stencils + +void CShaderAPIDx11::SetStencilEnable( bool onoff ) +{ + //m_TargetState.shadow.depthStencil.StencilEnable = onoff; +} + +void CShaderAPIDx11::SetStencilFailOperation( StencilOperation_t op ) +{ + //m_TargetState.shadow.depthStencil.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)op; +} + +void CShaderAPIDx11::SetStencilZFailOperation( StencilOperation_t op ) +{ + //m_TargetState.shadow.depthStencil.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)op; +} + +void CShaderAPIDx11::SetStencilPassOperation( StencilOperation_t op ) +{ + //m_TargetState.shadow.depthStencil.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)op; +} + +void CShaderAPIDx11::SetStencilCompareFunction( StencilComparisonFunction_t cmpfn ) +{ + //m_TargetState.shadow.depthStencil.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)cmpfn; +} + +void CShaderAPIDx11::SetStencilReferenceValue( int ref ) +{ + //m_TargetState.shadow.depthStencil.StencilRef = ref; +} + +void CShaderAPIDx11::SetStencilTestMask( uint32 msk ) +{ + //m_TargetState.shadow.depthStencil.StencilReadMask = msk; +} + +void CShaderAPIDx11::SetStencilWriteMask( uint32 msk ) +{ + //m_TargetState.shadow.depthStencil.StencilWriteMask = msk; +} + +int CShaderAPIDx11::CompareSnapshots( StateSnapshot_t snapshot0, StateSnapshot_t snapshot1 ) +{ + LOCK_SHADERAPI(); + + const StatesDx11::ShadowState *shadow0 = g_pShaderShadowDx11->GetShadowState( snapshot0 ); + const StatesDx11::ShadowState *shadow1 = g_pShaderShadowDx11->GetShadowState( snapshot1 ); + + if ( shadow0 == shadow1 ) + return 0; + return shadow0 > shadow1 ? -1 : 1; +} + +IDirect3DBaseTexture *CShaderAPIDx11::GetD3DTexture( ShaderAPITextureHandle_t handle ) +{ + if ( handle == INVALID_SHADERAPI_TEXTURE_HANDLE ) + return NULL; + + CTextureDx11 &tex = GetTexture( handle ); + if ( tex.m_NumCopies == 1 ) + return tex.GetTexture(); + else + return tex.GetTexture( tex.m_CurrentCopy ); +} + +bool CShaderAPIDx11::SetMode( void *hwnd, int nAdapter, const ShaderDeviceInfo_t &mode ) +{ + return g_pShaderDeviceMgr->SetMode( hwnd, nAdapter, mode ) != NULL; +} + + +//-------------------------------------------------------------------- +// Occlusion queries +//-------------------------------------------------------------------- + +ShaderAPIOcclusionQuery_t CShaderAPIDx11::CreateOcclusionQueryObject( void ) +{ + return g_pShaderDeviceDx11->CreateOcclusionQuery(); +} + +void CShaderAPIDx11::DestroyOcclusionQueryObject( ShaderAPIOcclusionQuery_t handle ) +{ + g_pShaderDeviceDx11->DestroyOcclusionQuery( handle ); +} + +void CShaderAPIDx11::BeginOcclusionQueryDrawing( ShaderAPIOcclusionQuery_t handle ) +{ + if ( handle != INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE ) + { + D3D11DeviceContext()->Begin( (ID3D11Query *)handle ); + } +} + +void CShaderAPIDx11::EndOcclusionQueryDrawing( ShaderAPIOcclusionQuery_t handle ) +{ + if ( handle != INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE ) + { + D3D11DeviceContext()->End( (ID3D11Query *)handle ); + } +} + +int CShaderAPIDx11::OcclusionQuery_GetNumPixelsRendered( ShaderAPIOcclusionQuery_t handle, bool bFlush ) +{ + if ( handle == INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE ) + { + return OCCLUSION_QUERY_RESULT_ERROR; + } + + uint64 nPixels; + HRESULT hr = D3D11DeviceContext()->GetData( (ID3D11Query *)handle, &nPixels, sizeof( uint64 ), + bFlush ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH ); + if ( FAILED( hr ) ) + { + return OCCLUSION_QUERY_RESULT_ERROR; + } + + if ( hr == S_FALSE ) // not ready yet + { + return OCCLUSION_QUERY_RESULT_PENDING; + } + + return (int)nPixels; +} + +void CShaderAPIDx11::BindStandardTexture( Sampler_t stage, StandardTextureId_t id ) +{ + ShaderUtil()->BindStandardTexture( stage, id ); +} + +void CShaderAPIDx11::BindVertexTexture( VertexTextureSampler_t stage, ShaderAPITextureHandle_t hTexture ) +{ + CTextureDx11 *pTex = &GetTexture( hTexture ); + + if ( !pTex ) + return; + + StatesDx11::DynamicState &dynamic = m_DynamicState; + + ID3D11ShaderResourceView *pView = pTex->GetView(); + ID3D11SamplerState *pSampler = pTex->GetSamplerState(); + + if ( pView != dynamic.m_ppVertexTextures[stage] ) + { + dynamic.m_ppVertexTextures[stage] = pView; + SetStateFlag( STATE_CHANGED_VERTEXTEXTURES ); + } + + if ( pSampler != dynamic.m_ppVertexSamplers[stage] ) + { + dynamic.m_ppVertexSamplers[stage] = pSampler; + SetStateFlag( STATE_CHANGED_VERTEXSAMPLERS ); + } + + if ( stage > dynamic.m_MaxVSSampler ) + { + dynamic.m_MaxVSSampler = stage; + if ( dynamic.m_MaxVSSampler > dynamic.m_PrevMaxVSSampler ) + { + SetStateFlag( STATE_CHANGED_VERTEXSAMPLERS | STATE_CHANGED_VERTEXTEXTURES ); + } + } +} + +void CShaderAPIDx11::SetFlexWeights( int nFirstWeight, int nCount, const MorphWeight_t *pWeights ) +{ + LOCK_SHADERAPI(); + + //m_ShaderState.morph.m_nFirstWeight = nFirstWeight; + //m_ShaderState.morph.m_nCount = nCount; + //int numLoaded = nFirstWeight + nCount; + //if ( numLoaded > m_ShaderState.morph.m_nMaxWeightLoaded ) + //{ + // m_ShaderState.morph.m_nMaxWeightLoaded = numLoaded; + //} + //memcpy( m_ShaderState.morph.m_pWeights + nFirstWeight, pWeights, sizeof( MorphWeight_t ) * nCount ); + //m_ShaderState.morph.m_bMorphChanged = true; +} + +void CShaderAPIDx11::SetToneMappingScaleLinear( const Vector &scale ) +{ + // Flush buffered primitives before changing the tone map scalar! + FlushBufferedPrimitives(); + + Vector4D old = m_ShaderState.m_ToneMappingScale; + + Vector scale_to_use = scale; + m_ShaderState.m_ToneMappingScale.AsVector3D() = scale_to_use; + + bool mode_uses_srgb = false; + + switch ( HardwareConfig()->GetHDRType() ) + { + case HDR_TYPE_NONE: + m_ShaderState.m_ToneMappingScale.x = 1.0; // output scale + m_ShaderState.m_ToneMappingScale.z = 1.0; // reflection map scale + break; + + case HDR_TYPE_FLOAT: + m_ShaderState.m_ToneMappingScale.x = scale_to_use.x; // output scale + m_ShaderState.m_ToneMappingScale.z = 1.0; // reflection map scale + break; + + case HDR_TYPE_INTEGER: + mode_uses_srgb = true; + m_ShaderState.m_ToneMappingScale.x = scale_to_use.x; // output scale + m_ShaderState.m_ToneMappingScale.z = 16.0; // reflection map scale + break; + } + + m_ShaderState.m_ToneMappingScale.y = GetLightMapScaleFactor(); // light map scale + + // w component gets gamma scale + m_ShaderState.m_ToneMappingScale.w = LinearToGammaFullRange( m_ShaderState.m_ToneMappingScale.x ); + + if ( old != m_ShaderState.m_ToneMappingScale ) + { + m_ShaderState.m_bToneMappingScaleChanged = true; + } +} + +void CShaderAPIDx11::BindStandardVertexTexture( VertexTextureSampler_t stage, StandardTextureId_t id ) +{ + ShaderUtil()->BindStandardVertexTexture( stage, id ); +} + +template FORCEINLINE T GetData( uint8 const *pData ) +{ + return *( reinterpret_cast( pData ) ); +} + +void CShaderAPIDx11::ExecuteCommandBuffer( uint8 *pCmdBuf ) +{ + uint8 *pReturnStack[20]; + uint8 **pSP = &pReturnStack[ARRAYSIZE( pReturnStack )]; + uint8 *pLastCmd; + for ( ;;) + { + uint8 *pCmd = pCmdBuf; + int nCmd = GetData( pCmdBuf ); + switch ( nCmd ) + { + case CBCMD_END: + { + if ( pSP == &pReturnStack[ARRAYSIZE( pReturnStack )] ) + return; + else + { + // pop pc + pCmdBuf = *( pSP++ ); + break; + } + } + + case CBCMD_JUMP: + pCmdBuf = GetData( pCmdBuf + sizeof( int ) ); + break; + + case CBCMD_JSR: + { + Assert( pSP > &( pReturnStack[0] ) ); + ExecuteCommandBuffer( GetData( pCmdBuf + sizeof( int ) ) ); + pCmdBuf = pCmdBuf + sizeof( int ) + sizeof( uint8 * ); + break; + } + case CBCMD_BIND_STANDARD_TEXTURE: + { + int nSampler = GetData( pCmdBuf + sizeof( int ) ); + int nTextureID = GetData( pCmdBuf + 2 * sizeof( int ) ); + pCmdBuf += 3 * sizeof( int ); + ShaderUtil()->BindStandardTexture( (Sampler_t)nSampler, (StandardTextureId_t)nTextureID ); + break; + } + + case CBCMD_BIND_SHADERAPI_TEXTURE_HANDLE: + { + int nSampler = GetData( pCmdBuf + sizeof( int ) ); + ShaderAPITextureHandle_t hTexture = GetData( pCmdBuf + 2 * sizeof( int ) ); + Assert( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE ); + pCmdBuf += 2 * sizeof( int ) + sizeof( ShaderAPITextureHandle_t ); + BindTexture( (Sampler_t)nSampler, hTexture ); + break; + } + + case CBCMD_SET_PSHINDEX: + { + int nIdx = GetData( pCmdBuf + sizeof( int ) ); + SetPixelShaderIndex( nIdx ); + pCmdBuf += 2 * sizeof( int ); + break; + } + + case CBCMD_SET_VSHINDEX: + { + int nIdx = GetData( pCmdBuf + sizeof( int ) ); + SetVertexShaderIndex( nIdx ); + pCmdBuf += 2 * sizeof( int ); + break; + } +#ifndef NDEBUG + default: + { + Assert( 0 ); + } +#endif + } + pLastCmd = pCmd; + } +} + +bool CShaderAPIDx11::ShouldWriteDepthToDestAlpha() const +{ + return IsPC() && g_pHardwareConfig->SupportsPixelShaders_2_b() && + ( m_ShaderState.fog.m_FogMode != MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) && + ( GetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA ) != 0 ); +} + +void CShaderAPIDx11::ClearVertexAndPixelShaderRefCounts() +{ + LOCK_SHADERAPI(); + ShaderManager()->ClearVertexAndPixelShaderRefCounts(); +} + +void CShaderAPIDx11::PurgeUnusedVertexAndPixelShaders() +{ + LOCK_SHADERAPI(); + ShaderManager()->PurgeUnusedVertexAndPixelShaders(); +} + +void CShaderAPIDx11::SetFlashlightState( const FlashlightState_t &state, const VMatrix &worldToTexture ) +{ + LOCK_SHADERAPI(); + SetFlashlightStateEx( state, worldToTexture, NULL ); +} + +void CShaderAPIDx11::SetFlashlightStateEx( const FlashlightState_t &state, const VMatrix &worldToTexture, ITexture *pFlashlightDepthTexture ) +{ + LOCK_SHADERAPI(); + + bool bFlushed = false; + if ( memcmp( &state, &m_FlashlightState, sizeof( FlashlightState_t ) ) ) + { + FlushBufferedPrimitives(); + bFlushed = true; + + m_FlashlightState = state; + m_bFlashlightStateChanged = true; + } + if ( worldToTexture != m_FlashlightWorldToTexture ) + { + if ( !bFlushed ) + { + FlushBufferedPrimitives(); + bFlushed = true; + } + m_FlashlightWorldToTexture = worldToTexture; + m_bFlashlightStateChanged = true; + } + if ( pFlashlightDepthTexture != m_pFlashlightDepthTexture ) + { + if ( !bFlushed ) + { + FlushBufferedPrimitives(); + bFlushed = true; + } + m_pFlashlightDepthTexture = pFlashlightDepthTexture; + m_bFlashlightStateChanged = true; + } +} + +const FlashlightState_t &CShaderAPIDx11::GetFlashlightState( VMatrix &worldToTexture ) const +{ + worldToTexture = m_FlashlightWorldToTexture; + return m_FlashlightState; +} + +const FlashlightState_t &CShaderAPIDx11::GetFlashlightStateEx( VMatrix &worldToTexture, ITexture **pFlashlightDepthTexture ) const +{ + worldToTexture = m_FlashlightWorldToTexture; + *pFlashlightDepthTexture = m_pFlashlightDepthTexture; + return m_FlashlightState; +} + +#define MAX_LIGHTS 4 + +void CShaderAPIDx11::GetDX9LightState( LightState_t *state ) const +{ + // hack . . do this a cheaper way. + if ( m_ShaderState.light.m_AmbientLightCube[0][0] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[0][1] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[0][2] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[1][0] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[1][1] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[1][2] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[2][0] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[2][1] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[2][2] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[3][0] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[3][1] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[3][2] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[4][0] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[4][1] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[4][2] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[5][0] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[5][1] == 0.0f && + m_ShaderState.light.m_AmbientLightCube[5][2] == 0.0f ) + { + state->m_bAmbientLight = false; + } + else + { + state->m_bAmbientLight = true; + } + + Assert( m_pMesh ); + Assert( m_ShaderState.light.m_NumLights <= 4 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + Assert( m_ShaderState.light.m_NumLights <= MAX_LIGHTS ); // 2b hardware gets four lights + } + else + { + Assert( m_ShaderState.light.m_NumLights <= ( MAX_LIGHTS - 2 ) ); // 2.0 hardware gets two less + } + + state->m_nNumLights = m_ShaderState.light.m_NumLights; + state->m_bStaticLightVertex = m_pMesh->HasColorMesh(); + state->m_bStaticLightTexel = false; // For now +} + + +void CShaderAPIDx11::CopyRenderTargetToTextureEx( ShaderAPITextureHandle_t textureHandle, int nRenderTargetID, Rect_t *pSrcRect, Rect_t *pDstRect ) +{ + // don't use this + return; + + // LOCK_SHADERAPI(); + //VPROF_BUDGET( "CShaderAPIDx11::CopyRenderTargetToTexture", "Refraction overhead" ); + + /*if ( !TextureIsAllocated( textureHandle ) ) + return; + + CTextureDx11 *pTexture = &GetTexture( textureHandle ); + Assert( pTexture ); + ID3D11Resource *pD3DTexture = pTexture->GetTexture(); + Assert( pD3DTexture ); + + ITexture *rt = g_pShaderUtil->GetRenderTargetEx( nRenderTargetID ); + + CTextureDx11 *pTextureRT; + if ( rt == NULL ) + { + pTextureRT = &GetTexture( 0 ); // copy back buffer + } + else + { + ITextureInternal* texInt = static_cast(rt); + ShaderAPITextureHandle_t texHandle = texInt->GetTextureHandle( 0 ); + pTextureRT = &GetTexture( texHandle ); + } + + ID3D11Resource *pD3DTextureRT = pTextureRT->GetTexture(); + Assert( pD3DTextureRT );*/ + + // need to draw a quad with the texture and downscale it +} + +void CShaderAPIDx11::CopyTextureToRenderTargetEx(int nRenderTargetID, ShaderAPITextureHandle_t textureHandle, Rect_t* pSrcRect, Rect_t* pDstRect) +{ + // don't use this + return; + + // LOCK_SHADERAPI(); + //VPROF_BUDGET( "CShaderAPIDx11::CopyRenderTargetToTexture", "Refraction overhead" ); + + /*if (!TextureIsAllocated(textureHandle)) + return; + + CTextureDx11* pTexture = &GetTexture(textureHandle); + Assert(pTexture); + ID3D11Resource* pD3DTexture = pTexture->GetTexture(); + Assert(pD3DTexture); + + ITexture* rt = g_pShaderUtil->GetRenderTargetEx(nRenderTargetID); + + CTextureDx11* pTextureRT; + if (rt == NULL) + { + pTextureRT = &GetTexture(0); // copy back buffer + } + else + { + ITextureInternal* texInt = static_cast(rt); + ShaderAPITextureHandle_t texHandle = texInt->GetTextureHandle(0); + pTextureRT = &GetTexture(texHandle); + } + + ID3D11Resource* pD3DTextureRT = pTextureRT->GetTexture(); + Assert(pD3DTextureRT);*/ + + // need to draw a quad with the texture and downscale it +} + +//------------------------------------------------------------------------------------ +// UNUSED/UNSUPPORTED FUNCTIONS!!! +//------------------------------------------------------------------------------------ + +// Lightmap texture binding +void CShaderAPIDx11::BindLightmap( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindBumpLightmap( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindFullbrightLightmap( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindWhite( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindBlack( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindGrey( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::SetTextureTransformDimension( TextureStage_t textureStage, int dimension, bool projected ) +{ + //Warning( "Unsupported CShaderAPIDx11::SetTextureTransformDimension() called!\n" ); +} + +void CShaderAPIDx11::SetBumpEnvMatrix( TextureStage_t textureStage, float m00, float m01, float m10, float m11 ) +{ + //Warning( "Unsupported CShaderAPIDx11::SetBumpEnvMatrix() called!\n" ); +} + +void CShaderAPIDx11::SetAmbientLight( float r, float g, float b ) +{ + //Warning( "Unsupported CShaderAPIDx11::SetAmbientLight() called!\n" ); +} + +//----------------------------------------------------------------------------- +// Methods related to state objects +//----------------------------------------------------------------------------- +void CShaderAPIDx11::SetRasterState( const ShaderRasterState_t &state ) +{ + //Warning( "Unsupported CShaderAPIDx11::SetRasterState() called!\n" ); +} + +// The shade mode +void CShaderAPIDx11::ShadeMode( ShaderShadeMode_t mode ) +{ + //Warning( "Unsupported CShaderAPIDx11::ShadeMode() called!\n" ); +} + +void CShaderAPIDx11::TexSetPriority( int priority ) +{ + //Warning( "Unsupported CShaderAPIDx11::SetTexPriority() called!\n" ); +} + +// Sets the constant register for vertex and pixel shaders +void CShaderAPIDx11::SetVertexShaderConstant( int var, float const *pVec, int numConst, bool bForce ) +{ +} + +void CShaderAPIDx11::SetPixelShaderConstant( int var, float const *pVec, int numConst, bool bForce ) +{ +} + +void CShaderAPIDx11::SetPixelShaderFogParams( int psReg ) +{ +} + +bool CShaderAPIDx11::InFlashlightMode() const +{ + return ShaderUtil()->InFlashlightMode(); +} + +bool CShaderAPIDx11::InEditorMode() const +{ + return ShaderUtil()->InEditorMode(); +} + +void CShaderAPIDx11::InvalidateDelayedShaderConstants( void ) +{ + //Warning( "Unsupported CShaderAPIDx11::InvalidateDelayedShaderConstants() called!\n" ); +} + +//Set's the linear->gamma conversion textures to use for this hardware for both srgb writes enabled and disabled(identity) +void CShaderAPIDx11::SetLinearToGammaConversionTextures( ShaderAPITextureHandle_t hSRGBWriteEnabledTexture, ShaderAPITextureHandle_t hIdentityTexture ) +{ + //Warning( "Unsupported CShaderAPIDx11::SetLinearToGammaConversionTextures() called!\n" ); +} + +// Special system flat normal map binding. +void CShaderAPIDx11::BindFlatNormalMap( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindNormalizationCubeMap( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindSignedNormalizationCubeMap( TextureStage_t stage ) +{ + // Unused +} + +void CShaderAPIDx11::BindFBTexture( TextureStage_t stage, int textureIndex ) +{ + // Unused +} + +// Render state for the ambient light cube (vertex shaders) +void CShaderAPIDx11::SetVertexShaderStateAmbientLightCube() +{ + //Warning( "Unsupported CShaderAPIDx11::SetVertexShaderStateAmbientLightCube() called!\n" ); +} \ No newline at end of file diff --git a/materialsystem/shaderapidx11/shaderapidx11.h b/materialsystem/shaderapidx11/shaderapidx11.h new file mode 100644 index 0000000..3473b65 --- /dev/null +++ b/materialsystem/shaderapidx11/shaderapidx11.h @@ -0,0 +1,964 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef SHADERAPIDX11_H +#define SHADERAPIDX11_H + +#ifdef _WIN32 +#pragma once +#endif + +#include + +#include "renderparm.h" +#include "shaderapidx9/shaderapibase.h" +#include "shaderapi/ishadershadow.h" +#include "materialsystem/idebugtextureinfo.h" +#include "shaderapidx9/hardwareconfig.h" +#include "imaterialinternal.h" +#include "shaderapidx9/meshbase.h" +#include "ShaderConstantBufferDx11.h" +#include "utllinkedlist.h" +#include "StatesDx11.h" +#include "TextureDx11.h" +#include "meshdx11.h" +#include "materialsystem/imesh.h" +#include "utlstack.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +struct MaterialSystemHardwareIdentifier_t; + +//----------------------------------------------------------------------------- +// The Dx11 implementation of the shader API +//----------------------------------------------------------------------------- +class CShaderAPIDx11 : public CShaderAPIBase, public IDebugTextureInfo +{ + typedef CShaderAPIBase BaseClass; + +public: + // constructor, destructor + CShaderAPIDx11(); + virtual ~CShaderAPIDx11(); + + // Methods of IShaderAPI + // NOTE: These methods have been ported over +public: + virtual void SetViewports( int nCount, const ShaderViewport_t *pViewports ); + virtual int GetViewports( ShaderViewport_t *pViewports, int nMax ) const; + virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil, int renderTargetWidth, int renderTargetHeight ); + virtual void ClearColor3ub( unsigned char r, unsigned char g, unsigned char b ); + virtual void ClearColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + virtual void SetRasterState( const ShaderRasterState_t &state ); + virtual void BindVertexShader( VertexShaderHandle_t hVertexShader ); + virtual void BindGeometryShader( GeometryShaderHandle_t hGeometryShader ); + virtual void BindPixelShader( PixelShaderHandle_t hPixelShader ); + virtual void BindVertexBuffer( int nStreamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, + int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 ); + void SetUsingExtraVertexBuffers( bool bStaticLit, bool bUsingFlex, bool bUsingMorph ); + virtual void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ); + virtual void Draw( MaterialPrimitiveType_t primitiveType, int nFirstIndex, int nIndexCount ); + void DrawIndexed( int nFirstIndex, int nIndexCount, int nBaseVertexLocation ); + void DrawNotIndexed( int nFirstVertex, int nVertCount ); + void DrawMesh( IMesh *pMesh ); + + virtual void UpdateConstantBuffer( ConstantBufferHandle_t cbuffer, void *pNewData ); + virtual ConstantBufferHandle_t GetInternalConstantBuffer( int type ); + + FORCEINLINE bool TextureIsAllocated( ShaderAPITextureHandle_t hTexture ) + { + return m_Textures.IsValidIndex( hTexture ) && ( GetTexture( hTexture ).m_nFlags & CTextureDx11::IS_ALLOCATED ); + } + + // Methods of IShaderDynamicAPI +public: + virtual void GetBackBufferDimensions( int &nWidth, int &nHeight ) const; + +public: + // Methods of CShaderAPIBase + virtual bool OnDeviceInit(); + virtual void OnDeviceShutdown(); + virtual void ReleaseShaderObjects(); + virtual void RestoreShaderObjects(); + virtual void BeginPIXEvent( unsigned long color, const char *szName ) + { + } + virtual void EndPIXEvent() + { + } + virtual void AdvancePIXFrame() + { + } + + // NOTE: These methods have not been ported over. + // IDebugTextureInfo implementation. +public: + virtual bool IsDebugTextureListFresh( int numFramesAllowed = 1 ) + { + return false; + } + virtual void EnableDebugTextureList( bool bEnable ) + { + } + virtual void EnableGetAllTextures( bool bEnable ) + { + } + virtual KeyValues *GetDebugTextureList() + { + return NULL; + } + virtual int GetTextureMemoryUsed( TextureMemoryType eTextureMemory ) + { + return 0; + } + virtual bool SetDebugTextureRendering( bool bEnable ) + { + return false; + } + +public: + // Other public methods + void Unbind( VertexShaderHandle_t hShader ); + void Unbind( GeometryShaderHandle_t hShader ); + void Unbind( PixelShaderHandle_t hShader ); + void UnbindVertexBuffer( ID3D11Buffer *pBuffer ); + void UnbindIndexBuffer( ID3D11Buffer *pBuffer ); + + void SetTopology( MaterialPrimitiveType_t topology ); + + void IssueStateChanges( bool bForce = false ); + IMaterialInternal *GetBoundMaterial() const; + + void GetMatrix( MaterialMatrixMode_t matrixMode, DirectX::XMMATRIX &dst ); + D3D11_CULL_MODE GetCullMode() const; + +private: + // Returns a d3d texture associated with a texture handle + virtual IDirect3DBaseTexture *GetD3DTexture( ShaderAPITextureHandle_t hTexture ); + + virtual void QueueResetRenderState() + { + } + + virtual bool DoRenderTargetsNeedSeparateDepthBuffer() const; + + void SetHardwareGammaRamp( float fGamma ) + { + } + + // Used to clear the transition table when we know it's become invalid. + void ClearSnapshots(); + + // Sets the mode... + bool SetMode( void *hwnd, int nAdapter, const ShaderDeviceInfo_t &info ); + + void ChangeVideoMode( const ShaderDeviceInfo_t &info ) + { + } + + // Called when the dx support level has changed + virtual void DXSupportLevelChanged() + { + } + + virtual void EnableUserClipTransformOverride( bool bEnable ) + { + } + virtual void UserClipTransform( const VMatrix &worldToView ) + { + } + virtual bool GetUserClipTransform( VMatrix &worldToView ) + { + return false; + } + + // Sets the default *dynamic* state + void SetDefaultState(); + + // Returns the snapshot id for the shader state + StateSnapshot_t TakeSnapshot(); + + // Returns true if the state snapshot is transparent + bool IsTranslucent( StateSnapshot_t id ) const; + bool IsAlphaTested( StateSnapshot_t id ) const; + bool UsesVertexAndPixelShaders( StateSnapshot_t id ) const; + virtual bool IsDepthWriteEnabled( StateSnapshot_t id ) const; + + // Gets the vertex format for a set of snapshot ids + VertexFormat_t ComputeVertexFormat( int numSnapshots, StateSnapshot_t *pIds ) const; + + // Gets the vertex format for a set of snapshot ids + VertexFormat_t ComputeVertexUsage( int numSnapshots, StateSnapshot_t *pIds ) const; + + // Begins a rendering pass that uses a state snapshot + void BeginPass( StateSnapshot_t snapshot ); + + // Uses a state snapshot + void UseSnapshot( StateSnapshot_t snapshot ); + + // Use this to get the mesh builder that allows us to modify vertex data + CMeshBuilder *GetVertexModifyBuilder(); + + // Sets the color to modulate by + void Color3f( float r, float g, float b ); + void Color3fv( float const *pColor ); + void Color4f( float r, float g, float b, float a ); + void Color4fv( float const *pColor ); + + // Faster versions of color + void Color3ub( unsigned char r, unsigned char g, unsigned char b ); + void Color3ubv( unsigned char const *rgb ); + void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Color4ubv( unsigned char const *rgba ); + + // Sets the lights + void SetLight( int lightNum, const LightDesc_t &desc ); + void SetAmbientLight( float r, float g, float b ); + void SetAmbientLightCube( Vector4D cube[6] ); + virtual void DisableAllLocalLights(); + virtual void SetLightingOrigin( Vector vLightingOrigin ) + { + } + + // Get the lights + int GetMaxLights( void ) const; + const LightDesc_t &GetLight( int lightNum ) const; + + // Render state for the ambient light cube (vertex shaders) + void SetVertexShaderStateAmbientLightCube(); + virtual void SetPixelShaderStateAmbientLightCube( int pshReg, bool bForceToBlack = false ) + { + } + void SetPixelShaderStateAmbientLightCube( int pshReg ) + { + } + virtual void GetDX9LightState( LightState_t *state ) const; + + float GetAmbientLightCubeLuminance( void ); + + void SetSkinningMatrices(); + + + // Lightmap texture binding + void BindLightmap( TextureStage_t stage ); + void BindLightmapAlpha( TextureStage_t stage ) + { + } + void BindBumpLightmap( TextureStage_t stage ); + void BindFullbrightLightmap( TextureStage_t stage ); + void BindWhite( TextureStage_t stage ); + void BindBlack( TextureStage_t stage ); + void BindGrey( TextureStage_t stage ); + void BindFBTexture( TextureStage_t stage, int textureIdex ); + void CopyRenderTargetToTexture( ShaderAPITextureHandle_t textureHandle ) + { + CopyRenderTargetToTextureEx( textureHandle, 0, NULL, NULL ); + } + + void CopyRenderTargetToTextureEx( ShaderAPITextureHandle_t textureHandle, int nRenderTargetID, Rect_t *pSrcRect, Rect_t *pDstRect ); + void CopyTextureToRenderTargetEx(int nRenderTargetID, ShaderAPITextureHandle_t textureHandle, Rect_t* pSrcRect = NULL, Rect_t* pDstRect = NULL); + + // Special system flat normal map binding. + void BindFlatNormalMap( TextureStage_t stage ); + void BindNormalizationCubeMap( TextureStage_t stage ); + void BindSignedNormalizationCubeMap( TextureStage_t stage ); + + // Set the number of bone weights + void SetNumBoneWeights( int numBones ); + + // Flushes any primitives that are buffered + void FlushBufferedPrimitives(); + + // Creates/destroys Mesh + IMesh *CreateStaticMesh( VertexFormat_t fmt, const char *pTextureBudgetGroup, IMaterial *pMaterial = NULL ); + void DestroyStaticMesh( IMesh *mesh ); + + // Gets the dynamic mesh; note that you've got to render the mesh + // before calling this function a second time. Clients should *not* + // call DestroyStaticMesh on the mesh returned by this call. + IMesh *GetDynamicMesh( IMaterial *pMaterial, int nHWSkinBoneCount, bool buffered, IMesh *pVertexOverride, IMesh *pIndexOverride ); + IMesh *GetDynamicMeshEx( IMaterial *pMaterial, VertexFormat_t fmt, int nHWSkinBoneCount, bool buffered, IMesh *pVertexOverride, IMesh *pIndexOverride ); + IVertexBuffer *GetDynamicVertexBuffer( IMaterial *pMaterial, bool buffered ); + IIndexBuffer *GetDynamicIndexBuffer( IMaterial *pMaterial, bool buffered ); + IMesh *GetFlexMesh(); + + // Renders a single pass of a material + void RenderPass( int nPass, int nPassCount ); + + // stuff related to matrix stacks + void MatrixMode( MaterialMatrixMode_t matrixMode ); + void PushMatrix(); + void PopMatrix(); + void LoadMatrix( float *m ); + void LoadBoneMatrix( int boneIndex, const float *m ); + void MultMatrix( float *m ); + void MultMatrixLocal( float *m ); + void GetMatrix( MaterialMatrixMode_t matrixMode, float *dst ); + void LoadIdentity( void ); + void LoadCameraToWorld( void ); + void Ortho( double left, double top, double right, double bottom, double zNear, double zFar ); + void PerspectiveX( double fovx, double aspect, double zNear, double zFar ); + void PerspectiveOffCenterX( double fovx, double aspect, double zNear, double zFar, double bottom, double top, double left, double right ); + void PickMatrix( int x, int y, int width, int height ); + void Rotate( float angle, float x, float y, float z ); + void Translate( float x, float y, float z ); + void Scale( float x, float y, float z ); + void ScaleXY( float x, float y ); + + // Fog methods... + void FogMode( MaterialFogMode_t fogMode ); + void FogStart( float fStart ); + void FogEnd( float fEnd ); + void SetFogZ( float fogZ ); + void FogMaxDensity( float flMaxDensity ); + void GetFogDistances( float *fStart, float *fEnd, float *fFogZ ); + void FogColor3f( float r, float g, float b ); + void FogColor3fv( float const *rgb ); + void FogColor3ub( unsigned char r, unsigned char g, unsigned char b ); + void FogColor3ubv( unsigned char const *rgb ); + virtual void GetFogColor( float *rgb ); + virtual void GetFogParamsAndColor( float *params, float *rgba ); + + virtual void SceneFogColor3ub( unsigned char r, unsigned char g, unsigned char b ); + virtual void SceneFogMode( MaterialFogMode_t fogMode ); + virtual void GetSceneFogColor( unsigned char *rgb ); + virtual MaterialFogMode_t GetSceneFogMode(); + virtual int GetPixelFogCombo(); + + void SetHeightClipZ( float z ); + void SetHeightClipMode( enum MaterialHeightClipMode_t heightClipMode ); + + void SetClipPlane( int index, const float *pPlane ); + void EnableClipPlane( int index, bool bEnable ); + + void SetFastClipPlane( const float *pPlane ); + void EnableFastClip( bool bEnable ); + + // We use smaller dynamic VBs during level transitions, to free up memory + virtual int GetCurrentDynamicVBSize( void ); + virtual void DestroyVertexBuffers( bool bExitingLevel = false ); + + // Sets the vertex and pixel shaders + void SetVertexShaderIndex( ShaderIndex_t vshIndex ); + void SetPixelShaderIndex( ShaderIndex_t pshIndex ); + + // Sets the constant register for vertex and pixel shaders + void SetVertexShaderConstant( int var, float const *pVec, int numConst = 1, bool bForce = false ); + void SetPixelShaderConstant( int var, float const *pVec, int numConst = 1, bool bForce = false ); + + void SetBooleanVertexShaderConstant( int var, BOOL const *pVec, int numBools = 1, bool bForce = false ) + { + Assert( 0 ); + } + + void SetIntegerVertexShaderConstant( int var, int const *pVec, int numIntVecs = 1, bool bForce = false ) + { + Assert( 0 ); + } + + void SetBooleanPixelShaderConstant( int var, BOOL const *pVec, int numBools = 1, bool bForce = false ) + { + Assert( 0 ); + } + + void SetIntegerPixelShaderConstant( int var, int const *pVec, int numIntVecs = 1, bool bForce = false ) + { + Assert( 0 ); + } + + bool ShouldWriteDepthToDestAlpha( void ) const; + + void InvalidateDelayedShaderConstants( void ); + + // Gamma<->Linear conversions according to the video hardware we're running on + float GammaToLinear_HardwareSpecific( float fGamma ) const + { + return 0.; + } + + float LinearToGamma_HardwareSpecific( float fLinear ) const + { + return 0.; + } + + //Set's the linear->gamma conversion textures to use for this hardware for both srgb writes enabled and disabled(identity) + void SetLinearToGammaConversionTextures( ShaderAPITextureHandle_t hSRGBWriteEnabledTexture, ShaderAPITextureHandle_t hIdentityTexture ); + + // Cull mode + void CullMode( MaterialCullMode_t cullMode ); + + // Force writes only when z matches. . . useful for stenciling things out + // by rendering the desired Z values ahead of time. + void ForceDepthFuncEquals( bool bEnable ); + + // Forces Z buffering on or off + void OverrideDepthEnable( bool bEnable, bool bDepthEnable ); + + // Sets the shade mode + void ShadeMode( ShaderShadeMode_t mode ); + + // Binds a particular material to render with + void Bind( IMaterial *pMaterial ); + + // Returns the nearest supported format + virtual ImageFormat GetNearestSupportedFormat(ImageFormat fmt, bool bFilteringRequired = true) const; + virtual ImageFormat GetNearestRenderTargetFormat(ImageFormat fmt) const; + + // Sets the texture state + void BindTexture( Sampler_t stage, ShaderAPITextureHandle_t textureHandle ); + void UnbindTexture( ShaderAPITextureHandle_t textureHandle ); + + void SetRenderTarget( ShaderAPITextureHandle_t colorTextureHandle, ShaderAPITextureHandle_t depthTextureHandle ) + { + SetRenderTargetEx( 0, colorTextureHandle, depthTextureHandle ); + } + + void SetRenderTargetEx( int nRenderTargetID, ShaderAPITextureHandle_t colorTextureHandle, ShaderAPITextureHandle_t depthTextureHandle ); + + // Indicates we're going to be modifying this texture + // TexImage2D, TexSubImage2D, TexWrap, TexMinFilter, and TexMagFilter + // all use the texture specified by this function. + void ModifyTexture( ShaderAPITextureHandle_t textureHandle ); + + // Texture management methods + void TexImage2D( int level, int cubeFace, ImageFormat dstFormat, int zOffset, int width, int height, + ImageFormat srcFormat, bool bSrcIsTiled, void *imageData ); + void TexSubImage2D( int level, int cubeFace, int xOffset, int yOffset, int zOffset, int width, int height, + ImageFormat srcFormat, int srcStride, bool bSrcIsTiled, void *imageData ); + + virtual void TexImageFromVTF(IVTFTexture* pVTF, int iVTFFrame); + + bool TexLock( int level, int cubeFaceID, int xOffset, int yOffset, + int width, int height, CPixelWriter &writer ); + void TexUnlock(); + + // These are bound to the texture, not the texture environment + void TexMinFilter( ShaderTexFilterMode_t texFilterMode ); + void TexMagFilter( ShaderTexFilterMode_t texFilterMode ); + void TexWrap( ShaderTexCoordComponent_t coord, ShaderTexWrapMode_t wrapMode ); + void TexSetPriority( int priority ); + + ShaderAPITextureHandle_t CreateTexture( + int width, + int height, + int depth, + ImageFormat dstImageFormat, + int numMipLevels, + int numCopies, + int flags, + const char *pDebugName, + const char *pTextureGroupName ); + void CreateTextures( + ShaderAPITextureHandle_t *pHandles, + int count, + int width, + int height, + int depth, + ImageFormat dstImageFormat, + int numMipLevels, + int numCopies, + int flags, + const char *pDebugName, + const char *pTextureGroupName ); + ShaderAPITextureHandle_t CreateDepthTexture( ImageFormat renderFormat, int width, int height, const char *pDebugName, bool bTexture ); + void DeleteTexture( ShaderAPITextureHandle_t textureHandle ); + bool IsTexture( ShaderAPITextureHandle_t textureHandle ); + bool IsTextureResident( ShaderAPITextureHandle_t textureHandle ); + + // stuff that isn't to be used from within a shader + void ClearBuffersObeyStencil(bool bClearColor, bool bClearDepth); + void ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ); + void PerformFullScreenStencilOperation( void ); + void ReadPixels( int x, int y, int width, int height, unsigned char *data, ImageFormat dstFormat ); + virtual void ReadPixels( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *data, ImageFormat dstFormat, int nDstStride ); + + // Selection mode methods + int SelectionMode( bool selectionMode ); + void SelectionBuffer( unsigned int *pBuffer, int size ); + void ClearSelectionNames(); + void LoadSelectionName( int name ); + void PushSelectionName( int name ); + void PopSelectionName(); + void WriteHitRecord(); + bool IsInSelectionMode() const; + void RegisterSelectionHit( float minz, float maxz ); + + void FlushHardware(); + void ResetRenderState( bool bFullReset = true ); + + // Can we download textures? + virtual bool CanDownloadTextures() const; + + bool IsStateSet( unsigned int flag ) const + { + return ( m_StateChangeFlags & flag ) != 0; + } + + void SetStateFlag( unsigned int flag ) + { + m_StateChangeFlags |= flag; + } + + // Allows copying a render target to another texture by specifying them both. + virtual void CopyRenderTargetToScratchTexture(ShaderAPITextureHandle_t srcRt, ShaderAPITextureHandle_t dstTex, Rect_t* pSrcRect = NULL, Rect_t* pDstRect = NULL); + + // Allows locking and unlocking of very specific surface types. + virtual void LockRect(void** pOutBits, int* pOutPitch, ShaderAPITextureHandle_t texHandle, int mipmap, int x, int y, int w, int h, bool bWrite, bool bRead); + virtual void UnlockRect(ShaderAPITextureHandle_t texHandle, int mipmap); + + // Board-independent calls, here to unify how shaders set state + // Implementations should chain back to IShaderUtil->BindTexture(), etc. + + // Use this to begin and end the frame + void BeginFrame(); + void EndFrame(); + + // returns current time + double CurrentTime() const; + + // Get the current camera position in world space. + void GetWorldSpaceCameraPosition( float *pPos ) const; + + void ForceHardwareSync( void ); + + int GetCurrentNumBones( void ) const; + bool IsHWMorphingEnabled() const; + int GetCurrentLightCombo( void ) const; + int MapLightComboToPSLightCombo( int nLightCombo ) const; + MaterialFogMode_t GetCurrentFogType( void ) const; + + void RecordString( const char *pStr ); + + void EvictManagedResources(); + + void SetTextureTransformDimension( TextureStage_t textureStage, int dimension, bool projected ); + void DisableTextureTransform( TextureStage_t textureStage ) + { + } + void SetBumpEnvMatrix( TextureStage_t textureStage, float m00, float m01, float m10, float m11 ); + + // Gets the lightmap dimensions + virtual void GetLightmapDimensions( int *w, int *h ); + + virtual void SyncToken( const char *pToken ); + + // Setup standard vertex shader constants (that don't change) + // This needs to be called anytime that overbright changes. + virtual void SetStandardVertexShaderConstants( float fOverbright ) + { + } + + // Scissor Rect + virtual void SetScissorRect( const int nLeft, const int nTop, const int nRight, const int nBottom, const bool bEnableScissor ) + { + } + + // Reports support for a given CSAA mode + bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ) + { + return false; + } + + // Level of anisotropic filtering + virtual void SetAnisotropicLevel( int nAnisotropyLevel ); + + void SetDefaultDynamicState() + { + m_ShaderState.SetDefault(); + } + virtual void CommitPixelShaderLighting( int pshReg ) + { + } + + virtual void MarkUnusedVertexFields( unsigned int nFlags, int nTexCoordCount, bool *pUnusedTexCoords ) + { + } + + // Occlusion queries + ShaderAPIOcclusionQuery_t CreateOcclusionQueryObject( void ); + void DestroyOcclusionQueryObject( ShaderAPIOcclusionQuery_t handle ); + void BeginOcclusionQueryDrawing( ShaderAPIOcclusionQuery_t handle ); + void EndOcclusionQueryDrawing( ShaderAPIOcclusionQuery_t handle ); + int OcclusionQuery_GetNumPixelsRendered( ShaderAPIOcclusionQuery_t handle, bool bFlush ); + + virtual void AcquireThreadOwnership() + { + } + virtual void ReleaseThreadOwnership() + { + } + + virtual bool SupportsNormalMapCompression() const + { + return false; + } + virtual bool SupportsBorderColor() const + { + return false; + } + virtual bool SupportsFetch4() const + { + return true; + } + virtual void EnableBuffer2FramesAhead( bool bEnable ) + { + } + + virtual void SetDepthFeatheringPixelShaderConstant( int iConstant, float fDepthBlendScale ) + { + } + + + // debug logging + // only implemented in some subclasses + virtual void PrintfVA(char* fmt, va_list vargs) {}; + virtual void Printf(PRINTF_FORMAT_STRING const char* fmt, ...) {}; + virtual float Knob(char* knobname, float* setvalue = NULL) {return 0.0f;}; + // Allows us to override the alpha write setting of a material + virtual void OverrideAlphaWriteEnable(bool bEnable, bool bAlphaWriteEnable); + virtual void OverrideColorWriteEnable(bool bOverrideEnable, bool bColorWriteEnable); + + void SetPixelShaderFogParams( int reg ); + + virtual bool InFlashlightMode() const; + virtual bool InEditorMode() const; + + // What fields in the morph do we actually use? + virtual MorphFormat_t ComputeMorphFormat( int numSnapshots, StateSnapshot_t *pIds ) const; + + // Gets the bound morph's vertex format; returns 0 if no morph is bound + virtual MorphFormat_t GetBoundMorphFormat(); + + void GetStandardTextureDimensions( int *pWidth, int *pHeight, StandardTextureId_t id ); + + // Binds a standard texture + virtual void BindStandardTexture( Sampler_t stage, StandardTextureId_t id ); + virtual void BindStandardVertexTexture( VertexTextureSampler_t stage, StandardTextureId_t id ); + + virtual void SetFlashlightState( const FlashlightState_t &state, const VMatrix &worldToTexture ); + virtual void SetFlashlightStateEx( const FlashlightState_t &state, const VMatrix &worldToTexture, ITexture *pFlashlightDepthTexture ); + virtual const FlashlightState_t &GetFlashlightState( VMatrix &worldToTexture ) const; + virtual const FlashlightState_t &GetFlashlightStateEx( VMatrix &worldToTexture, ITexture **pFlashlightDepthTexture ) const; + + virtual void SetModeChangeCallback( ModeChangeCallbackFunc_t func ) + { + } + + virtual void ClearVertexAndPixelShaderRefCounts(); + virtual void PurgeUnusedVertexAndPixelShaders(); + + // Binds a vertex texture to a particular texture stage in the vertex pipe + virtual void BindVertexTexture( VertexTextureSampler_t nStage, ShaderAPITextureHandle_t hTexture ); + + // Sets morph target factors + virtual void SetFlexWeights( int nFirstWeight, int nCount, const MorphWeight_t *pWeights ); + + // NOTE: Stuff after this is added after shipping HL2. + ITexture *GetRenderTargetEx( int nRenderTargetID ) + { + return NULL; + } + + void SetToneMappingScaleLinear( const Vector &scale ); + + const Vector &GetToneMappingScaleLinear( void ) const + { + return m_ShaderState.m_ToneMappingScale.AsVector3D(); + } + + virtual float GetLightMapScaleFactor( void ) const; + + // For dealing with device lost in cases where SwapBuffers isn't called all the time (Hammer) + virtual void HandleDeviceLost() + { + } + + virtual void EnableLinearColorSpaceFrameBuffer( bool bEnable ) + { + } + + // Lets the shader know about the full-screen texture so it can + virtual void SetFullScreenTextureHandle( ShaderAPITextureHandle_t h ) + { + } + + void SetFloatRenderingParameter( int parm_number, float value ); + void SetIntRenderingParameter( int parm_number, int value ); + void SetVectorRenderingParameter( int parm_number, Vector const &value ); + float GetFloatRenderingParameter( int parm_number ) const; + int GetIntRenderingParameter( int parm_number ) const; + Vector GetVectorRenderingParameter( int parm_number ) const; + + // Methods related to stencil + void SetStencilEnable( bool onoff ); + void SetStencilFailOperation( StencilOperation_t op ); + void SetStencilZFailOperation( StencilOperation_t op ); + void SetStencilPassOperation( StencilOperation_t op ); + void SetStencilCompareFunction( StencilComparisonFunction_t cmpfn ); + void SetStencilReferenceValue( int ref ); + void SetStencilTestMask( uint32 msk ); + void SetStencilWriteMask( uint32 msk ); + + void ClearStencilBufferRectangle( int xmin, int ymin, int xmax, int ymax, int value ) + { + } + + virtual void GetDXLevelDefaults( uint &max_dxlevel, uint &recommended_dxlevel ) + { + max_dxlevel = recommended_dxlevel = 110; + } + + virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) + { + MeshMgr()->GetMaxToRender( pMesh, bMaxUntilFlush, pMaxVerts, pMaxIndices ); + } + + // Returns the max possible vertices + indices to render in a single draw call + virtual int GetMaxVerticesToRender( IMaterial *pMaterial ) + { + return MeshMgr()->GetMaxVerticesToRender( pMaterial ); + } + + virtual int GetMaxIndicesToRender() + { + return MeshMgr()->GetMaxIndicesToRender(); + } + virtual int CompareSnapshots( StateSnapshot_t snapshot0, StateSnapshot_t snapshot1 ); + + virtual bool SupportsMSAAMode( int nMSAAMode ) + { + return true; + } + + // Hooks for firing PIX events from outside the Material System... + virtual void SetPIXMarker( unsigned long color, const char *szName ) + { + } + + virtual void ComputeVertexDescription( unsigned char *pBuffer, VertexFormat_t vertexFormat, MeshDesc_t &desc ) const + { + return MeshMgr()->ComputeVertexDescription( pBuffer, vertexFormat, desc ); + } + + virtual bool SupportsShadowDepthTextures() + { + return false; + } + + virtual int NeedsShaderSRGBConversion( void ) const + { + return 0; + } + + virtual bool SupportsFetch4() + { + return false; + } + + virtual void SetShadowDepthBiasFactors( float fShadowSlopeScaleDepthBias, float fShadowDepthBias ) + { + } + + virtual void SetDisallowAccess( bool ) + { + } + virtual void EnableShaderShaderMutex( bool ) + { + } + virtual void ShaderLock() + { + } + virtual void ShaderUnlock() + { + } + virtual void EnableHWMorphing( bool bEnable ) + { + } + ImageFormat GetNullTextureFormat( void ) + { + return IMAGE_FORMAT_RGBA8888; + } // stub + virtual void PushDeformation( DeformationBase_t const *Deformation ) + { + } + + virtual void PopDeformation() + { + } + + virtual int GetNumActiveDeformations() const + { + return 0; + } + + virtual void ExecuteCommandBuffer( uint8 *pBuf ); + + void SetStandardTextureHandle( StandardTextureId_t, ShaderAPITextureHandle_t ) + { + } + + + virtual void SetPSNearAndFarZ(int pshReg) + { + } + + int GetPackedDeformationInformation( int nMaskOfUnderstoodDeformations, + float *pConstantValuesOut, + int nBufferSize, + int nMaximumDeformations, + int *pNumDefsOut ) const + { + *pNumDefsOut = 0; + return 0; + } + + virtual bool OwnGPUResources( bool bEnable ) + { + return false; + } + +private: + enum + { + TRANSLUCENT = 0x1, + ALPHATESTED = 0x2, + VERTEX_AND_PIXEL_SHADERS = 0x4, + DEPTHWRITE = 0x8, + }; + void EnableAlphaToCoverage(){}; + void DisableAlphaToCoverage(){}; + + ImageFormat GetShadowDepthTextureFormat() + { + return IMAGE_FORMAT_NV_DST24; + }; + + // + // NOTE: Under here are real methods being used by dx11 implementation + // above is stuff I still have to port over. + // +private: + //void ClearShaderState( ShaderStateDx11_t *pState ); + + void CreateTextureHandles( ShaderAPITextureHandle_t *handles, int count ); + CTextureDx11 &GetTexture(ShaderAPITextureHandle_t handle); + ShaderAPITextureHandle_t CreateTextureHandle(); + + void GammaCorrectFogColor( float *rgb ); + + void DoIssueVertexShader(); + void DoIssuePixelShader(); + void DoIssueGeometryShader(); + bool DoIssueConstantBuffers( bool bForce ); + void DoIssueSampler( bool bPixel, bool bVertex ); + void DoIssueTexture( bool bPixel, bool bVertex ); + void DoIssueRasterState(); + void DoIssueBlendState(); + void DoIssueDepthStencilState(); + bool DoIssueVertexBuffer(); + void DoIssueIndexBuffer(); + void DoIssueInputLayout(); + void DoIssueTopology(); + void DoIssueViewports(); + void DoIssueShaderState( bool bForce ); + void DoIssueRenderTargets(); + + void SortLights( int *index = NULL ); + + void AdvanceCurrentTextureCopy( ShaderAPITextureHandle_t handle ); + + bool MatrixIsChanging(); + bool IsDeactivated() const; + DirectX::XMMATRIX &GetMatrix( MaterialMatrixMode_t mode ); + DirectX::XMMATRIX &GetCurrentMatrix(); + DirectX::XMMATRIX GetMatrixCopy( MaterialMatrixMode_t mode ) const; + DirectX::XMMATRIX GetCurrentMatrixCopy() const; + void HandleMatrixModified(); + + void RenderPassWithVertexAndIndexBuffers(); + + int ComputeNumLights() const; + +private: + // Current material + mesh + IMaterialInternal *m_pMaterial; + CMeshBase *m_pMesh; + int m_nDynamicVBSize; + + FlashlightState_t m_FlashlightState; + bool m_bFlashlightStateChanged; + VMatrix m_FlashlightWorldToTexture; + ITexture *m_pFlashlightDepthTexture; + + // rendering parameter storage + int IntRenderingParameters[MAX_INT_RENDER_PARMS]; + float FloatRenderingParameters[MAX_FLOAT_RENDER_PARMS]; + Vector VectorRenderingParameters[MAX_VECTOR_RENDER_PARMS]; + + // Members related to textures + // UNDONE: Should this stuff be in ShaderDeviceDx11? + CUtlVector m_Textures; + unsigned char m_TexAnisotropy; + char m_ModifyTextureLockedLevel; + char m_ModifyTextureLockedFace; + ShaderAPITextureHandle_t m_ModifyTextureHandle; + ShaderAPITextureHandle_t m_hBackBuffer; + ShaderAPITextureHandle_t m_hDepthBuffer; + + // Common constant buffers + ConstantBufferHandle_t m_hPerModelConstants; + ConstantBufferHandle_t m_hPerSceneConstants; + ConstantBufferHandle_t m_hPerFrameConstants; + ConstantBufferHandle_t m_hSkinningConstants; + ConstantBufferHandle_t m_hFlexConstants; + + // Current and target states + StateSnapshot_t m_CurrentSnapshot; + bool m_bResettingRenderState : 1; + + const StatesDx11::ShadowState *m_ShadowState; + StatesDx11::DynamicState m_DynamicState; + StatesDx11::ShaderState m_ShaderState; + unsigned int m_StateChangeFlags; + + // Setting matrices + MaterialMatrixMode_t m_MatrixMode; + StatesDx11::MatrixItem_t *m_pCurMatrixItem; + + bool m_bSelectionMode; + + // Mesh builder used to modify vertex data + CMeshBuilder m_ModifyBuilder; + + // Selection name stack + CUtlStack< int > m_SelectionNames; + bool m_InSelectionMode; + unsigned int *m_pSelectionBufferEnd; + unsigned int *m_pSelectionBuffer; + unsigned int *m_pCurrSelectionRecord; + float m_SelectionMinZ; + float m_SelectionMaxZ; + int m_NumHits; + + friend class CTempMeshDX11; + friend class CMeshDX11; + friend class CDynamicMeshDX11; + friend class CBufferedMeshDX11; + friend class CMeshMgr; + friend class CShaderDeviceDx11; + friend class CShaderShadowDx11; + +}; + +//----------------------------------------------------------------------------- +// Singleton global +//----------------------------------------------------------------------------- +extern CShaderAPIDx11 *g_pShaderAPIDx11; + +#endif // SHADERAPIDX11_H diff --git a/materialsystem/shaderapidx11/shaderapidx11.qpc b/materialsystem/shaderapidx11/shaderapidx11.qpc new file mode 100644 index 0000000..23100a8 --- /dev/null +++ b/materialsystem/shaderapidx11/shaderapidx11.qpc @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// SHADERAPIDX11.QPC +// +// Project Script +//----------------------------------------------------------------------------- + +macro SRCDIR "..\.." +macro OUTBINDIR "$BINDEFAULT" +macro DX9DIR "..\shaderapidx9" +macro OPENVR_DIR "$SRCDIR/thirdparty/openvr" [!$OPENVR_DIR] + +include "$SRCDIR\_qpc_scripts\source_dll_base.qpc" + +configuration +{ + + general + { + int_dir "./$CONFIG/$PLATFORM/dx11" + + include_directories + { + ".." + "$OPENVR_DIR/headers" + } + } + + compiler + { + preprocessor_definitions + { + "DX11" + "SHADERAPIDX11" + "SHADER_DLL_EXPORT" + "PROTECTED_THINGS_ENABLE" + "strncpy=use_Q_strncpy_instead" + "_snprintf=use_Q_snprintf_instead" + } + } + + linker + { + libraries + { + "$LIBPUBLIC/tier2" + "$LIBPUBLIC/bitmap" + "$LIBPUBLIC/mathlib" + "$LIBCOMMON/bzip2" + "dxgi.lib" + "d3d11.lib" + "D3DCompiler.lib" + "dxguid.lib" + "$OPENVR_DIR/lib/win32/openvr_api.lib" + } + } +} + +dependencies +{ + "bitmap/bitmap.qpc" + "mathlib/mathlib.qpc" + "tier2/tier2.qpc" + "thirdparty/bzip2/bzip2.qpc" +} + +files +{ + folder "Source Files" + { + // Shared riles + "$DX9DIR\cvballoctracker.cpp" + "$DX9DIR\shaderdevicebase.cpp" + "$DX9DIR\shaderapibase.cpp" + "$DX9DIR\meshbase.cpp" + "$DX9DIR\hardwareconfig.cpp" + + // DX11 related files + "vertexshaderdx11.cpp" + "ShaderDeviceDx11.cpp" + "ShaderAPIDx11.cpp" + "MeshDx11.cpp" + "InputLayoutDx11.cpp" + "ShaderShadowDx11.cpp" + "IndexBufferDx11.cpp" + "VertexBufferDx11.cpp" + "ShaderConstantBufferDx11.cpp" + "TextureDx11.cpp" + } + + folder "Public Header Files" + { + "$SRCDIR\public\shaderapi\ishaderdevice.h" + "$SRCDIR\public\shaderapi\ishaderutil.h" + "$SRCDIR\public\shaderapi\ishaderapi.h" + "$SRCDIR\public\shaderapi\ishaderdynamic.h" + "$SRCDIR\public\shaderapi\ishadershadow.h" + "$SRCDIR\public\materialsystem\idebugtextureinfo.h" + "$SRCDIR\public\materialsystem\ivballoctracker.h" + "$SRCDIR\public\materialsystem\shader_vcs_version.h" + } + + folder "Header Files" + { + // Shared files + "$DX9DIR\meshbase.h" + "$DX9DIR\shaderdevicebase.h" + "$DX9DIR\shaderapibase.h" + "$DX9DIR\shaderapi_global.h" + "$DX9DIR\HardwareConfig.h" + + // DX11 related files + "ShaderDeviceDx11.h" + "ShaderAPIDx11.h" + "MeshDx11.h" + "ShaderShadowDx11.h" + "shaderapidx11_global.h" + "inputlayoutdx11.h" + "vertexshaderdx11.h" + "StatesDx11.h" + "Dx11Global.h" + "IndexBufferDx11.h" + "ShaderConstantBufferDx11.h" + "TextureDx11.h" + "VertexBufferDx11.h" + } +} diff --git a/materialsystem/shaderapidx11/shaderapidx11.vpc b/materialsystem/shaderapidx11/shaderapidx11.vpc new file mode 100644 index 0000000..a071d88 --- /dev/null +++ b/materialsystem/shaderapidx11/shaderapidx11.vpc @@ -0,0 +1,176 @@ +//----------------------------------------------------------------------------- +// SHADERAPIDX11.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" +$macro DX9DIR "..\shaderapidx9" + +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" + +$Configuration "Debug" +{ + $General + { + $OutputDirectory ".\Debug\$PLATSUBDIR\dx11" + $IntermediateDirectory ".\Debug\$PLATSUBDIR\dx11" + } +} + +$Configuration "Release" +{ + $General + { + $OutputDirectory ".\Release\$PLATSUBDIR\dx11" + $IntermediateDirectory ".\Release\$PLATSUBDIR\dx11" + } +} + +// Common Configuration +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;..\" + $PreprocessorDefinitions "$BASE;DX11;SHADERAPIDX11;SHADER_DLL_EXPORT;PROTECTED_THINGS_ENABLE;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead" + +// $AdditionalOptions "/FC" + } + + $Linker + { + $AdditionalDependencies "$BASE dxgi.lib d3d11.lib D3DCompiler.lib dxguid.lib legacy_stdio_definitions.lib" [$WIN32] + } +} + +$Project "shaderapidx11" +{ + $Folder "Source Files" + { + // Shared riles + $File "$DX9DIR\cvballoctracker.cpp" + $File "$DX9DIR\shaderdevicebase.cpp" + $File "$DX9DIR\shaderapibase.cpp" + $File "$DX9DIR\meshbase.cpp" + + $File "vertexshaderdx11.cpp" + + // DX11 related files + $File "ShaderDeviceDx11.cpp" \ + "ShaderAPIDx11.cpp" \ + "MeshDx11.cpp" \ + "InputLayoutDx11.cpp" \ + "ShaderShadowDx11.cpp" \ + "TextureDx11.cpp" \ + "IndexBufferDx11.cpp" \ + "VertexBufferDx11.cpp" \ + "ShaderConstantBufferDx11.cpp" + { + $Configuration + { + $Compiler + { + $PreprocessorDefinitions "DX11" + } + } + } + + // DX9 related files + //$File "$DX9DIR\ColorFormatDX8.cpp" + //$File "$DX9DIR\d3d_async.cpp" + //$File "$SRCDIR\public\filesystem_helpers.cpp" + $File "$DX9DIR\HardwareConfig.cpp" + //$File "$DX9DIR\MeshDX8.cpp" + //$File "$DX9DIR\Recording.cpp" + //$File "$DX9DIR\ShaderAPIDX8.cpp" + //$File "$DX9DIR\ShaderDeviceDX8.cpp" + //$File "$DX9DIR\ShaderShadowDX8.cpp" + //$File "$DX9DIR\TextureDX8.cpp" + //$File "$DX9DIR\TransitionTable.cpp" + //$File "$DX9DIR\vertexdecl.cpp" + //$File "$DX9DIR\VertexShaderDX8.cpp" + //$File "$DX9DIR\wmi.cpp" + } + + $Folder "Public Header Files" + { + $File "$SRCDIR\public\shaderapi\ishaderdevice.h" + $File "$SRCDIR\public\shaderapi\ishaderutil.h" + $File "$SRCDIR\public\shaderapi\ishaderapi.h" + $File "$SRCDIR\public\shaderapi\ishaderdynamic.h" + $File "$SRCDIR\public\shaderapi\ishadershadow.h" + $File "$SRCDIR\public\materialsystem\idebugtextureinfo.h" + $File "$SRCDIR\public\materialsystem\ivballoctracker.h" + $File "$SRCDIR\public\materialsystem\shader_vcs_version.h" + } + + $Folder "Header Files" + { + // Shared files + $File "$DX9DIR\meshbase.h" + $File "$DX9DIR\shaderdevicebase.h" + $File "$DX9DIR\shaderapibase.h" + $File "$DX9DIR\shaderapi_global.h" + $File "$DX9DIR\HardwareConfig.h" + + // DX11 related files + $File "ShaderDeviceDx11.h" + $File "ShaderAPIDx11.h" + $File "MeshDx11.h" + $File "ShaderShadowDx11.h" + $File "shaderapidx11_global.h" + $File "inputlayoutdx11.h" + $File "vertexshaderdx11.h" + + // DX9 related files + //$File "$DX9DIR\TransitionTable.h" + //$File "$DX9DIR\vertexdecl.h" +// $File "..\CMaterialSystemStats.h" + //$File "$DX9DIR\ColorFormatDX8.h" + //$File "$DX9DIR\d3d_async.h" + //$File "$DX9DIR\dynamicib.h" + //$File "$DX9DIR\dynamicvb.h" + //$File "$DX9DIR\IMeshDX8.h" + //$File "$DX9DIR\locald3dtypes.h" + //$File "$DX9DIR\Recording.h" + //$File "$DX9DIR\ShaderAPIDX8.h" + //$File "$DX9DIR\ShaderAPIDX8_Global.h" + //$File "$DX9DIR\ShaderShadowDX8.h" + //$File "$DX9DIR\stubd3ddevice.h" + //$File "$DX9DIR\TextureDX8.h" + //$File "$DX9DIR\VertexShaderDX8.h" + //$File "$DX9DIR\wmi.h" + } + + $Folder "Link Libraries" + { + $Lib "$LIBPUBLIC\tier2" + $Lib "$LIBPUBLIC\bitmap" + $Lib "$LIBPUBLIC\mathlib" + $Lib "$LIBCOMMON\bzip2" + + //$File "$SRCDIR\dx10sdk\lib\d3d9.lib" + //$File "$SRCDIR\dx10sdk\lib\d3d10.lib" + //$File "$SRCDIR\dx10sdk\lib\dxgi.lib" + + //$File "$SRCDIR\dx10sdk\lib\d3dx10.lib" \ + // "$SRCDIR\dx10sdk\lib\d3dx9.lib" + //{ + // $Configuration "Debug" + // { + // $ExcludedFromBuild "Yes" + // } + //} + + //$File "$SRCDIR\dx10sdk\lib\d3dx10d.lib" \ + // "$SRCDIR\dx10sdk\lib\d3dx9d.lib" + //{ + // $Configuration "Release" + // { + // $ExcludedFromBuild "Yes" + // } + //} + } +} diff --git a/materialsystem/shaderapidx11/shaderapidx11_global.h b/materialsystem/shaderapidx11/shaderapidx11_global.h new file mode 100644 index 0000000..a7bae6a --- /dev/null +++ b/materialsystem/shaderapidx11/shaderapidx11_global.h @@ -0,0 +1,27 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef SHADERAPIDX11_GLOBAL_H +#define SHADERAPIDX11_GLOBAL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderapidx9/shaderapi_global.h" +#include "tier2/tier2.h" + +//----------------------------------------------------------------------------- +// The main hardware config interface +//----------------------------------------------------------------------------- +inline IMaterialSystemHardwareConfig* HardwareConfig() +{ + return g_pMaterialSystemHardwareConfig; +} + +#endif // SHADERAPIDX11_GLOBAL_H diff --git a/materialsystem/shaderapidx11/shaderdevicedx11.cpp b/materialsystem/shaderapidx11/shaderdevicedx11.cpp new file mode 100644 index 0000000..465a84e --- /dev/null +++ b/materialsystem/shaderapidx11/shaderdevicedx11.cpp @@ -0,0 +1,1154 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "Dx11Global.h" +#include "shaderdevicedx11.h" +#include "shaderapi/ishaderutil.h" +#include "shaderapidx11.h" +#include "shadershadowdx11.h" +#include "IndexBufferDx11.h" +#include "VertexBufferDx11.h" +#include "shaderapidx11_global.h" +#include "tier1/keyvalues.h" +#include "tier2/tier2.h" +#include "tier0/icommandline.h" +#include "inputlayoutdx11.h" +#include "shaderapidx9/shaderapibase.h" +#include "meshdx11.h" +#include "TextureDx11.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +// this is hooked into the engines convar +ConVar mat_debugalttab( "mat_debugalttab", "0", FCVAR_CHEAT ); + +// For testing Fast Clip +ConVar mat_fastclip("mat_fastclip", "0", FCVAR_CHEAT); + + +//----------------------------------------------------------------------------- +// Explicit instantiation of shader buffer implementation +//----------------------------------------------------------------------------- +template class CShaderBuffer< ID3DBlob >; + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +ID3D11Device *g_pD3DDevice = NULL; +ID3D11DeviceContext *g_pD3DDeviceContext = NULL; +IDXGISwapChain *g_pD3DSwapChain = NULL; + +//----------------------------------------------------------------------------- +// +// Device manager +// +//----------------------------------------------------------------------------- +static CShaderDeviceMgrDx11 g_ShaderDeviceMgrDx11; + +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderDeviceMgrDx11, IShaderDeviceMgr, + SHADER_DEVICE_MGR_INTERFACE_VERSION, g_ShaderDeviceMgrDx11 ) + +static CShaderDeviceDx11 g_ShaderDeviceDx11; +CShaderDeviceDx11* g_pShaderDeviceDx11 = &g_ShaderDeviceDx11; + +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderDeviceDx11, IShaderDevice, + SHADER_DEVICE_INTERFACE_VERSION, g_ShaderDeviceDx11 ) + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CShaderDeviceMgrDx11::CShaderDeviceMgrDx11() +{ + m_pDXGIFactory = NULL; + m_bSetupAdapters = false; + m_bObeyDxCommandlineOverride = true; +} + +CShaderDeviceMgrDx11::~CShaderDeviceMgrDx11() +{ +} + + +//----------------------------------------------------------------------------- +// Connect, disconnect +//----------------------------------------------------------------------------- +bool CShaderDeviceMgrDx11::Connect( CreateInterfaceFn factory ) +{ + LOCK_SHADERAPI(); + + Log("Connecting CShaderDeviceMgrDx11...\n"); + + if ( !BaseClass::Connect( factory ) ) + return false; + + HRESULT hr = CreateDXGIFactory1( __uuidof(IDXGIFactory1), (void**)(&m_pDXGIFactory) ); + if ( FAILED( hr ) ) + { + Warning( "Failed to create the DXGI Factory!\n" ); + return false; + } + + InitAdapterInfo(); + return true; +} + +void CShaderDeviceMgrDx11::Disconnect() +{ + LOCK_SHADERAPI(); + + if ( m_pDXGIFactory ) + { + m_pDXGIFactory->Release(); + m_pDXGIFactory = NULL; + } + + BaseClass::Disconnect(); +} + + +//----------------------------------------------------------------------------- +// Initialization +//----------------------------------------------------------------------------- +InitReturnVal_t CShaderDeviceMgrDx11::Init( ) +{ + LOCK_SHADERAPI(); + + InitAdapterInfo(); + + return INIT_OK; +} + + +//----------------------------------------------------------------------------- +// Shutdown +//----------------------------------------------------------------------------- +void CShaderDeviceMgrDx11::Shutdown( ) +{ + LOCK_SHADERAPI(); + + if ( g_pShaderDevice ) + { + g_pShaderDevice->ShutdownDevice(); + g_pShaderDevice = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Initialize adapter information +//----------------------------------------------------------------------------- +void CShaderDeviceMgrDx11::InitAdapterInfo() +{ + if ( m_bSetupAdapters ) + return; + + m_Adapters.RemoveAll(); + + IDXGIAdapter *pAdapter; + for( UINT nCount = 0; m_pDXGIFactory->EnumAdapters( nCount, &pAdapter ) != DXGI_ERROR_NOT_FOUND; ++nCount ) + { + IDXGIOutput *pOutput = GetAdapterOutput( nCount ); + //Log( "pOutput: %p\n", pAdapter ); + if ( !pOutput ) + break; + + int j = m_Adapters.AddToTail(); + AdapterInfo_t &info = m_Adapters[j]; + +#ifdef _DEBUG + memset( &info.m_ActualCaps, 0xDD, sizeof(info.m_ActualCaps) ); +#endif + + + info.m_ActualCaps.m_bDeviceOk = ComputeCapsFromD3D( &info.m_ActualCaps, pAdapter, pOutput ); + if ( !info.m_ActualCaps.m_bDeviceOk ) + continue; + + ReadDXSupportLevels( info.m_ActualCaps ); + + // Read dxsupport.cfg which has config overrides for particular cards. + ReadHardwareCaps( info.m_ActualCaps, info.m_ActualCaps.m_nMaxDXSupportLevel ); + + // What's in "-shader" overrides dxsupport.cfg + const char *pShaderParam = CommandLine()->ParmValue( "-shader" ); + if ( pShaderParam ) + { + Q_strncpy( info.m_ActualCaps.m_pShaderDLL, pShaderParam, sizeof( info.m_ActualCaps.m_pShaderDLL ) ); + } + } + + m_bSetupAdapters = true; +} + + +//----------------------------------------------------------------------------- +// Determines hardware caps from D3D +//----------------------------------------------------------------------------- +bool CShaderDeviceMgrDx11::ComputeCapsFromD3D( HardwareCaps_t *pCaps, IDXGIAdapter *pAdapter, IDXGIOutput *pOutput ) +{ + DXGI_ADAPTER_DESC desc; + HRESULT hr = pAdapter->GetDesc( &desc ); + Assert( !FAILED( hr ) ); + if ( FAILED( hr ) ) + { + Warning( "Dx11: Couldn't get adapter desc\n" ); + return false; + } + + + bool bForceFloatHDR = ( CommandLine()->CheckParm( "-floathdr" ) != NULL ); + + // DX10 settings + // NOTE: We'll need to have different settings for dx10.1 and dx11 + Q_UnicodeToUTF8( desc.Description, pCaps->m_pDriverName, MATERIAL_ADAPTER_NAME_LENGTH ); + pCaps->m_VendorID = desc.VendorId; + pCaps->m_DeviceID = desc.DeviceId; + pCaps->m_SubSysID = desc.SubSysId; + pCaps->m_Revision = desc.Revision; + pCaps->m_NumSamplers = 16; + pCaps->m_NumTextureStages = 0; + pCaps->m_HasSetDeviceGammaRamp = true; + pCaps->m_bSoftwareVertexProcessing = false; + pCaps->m_SupportsVertexShaders = true; + pCaps->m_SupportsVertexShaders_2_0 = true; + pCaps->m_SupportsPixelShaders = true; + pCaps->m_SupportsPixelShaders_1_4 = true; + pCaps->m_SupportsPixelShaders_2_0 = true; + pCaps->m_SupportsPixelShaders_2_b = true; + pCaps->m_SupportsShaderModel_3_0 = true; + pCaps->m_SupportsCompressedTextures = COMPRESSED_TEXTURES_ON; + pCaps->m_SupportsCompressedVertices = VERTEX_COMPRESSION_ON; + pCaps->m_bSupportsAnisotropicFiltering = true; + pCaps->m_bSupportsMagAnisotropicFiltering = true; + pCaps->m_bSupportsVertexTextures = true; + pCaps->m_nMaxAnisotropy = D3D11_REQ_MAXANISOTROPY; + pCaps->m_MaxTextureWidth = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + pCaps->m_MaxTextureHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + pCaps->m_MaxTextureDepth = D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + pCaps->m_MaxTextureAspectRatio = 1024; // FIXME + pCaps->m_MaxPrimitiveCount = 65536; // FIXME + pCaps->m_ZBiasAndSlopeScaledDepthBiasSupported = true; + pCaps->m_SupportsMipmapping = false; // FIXME + pCaps->m_SupportsOverbright = true; + pCaps->m_SupportsCubeMaps = true; + pCaps->m_NumPixelShaderConstants = 1024; // FIXME + pCaps->m_NumVertexShaderConstants = 1024; // FIXME + pCaps->m_TextureMemorySize = desc.DedicatedVideoMemory; + pCaps->m_MaxNumLights = 4; + pCaps->m_SupportsHardwareLighting = false; + pCaps->m_MaxBlendMatrices = 0; + pCaps->m_MaxBlendMatrixIndices = 0; + pCaps->m_MaxVertexShaderBlendMatrices = 53; // FIXME + pCaps->m_SupportsMipmappedCubemaps = true; + pCaps->m_SupportsNonPow2Textures = true; + pCaps->m_nDXSupportLevel = 110; + pCaps->m_PreferDynamicTextures = true; + pCaps->m_HasProjectedBumpEnv = true; + pCaps->m_MaxUserClipPlanes = 6; // FIXME + pCaps->m_HDRType = bForceFloatHDR ? HDR_TYPE_FLOAT : HDR_TYPE_INTEGER; + pCaps->m_MaxHDRType = HDR_TYPE_FLOAT; + pCaps->m_SupportsSRGB = true; + pCaps->m_bSupportsSpheremapping = true; + pCaps->m_UseFastClipping = false; + pCaps->m_pShaderDLL[0] = 0; + pCaps->m_bNeedsATICentroidHack = false; + pCaps->m_bColorOnSecondStream = true; + pCaps->m_bSupportsStreamOffset = true; + pCaps->m_nMaxDXSupportLevel = 110; + pCaps->m_bFogColorSpecifiedInLinearSpace = ( desc.VendorId == VENDORID_NVIDIA ); + pCaps->m_nVertexTextureCount = 16; + pCaps->m_nMaxVertexTextureDimension = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + pCaps->m_bSupportsAlphaToCoverage = true; // FIXME + pCaps->m_bSupportsShadowDepthTextures = true; + pCaps->m_bSupportsFetch4 = ( desc.VendorId == VENDORID_ATI ); +#if defined( COMPRESSED_NORMAL_FORMATS ) + pCaps->m_bSupportsNormalMapCompression = true; +#else + pCaps->m_bSupportsNormalMapCompression = false; +#endif + pCaps->m_bSupportsBorderColor = true; + pCaps->m_ShadowDepthTextureFormat = IMAGE_FORMAT_UNKNOWN; + pCaps->m_nMaxViewports = 4; + + //DXGI_GAMMA_CONTROL_CAPABILITIES gammaCaps; + //pOutput->GetGammaControlCapabilities( &gammaCaps ); + //pCaps->m_flMinGammaControlPoint = gammaCaps.MinConvertedValue; + //pCaps->m_flMaxGammaControlPoint = gammaCaps.MaxConvertedValue; + //pCaps->m_nGammaControlPointCount = gammaCaps.NumGammaControlPoints; + pCaps->m_flMinGammaControlPoint = 0.0f; + pCaps->m_flMaxGammaControlPoint = 65535.0f; + pCaps->m_nGammaControlPointCount = 256; + Log( "Set gamma control capabilities %f %f %i\n", pCaps->m_flMaxGammaControlPoint, pCaps->m_flMaxGammaControlPoint, pCaps->m_nGammaControlPointCount ); + + return true; +} + + +//----------------------------------------------------------------------------- +// Gets the number of adapters... +//----------------------------------------------------------------------------- +int CShaderDeviceMgrDx11::GetAdapterCount() const +{ + return m_Adapters.Count(); +} + + +//----------------------------------------------------------------------------- +// Returns info about each adapter +//----------------------------------------------------------------------------- +void CShaderDeviceMgrDx11::GetAdapterInfo( int nAdapter, MaterialAdapterInfo_t& info ) const +{ + Assert( ( nAdapter >= 0 ) && ( nAdapter < m_Adapters.Count() ) ); + const HardwareCaps_t &caps = m_Adapters[ nAdapter ].m_ActualCaps; + //Log( "Driver name: %s\n", caps.m_pDriverName ); + memcpy( &info, &caps, sizeof(MaterialAdapterInfo_t) ); +} + + +//----------------------------------------------------------------------------- +// Returns the adapter interface for a particular adapter +//----------------------------------------------------------------------------- +IDXGIAdapter* CShaderDeviceMgrDx11::GetAdapter( int nAdapter ) const +{ + Assert( m_pDXGIFactory ); + + IDXGIAdapter *pAdapter; + HRESULT hr = m_pDXGIFactory->EnumAdapters( nAdapter, &pAdapter ); + return ( FAILED(hr) ) ? NULL : pAdapter; +} + + +//----------------------------------------------------------------------------- +// Returns the amount of video memory in bytes for a particular adapter +//----------------------------------------------------------------------------- +int CShaderDeviceMgrDx11::GetVidMemBytes( int nAdapter ) const +{ + LOCK_SHADERAPI(); + IDXGIAdapter *pAdapter = GetAdapter( nAdapter ); + if ( !pAdapter ) + return 0; + + DXGI_ADAPTER_DESC desc; + +#ifdef _DEBUG + HRESULT hr = +#endif + pAdapter->GetDesc( &desc ); + Assert( !FAILED( hr ) ); + return desc.DedicatedVideoMemory; +} + + +//----------------------------------------------------------------------------- +// Returns the appropriate adapter output to use +//----------------------------------------------------------------------------- +IDXGIOutput* CShaderDeviceMgrDx11::GetAdapterOutput( int nAdapter ) const +{ + LOCK_SHADERAPI(); + IDXGIAdapter *pAdapter = GetAdapter( nAdapter ); + if ( !pAdapter ) + return 0; + + IDXGIOutput *pOutput; + for( UINT i = 0; pAdapter->EnumOutputs( i, &pOutput ) != DXGI_ERROR_NOT_FOUND; ++i ) + { + DXGI_OUTPUT_DESC desc; + HRESULT hr = pOutput->GetDesc( &desc ); + if ( FAILED( hr ) ) + continue; + + // FIXME: Is this what I want? Or should I be looking at other fields, + // like DXGI_MODE_ROTATION_IDENTITY? + if ( !desc.AttachedToDesktop ) + continue; + + return pOutput; + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Returns the number of modes +//----------------------------------------------------------------------------- +int CShaderDeviceMgrDx11::GetModeCount( int nAdapter ) const +{ + LOCK_SHADERAPI(); + Assert( m_pDXGIFactory && ( nAdapter < GetAdapterCount() ) ); + + IDXGIOutput *pOutput = GetAdapterOutput( nAdapter ); + if ( !pOutput ) + return 0; + + UINT num = 0; + DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; //desired color format + UINT flags = DXGI_ENUM_MODES_INTERLACED; //desired scanline order and/or scaling + + // get the number of available display mode for the given format and scanline order + HRESULT hr = pOutput->GetDisplayModeList( format, flags, &num, 0 ); + return ( FAILED(hr) ) ? 0 : num; +} + + +//----------------------------------------------------------------------------- +// Returns mode information.. +//----------------------------------------------------------------------------- +void CShaderDeviceMgrDx11::GetModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter, int nMode ) const +{ + // Default error state + pInfo->m_nWidth = pInfo->m_nHeight = 0; + pInfo->m_Format = IMAGE_FORMAT_UNKNOWN; + pInfo->m_nRefreshRateNumerator = pInfo->m_nRefreshRateDenominator = 0; + + LOCK_SHADERAPI(); + Assert( m_pDXGIFactory && ( nAdapter < GetAdapterCount() ) ); + + IDXGIOutput *pOutput = GetAdapterOutput( nAdapter ); + if ( !pOutput ) + return; + + UINT num = 0; + DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; //desired color format + UINT flags = DXGI_ENUM_MODES_INTERLACED; //desired scanline order and/or scaling + + // get the number of available display mode for the given format and scanline order + HRESULT hr = pOutput->GetDisplayModeList( format, flags, &num, 0 ); + Assert( !FAILED( hr ) ); + + if ( (UINT)nMode >= num ) + return; + + DXGI_MODE_DESC *pDescs = (DXGI_MODE_DESC*)_alloca( num * sizeof( DXGI_MODE_DESC ) ); + hr = pOutput->GetDisplayModeList( format, flags, &num, pDescs ); + Assert( !FAILED( hr ) ); + + pInfo->m_nWidth = pDescs[nMode].Width; + pInfo->m_nHeight = pDescs[nMode].Height; + pInfo->m_Format = CTextureDx11::GetImageFormat( pDescs[nMode].Format ); + pInfo->m_nRefreshRateNumerator = pDescs[nMode].RefreshRate.Numerator; + pInfo->m_nRefreshRateDenominator = pDescs[nMode].RefreshRate.Denominator; +} + + +//----------------------------------------------------------------------------- +// Returns the current mode for an adapter +//----------------------------------------------------------------------------- +void CShaderDeviceMgrDx11::GetCurrentModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter ) const +{ + // FIXME: Implement! + Assert( 0 ); +} + + +//----------------------------------------------------------------------------- +// Initialization, shutdown +//----------------------------------------------------------------------------- +bool CShaderDeviceMgrDx11::SetAdapter( int nAdapter, int nFlags ) +{ + Assert( m_bSetupAdapters && nAdapter < m_Adapters.Count() ); + HardwareCaps_t &actualCaps = g_pHardwareConfig->ActualCapsForEdit(); + ComputeCapsFromD3D( &actualCaps, GetAdapter( nAdapter ), GetAdapterOutput( nAdapter ) ); + ReadDXSupportLevels( actualCaps ); + ReadHardwareCaps( actualCaps, actualCaps.m_nMaxDXSupportLevel ); + + // What's in "-shader" overrides dxsupport.cfg + const char *pShaderParam = CommandLine()->ParmValue( "-shader" ); + if ( pShaderParam ) + { + Q_strncpy( actualCaps.m_pShaderDLL, pShaderParam, sizeof( actualCaps.m_pShaderDLL ) ); + } + + g_pHardwareConfig->SetupHardwareCaps( actualCaps.m_nDXSupportLevel, actualCaps ); + + g_pShaderDevice = g_pShaderDeviceDx11; + g_pShaderDeviceDx11->m_nAdapter = nAdapter; + + return true; +} + + +//----------------------------------------------------------------------------- +// Sets the mode +//----------------------------------------------------------------------------- +CreateInterfaceFn CShaderDeviceMgrDx11::SetMode( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode ) +{ + LOCK_SHADERAPI(); + + //Log("Calling CShaderDeviceMgrDx11::SetMode()\n"); + + Assert( nAdapter < GetAdapterCount() ); + int nDXLevel = mode.m_nDXLevel != 0 ? mode.m_nDXLevel : m_Adapters[nAdapter].m_ActualCaps.m_nDXSupportLevel; + if ( m_bObeyDxCommandlineOverride ) + { + nDXLevel = CommandLine()->ParmValue( "-dxlevel", nDXLevel ); + m_bObeyDxCommandlineOverride = false; + } + if ( nDXLevel > m_Adapters[nAdapter].m_ActualCaps.m_nMaxDXSupportLevel ) + { + nDXLevel = m_Adapters[nAdapter].m_ActualCaps.m_nMaxDXSupportLevel; + } + nDXLevel = GetClosestActualDXLevel( nDXLevel ); + Log("nDXLevel: %i\n", nDXLevel); + if ( nDXLevel < 110 ) + { + // Fall back to the Dx9 implementations + //return g_pShaderDeviceMgrDx8->SetMode( hWnd, nAdapter, mode ); + Error( "DirectX 11 unsupported!" ); + Assert( 0 ); + return NULL; + } + + if ( g_pShaderAPI ) + { + g_pShaderAPI->OnDeviceShutdown(); + g_pShaderAPI = NULL; + } + + if ( g_pShaderDevice ) + { + g_pShaderDevice->ShutdownDevice(); + g_pShaderDevice = NULL; + } + + g_pShaderShadow = NULL; + + ShaderDeviceInfo_t adjustedMode = mode; + adjustedMode.m_nDXLevel = nDXLevel; + if ( !g_pShaderDeviceDx11->InitDevice( hWnd, nAdapter, adjustedMode ) ) + return NULL; + + if ( !g_pShaderAPIDx11->OnDeviceInit() ) + return NULL; + + g_pShaderDevice = g_pShaderDeviceDx11; + g_pShaderAPI = g_pShaderAPIDx11; + g_pShaderShadow = g_pShaderShadowDx11; + + return ShaderInterfaceFactory; +} + + +//----------------------------------------------------------------------------- +// +// Device +// +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CShaderDeviceDx11::CShaderDeviceDx11() +{ + m_pDevice = NULL; + m_pDeviceContext = NULL; + m_pOutput = NULL; + m_pSwapChain = NULL; + m_bDeviceInitialized = false; +} + +CShaderDeviceDx11::~CShaderDeviceDx11() +{ +} + + +//----------------------------------------------------------------------------- +// Sets the mode +//----------------------------------------------------------------------------- +bool CShaderDeviceDx11::InitDevice( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode ) +{ + // Make sure we've been shutdown previously + if ( m_bDeviceInitialized ) + { + Warning( "CShaderDeviceDx11::SetMode: Previous mode has not been shut down!\n" ); + return false; + } + + LOCK_SHADERAPI(); + IDXGIAdapter *pAdapter = g_ShaderDeviceMgrDx11.GetAdapter( nAdapter ); + if ( !pAdapter ) + return false; + + m_pOutput = g_ShaderDeviceMgrDx11.GetAdapterOutput( nAdapter ); + if ( !m_pOutput ) + return false; + m_pOutput->AddRef(); + + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory( &sd, sizeof(sd) ); + sd.BufferDesc.Width = mode.m_DisplayMode.m_nWidth; + sd.BufferDesc.Height = mode.m_DisplayMode.m_nHeight; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + sd.BufferDesc.RefreshRate.Numerator = mode.m_DisplayMode.m_nRefreshRateNumerator; + sd.BufferDesc.RefreshRate.Denominator = mode.m_DisplayMode.m_nRefreshRateDenominator; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT; + sd.BufferCount = mode.m_nBackBufferCount; + sd.OutputWindow = (HWND)hWnd; + sd.Windowed = mode.m_bWindowed ? TRUE : FALSE; + sd.Flags = mode.m_bWindowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + // NOTE: Having more than 1 back buffer disables MSAA! + sd.SwapEffect = mode.m_nBackBufferCount > 1 ? DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD; + + // FIXME: Chicken + egg problem with SampleDesc. + sd.SampleDesc.Count = mode.m_nAASamples ? mode.m_nAASamples : 1; + sd.SampleDesc.Quality = mode.m_nAAQuality; + + UINT nDeviceFlags = 0; +#ifdef _DEBUG + nDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + HRESULT hr = D3D11CreateDeviceAndSwapChain( pAdapter, D3D_DRIVER_TYPE_UNKNOWN, + NULL, nDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &sd, &m_pSwapChain, + &m_pDevice, NULL, &m_pDeviceContext ); + + if ( FAILED( hr ) ) + return false; + + g_pD3DDevice = m_pDevice; + g_pD3DDeviceContext = m_pDeviceContext; + g_pD3DSwapChain = m_pSwapChain; + + m_hWnd = hWnd; + m_nAdapter = nAdapter; + + // This is our current view. + m_ViewHWnd = hWnd; + GetWindowSize( m_nWindowWidth, m_nWindowHeight ); + + Log( "InitDevice: setupHardwareCaps\n" ); + const HardwareCaps_t &caps = g_ShaderDeviceMgrDx11.GetHardwareCaps( nAdapter ); + g_pHardwareConfig->SetupHardwareCaps( mode, caps ); + + m_bDeviceInitialized = true; + + return true; +} + + +//----------------------------------------------------------------------------- +// Shuts down the mode +//----------------------------------------------------------------------------- +void CShaderDeviceDx11::ShutdownDevice() +{ + if ( m_pDeviceContext ) + { + m_pDeviceContext->Release(); + m_pDeviceContext = NULL; + } + + if ( m_pDevice ) + { + m_pDevice->Release(); + m_pDevice = NULL; + } + + if ( m_pSwapChain ) + { + m_pSwapChain->Release(); + m_pSwapChain = NULL; + } + + if ( m_pOutput ) + { + m_pOutput->Release(); + m_pOutput = NULL; + } + + m_hWnd = NULL; + //m_nAdapter = -1; + m_bDeviceInitialized = false; +} + + +//----------------------------------------------------------------------------- +// Are we using graphics? +//----------------------------------------------------------------------------- +bool CShaderDeviceDx11::IsUsingGraphics() const +{ + return m_bDeviceInitialized; +} + + +//----------------------------------------------------------------------------- +// Returns the adapter +//----------------------------------------------------------------------------- +int CShaderDeviceDx11::GetCurrentAdapter() const +{ + return m_nAdapter; +} + + +//----------------------------------------------------------------------------- +// Get back buffer information +//----------------------------------------------------------------------------- +ImageFormat CShaderDeviceDx11::GetBackBufferFormat() const +{ + return IMAGE_FORMAT_RGB888; +} + +void CShaderDeviceDx11::GetBackBufferDimensions( int& width, int& height ) const +{ + //width = 1024; + //height = 768; + DXGI_SWAP_CHAIN_DESC desc; + m_pSwapChain->GetDesc( &desc ); + width = desc.BufferDesc.Width; + height = desc.BufferDesc.Height; +} + + +//----------------------------------------------------------------------------- +// Use this to spew information about the 3D layer +//----------------------------------------------------------------------------- +void CShaderDeviceDx11::SpewDriverInfo() const +{ + Warning( "Dx11 Driver!\n" ); +} + + + +//----------------------------------------------------------------------------- +// Swap buffers +//----------------------------------------------------------------------------- +void CShaderDeviceDx11::Present() +{ + // Draw buffered primitives + g_pShaderAPIDx11->FlushBufferedPrimitives(); + + // FIXME: Deal with window occlusion, alt-tab, etc. + HRESULT hr = m_pSwapChain->Present( 0, 0 ); + if ( FAILED(hr) ) + { + D3D11Device()->GetDeviceRemovedReason(); + Assert( 0 ); + } + + // Make all vertex and index buffers flush + // the next time they are locked. + MeshMgr()->DiscardVertexBuffers(); +} + + +//----------------------------------------------------------------------------- +// Camma ramp +//----------------------------------------------------------------------------- +void CShaderDeviceDx11::SetHardwareGammaRamp( float fGamma, float fGammaTVRangeMin, float fGammaTVRangeMax, float fGammaTVExponent, bool bTVEnabled ) +{ + DevMsg( "SetHardwareGammaRamp( %f )\n", fGamma ); + + Assert( m_pOutput ); + if( !m_pOutput ) + return; + + float flMin = g_pHardwareConfig->Caps().m_flMinGammaControlPoint; + float flMax = g_pHardwareConfig->Caps().m_flMaxGammaControlPoint; + int nGammaPoints = g_pHardwareConfig->Caps().m_nGammaControlPointCount; + + DXGI_GAMMA_CONTROL gammaControl; + gammaControl.Scale.Red = gammaControl.Scale.Green = gammaControl.Scale.Blue = 1.0f; + gammaControl.Offset.Red = gammaControl.Offset.Green = gammaControl.Offset.Blue = 0.0f; + float flOOCount = 1.0f / ( nGammaPoints - 1 ); + for ( int i = 0; i < nGammaPoints; i++ ) + { + float flGamma22 = i * flOOCount; + float flCorrection = pow( flGamma22, fGamma / 2.2f ); + flCorrection = clamp( flCorrection, flMin, flMax ); + + gammaControl.GammaCurve[i].Red = flCorrection; + gammaControl.GammaCurve[i].Green = flCorrection; + gammaControl.GammaCurve[i].Blue = flCorrection; + } + + HRESULT hr = m_pOutput->SetGammaControl( &gammaControl ); + if ( FAILED(hr) ) + { + Warning( "CShaderDeviceDx11::SetHardwareGammaRamp: Unable to set gamma controls!\n" ); + } +} + + +//----------------------------------------------------------------------------- +// Compiles all manner of shaders +//----------------------------------------------------------------------------- +IShaderBuffer* CShaderDeviceDx11::CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion ) +{ + int nCompileFlags = D3DCOMPILE_AVOID_FLOW_CONTROL; + nCompileFlags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; + +#ifdef _DEBUG + nCompileFlags |= D3DCOMPILE_DEBUG; +#endif + + ID3DBlob *pCompiledShader, *pErrorMessages; + HRESULT hr = D3DCompile( pProgram, nBufLen, "", + NULL, NULL, "main", pShaderVersion, nCompileFlags, 0, &pCompiledShader, + &pErrorMessages ); + + if ( FAILED( hr ) ) + { + if ( pErrorMessages ) + { + const char *pErrorMessage = (const char *)pErrorMessages->GetBufferPointer(); + Warning( "Vertex shader compilation failed! Reported the following errors:\n%s\n", pErrorMessage ); + pErrorMessages->Release(); + } + return NULL; + } + + // NOTE: This uses small block heap allocator; so I'm not going + // to bother creating a memory pool. + CShaderBuffer< ID3DBlob > *pShaderBuffer = new CShaderBuffer< ID3DBlob >( pCompiledShader ); + if ( pErrorMessages ) + { + pErrorMessages->Release(); + } + + return pShaderBuffer; +} + + +//----------------------------------------------------------------------------- +// Release input layouts +//----------------------------------------------------------------------------- +void CShaderDeviceDx11::ReleaseInputLayouts( VertexShaderIndex_t nIndex ) +{ + InputLayoutDict_t &dict = m_VertexShaderDict[nIndex].m_InputLayouts; + unsigned short hCurr = dict.FirstInorder(); + while( hCurr != dict.InvalidIndex() ) + { + if ( dict[hCurr].m_pInputLayout ) + { + dict[hCurr].m_pInputLayout->Release(); + dict[hCurr].m_pInputLayout = NULL; + } + hCurr = dict.NextInorder( hCurr ); + } +} + + +//----------------------------------------------------------------------------- +// Create, destroy vertex shader +//----------------------------------------------------------------------------- +VertexShaderHandle_t CShaderDeviceDx11::CreateVertexShader( IShaderBuffer* pShaderBuffer ) +{ + return CreateVertexShader( pShaderBuffer->GetBits(), pShaderBuffer->GetSize() ); +} + +VertexShaderHandle_t CShaderDeviceDx11::CreateVertexShader( const void* pBuffer, size_t nBufLen ) +{ + // Create the vertex shader + ID3D11VertexShader* pShader = NULL; + HRESULT hr = m_pDevice->CreateVertexShader( pBuffer, nBufLen, NULL, &pShader ); + + if ( FAILED( hr ) || !pShader ) + { + Log( "D3D11Device->CreateVertexShader() failed: error %i\n", hr ); + return VERTEX_SHADER_HANDLE_INVALID; + } + + ID3D11ShaderReflection* pInfo; + hr = D3DReflect( pBuffer, nBufLen, IID_ID3D11ShaderReflection, (void**)&pInfo ); + if ( FAILED( hr ) || !pInfo ) + { + pShader->Release(); + return VERTEX_SHADER_HANDLE_INVALID; + } + + // Insert the shader into the dictionary of shaders + VertexShaderIndex_t i = m_VertexShaderDict.AddToTail(); + VertexShader_t& dict = m_VertexShaderDict[i]; + dict.m_pShader = pShader; + dict.m_pInfo = pInfo; + dict.m_nByteCodeLen = nBufLen; + dict.m_pByteCode = new unsigned char[dict.m_nByteCodeLen]; + memcpy( dict.m_pByteCode, pBuffer, dict.m_nByteCodeLen ); + return (VertexShaderHandle_t)i; +} + +void CShaderDeviceDx11::DestroyVertexShader( VertexShaderHandle_t hShader ) +{ + if ( hShader == VERTEX_SHADER_HANDLE_INVALID ) + return; + + g_pShaderAPIDx11->Unbind( hShader ); + + VertexShaderIndex_t i = (VertexShaderIndex_t)hShader; + VertexShader_t &dict = m_VertexShaderDict[i]; + VerifyEquals( dict.m_pShader->Release(), 0 ); + VerifyEquals( dict.m_pInfo->Release(), 0 ); + delete[] dict.m_pByteCode; + ReleaseInputLayouts( i ); + m_VertexShaderDict.Remove( i ); +} + + +//----------------------------------------------------------------------------- +// Create, destroy geometry shader +//----------------------------------------------------------------------------- +GeometryShaderHandle_t CShaderDeviceDx11::CreateGeometryShader( IShaderBuffer* pShaderBuffer ) +{ + return CreateGeometryShader( pShaderBuffer->GetBits(), pShaderBuffer->GetSize() ); +} + +GeometryShaderHandle_t CShaderDeviceDx11::CreateGeometryShader( const void* pBuffer, size_t nBufLen ) +{ + // Create the geometry shader + ID3D11GeometryShader* pShader = NULL; + HRESULT hr = m_pDevice->CreateGeometryShader( pBuffer, + nBufLen, NULL, &pShader ); + + if ( FAILED( hr ) || !pShader ) + return GEOMETRY_SHADER_HANDLE_INVALID; + + ID3D11ShaderReflection* pInfo; + hr = D3DReflect( pBuffer, nBufLen, IID_ID3D11ShaderReflection, (void**)&pInfo ); + if ( FAILED( hr ) || !pInfo ) + { + pShader->Release(); + return GEOMETRY_SHADER_HANDLE_INVALID; + } + + // Insert the shader into the dictionary of shaders + GeometryShaderIndex_t i = m_GeometryShaderDict.AddToTail(); + m_GeometryShaderDict[i].m_pShader = pShader; + m_GeometryShaderDict[i].m_pInfo = pInfo; + return (GeometryShaderHandle_t)i; +} + +void CShaderDeviceDx11::DestroyGeometryShader( GeometryShaderHandle_t hShader ) +{ + if ( hShader == GEOMETRY_SHADER_HANDLE_INVALID ) + return; + + g_pShaderAPIDx11->Unbind( hShader ); + + GeometryShaderIndex_t i = (GeometryShaderIndex_t)hShader; + VerifyEquals( m_GeometryShaderDict[ i ].m_pShader->Release(), 0 ); + VerifyEquals( m_GeometryShaderDict[ i ].m_pInfo->Release(), 0 ); + m_GeometryShaderDict.Remove( i ); +} + + +//----------------------------------------------------------------------------- +// Create, destroy pixel shader +//----------------------------------------------------------------------------- +PixelShaderHandle_t CShaderDeviceDx11::CreatePixelShader( IShaderBuffer* pShaderBuffer ) +{ + return CreatePixelShader( pShaderBuffer->GetBits(), pShaderBuffer->GetSize() ); +} + +PixelShaderHandle_t CShaderDeviceDx11::CreatePixelShader( const void* pBuffer, size_t nBufLen ) +{ + // Create the pixel shader + ID3D11PixelShader* pShader = NULL; + HRESULT hr = m_pDevice->CreatePixelShader( pBuffer, + nBufLen, NULL, &pShader ); + + if ( FAILED( hr ) || !pShader ) + return PIXEL_SHADER_HANDLE_INVALID; + + ID3D11ShaderReflection* pInfo; + hr = D3DReflect( pBuffer, nBufLen, IID_ID3D11ShaderReflection, (void**)&pInfo ); + if ( FAILED( hr ) || !pInfo ) + { + pShader->Release(); + return PIXEL_SHADER_HANDLE_INVALID; + } + + // Insert the shader into the dictionary of shaders + PixelShaderIndex_t i = m_PixelShaderDict.AddToTail(); + m_PixelShaderDict[i].m_pShader = pShader; + m_PixelShaderDict[i].m_pInfo = pInfo; + return (PixelShaderHandle_t)i; +} + +void CShaderDeviceDx11::DestroyPixelShader( PixelShaderHandle_t hShader ) +{ + if ( hShader == PIXEL_SHADER_HANDLE_INVALID ) + return; + + g_pShaderAPIDx11->Unbind( hShader ); + + PixelShaderIndex_t i = (PixelShaderIndex_t)hShader; + VerifyEquals( m_PixelShaderDict[ i ].m_pShader->Release(), 0 ); + VerifyEquals( m_PixelShaderDict[ i ].m_pInfo->Release(), 0 ); + m_PixelShaderDict.Remove( i ); +} + + +//----------------------------------------------------------------------------- +// Finds or creates an input layout for a given vertex shader + stream format +//----------------------------------------------------------------------------- +ID3D11InputLayout* CShaderDeviceDx11::GetInputLayout( VertexShaderHandle_t hShader, VertexFormat_t format, + bool bStaticLit, bool bUsingFlex, bool bUsingMorph ) +{ + if ( hShader == VERTEX_SHADER_HANDLE_INVALID ) + return NULL; + + // FIXME: VertexFormat_t is not the appropriate way of specifying this + // because it has no stream information + InputLayout_t insert; + insert.m_VertexFormat = format; + insert.m_bStaticLit = bStaticLit; + insert.m_bUsingFlex = bUsingFlex; + insert.m_bUsingMorph = bUsingMorph; + + VertexShaderIndex_t i = (VertexShaderIndex_t)hShader; + InputLayoutDict_t &dict = m_VertexShaderDict[i].m_InputLayouts; + unsigned short hIndex = dict.Find( insert ); + if ( hIndex != dict.InvalidIndex() ) + return dict[hIndex].m_pInputLayout; + + VertexShader_t &shader = m_VertexShaderDict[i]; + insert.m_pInputLayout = CreateInputLayout( format, bStaticLit, bUsingFlex, bUsingMorph, shader.m_pInfo, shader.m_pByteCode, shader.m_nByteCodeLen ); + dict.Insert( insert ); + return insert.m_pInputLayout; +} + + +//----------------------------------------------------------------------------- +// Creates/destroys Mesh +//----------------------------------------------------------------------------- +IMesh* CShaderDeviceDx11::CreateStaticMesh( VertexFormat_t vertexFormat, const char *pBudgetGroup, IMaterial * pMaterial ) +{ + LOCK_SHADERAPI(); + return g_pShaderAPIDx11->CreateStaticMesh( vertexFormat, pBudgetGroup, pMaterial ); +} + +void CShaderDeviceDx11::DestroyStaticMesh( IMesh* pMesh ) +{ + LOCK_SHADERAPI(); + g_pShaderAPIDx11->DestroyStaticMesh( pMesh ); +} + + +//----------------------------------------------------------------------------- +// Creates/destroys vertex buffers + index buffers +//----------------------------------------------------------------------------- +IVertexBuffer *CShaderDeviceDx11::CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup ) +{ + LOCK_SHADERAPI(); + CVertexBufferDx11 *pVertexBuffer = new CVertexBufferDx11( type, fmt, nVertexCount, pBudgetGroup ); + return pVertexBuffer; +} + +void CShaderDeviceDx11::DestroyVertexBuffer( IVertexBuffer *pVertexBuffer ) +{ + LOCK_SHADERAPI(); + if ( pVertexBuffer ) + { + CVertexBufferDx11 *pVertexBufferBase = assert_cast( pVertexBuffer ); + g_pShaderAPIDx11->UnbindVertexBuffer( pVertexBufferBase->GetDx11Buffer() ); + delete pVertexBufferBase; + } +} + +IIndexBuffer *CShaderDeviceDx11::CreateIndexBuffer( ShaderBufferType_t type, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup ) +{ + LOCK_SHADERAPI(); + CIndexBufferDx11 *pIndexBuffer = new CIndexBufferDx11( type, fmt, nIndexCount, pBudgetGroup ); + return pIndexBuffer; +} + +void CShaderDeviceDx11::DestroyIndexBuffer( IIndexBuffer *pIndexBuffer ) +{ + LOCK_SHADERAPI(); + if ( pIndexBuffer ) + { + CIndexBufferDx11 *pIndexBufferBase = assert_cast( pIndexBuffer ); + g_pShaderAPIDx11->UnbindIndexBuffer( pIndexBufferBase->GetDx11Buffer() ); + delete pIndexBufferBase; + } +} + +ConstantBufferHandle_t CShaderDeviceDx11::CreateConstantBuffer( size_t nBufLen ) +{ + CShaderConstantBufferDx11 *pBuf = new CShaderConstantBufferDx11; + pBuf->Create( nBufLen ); + return (ConstantBufferHandle_t)pBuf; +} + +void CShaderDeviceDx11::UpdateConstantBuffer( ConstantBufferHandle_t hBuffer, void *pData ) +{ + ( (IShaderConstantBuffer *)hBuffer )->Update( pData ); +} + +void CShaderDeviceDx11::UploadConstantBuffers( ConstantBufferHandle_t *pBuffers, int nBuffers ) +{ + for ( int i = 0; i < nBuffers; i++ ) + { + ( (IShaderConstantBuffer *)pBuffers[i] )->UploadToGPU(); + } +} + +ConstantBufferHandle_t CShaderDeviceDx11::GetInternalConstantBuffer( int buffer ) +{ + return CONSTANT_BUFFER_HANDLE_INVALID; +} + +void CShaderDeviceDx11::DestroyConstantBuffer( ConstantBufferHandle_t hBuffer ) +{ + if ( hBuffer != CONSTANT_BUFFER_HANDLE_INVALID ) + { + IShaderConstantBuffer *pBuffer = (IShaderConstantBuffer *)hBuffer; + pBuffer->Destroy(); + } +} + +// NOTE: I don't see these functions being called by anybody. I think they should be removed. +IVertexBuffer *CShaderDeviceDx11::GetDynamicVertexBuffer( int nStreamID, VertexFormat_t vertexFormat, bool bBuffered ) +{ + LOCK_SHADERAPI(); + return NULL; +} + +IIndexBuffer *CShaderDeviceDx11::GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered ) +{ + LOCK_SHADERAPI(); + return NULL; +} + +char* CShaderDeviceDx11::GetDisplayDeviceName() +{ + if (m_sDisplayDeviceName.IsEmpty()) + { + DXGI_ADAPTER_DESC desc; + g_ShaderDeviceMgrDx11.GetAdapter(m_nAdapter)->GetDesc(&desc); + m_sDisplayDeviceName = (char*)desc.Description; + } + return m_sDisplayDeviceName.GetForModify(); +} + +ShaderAPIOcclusionQuery_t CShaderDeviceDx11::CreateOcclusionQuery() +{ + CD3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_OCCLUSION; + desc.MiscFlags = 0; + ID3D11Query *pQuery = NULL; + HRESULT hr = D3D11Device()->CreateQuery( &desc, &pQuery ); + if ( FAILED( hr ) ) + { + return INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE; + } + return (ShaderAPIOcclusionQuery_t)pQuery; +} + +void CShaderDeviceDx11::DestroyOcclusionQuery( ShaderAPIOcclusionQuery_t hQuery ) +{ + if ( hQuery != INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE ) + { + ( (ID3D11Query *)hQuery )->Release(); + } +} diff --git a/materialsystem/shaderapidx11/shaderdevicedx11.h b/materialsystem/shaderapidx11/shaderdevicedx11.h new file mode 100644 index 0000000..fe3f6ca --- /dev/null +++ b/materialsystem/shaderapidx11/shaderdevicedx11.h @@ -0,0 +1,278 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef SHADERDEVICEDX11_H +#define SHADERDEVICEDX11_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "ShaderConstantBufferDx11.h" +#include "shaderapi/ishaderapi.h" +#include "shaderapidx9/shaderdevicebase.h" +#include "tier1/utlvector.h" +#include "tier1/utlrbtree.h" +#include "tier1/utllinkedlist.h" + +//----------------------------------------------------------------------------- +// Forward declaration +//----------------------------------------------------------------------------- +struct IDXGIFactory; +struct IDXGIAdapter; +struct IDXGIOutput; +struct IDXGISwapChain; +struct ID3D11Device; +struct ID3D11RenderTargetView; +struct ID3D11VertexShader; +struct ID3D11PixelShader; +struct ID3D11GeometryShader; +struct ID3D11InputLayout; +struct ID3D11ShaderReflection; + +//----------------------------------------------------------------------------- +// The Base implementation of the shader device +//----------------------------------------------------------------------------- +class CShaderDeviceMgrDx11 : public CShaderDeviceMgrBase +{ + typedef CShaderDeviceMgrBase BaseClass; + +public: + // constructor, destructor + CShaderDeviceMgrDx11(); + virtual ~CShaderDeviceMgrDx11(); + + // Methods of IAppSystem + virtual bool Connect( CreateInterfaceFn factory ); + virtual void Disconnect(); + virtual InitReturnVal_t Init(); + virtual void Shutdown(); + + // Methods of IShaderDeviceMgr + virtual int GetAdapterCount() const; + virtual void GetAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const; + virtual int GetModeCount( int nAdapter ) const; + virtual void GetModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter, int mode ) const; + virtual void GetCurrentModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter ) const; + virtual bool SetAdapter( int nAdapter, int nFlags ); + virtual CreateInterfaceFn SetMode( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode ); + +private: + // Initialize adapter information + void InitAdapterInfo(); + + // Determines hardware caps from D3D + bool ComputeCapsFromD3D( HardwareCaps_t *pCaps, IDXGIAdapter *pAdapter, IDXGIOutput *pOutput ); + + // Returns the amount of video memory in bytes for a particular adapter + virtual int GetVidMemBytes( int nAdapter ) const; + + // Returns the appropriate adapter output to use + IDXGIOutput* GetAdapterOutput( int nAdapter ) const; + + // Returns the adapter interface for a particular adapter + IDXGIAdapter* GetAdapter( int nAdapter ) const; + + // Used to enumerate adapters, attach to windows + IDXGIFactory1 *m_pDXGIFactory; + + bool m_bObeyDxCommandlineOverride: 1; + + bool m_bSetupAdapters; + + friend class CShaderDeviceDx11; +}; + + +//----------------------------------------------------------------------------- +// The Dx11 implementation of the shader device +//----------------------------------------------------------------------------- +class CShaderDeviceDx11 : public CShaderDeviceBase +{ +public: + // constructor, destructor + CShaderDeviceDx11(); + virtual ~CShaderDeviceDx11(); + +public: + // Methods of IShaderDevice + virtual bool IsUsingGraphics() const; + virtual int GetCurrentAdapter() const; + virtual ImageFormat GetBackBufferFormat() const; + virtual void GetBackBufferDimensions( int& width, int& height ) const; + virtual void SpewDriverInfo() const; + virtual void Present(); + virtual IShaderBuffer* CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion ); + virtual VertexShaderHandle_t CreateVertexShader( IShaderBuffer *pShader ); + VertexShaderHandle_t CreateVertexShader( const void* pBuffer, size_t nBufLen ); + virtual void DestroyVertexShader( VertexShaderHandle_t hShader ); + virtual GeometryShaderHandle_t CreateGeometryShader( IShaderBuffer* pShaderBuffer ); + GeometryShaderHandle_t CreateGeometryShader( const void* pBuffer, size_t nBufLen ); + virtual void DestroyGeometryShader( GeometryShaderHandle_t hShader ); + virtual PixelShaderHandle_t CreatePixelShader( IShaderBuffer* pShaderBuffer ); + PixelShaderHandle_t CreatePixelShader( const void* pBuffer, size_t nBufLen ); + virtual void DestroyPixelShader( PixelShaderHandle_t hShader ); + virtual void ReleaseResources() {} + virtual void ReacquireResources() {} + virtual IMesh* CreateStaticMesh( VertexFormat_t format, const char *pTextureBudgetGroup, IMaterial * pMaterial ); + virtual void DestroyStaticMesh( IMesh* mesh ); + virtual IVertexBuffer *CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pTextureBudgetGroup ); + virtual void DestroyVertexBuffer( IVertexBuffer *pVertexBuffer ); + virtual IIndexBuffer *CreateIndexBuffer( ShaderBufferType_t type, MaterialIndexFormat_t fmt, int nIndexCount, const char *pTextureBudgetGroup ); + virtual void DestroyIndexBuffer( IIndexBuffer *pIndexBuffer ); + virtual ConstantBufferHandle_t CreateConstantBuffer( size_t nBufSize ); + virtual void UpdateConstantBuffer( ConstantBufferHandle_t hBuffer, void *pData ); + virtual void UploadConstantBuffers( ConstantBufferHandle_t *pBuffers, int nBuffers ); + virtual void DestroyConstantBuffer( ConstantBufferHandle_t hBuffer ); + virtual ConstantBufferHandle_t GetInternalConstantBuffer( int type ); + virtual IVertexBuffer *GetDynamicVertexBuffer( int nStreamID, VertexFormat_t vertexFormat, bool bBuffered = true ); + virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true ); + virtual void SetHardwareGammaRamp( float fGamma, float fGammaTVRangeMin, float fGammaTVRangeMax, float fGammaTVExponent, bool bTVEnabled ); + + // A special path used to tick the front buffer while loading on the 360 + virtual void EnableNonInteractiveMode( MaterialNonInteractiveMode_t mode, ShaderNonInteractiveInfo_t *pInfo ) {} + virtual void RefreshFrontBufferNonInteractive( ) {} + virtual void HandleThreadEvent(uint32 threadEvent) {}; + + virtual char* GetDisplayDeviceName(); + + ShaderAPIOcclusionQuery_t CreateOcclusionQuery(); + void DestroyOcclusionQuery( ShaderAPIOcclusionQuery_t hQuery ); + +public: + // Methods of CShaderDeviceBase + virtual bool InitDevice( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode ); + virtual void ShutdownDevice(); + virtual bool IsDeactivated() const { return !m_bDeviceInitialized; } + + // Other public methods + ID3D11VertexShader* GetVertexShader( VertexShaderHandle_t hShader ) const; + ID3D11GeometryShader* GetGeometryShader( GeometryShaderHandle_t hShader ) const; + ID3D11PixelShader* GetPixelShader( PixelShaderHandle_t hShader ) const; + ID3D11InputLayout* GetInputLayout( VertexShaderHandle_t hShader, VertexFormat_t format, + bool bStaticLit, bool bUsingFlex, bool bUsingMorph ); + +private: + struct InputLayout_t + { + ID3D11InputLayout *m_pInputLayout; + VertexFormat_t m_VertexFormat; + bool m_bStaticLit; + bool m_bUsingFlex; + bool m_bUsingMorph; + + InputLayout_t() + { + m_pInputLayout = NULL; + m_VertexFormat = VERTEX_FORMAT_UNKNOWN; + m_bStaticLit = false; + m_bUsingFlex = false; + m_bUsingMorph = false; + } + }; + + typedef CUtlRBTree< InputLayout_t, unsigned short > InputLayoutDict_t; + + static bool InputLayoutLessFunc( const InputLayout_t &lhs, const InputLayout_t &rhs ) + { + if ( lhs.m_VertexFormat != rhs.m_VertexFormat ) + { + return lhs.m_VertexFormat < rhs.m_VertexFormat; + } + if ( lhs.m_bStaticLit != rhs.m_bStaticLit ) + { + return lhs.m_bStaticLit < rhs.m_bStaticLit; + } + if ( lhs.m_bUsingFlex != rhs.m_bUsingFlex ) + { + return lhs.m_bUsingFlex < rhs.m_bUsingFlex; + } + return lhs.m_bUsingMorph < rhs.m_bUsingMorph; + } + + struct VertexShader_t + { + ID3D11VertexShader *m_pShader; + ID3D11ShaderReflection *m_pInfo; + void *m_pByteCode; + size_t m_nByteCodeLen; + InputLayoutDict_t m_InputLayouts; + + VertexShader_t() : m_InputLayouts( 0, 0, InputLayoutLessFunc ) {} + }; + + struct GeometryShader_t + { + ID3D11GeometryShader *m_pShader; + ID3D11ShaderReflection *m_pInfo; + }; + + struct PixelShader_t + { + ID3D11PixelShader *m_pShader; + ID3D11ShaderReflection *m_pInfo; + }; + + typedef CUtlFixedLinkedList< VertexShader_t >::IndexType_t VertexShaderIndex_t; + typedef CUtlFixedLinkedList< GeometryShader_t >::IndexType_t GeometryShaderIndex_t; + typedef CUtlFixedLinkedList< PixelShader_t >::IndexType_t PixelShaderIndex_t; + + void SetupHardwareCaps(); + void ReleaseInputLayouts( VertexShaderIndex_t nIndex ); + + bool m_bDeviceInitialized; + + IDXGIOutput *m_pOutput; + ID3D11Device *m_pDevice; + ID3D11DeviceContext* m_pDeviceContext; + IDXGISwapChain *m_pSwapChain; + + CUtlFixedLinkedList< VertexShader_t > m_VertexShaderDict; + CUtlFixedLinkedList< GeometryShader_t > m_GeometryShaderDict; + CUtlFixedLinkedList< PixelShader_t > m_PixelShaderDict; + + friend ID3D11Device *D3D11Device(); + friend ID3D11DeviceContext *D3D11DeviceContext(); + friend IDXGISwapChain *D3D11SwapChain(); + + CUtlString m_sDisplayDeviceName; + + friend class CShaderDeviceMgrDx11; +}; + +//----------------------------------------------------------------------------- +// Inline methods of CShaderDeviceDx11 +//----------------------------------------------------------------------------- +inline ID3D11VertexShader* CShaderDeviceDx11::GetVertexShader( VertexShaderHandle_t hShader ) const +{ + if ( hShader != VERTEX_SHADER_HANDLE_INVALID ) + return m_VertexShaderDict[ (VertexShaderIndex_t)hShader ].m_pShader; + return NULL; +} + +inline ID3D11GeometryShader* CShaderDeviceDx11::GetGeometryShader( GeometryShaderHandle_t hShader ) const +{ + if ( hShader != GEOMETRY_SHADER_HANDLE_INVALID ) + return m_GeometryShaderDict[ (GeometryShaderIndex_t)hShader ].m_pShader; + return NULL; +} + +inline ID3D11PixelShader* CShaderDeviceDx11::GetPixelShader( PixelShaderHandle_t hShader ) const +{ + if ( hShader != PIXEL_SHADER_HANDLE_INVALID ) + return m_PixelShaderDict[ (PixelShaderIndex_t)hShader ].m_pShader; + return NULL; +} + +//----------------------------------------------------------------------------- +// Singleton +//----------------------------------------------------------------------------- +extern CShaderDeviceDx11* g_pShaderDeviceDx11; + +#endif // SHADERDEVICEDX11_H \ No newline at end of file diff --git a/materialsystem/shaderapidx11/shadershadowdx11.cpp b/materialsystem/shaderapidx11/shadershadowdx11.cpp new file mode 100644 index 0000000..78b1ac2 --- /dev/null +++ b/materialsystem/shaderapidx11/shadershadowdx11.cpp @@ -0,0 +1,607 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +// HUH??? +#define RAD_TELEMETRY_DISABLED + +#include "shadershadowdx11.h" +#include "utlvector.h" +#include "materialsystem/imaterialsystem.h" +#include "IHardwareConfigInternal.h" +//#include "shadersystem.h" +//#include "shaderapi/ishaderutil.h" +#include "shaderapidx11_global.h" +#include "materialsystem/imesh.h" +#include "tier0/dbg.h" +#include "materialsystem/idebugtextureinfo.h" +#include "vertexshaderdx11.h" + +#include "shaderapidx11.h" +#include "shaderdevicedx11.h" +#include "meshdx11.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Class Factory +//----------------------------------------------------------------------------- +static CShaderShadowDx11 s_ShaderShadow; +CShaderShadowDx11 *g_pShaderShadowDx11 = &s_ShaderShadow; + +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderShadowDx11, IShaderShadow, + SHADERSHADOW_INTERFACE_VERSION, s_ShaderShadow ) + +//----------------------------------------------------------------------------- +// The shader shadow interface +//----------------------------------------------------------------------------- +CShaderShadowDx11::CShaderShadowDx11() +{ + // Setup default shadow states + + m_DefaultShadowState.desc.SetDefault(); + + m_DefaultCBState.SetDefault(); + unsigned int iDefaultCB = FindOrCreateConstantBufferState( m_DefaultCBState ); + m_DefaultShadowState.m_iGSConstantBufferState = iDefaultCB; + m_DefaultShadowState.m_iPSConstantBufferState = iDefaultCB; + m_DefaultShadowState.m_iVSConstantBufferState = iDefaultCB; + + m_DefaultDepthStencilState.SetDefault(); + m_DefaultRasterState.SetDefault(); + m_DefaultBlendState.SetDefault(); +} + +CShaderShadowDx11::~CShaderShadowDx11() +{ +} + +// Sets the default *shadow* state +void CShaderShadowDx11::SetDefaultState() +{ + m_ShadowState = StatesDx11::ShadowStateDesc(); + m_ShadowState.SetDefault(); +} + +// Methods related to depth buffering +void CShaderShadowDx11::DepthFunc( ShaderDepthFunc_t depthFunc ) +{ + m_ShadowState.depthStencil.DepthFunc = (D3D11_COMPARISON_FUNC)depthFunc; +} + +void CShaderShadowDx11::EnableDepthWrites( bool bEnable ) +{ + m_ShadowState.depthStencil.DepthWriteMask = bEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; +} + +void CShaderShadowDx11::EnableDepthTest( bool bEnable ) +{ + m_ShadowState.depthStencil.DepthEnable = bEnable; +} + +void CShaderShadowDx11::EnablePolyOffset( PolygonOffsetMode_t nOffsetMode ) +{ + //m_ShadowState.rasterizer.DepthBias = +} + +// Suppresses/activates color writing +void CShaderShadowDx11::EnableColorWrites( bool bEnable ) +{ + if ( bEnable ) + { + m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask |= + D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | + D3D11_COLOR_WRITE_ENABLE_BLUE; + } + else + { + m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask &= + ~( D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | + D3D11_COLOR_WRITE_ENABLE_BLUE ); + } + +} + +// Suppresses/activates alpha writing +void CShaderShadowDx11::EnableAlphaWrites( bool bEnable ) +{ + if ( bEnable ) + { + m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + } + else + { + m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask &= ~D3D11_COLOR_WRITE_ENABLE_ALPHA; + } +} + +// Methods related to alpha blending +void CShaderShadowDx11::EnableBlending( bool bEnable ) +{ + m_ShadowState.blend.RenderTarget[0].BlendEnable = bEnable ? TRUE : FALSE; +} + +void CShaderShadowDx11::BlendFunc( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor ) +{ + m_ShadowState.blend.RenderTarget[0].SrcBlend = TranslateD3D11BlendFunc( srcFactor ); + m_ShadowState.blend.RenderTarget[0].DestBlend = TranslateD3D11BlendFunc( dstFactor ); +} + +// Alpha testing +// NOTE: Unused since alpha testing is no longer fixed-function in DX11. +// Just set an ALPHA_TEST combo in your shader and provide the +// reference value as a constant. +// +void CShaderShadowDx11::EnableAlphaTest( bool bEnable ) +{ + //m_ShadowState.bEnableAlphaTest = bEnable; +} + +void CShaderShadowDx11::AlphaFunc( ShaderAlphaFunc_t alphaFunc, float alphaRef /* [0-1] */ ) +{ + //m_ShadowState.alphaTestFunc = alphaFunc; + //m_ShadowState.alphaTestRef = alphaRef; +} + +// Wireframe/filled polygons +void CShaderShadowDx11::PolyMode( ShaderPolyModeFace_t face, ShaderPolyMode_t polyMode ) +{ + D3D11_FILL_MODE mode; + switch ( polyMode ) + { + case SHADER_POLYMODE_FILL: + mode = D3D11_FILL_SOLID; + break; + case SHADER_POLYMODE_LINE: + case SHADER_POLYMODE_POINT: + default: + mode = D3D11_FILL_WIREFRAME; + break; + } + m_ShadowState.rasterizer.FillMode = mode; + //m_ShadowState.rasterizer.CullMode = + //m_ShadowState.renderModeAttrib.polyMode = polyMode; +// m_ShadowState.renderModeAttrib.faceMode = face; +} + + +// Back face culling +void CShaderShadowDx11::EnableCulling( bool bEnable ) +{ + // DX11FIXME + //m_ShadowState.cullFaceAttrib.bEnable = bEnable; + m_ShadowState.rasterizer.CullMode = bEnable ? D3D11_CULL_BACK : D3D11_CULL_NONE; + //m_ShadowState.cullFaceAttrib.cullMode = MATERIAL_CULLMODE_CCW; +} + +// constant color + transparency +void CShaderShadowDx11::EnableConstantColor( bool bEnable ) +{ + //m_ShadowState.bConstantColor = bEnable; +} + + +// Indicates the vertex format for use with a vertex shader +// The flags to pass in here come from the VertexFormatFlags_t enum +// If pTexCoordDimensions is *not* specified, we assume all coordinates +// are 2-dimensional +void CShaderShadowDx11::VertexShaderVertexFormat( unsigned int flags, + int numTexCoords, int* pTexCoordDimensions, + int userDataSize ) +{ + // Code that creates a Mesh should specify whether it contains bone weights+indices, *not* the shader. + Assert( ( flags & VERTEX_BONE_INDEX ) == 0 ); + flags &= ~VERTEX_BONE_INDEX; + + // This indicates we're using a vertex shader + flags |= VERTEX_FORMAT_VERTEX_SHADER; + m_ShadowState.vertexFormat = MeshMgr()->ComputeVertexFormat( flags, numTexCoords, + pTexCoordDimensions, 0, userDataSize ); + // Avoid an error if vertex stream 0 is too narrow + if ( CVertexBufferBase::VertexFormatSize( m_ShadowState.vertexFormat ) <= 16 ) + { + // FIXME: this is only necessary because we + // (a) put the flex normal/position stream in ALL vertex decls + // (b) bind stream 0's VB to stream 2 if there is no actual flex data + // ...it would be far more sensible to not add stream 2 to all vertex decls. + static bool bComplained = false; + if ( !bComplained ) + { + Warning( "ERROR: shader asking for a too-narrow vertex format - you will see errors if running with debug D3D DLLs!\n\tPadding the vertex format with extra texcoords\n\tWill not warn again.\n" ); + bComplained = true; + } + // All vertex formats should contain position... + Assert( flags & VERTEX_POSITION ); + flags |= VERTEX_POSITION; + // This error should occur only if we have zero texcoords, or if we have a single, 1-D texcoord + Assert( ( userDataSize == 0 ) || + ( ( userDataSize == 1 ) && pTexCoordDimensions && ( pTexCoordDimensions[0] == 1 ) ) ); + numTexCoords = 1; + m_ShadowState.vertexFormat = MeshMgr()->ComputeVertexFormat( + flags, numTexCoords, NULL, 0, userDataSize ); + } +} + +// Indicates we're going to light the model +void CShaderShadowDx11::EnableLighting( bool bEnable ) +{ + //m_ShadowState.bLighting = bEnable; +} + +// Activate/deactivate skinning +void CShaderShadowDx11::EnableVertexBlend( bool bEnable ) +{ + // Activate/deactivate skinning. Indexed blending is automatically + // enabled if it's available for this hardware. When blending is enabled, + // we allocate enough room for 3 weights (max allowed) + //if ( ( HardwareConfig()->MaxBlendMatrices() > 0 ) || ( !bEnable ) ) + //{ + //m_ShadowState.bVertexBlend = bEnable; + //} +} + +void CShaderShadowDx11::EnableTexture( Sampler_t sampler, bool bEnable ) +{ + //if ( sampler < HardwareConfig()->GetSamplerCount() ) + //{ + // m_ShadowState.samplerAttrib.EnableTexture( sampler, bEnable ); + //} + //else + //{ + // Warning( "Attempting to bind a texture to an invalid sampler (%d)!\n", sampler ); + //} +} + +// Sets the vertex and pixel shaders +void CShaderShadowDx11::SetVertexShader( const char *pShaderName, ShaderIndex_t vshIndex ) +{ + m_ShadowState.vertexShader = ShaderManager()->CreateVertexShader( pShaderName, vshIndex ); + m_ShadowState.staticVertexShaderIndex = vshIndex; +} + +void CShaderShadowDx11::EnableBlendingSeparateAlpha( bool bEnable ) +{ + // DX11FIXME + //m_ShadowState.m_SeparateAlphaBlendEnable = bEnable; + //m_ShadowState.colorBlendAttrib.bIndependentAlphaBlend = bEnable; +} + +void CShaderShadowDx11::SetPixelShader( const char *pShaderName, ShaderIndex_t pshIndex ) +{ + m_ShadowState.pixelShader = ShaderManager()->CreatePixelShader( pShaderName, pshIndex ); + m_ShadowState.staticPixelShaderIndex = pshIndex; +} + +void CShaderShadowDx11::SetMorphFormat( MorphFormat_t flags ) +{ + m_ShadowState.morphFormat = flags; +} + +void CShaderShadowDx11::EnableStencil( bool bEnable ) +{ + m_ShadowState.depthStencil.StencilEnable = bEnable; +} + +void CShaderShadowDx11::StencilFunc( ShaderStencilFunc_t stencilFunc ) +{ + m_ShadowState.depthStencil.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)stencilFunc; +} + +void CShaderShadowDx11::StencilPassOp( ShaderStencilOp_t stencilOp ) +{ + m_ShadowState.depthStencil.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)stencilOp; +} + +void CShaderShadowDx11::StencilFailOp( ShaderStencilOp_t stencilOp ) +{ + m_ShadowState.depthStencil.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)stencilOp; +} + +void CShaderShadowDx11::StencilDepthFailOp( ShaderStencilOp_t stencilOp ) +{ + m_ShadowState.depthStencil.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)stencilOp; +} + +void CShaderShadowDx11::StencilReference( int nReference ) +{ + m_ShadowState.depthStencil.StencilRef = nReference; +} + +void CShaderShadowDx11::StencilMask( int nMask ) +{ + m_ShadowState.depthStencil.StencilWriteMask = nMask; +} + +void CShaderShadowDx11::StencilWriteMask( int nMask ) +{ + m_ShadowState.depthStencil.StencilReadMask = nMask; +} + +void CShaderShadowDx11::BlendFuncSeparateAlpha( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor ) +{ + //m_ShadowState.colorBlendAttrib.bIndependentAlphaBlend = true; + m_ShadowState.blend.RenderTarget[0].SrcBlendAlpha = TranslateD3D11BlendFunc( srcFactor ); + m_ShadowState.blend.RenderTarget[0].DestBlendAlpha = TranslateD3D11BlendFunc( dstFactor ); +} + +// Alpha to coverage +void CShaderShadowDx11::EnableAlphaToCoverage( bool bEnable ) +{ + m_ShadowState.blend.AlphaToCoverageEnable = bEnable ? TRUE : FALSE; +} + +void CShaderShadowDx11::FogMode( ShaderFogMode_t fogMode ) +{ + m_ShadowState.fogMode = fogMode; +} + + +StateSnapshot_t CShaderShadowDx11::FindOrCreateSnapshot() +{ + StatesDx11::ShadowState lookup; + lookup.desc = m_ShadowState; + int i = m_ShadowStates.Find( lookup ); + if ( i != m_ShadowStates.InvalidIndex() ) + { + return i; + } + + // Didn't find it, add entry + + lookup.m_iBlendState = FindOrCreateBlendState( lookup.desc.blend ); + lookup.m_iDepthStencilState = FindOrCreateDepthStencilState( lookup.desc.depthStencil ); + lookup.m_iRasterState = FindOrCreateRasterState( lookup.desc.rasterizer ); + lookup.m_iVSConstantBufferState = FindOrCreateConstantBufferState( lookup.desc.vsConstantBuffers ); + lookup.m_iGSConstantBufferState = FindOrCreateConstantBufferState( lookup.desc.gsConstantBuffers ); + lookup.m_iPSConstantBufferState = FindOrCreateConstantBufferState( lookup.desc.psConstantBuffers ); + + StateSnapshot_t snap = m_ShadowStates.AddToTail( lookup ); + return snap; +} + +const StatesDx11::ShadowState *CShaderShadowDx11::GetShadowState( StateSnapshot_t id ) +{ + if ( id == DEFAULT_SHADOW_STATE_ID ) + return GetDefaultShadowState(); + + return &m_ShadowStates.Element( id ); +} + +const StatesDx11::ShadowState *CShaderShadowDx11::GetDefaultShadowState() +{ + if ( !m_DefaultShadowState.desc.blend.m_pD3DState ) + { + // Needed to wait until this was called to create the D3D state objects because + // D3D is not initialized when the constructor of this class is called. + + m_DefaultDepthStencilState.SetDefault(); + unsigned int iDefaultDS = FindOrCreateDepthStencilState( m_DefaultDepthStencilState ); + m_DefaultShadowState.desc.depthStencil = m_DefaultDepthStencilState; + m_DefaultShadowState.m_iDepthStencilState = iDefaultDS; + + m_DefaultRasterState.SetDefault(); + unsigned int iDefaultRS = FindOrCreateRasterState( m_DefaultRasterState ); + m_DefaultShadowState.desc.rasterizer = m_DefaultRasterState; + m_DefaultShadowState.m_iRasterState = iDefaultRS; + + m_DefaultBlendState.SetDefault(); + unsigned int iDefaultBS = FindOrCreateBlendState( m_DefaultBlendState ); + m_DefaultShadowState.desc.blend = m_DefaultBlendState; + m_DefaultShadowState.m_iBlendState = iDefaultBS; + } + + return &m_DefaultShadowState; +} + +// Constant buffer setting + +void CShaderShadowDx11::SetVertexShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer ) +{ + m_ShadowState.vsConstantBuffers.m_ppBuffers[slot] = ( (CShaderConstantBufferDx11 *)cbuffer )->GetD3DBuffer(); + if ( slot > m_ShadowState.vsConstantBuffers.m_MaxSlot ) + { + m_ShadowState.vsConstantBuffers.m_MaxSlot = slot; + } +} + +void CShaderShadowDx11::SetVertexShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer ) +{ + SetVertexShaderConstantBuffer( slot, g_pShaderAPIDx11->GetInternalConstantBuffer( cbuffer ) ); +} + +void CShaderShadowDx11::SetGeometryShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer ) +{ + m_ShadowState.gsConstantBuffers.m_ppBuffers[slot] = ( (CShaderConstantBufferDx11 *)cbuffer )->GetD3DBuffer(); + if ( slot > m_ShadowState.gsConstantBuffers.m_MaxSlot ) + { + m_ShadowState.gsConstantBuffers.m_MaxSlot = slot; + } +} + +void CShaderShadowDx11::SetGeometryShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer ) +{ + SetGeometryShaderConstantBuffer( slot, g_pShaderAPIDx11->GetInternalConstantBuffer( cbuffer ) ); +} + +void CShaderShadowDx11::SetPixelShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer ) +{ + m_ShadowState.psConstantBuffers.m_ppBuffers[slot] = ( (CShaderConstantBufferDx11 *)cbuffer )->GetD3DBuffer(); + if ( slot > m_ShadowState.psConstantBuffers.m_MaxSlot ) + { + m_ShadowState.psConstantBuffers.m_MaxSlot = slot; + } +} + +void CShaderShadowDx11::SetPixelShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer ) +{ + SetPixelShaderConstantBuffer( slot, g_pShaderAPIDx11->GetInternalConstantBuffer( cbuffer ) ); +} + +unsigned int CShaderShadowDx11::FindOrCreateConstantBufferState( StatesDx11::ConstantBufferDesc &desc ) +{ + int i = m_ConstantBufferStates.Find( desc ); + if ( m_ConstantBufferStates.IsValidIndex( i ) ) + { + return i; + } + + // Make a new state + return m_ConstantBufferStates.AddToTail( desc ); +} + +unsigned int CShaderShadowDx11::FindOrCreateDepthStencilState( StatesDx11::DepthStencilDesc &desc ) +{ + int i = m_DepthStencilStates.Find( desc ); + if ( m_DepthStencilStates.IsValidIndex( i ) ) + { + desc.m_pD3DState = m_DepthStencilStates[i].m_pD3DState; + return i; + } + + D3D11Device()->CreateDepthStencilState( &desc, &desc.m_pD3DState ); + Assert( SUCCEEDED( hr ) ); + + i = m_DepthStencilStates.AddToTail( desc ); + return i; +} + +unsigned int CShaderShadowDx11::FindOrCreateBlendState( StatesDx11::BlendDesc &desc ) +{ + int i = m_BlendStates.Find( desc ); + if ( m_BlendStates.IsValidIndex( i ) ) + { + desc.m_pD3DState = m_BlendStates[i].m_pD3DState; + return i; + } + + D3D11Device()->CreateBlendState( &desc, &desc.m_pD3DState ); + Assert( SUCCEEDED( hr ) ); + + i = m_BlendStates.AddToTail( desc ); + return i; +} + +unsigned int CShaderShadowDx11::FindOrCreateRasterState( StatesDx11::RasterDesc &desc ) +{ + int i = m_RasterizerStates.Find( desc ); + if ( m_RasterizerStates.IsValidIndex( i ) ) + { + desc.m_pD3DState = m_RasterizerStates[i].m_pD3DState; + return i; + } + + D3D11Device()->CreateRasterizerState( &desc, &desc.m_pD3DState ); + Assert( SUCCEEDED( hr ) ); + + i = m_RasterizerStates.AddToTail( desc ); + return i; +} + +// --------------------------------------------------- +// Below are unsupported by Dx11, only included to +// not break compatibility with Dx9. +// --------------------------------------------------- + +// A simpler method of dealing with alpha modulation +void CShaderShadowDx11::EnableAlphaPipe( bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableAlphaPipe() called\n" ); +} + +void CShaderShadowDx11::EnableConstantAlpha( bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableConstantAlpha() called\n" ); +} + +void CShaderShadowDx11::EnableVertexAlpha( bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableVertexAlpha() called\n" ); +} + +void CShaderShadowDx11::EnableTextureAlpha( TextureStage_t stage, bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableTextureAlpha() called\n" ); +} + +void CShaderShadowDx11::SetShadowDepthFiltering( Sampler_t stage ) +{ + //Warning( "Unsupported CShaderShadowDx11::SetShadowDepthFiltering() called\n" ); +} + +void CShaderShadowDx11::EnableCustomPixelPipe( bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableCustomPixelPipe() called\n" ); +} + +void CShaderShadowDx11::CustomTextureStages( int stageCount ) +{ + //Warning( "Unsupported CShaderShadowDx11::CustomTextureStages() called\n" ); +} + +void CShaderShadowDx11::CustomTextureOperation( TextureStage_t stage, ShaderTexChannel_t channel, + ShaderTexOp_t op, ShaderTexArg_t arg1, ShaderTexArg_t arg2 ) +{ + //Warning( "Unsupported CShaderShadowDx11::CustomTextureOperation() called\n" ); +} + +void CShaderShadowDx11::EnableSRGBWrite( bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableSRGBWrite() called\n" ); +} + +void CShaderShadowDx11::EnableSRGBRead( Sampler_t stage, bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableSRGBRead() called\n" ); +} +void CShaderShadowDx11::SetDiffuseMaterialSource( ShaderMaterialSource_t materialSource ) +{ + //Warning( "Unsupported CShaderShadowDx11::SetDiffuseMaterialSource() called\n" ); +} + +void CShaderShadowDx11::EnableTexGen( TextureStage_t stage, bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableTexGen() called\n" ); +} + +void CShaderShadowDx11::TexGen( TextureStage_t stage, ShaderTexGenParam_t param ) +{ + //Warning( "Unsupported CShaderShadowDx11::TexGen() called\n" ); +} + +// per texture unit stuff +void CShaderShadowDx11::OverbrightValue( TextureStage_t stage, float value ) +{ + //Warning( "Unsupported CShaderShadowDx11::OverbrightValue() called\n" ); +} + +void CShaderShadowDx11::DisableFogGammaCorrection( bool bDisable ) +{ + m_ShadowState.disableFogGammaCorrection = bDisable; +} + +void CShaderShadowDx11::EnableSpecular( bool bEnable ) +{ + //Warning( "Unsupported CShaderShadowDx11::EnableSpecular() called!\n" ); +} + +// indicates what per-vertex data we're providing +void CShaderShadowDx11::DrawFlags( unsigned int drawFlags ) +{ + //Warning( "Unsupported CShaderShadowDx11::DrawFlags() called!\n" ); +} + +void CShaderShadowDx11::BlendOp(ShaderBlendOp_t blendOp) +{ + //Warning( "Unsupported CShaderShadowDx11::BlendOp() called!\n" ); +} + +void CShaderShadowDx11::BlendOpSeparateAlpha(ShaderBlendOp_t blendOp) +{ + //Warning( "Unsupported CShaderShadowDx11::BlendOpSeparateAlpha() called!\n" ); +} diff --git a/materialsystem/shaderapidx11/vertexshaderdx11.cpp b/materialsystem/shaderapidx11/vertexshaderdx11.cpp new file mode 100644 index 0000000..333c20f --- /dev/null +++ b/materialsystem/shaderapidx11/vertexshaderdx11.cpp @@ -0,0 +1,2558 @@ +//==== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// +// +// Vertex/Pixel Shaders +// +//===========================================================================// + +#if defined( _WIN32 ) && !defined( _X360 ) +#include +#endif +#include "vertexshaderdx11.h" +#include "tier1/UtlSymbol.h" +#include "tier1/UtlVector.h" +#include "tier1/UtlDict.h" +#include "tier1/utllinkedlist.h" +#include "tier1/UtlBuffer.h" +#include "tier1/UtlStringMap.h" +#include "shaderapidx9/locald3dtypes.h" +#include "shaderapidx11_global.h" +#include "shaderapidx9/recording.h" +#include "tier0/vprof.h" +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "shaderapidx11.h" +#include "materialsystem/ishader.h" +#include "ishadersystem.h" +#include "tier0/fasttimer.h" +#include +#include "filesystem.h" +#include "convar.h" +#include "materialsystem/shader_vcs_version.h" +#include "tier1/lzmadecoder.h" +#include "tier1/utlmap.h" + +#include "datacache/idatacache.h" +#include "tier1/diff.h" +#include "shaderdevicedx11.h" +#include "filesystem/IQueuedLoader.h" +#include "tier2/tier2.h" +#include "shaderapi/ishaderutil.h" +#include "tier0/icommandline.h" + +#include "Color.h" +#include "tier0/dbg.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +#if 0 //def USE_ACTUAL_DX + +#include "../utils/bzip2/bzlib.h" + +#else + +int BZ2_bzBuffToBuffDecompress( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int _small, + int verbosity +) +{ + return 0; +} + +#endif + + +// uncomment to get dynamic compilation for HLSL shaders +// i don't think this works atm, but im probably using this wrong +// X360 NOTE: By default, the system looks for a shared folder named "stdshaders" on the host machine and is completely compatible with -dvd. Ensure that the share is writable if you plan on generating UPDB's. +#define DYNAMIC_SHADER_COMPILE + +// uncomment to get spew about what combos are being compiled. +//#define DYNAMIC_SHADER_COMPILE_VERBOSE + +// uncomment and fill in with a path to use a specific set of shader source files. Meant for network use. +// PC path format is of style "\\\\somemachine\\sourcetreeshare\\materialsystem\\stdshaders" +// Xbox path format is of style "net:\\smb\\somemachine\\sourcetreeshare\\materialsystem\\stdshaders" +// - Xbox dynamic compiles without a custom path default to look directly for "stdshaders" share on host pc + +//#define DYNAMIC_SHADER_COMPILE_CUSTOM_PATH "" + +// uncomment to get disassembled (asm) shader code in your game dir as *.asm +//#define DYNAMIC_SHADER_COMPILE_WRITE_ASSEMBLY + +// uncomment to get disassembled (asm) shader code in your game dir as *.asm +//#define WRITE_ASSEMBLY + +//#define PROFILE_SHADER_CREATE + +// debugging aid +#define MAX_SHADER_HISTORY 16 + +#if !defined( _X360 ) +#define SHADER_FNAME_EXTENSION ".vcs" +#else +#define SHADER_FNAME_EXTENSION ".360.vcs" +#endif + +#ifdef DYNAMIC_SHADER_COMPILE +volatile static char s_ShaderCompileString[]="dynamic_shader_compile_is_on"; +#endif + +static const char *GetLightTypeName( VertexShaderLightTypes_t type ) +{ + static const char *s_VertexShaderLightTypeNames[] = + { + "LIGHT_NONE", + "LIGHT_SPOT", + "LIGHT_POINT", + "LIGHT_DIRECTIONAL", + "LIGHT_STATIC", + "LIGHT_AMBIENTCUBE", + }; + return s_VertexShaderLightTypeNames[type+1]; +} + +#ifdef PROFILE_SHADER_CREATE +static FILE *GetDebugFileHandle( void ) +{ + static FILE *fp = NULL; + if( !fp ) + { + fp = fopen( "shadercreate.txt", "w" ); + Assert( fp ); + } + return fp; +} +#endif // PROFILE_SHADER_CREATE + + +//----------------------------------------------------------------------------- +// Explicit instantiation of shader buffer implementation +//----------------------------------------------------------------------------- +template class CShaderBuffer< ID3DBlob >; + + +//----------------------------------------------------------------------------- +// Used to find unique shaders +//----------------------------------------------------------------------------- +#ifdef MEASURE_DRIVER_ALLOCATIONS +static CUtlMap< CRC32_t, int, int > s_UniqueVS( 0, 0, DefLessFunc( CRC32_t ) ); +static CUtlMap< CRC32_t, int, int > s_UniquePS( 0, 0, DefLessFunc( CRC32_t ) ); +static CUtlMap< IDirect3DVertexShader9*, CRC32_t, int > s_VSLookup( 0, 0, DefLessFunc( IDirect3DVertexShader9* ) ); +static CUtlMap< IDirect3DPixelShader9*, CRC32_t, int > s_PSLookup( 0, 0, DefLessFunc( IDirect3DPixelShader9* ) ); +#endif + +static void RegisterVS( const void* pShaderBits, int nShaderSize, ID3D11VertexShader* pShader ) +{ +#ifdef MEASURE_DRIVER_ALLOCATIONS + CRC32_t crc; + CRC32_Init( &crc ); + CRC32_ProcessBuffer( &crc, pShaderBits, nShaderSize ); + CRC32_Final( &crc ); + + s_VSLookup.Insert( pShader, crc ); + + int nIndex = s_UniqueVS.Find( crc ); + if ( nIndex != s_UniqueVS.InvalidIndex() ) + { + ++s_UniqueVS[nIndex]; + } + else + { + int nMemUsed = 23 * 1024; + s_UniqueVS.Insert( crc, 1 ); + VPROF_INCREMENT_GROUP_COUNTER( "unique vs count", COUNTER_GROUP_NO_RESET, 1 ); + VPROF_INCREMENT_GROUP_COUNTER( "vs driver mem", COUNTER_GROUP_NO_RESET, nMemUsed ); + VPROF_INCREMENT_GROUP_COUNTER( "total driver mem", COUNTER_GROUP_NO_RESET, nMemUsed ); + } +#endif +} + +static void RegisterPS( const void* pShaderBits, int nShaderSize, ID3D11PixelShader* pShader ) +{ +#ifdef MEASURE_DRIVER_ALLOCATIONS + CRC32_t crc; + CRC32_Init( &crc ); + CRC32_ProcessBuffer( &crc, pShaderBits, nShaderSize ); + CRC32_Final( &crc ); + + s_PSLookup.Insert( pShader, crc ); + + int nIndex = s_UniquePS.Find( crc ); + if ( nIndex != s_UniquePS.InvalidIndex() ) + { + ++s_UniquePS[nIndex]; + } + else + { + int nMemUsed = 400; + s_UniquePS.Insert( crc, 1 ); + VPROF_INCREMENT_GROUP_COUNTER( "unique ps count", COUNTER_GROUP_NO_RESET, 1 ); + VPROF_INCREMENT_GROUP_COUNTER( "ps driver mem", COUNTER_GROUP_NO_RESET, nMemUsed ); + VPROF_INCREMENT_GROUP_COUNTER( "total driver mem", COUNTER_GROUP_NO_RESET, nMemUsed ); + } +#endif +} + +static void UnregisterVS( ID3D11VertexShader* pShader ) +{ +#ifdef MEASURE_DRIVER_ALLOCATIONS + int nCRCIndex = s_VSLookup.Find( pShader ); + if ( nCRCIndex == s_VSLookup.InvalidIndex() ) + return; + + CRC32_t crc = s_VSLookup[nCRCIndex]; + s_VSLookup.RemoveAt( nCRCIndex ); + + int nIndex = s_UniqueVS.Find( crc ); + if ( nIndex != s_UniqueVS.InvalidIndex() ) + { + if ( --s_UniqueVS[nIndex] <= 0 ) + { + int nMemUsed = 23 * 1024; + VPROF_INCREMENT_GROUP_COUNTER( "unique vs count", COUNTER_GROUP_NO_RESET, -1 ); + VPROF_INCREMENT_GROUP_COUNTER( "vs driver mem", COUNTER_GROUP_NO_RESET, -nMemUsed ); + VPROF_INCREMENT_GROUP_COUNTER( "total driver mem", COUNTER_GROUP_NO_RESET, -nMemUsed ); + s_UniqueVS.Remove( nIndex ); + } + } +#endif +} + +static void UnregisterPS( ID3D11PixelShader* pShader ) +{ +#ifdef MEASURE_DRIVER_ALLOCATIONS + int nCRCIndex = s_PSLookup.Find( pShader ); + if ( nCRCIndex == s_PSLookup.InvalidIndex() ) + return; + + CRC32_t crc = s_PSLookup[nCRCIndex]; + s_PSLookup.RemoveAt( nCRCIndex ); + + int nIndex = s_UniquePS.Find( crc ); + if ( nIndex != s_UniquePS.InvalidIndex() ) + { + if ( --s_UniquePS[nIndex] <= 0 ) + { + int nMemUsed = 400; + VPROF_INCREMENT_GROUP_COUNTER( "unique ps count", COUNTER_GROUP_NO_RESET, -1 ); + VPROF_INCREMENT_GROUP_COUNTER( "ps driver mem", COUNTER_GROUP_NO_RESET, -nMemUsed ); + VPROF_INCREMENT_GROUP_COUNTER( "total driver mem", COUNTER_GROUP_NO_RESET, -nMemUsed ); + s_UniquePS.Remove( nIndex ); + } + } +#endif +} + +template int BinarySearchCombos( uint32 nStaticComboID, int nCombos, T const *pRecords ) +{ + // Use binary search - data is sorted + int nLowerIdx = 1; + int nUpperIdx = nCombos; + for (;;) + { + if ( nUpperIdx < nLowerIdx ) + return -1; + + int nMiddleIndex = ( nLowerIdx + nUpperIdx ) / 2; + uint32 nProbe = pRecords[nMiddleIndex-1].m_nStaticComboID; + if ( nStaticComboID < nProbe ) + { + nUpperIdx = nMiddleIndex - 1; + } + else + { + if ( nStaticComboID > nProbe ) + nLowerIdx = nMiddleIndex + 1; + else + return nMiddleIndex - 1; + } + } +} + +inline int FindShaderStaticCombo( uint32 nStaticComboID, const ShaderHeader_t& header, StaticComboRecord_t *pRecords ) +{ + if ( header.m_nVersion < 5 ) + return -1; + + return BinarySearchCombos( nStaticComboID, header.m_nNumStaticCombos, pRecords ); +} + +// cache redundant i/o fetched components of the vcs files +struct ShaderFileCache_t +{ + CUtlSymbol m_Name; + CUtlSymbol m_Filename; + ShaderHeader_t m_Header; + bool m_bVertexShader; + + // valid for diff version only - contains the microcode used as the reference for diff algorithm + CUtlBuffer m_ReferenceCombo; + + // valid for ver5 only - contains the directory + CUtlVector< StaticComboRecord_t > m_StaticComboRecords; + CUtlVector< StaticComboAliasRecord_t > m_StaticComboDupRecords; + + ShaderFileCache_t() + { + // invalid until version established + m_Header.m_nVersion = 0; + } + + bool IsValid() const + { + return m_Header.m_nVersion != 0; + } + + bool IsOldVersion() const + { + return m_Header.m_nVersion < 5; + } + + int IsVersion6() const + { + return ( m_Header.m_nVersion == 6 ); + } + + int FindCombo( uint32 nStaticComboID ) + { + int nSearchAliases = BinarySearchCombos( nStaticComboID, m_StaticComboDupRecords.Count(), m_StaticComboDupRecords.Base() ); + if ( nSearchAliases != -1 ) + nStaticComboID = m_StaticComboDupRecords[nSearchAliases].m_nSourceStaticCombo; + return FindShaderStaticCombo( nStaticComboID, m_Header, m_StaticComboRecords.Base() ); + } + + bool operator==( const ShaderFileCache_t& a ) const + { + return m_Name == a.m_Name && m_bVertexShader == a.m_bVertexShader; + } +}; + + +//----------------------------------------------------------------------------- +// Vertex + pixel shader manager +//----------------------------------------------------------------------------- +class CShaderManager : public IShaderManager +{ +public: + CShaderManager(); + virtual ~CShaderManager(); + + // Methods of IShaderManager + virtual void Init(); + virtual void Shutdown(); + virtual IShaderBuffer *CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion ); + virtual VertexShaderHandle_t CreateVertexShader( IShaderBuffer* pShaderBuffer ); + virtual void DestroyVertexShader( VertexShaderHandle_t hShader ); + virtual PixelShaderHandle_t CreatePixelShader( IShaderBuffer* pShaderBuffer ); + virtual void DestroyPixelShader( PixelShaderHandle_t hShader ); + virtual VertexShader_t CreateVertexShader( const char *pVertexShaderFile, ShaderIndex_t nStaticVshIndex = 0 ); + virtual PixelShader_t CreatePixelShader( const char *pPixelShaderFile, ShaderIndex_t nStaticPshIndex = 0 ); + virtual void SetVertexShader( VertexShader_t shader ); + virtual void SetPixelShader( PixelShader_t shader ); + virtual void BindVertexShader( VertexShaderHandle_t shader ); + virtual void BindPixelShader( PixelShaderHandle_t shader ); + virtual void *GetCurrentVertexShader(); + virtual void *GetCurrentPixelShader(); + virtual void ResetShaderState(); + void FlushShaders(); + virtual void ClearVertexAndPixelShaderRefCounts(); + virtual void PurgeUnusedVertexAndPixelShaders(); + void SpewVertexAndPixelShaders(); + const char *GetActiveVertexShaderName(); + const char *GetActivePixelShaderName(); + bool CreateDynamicCombos_Ver4( void *pContext, uint8 *pComboBuffer ); + bool CreateDynamicCombos_Ver5( void *pContext, uint8 *pComboBuffer ); + + static void QueuedLoaderCallback( void *pContext, void *pContext2, const void *pData, int nSize, LoaderError_t loaderError ); + +private: + + struct ShaderStaticCombos_t + { + int m_nCount; + + // Can't use CUtlVector here since you CUtlLinkedList> doesn't work. + HardwareShader_t *m_pHardwareShaders; + struct ShaderCreationData_t + { + CUtlVector ByteCode; + uint32 iCentroidMask; + }; + + ShaderCreationData_t *m_pCreationData; + }; + + struct ShaderLookupDx11_t + { + CUtlSymbol m_Name; + ShaderIndex_t m_nStaticIndex; + ShaderStaticCombos_t m_ShaderStaticCombos; + DWORD m_Flags; + int m_nRefCount; + unsigned int m_hShaderFileCache; + + // for queued loading, bias an aligned optimal buffer forward to correct location + int m_nDataOffset; + + // diff version, valid during load only + ShaderDictionaryEntry_t *m_pComboDictionary; + + bool operator=( const ShaderLookupDx11_t &other ) + { + m_Name = other.m_Name; + m_nStaticIndex = other.m_nStaticIndex; + m_ShaderStaticCombos = other.m_ShaderStaticCombos; + m_Flags = other.m_Flags; + m_nRefCount = other.m_nRefCount; + m_hShaderFileCache = other.m_hShaderFileCache; + m_nDataOffset = other.m_nDataOffset; + m_pComboDictionary = other.m_pComboDictionary; + } + ShaderLookupDx11_t() + { + m_Flags = 0; + m_nRefCount = 0; + m_ShaderStaticCombos.m_nCount = 0; + m_ShaderStaticCombos.m_pHardwareShaders = 0; + m_ShaderStaticCombos.m_pCreationData = 0; + m_pComboDictionary = NULL; + } + void IncRefCount() + { + m_nRefCount++; + } + bool operator==( const ShaderLookupDx11_t& a ) const + { + return m_Name == a.m_Name && m_nStaticIndex == a.m_nStaticIndex; + } + }; + +#ifdef DYNAMIC_SHADER_COMPILE + struct Combo_t + { + CUtlSymbol m_ComboName; + int m_nMin; + int m_nMax; + }; + + struct ShaderCombos_t + { + CUtlVector m_StaticCombos; + CUtlVector m_DynamicCombos; + uint64 GetNumDynamicCombos( void ) const + { + uint64 combos = 1; + int i; + for( i = 0; i < m_DynamicCombos.Count(); i++ ) + { + combos *= ( m_DynamicCombos[i].m_nMax - m_DynamicCombos[i].m_nMin + 1 ); + } + return combos; + } + uint64 GetNumStaticCombos( void ) const + { + uint64 combos = 1; + int i; + for( i = 0; i < m_StaticCombos.Count(); i++ ) + { + combos *= ( m_StaticCombos[i].m_nMax - m_StaticCombos[i].m_nMin + 1 ); + } + return combos; + } + }; +#endif + +private: + void CreateStaticShaders(); + void DestroyStaticShaders(); + + // The low-level dx call to set the vertex shader state + void SetVertexShaderState( HardwareShader_t shader, DataCacheHandle_t hCachedShader = DC_INVALID_HANDLE ); + + // The low-level dx call to set the pixel shader state + void SetPixelShaderState( HardwareShader_t shader, DataCacheHandle_t hCachedShader = DC_INVALID_HANDLE ); + + // Destroys all shaders + void DestroyAllShaders(); + + // Destroy a particular vertex shader + void DestroyVertexShader( VertexShader_t shader ); + // Destroy a particular pixel shader + void DestroyPixelShader( PixelShader_t shader ); + + bool LoadAndCreateShaders( ShaderLookupDx11_t &lookup, bool bVertexShader ); + FileHandle_t OpenFileAndLoadHeader( const char *pFileName, ShaderHeader_t *pHeader ); + +#ifdef DYNAMIC_SHADER_COMPILE + bool LoadAndCreateShaders_Dynamic( ShaderLookupDx11_t &lookup, bool bVertexShader ); + const ShaderCombos_t *FindOrCreateShaderCombos( const char *pShaderName ); + HardwareShader_t CompileShader( const char *pShaderName, ShaderIndex_t nStaticIndex, ShaderIndex_t nDynamicIndex, bool bVertexShader ); +#endif + + void DisassembleShader( ShaderLookupDx11_t *pLookup, ShaderIndex_t dynamicCombo, uint8 *pByteCode ); + + CUtlFixedLinkedList< ShaderLookupDx11_t > m_VertexShaderDict; + CUtlFixedLinkedList< ShaderLookupDx11_t > m_PixelShaderDict; + + CUtlSymbolTable m_ShaderSymbolTable; + +#ifdef DYNAMIC_SHADER_COMPILE + //typedef HRESULT (__stdcall *ShaderCompileFromFileFunc_t)( LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, + // LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, + // LPD3DXBUFFER* ppShader, LPD3DXBUFFER * ppErrorMsgs, LPD3DXCONSTANTTABLE * ppConstantTable ); + CUtlStringMap m_ShaderNameToCombos; +#endif + + // The current vertex and pixel shader + HardwareShader_t m_HardwareVertexShader; + HardwareShader_t m_HardwarePixelShader; + + CUtlFixedLinkedList< ShaderFileCache_t > m_ShaderFileCache; + + // false, creates during init. + // true, creates on access, helps reduce d3d memory for tools, but causes i/o hitches. + bool m_bCreateShadersOnDemand; + +#if defined( _DEBUG ) + // for debugging (can't resolve UtlSym) + // need some history because 360 d3d has rips related to sequencing + char vshDebugName[MAX_SHADER_HISTORY][64]; + int vshDebugIndex; + char pshDebugName[MAX_SHADER_HISTORY][64]; + int pshDebugIndex; +#endif +}; + + +//----------------------------------------------------------------------------- +// Singleton accessor +//----------------------------------------------------------------------------- +static CShaderManager s_ShaderManager; +IShaderManager *g_pShaderManager = &s_ShaderManager; +IShaderManager *g_pShaderManagerDx11 = g_pShaderManager; + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +CShaderManager::CShaderManager() : + m_ShaderSymbolTable( 0, 32, true /* caseInsensitive */ ), + m_VertexShaderDict( 32 ), + m_PixelShaderDict( 32 ), + m_ShaderFileCache( 32 ) +{ + m_bCreateShadersOnDemand = false; + +#ifdef _DEBUG + vshDebugIndex = 0; + pshDebugIndex = 0; +#endif +} + +CShaderManager::~CShaderManager() +{ +} + + +//----------------------------------------------------------------------------- +// Initialization, shutdown +//----------------------------------------------------------------------------- +void CShaderManager::Init() +{ + // incomptaible on the 360, violates loading system + // only used by pc to help tools reduce d3d footprint + m_bCreateShadersOnDemand = IsPC() && ( ShaderUtil()->InEditorMode() || CommandLine()->CheckParm( "-shadersondemand" ) ); + + CreateStaticShaders(); +} + +void CShaderManager::Shutdown() +{ + + DestroyAllShaders(); + DestroyStaticShaders(); +} + + +//----------------------------------------------------------------------------- +// Compiles shaders +//----------------------------------------------------------------------------- +IShaderBuffer *CShaderManager::CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion ) +{ + return g_pShaderDeviceDx11->CompileShader( pProgram, nBufLen, pShaderVersion ); +} + + +VertexShaderHandle_t CShaderManager::CreateVertexShader( IShaderBuffer* pShaderBuffer ) +{ + return g_pShaderDeviceDx11->CreateVertexShader( pShaderBuffer ); +} + +void CShaderManager::DestroyVertexShader( VertexShaderHandle_t hShader ) +{ + g_pShaderDeviceDx11->DestroyVertexShader( hShader ); +} + +PixelShaderHandle_t CShaderManager::CreatePixelShader( IShaderBuffer* pShaderBuffer ) +{ + return g_pShaderDeviceDx11->CreatePixelShader( pShaderBuffer ); +} + +void CShaderManager::DestroyPixelShader( PixelShaderHandle_t hShader ) +{ + g_pShaderDeviceDx11->DestroyPixelShader( hShader ); +} + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +HardwareShader_t s_pIllegalMaterialPS = INVALID_HARDWARE_SHADER; + +//----------------------------------------------------------------------------- +// Static methods +//----------------------------------------------------------------------------- +void CShaderManager::CreateStaticShaders() +{ + MEM_ALLOC_D3D_CREDIT(); + + if ( !HardwareConfig()->SupportsVertexAndPixelShaders() ) + { + return; + } + +#if 0 + if ( IsPC() ) + { + // GR - hack for illegal materials + const DWORD psIllegalMaterial[] = + { + 0xffff0101, 0x00000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, + 0x3f800000, 0x00000001, 0x800f0000, 0xa0e40000, 0x0000ffff + }; + // create default shader + Dx9Device()->CreatePixelShader( psIllegalMaterial, ( IDirect3DPixelShader9 ** )&s_pIllegalMaterialPS ); + } +#endif +} + +void CShaderManager::DestroyStaticShaders() +{ +#if 0 + // GR - invalid material hack + // destroy internal shader + if ( s_pIllegalMaterialPS != INVALID_HARDWARE_SHADER ) + { + ( ( IDirect3DPixelShader9 * )s_pIllegalMaterialPS )->Release(); + s_pIllegalMaterialPS = INVALID_HARDWARE_SHADER; + } +#endif +} + +#ifdef DYNAMIC_SHADER_COMPILE +static const char *GetShaderSourcePath( void ) +{ + static char shaderDir[MAX_PATH]; + // GR - just in case init this... + static bool bHaveShaderDir = false; + if( !bHaveShaderDir ) + { + bHaveShaderDir = true; +# if ( defined( DYNAMIC_SHADER_COMPILE_CUSTOM_PATH ) ) + { + Q_strncpy( shaderDir, DYNAMIC_SHADER_COMPILE_CUSTOM_PATH, MAX_PATH ); + } +# else + { +# if ( defined( _X360 ) ) + { + char hostName[128] = ""; + const char *pHostName = CommandLine()->ParmValue( "-host" ); + if ( !pHostName ) + { + // the 360 machine name must be _360 + DWORD length = sizeof( hostName ); + DmGetXboxName( hostName, &length ); + char *p = strstr( hostName, "_360" ); + *p = '\0'; + pHostName = hostName; + } + + Q_snprintf( shaderDir, MAX_PATH, "net:\\smb\\%s\\stdshaders", pHostName ); + } +# else + { + Q_strncpy( shaderDir, __FILE__, MAX_PATH ); + Q_StripFilename( shaderDir ); + Q_StripLastDir( shaderDir, MAX_PATH ); + Q_strncat( shaderDir, "stdshadersdx11", MAX_PATH, COPY_ALL_CHARACTERS ); + } +# endif + } +# endif + } + return shaderDir; +} +#endif + +#ifdef DYNAMIC_SHADER_COMPILE +const CShaderManager::ShaderCombos_t *CShaderManager::FindOrCreateShaderCombos( const char *pShaderName ) +{ + if( m_ShaderNameToCombos.Defined( pShaderName ) ) + { + return &m_ShaderNameToCombos[pShaderName]; + } + ShaderCombos_t &combos = m_ShaderNameToCombos[pShaderName]; + char filename[MAX_PATH]; + // try the vsh dir first. + Q_strncpy( filename, GetShaderSourcePath(), MAX_PATH ); + Q_strncat( filename, "\\", MAX_PATH, COPY_ALL_CHARACTERS ); + Q_strncat( filename, pShaderName, MAX_PATH, COPY_ALL_CHARACTERS ); + Q_strncat( filename, ".vsh", MAX_PATH, COPY_ALL_CHARACTERS ); + CUtlInplaceBuffer bffr( 0, 0, CUtlInplaceBuffer::TEXT_BUFFER ); + if ( bool bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ) ) + { + NULL; + } + else + { + // try the fxc dir. + Q_strncpy( filename, GetShaderSourcePath(), MAX_PATH ); + Q_strncat( filename, "\\", MAX_PATH, COPY_ALL_CHARACTERS ); + Q_strncat( filename, pShaderName, MAX_PATH, COPY_ALL_CHARACTERS ); + Q_strncat( filename, ".fxc", MAX_PATH, COPY_ALL_CHARACTERS ); + bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ); + + if ( !bOpenResult ) + { + // Maybe this is a specific version [20 & 20b] -> [2x] + if ( Q_strlen( pShaderName ) >= 3 ) + { + char *pszEndFilename = filename + strlen( filename ); + if ( !Q_stricmp( pszEndFilename - 6, "30.fxc" ) ) + { + // Total hack. Who knows what builds that 30 shader? + strcpy( pszEndFilename - 6, "20b.fxc" ); + bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ); + if ( !bOpenResult ) + { + strcpy( pszEndFilename - 6, "2x.fxc" ); + bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ); + } + if ( !bOpenResult ) + { + strcpy( pszEndFilename - 6, "20.fxc" ); + bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ); + } + } + else + { + if ( !stricmp( pszEndFilename - 6, "20.fxc" ) ) + { + pszEndFilename[ -5 ] = 'x'; + } + else if ( !stricmp( pszEndFilename - 7, "20b.fxc" ) ) + { + strcpy( pszEndFilename - 7, "2x.fxc" ); + --pszEndFilename; + } + else if ( !stricmp( pszEndFilename - 6, "11.fxc" ) ) + { + strcpy( pszEndFilename - 6, "xx.fxc" ); + } + + bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ); + if ( !bOpenResult ) + { + if ( !stricmp( pszEndFilename - 6, "2x.fxc" ) ) + { + pszEndFilename[ -6 ] = 'x'; + bOpenResult = g_pFullFileSystem->ReadFile( filename, NULL, bffr ); + } + } + } + } + } + + if ( !bOpenResult ) + { + Assert( 0 ); + return NULL; + } + } + + while( char *line = bffr.InplaceGetLinePtr() ) + { + // dear god perl is better at this kind of shit! + int begin = 0; + int end = 0; + + // check if the line starts with '//' + if( line[0] != '/' || line[1] != '/' ) + { + continue; + } + + // Check if line intended for platform lines + if( IsX360() ) + { + if ( Q_stristr( line, "[PC]" ) ) + continue; + } + else + { + if ( Q_stristr( line, "[360]" ) || Q_stristr( line, "[XBOX]" ) ) + continue; + } + + // Skip any lines intended for other shader version + if ( Q_stristr( pShaderName, "_ps20" ) && !Q_stristr( pShaderName, "_ps20b" ) && + Q_stristr( line, "[ps" ) && !Q_stristr( line, "[ps20]" ) ) + continue; + if ( Q_stristr( pShaderName, "_ps20b" ) && + Q_stristr( line, "[ps" ) && !Q_stristr( line, "[ps20b]" ) ) + continue; + if ( Q_stristr( pShaderName, "_ps30" ) && + Q_stristr( line, "[ps" ) && !Q_stristr( line, "[ps30]" ) ) + continue; + if ( Q_stristr( pShaderName, "_ps40" ) && + Q_stristr( line, "[ps" ) && !Q_stristr( line, "[ps40]" ) ) + continue; + if ( Q_stristr( pShaderName, "_vs20" ) && + Q_stristr( line, "[vs" ) && !Q_stristr( line, "[vs20]" ) ) + continue; + if ( Q_stristr( pShaderName, "_vs30" ) && + Q_stristr( line, "[vs" ) && !Q_stristr( line, "[vs30]" ) ) + continue; + if ( Q_stristr( pShaderName, "_vs40" ) && + Q_stristr( line, "[vs" ) && !Q_stristr( line, "[vs40]" ) ) + continue; + + char *pScan = &line[2]; + while( *pScan == ' ' || *pScan == '\t' ) + { + pScan++; + } + + bool bDynamic; + if( Q_strncmp( pScan, "DYNAMIC", 7 ) == 0 ) + { + bDynamic = true; + pScan += 7; + } + else if( Q_strncmp( pScan, "STATIC", 6 ) == 0 ) + { + bDynamic = false; + pScan += 6; + } + else + { + continue; + } + + // skip whitespace + while( *pScan == ' ' || *pScan == '\t' ) + { + pScan++; + } + + // check for colon + if( *pScan != ':' ) + { + continue; + } + pScan++; + + // skip whitespace + while( *pScan == ' ' || *pScan == '\t' ) + { + pScan++; + } + + // check for quote + if( *pScan != '\"' ) + { + continue; + } + pScan++; + + char *pBeginningOfName = pScan; + while( 1 ) + { + if( *pScan == '\0' ) + { + break; + } + if( *pScan == '\"' ) + { + break; + } + pScan++; + } + + if( *pScan == '\0' ) + { + continue; + } + + // must have hit a quote. .done with string. + // slam a NULL at the end quote of the string so that we have the string at pBeginningOfName. + *pScan = '\0'; + pScan++; + + // skip whitespace + while( *pScan == ' ' || *pScan == '\t' ) + { + pScan++; + } + + // check for quote + if( *pScan != '\"' ) + { + continue; + } + pScan++; + + // make sure that we have a number after the quote. + if( !isdigit( *pScan ) ) + { + continue; + } + + while( isdigit( *pScan ) ) + { + begin = begin * 10 + ( *pScan - '0' ); + pScan++; + } + + if( pScan[0] != '.' || pScan[1] != '.' ) + { + continue; + } + pScan += 2; + + // make sure that we have a number + if( !isdigit( *pScan ) ) + { + continue; + } + + while( isdigit( *pScan ) ) + { + end = end * 10 + ( *pScan - '0' ); + pScan++; + } + + if( pScan[0] != '\"' ) + { + continue; + } + + // sweet freaking jesus. .done parsing the line. +// char buf[1024]; +// sprintf( buf, "\"%s\" \"%s\" %d %d\n", bDynamic ? "DYNAMIC" : "STATIC", pBeginningOfName, begin, end ); +// Plat_DebugString( buf ); + + Combo_t *pCombo = NULL; + if( bDynamic ) + { + pCombo = &combos.m_DynamicCombos[combos.m_DynamicCombos.AddToTail()]; + } + else + { + pCombo = &combos.m_StaticCombos[combos.m_StaticCombos.AddToTail()]; + } + + pCombo->m_ComboName = m_ShaderSymbolTable.AddString( pBeginningOfName ); + pCombo->m_nMin = begin; + pCombo->m_nMax = end; + } + + return &combos; +} +#endif // DYNAMIC_SHADER_COMPILE + +#ifdef DYNAMIC_SHADER_COMPILE +//----------------------------------------------------------------------------- +// Used to deal with include files +//----------------------------------------------------------------------------- +class CDxInclude : public ID3DInclude +{ +public: + CDxInclude( const char *pMainFileName ); + + virtual HRESULT WINAPI Open( D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID * ppData, UINT * pBytes ); + + virtual HRESULT WINAPI Close( LPCVOID pData ); + +private: + char m_pBasePath[MAX_PATH]; + +#if defined( _X360 ) + char m_pFullPath[MAX_PATH]; +#endif +}; + +CDxInclude::CDxInclude( const char *pMainFileName ) +{ + Q_ExtractFilePath( pMainFileName, m_pBasePath, sizeof(m_pBasePath) ); +} + + +HRESULT CDxInclude::Open( D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID * ppData, UINT * pBytes ) +{ + char pTemp[MAX_PATH]; + if ( !Q_IsAbsolutePath( pFileName ) && ( IncludeType == D3D_INCLUDE_LOCAL ) ) + { + Q_ComposeFileName( m_pBasePath, pFileName, pTemp, sizeof(pTemp) ); + pFileName = pTemp; + } + + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + if ( !g_pFullFileSystem->ReadFile( pFileName, NULL, buf ) ) + return E_FAIL; + + *pBytes = buf.TellMaxPut(); + void *pMem = malloc( *pBytes ); + memcpy( pMem, buf.Base(), *pBytes ); + *ppData = pMem; + +# if ( defined( _X360 ) ) + { + Q_ComposeFileName( m_pBasePath, pFileName, m_pFullPath, sizeof(m_pFullPath) ); + pFullPath = m_pFullPath; + cbFullPath = MAX_PATH; + } +# endif + + return S_OK; +} + +HRESULT CDxInclude::Close( LPCVOID pData ) +{ + void *pMem = const_cast( pData ); + free( pMem ); + return S_OK; +} + +static const char *FileNameToShaderModel( const char *pShaderName, bool bVertexShader ) +{ + // Figure out the shader model + const char *pShaderModel = NULL; + if( bVertexShader ) + { + if ( Q_stristr( pShaderName, "vs40" ) ) + { + pShaderModel = "vs_4_0"; + bVertexShader = true; + } + else if( Q_stristr( pShaderName, "vs20" ) ) + { + pShaderModel = "vs_2_0"; + bVertexShader = true; + } + else if( Q_stristr( pShaderName, "vs11" ) ) + { + pShaderModel = "vs_1_1"; + bVertexShader = true; + } + else if( Q_stristr( pShaderName, "vs14" ) ) + { + pShaderModel = "vs_1_1"; + bVertexShader = true; + } + else if( Q_stristr( pShaderName, "vs30" ) ) + { + pShaderModel = "vs_3_0"; + bVertexShader = true; + } + else + { +#ifdef _DEBUG + Error( "Failed dynamic shader compiled\nBuild shaderapidx9.dll in debug to find problem\n" ); +#else + Assert( 0 ); +#endif + } + } + else + { + if ( Q_stristr( pShaderName, "ps40" ) ) + { + pShaderModel = "ps_4_0"; + } + else if( Q_stristr( pShaderName, "ps20b" ) ) + { + pShaderModel = "ps_2_b"; + } + else if( Q_stristr( pShaderName, "ps20" ) ) + { + pShaderModel = "ps_2_0"; + } + else if( Q_stristr( pShaderName, "ps11" ) ) + { + pShaderModel = "ps_1_1"; + } + else if( Q_stristr( pShaderName, "ps14" ) ) + { + pShaderModel = "ps_1_4"; + } + else if( Q_stristr( pShaderName, "ps30" ) ) + { + pShaderModel = "ps_3_0"; + } + else + { +#ifdef _DEBUG + Error( "Failed dynamic shader compiled\nBuild shaderapidx9.dll in debug to find problem\n" ); +#else + Assert( 0 ); +#endif + } + } + return pShaderModel; +} +#endif + +#ifdef DYNAMIC_SHADER_COMPILE + +#if defined( _X360 ) +static ConVar mat_flushshaders_generate_updbs( "mat_flushshaders_generate_updbs", "0", 0, "Generates UPDBs whenever you flush shaders." ); +#endif + +HardwareShader_t CShaderManager::CompileShader( const char *pShaderName, + ShaderIndex_t nStaticIndex, ShaderIndex_t nDynamicIndex, bool bVertexShader ) +{ + VPROF_BUDGET( "CompileShader", "CompileShader" ); + Assert( m_ShaderNameToCombos.Defined( pShaderName ) ); + if( !m_ShaderNameToCombos.Defined( pShaderName ) ) + { + return INVALID_HARDWARE_SHADER; + } + const ShaderCombos_t &combos = m_ShaderNameToCombos[pShaderName]; +#ifdef _DEBUG + uint64 numStaticCombos = combos.GetNumStaticCombos(); + uint64 numDynamicCombos = combos.GetNumDynamicCombos(); +#endif + Assert( nStaticIndex % numDynamicCombos == 0 ); + Assert( ( nStaticIndex % numDynamicCombos ) >= 0 && ( nStaticIndex % numDynamicCombos ) < numStaticCombos ); + Assert( nDynamicIndex >= 0 && nDynamicIndex < numDynamicCombos ); + +# ifdef DYNAMIC_SHADER_COMPILE_VERBOSE + + //Warning( "Compiling %s %s\n\tdynamic:", bVertexShader ? "vsh" : "psh", pShaderName ); + Warning( "Compiling " ); + if ( bVertexShader ) + ConColorMsg( Color( 0, 255, 0, 255 ), "vsh - %s ", pShaderName ); + else + ConColorMsg( Color( 0, 255, 255, 255 ), "psh - %s ", pShaderName ); + Warning( "\n\tdynamic:" ); + +# endif + + CUtlVector macros; + // plus 1 for null termination, plus 1 for #define SHADER_MODEL_*, and plus 1 for #define _X360 on 360 + macros.SetCount( combos.m_DynamicCombos.Count() + combos.m_StaticCombos.Count() + 2 + ( IsX360() ? 1 : 0 ) ); + + uint64 nCombo = nStaticIndex + nDynamicIndex; + int macroIndex = 0; + int i; + for( i = 0; i < combos.m_DynamicCombos.Count(); i++ ) + { + int countForCombo = combos.m_DynamicCombos[i].m_nMax - combos.m_DynamicCombos[i].m_nMin + 1; + int val = nCombo % countForCombo + combos.m_DynamicCombos[i].m_nMin; + nCombo /= countForCombo; + macros[macroIndex].Name = m_ShaderSymbolTable.String( combos.m_DynamicCombos[i].m_ComboName ); + char buf[16]; + sprintf( buf, "%d", val ); + CUtlSymbol valSymbol( buf ); + macros[macroIndex].Definition = valSymbol.String(); +# ifdef DYNAMIC_SHADER_COMPILE_VERBOSE + Warning( " %s=%s", macros[macroIndex].Name, macros[macroIndex].Definition ); +# endif + macroIndex++; + } + +# ifdef DYNAMIC_SHADER_COMPILE_VERBOSE + Warning( "\n\tstatic:" ); +# endif + for( i = 0; i < combos.m_StaticCombos.Count(); i++ ) + { + int countForCombo = combos.m_StaticCombos[i].m_nMax - combos.m_StaticCombos[i].m_nMin + 1; + int val = nCombo % countForCombo + combos.m_StaticCombos[i].m_nMin; + nCombo /= countForCombo; + macros[macroIndex].Name = m_ShaderSymbolTable.String( combos.m_StaticCombos[i].m_ComboName ); + char buf[16]; + sprintf( buf, "%d", val ); + CUtlSymbol valSymbol( buf ); + macros[macroIndex].Definition = valSymbol.String(); +# ifdef DYNAMIC_SHADER_COMPILE_VERBOSE + Warning( " %s=%s", macros[macroIndex].Name, macros[macroIndex].Definition ); +# endif + macroIndex++; + } + +# ifdef DYNAMIC_SHADER_COMPILE_VERBOSE + Warning( "\n" ); +# endif + + char filename[MAX_PATH]; + Q_strncpy( filename, GetShaderSourcePath(), MAX_PATH ); + Q_strncat( filename, "\\", MAX_PATH, COPY_ALL_CHARACTERS ); + Q_strncat( filename, pShaderName, MAX_PATH, COPY_ALL_CHARACTERS ); + Q_strncat( filename, ".fxc", MAX_PATH, COPY_ALL_CHARACTERS ); + + const char *pShaderModel = FileNameToShaderModel( pShaderName, bVertexShader ); + + // define the shader model + char shaderModelDefineString[1024]; + Q_snprintf( shaderModelDefineString, 1024, "SHADER_MODEL_%s", pShaderModel ); + Q_strupr( shaderModelDefineString ); + macros[macroIndex].Name = shaderModelDefineString; + macros[macroIndex].Definition = "1"; + macroIndex++; + + char x360DefineString[1024]; + if( IsX360() ) + { + Q_snprintf( x360DefineString, 1024, "_X360", pShaderModel ); + Q_strupr( x360DefineString ); + macros[macroIndex].Name = x360DefineString; + macros[macroIndex].Definition = "1"; + macroIndex++; + } + + // NULL terminate. + macros[macroIndex].Name = NULL; + macros[macroIndex].Definition = NULL; + + // Instead of erroring out, infinite-loop on shader compilation + // (i.e. give developers a chance to fix the shader code w/out restarting the game) +#ifdef _DEBUG + int retriesLeft = 20; +retry_compile: +#endif + + // Try and open the file to see if it exists + FileHandle_t fp = g_pFullFileSystem->Open( filename, "r" ); + + if ( fp == FILESYSTEM_INVALID_HANDLE ) + { + // Maybe this is a specific version [20 & 20b] -> [2x] + if ( strlen( pShaderName ) >= 3 ) + { + char *pszEndFilename = filename + strlen( filename ); + if ( !Q_stricmp( pszEndFilename - 6, "30.fxc" ) ) + { + strcpy( pszEndFilename - 6, "20b.fxc" ); + fp = g_pFullFileSystem->Open( filename, "r" ); + if ( fp == FILESYSTEM_INVALID_HANDLE ) + { + strcpy( pszEndFilename - 6, "2x.fxc" ); + fp = g_pFullFileSystem->Open( filename, "r" ); + } + if ( fp == FILESYSTEM_INVALID_HANDLE ) + { + strcpy( pszEndFilename - 6, "20.fxc" ); + fp = g_pFullFileSystem->Open( filename, "r" ); + } + } + else + { + if ( !Q_stricmp( pszEndFilename - 6, "20.fxc" ) ) + { + pszEndFilename[ -5 ] = 'x'; + fp = g_pFullFileSystem->Open( filename, "r" ); + } + else if ( !Q_stricmp( pszEndFilename - 7, "20b.fxc" ) ) + { + strcpy( pszEndFilename - 7, "2x.fxc" ); + fp = g_pFullFileSystem->Open( filename, "r" ); + } + else if ( !stricmp( pszEndFilename - 6, "11.fxc" ) ) + { + strcpy( pszEndFilename - 6, "xx.fxc" ); + fp = g_pFullFileSystem->Open( filename, "r" ); + } + + if ( fp == FILESYSTEM_INVALID_HANDLE ) + { + if ( !stricmp( pszEndFilename - 6, "2x.fxc" ) ) + { + pszEndFilename[ -6 ] = 'x'; + fp = g_pFullFileSystem->Open( filename, "r" ); + } + } + } + } + } + + if ( fp != FILESYSTEM_INVALID_HANDLE ) + { + g_pFullFileSystem->Close( fp ); + } + + wchar_t wfilename[MAX_PATH]; + memset( wfilename, 0, MAX_PATH ); + //mbtowc( wfilename, filename, strlen( filename ) ); + + int nCompileFlags = D3DCOMPILE_AVOID_FLOW_CONTROL; + nCompileFlags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; + +#ifdef _DEBUG + nCompileFlags |= D3DCOMPILE_DEBUG; +#endif + + LPD3DBLOB pShader; + LPD3DBLOB pErrorMessages; + HRESULT hr; + CDxInclude dxInclude( filename ); + // Open the top-level file via our include interface + LPCVOID lpcvData; + UINT numBytes; + hr = dxInclude.Open( (D3D_INCLUDE_TYPE)0, filename, NULL, &lpcvData, &numBytes ); + + LPCSTR pShaderData = (LPCSTR)lpcvData; + + MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, filename, -1, wfilename, MAX_PATH ); + hr = D3DCompile( pShaderData, numBytes, filename, macros.Base(), &dxInclude, "main", pShaderModel, nCompileFlags, 0, &pShader, &pErrorMessages ); + + dxInclude.Close( lpcvData ); + + if ( hr != S_OK && pErrorMessages ) + { + Warning( "Failed to compile shader %s:\n", filename ); + const char *pErrorMessageString = ( const char * )pErrorMessages->GetBufferPointer(); + Warning( pErrorMessageString ); + Warning( "\n" ); + +#if 0//#ifndef _DEBUG + if ( retriesLeft-- > 0 ) + { + DevMsg( 0, "Failed dynamic shader compiled - fix the shader while the debugger is at the breakpoint, then continue\n" ); + DebuggerBreakIfDebugging(); + goto retry_compile; + } + if( !IsX360() ) //errors make the 360 puke and die. We have a better solution for this particular error + Error( "Failed dynamic shader compile\nBuild shaderapidx9.dll in debug to find problem\n" ); +#else + Assert( 0 ); +#endif + + return INVALID_HARDWARE_SHADER; + } + else + { +#ifdef DYNAMIC_SHADER_COMPILE_WRITE_ASSEMBLY + // enable to dump the disassembly for shader validation + char exampleCommandLine[2048]; + Q_strncpy( exampleCommandLine, "// Run from stdshaders\n// ..\\..\\dx9sdk\\utilities\\fxc.exe ", sizeof( exampleCommandLine ) ); + int i; + for( i = 0; macros[i].Name; i++ ) + { + Q_strncat( exampleCommandLine, "/D", sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, macros[i].Name, sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, "=", sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, macros[i].Definition, sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, " ", sizeof( exampleCommandLine ) ); + } + + Q_strncat( exampleCommandLine, "/T", sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, pShaderModel, sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, " ", sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, filename, sizeof( exampleCommandLine ) ); + Q_strncat( exampleCommandLine, "\n", sizeof( exampleCommandLine ) ); + + ID3DBlob *pd3dxBuffer; + HRESULT hr; + hr = D3DDisassemble( pShader->GetBufferPointer(), pShader->GetBufferSize(), 0, NULL, &pd3dxBuffer ); + Assert( hr == D3D_OK ); + CUtlBuffer tempBuffer; + tempBuffer.SetBufferType( true, false ); + int exampleCommandLineLength = strlen( exampleCommandLine ); + tempBuffer.EnsureCapacity( pd3dxBuffer->GetBufferSize() + exampleCommandLineLength ); + memcpy( tempBuffer.Base(), exampleCommandLine, exampleCommandLineLength ); + memcpy( ( char * )tempBuffer.Base() + exampleCommandLineLength, pd3dxBuffer->GetBufferPointer(), pd3dxBuffer->GetBufferSize() ); + tempBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, pd3dxBuffer->GetBufferSize() + exampleCommandLineLength ); + char filename[MAX_PATH]; + sprintf( filename, "%s_%d_%d.asm", pShaderName, nStaticIndex, nDynamicIndex ); + g_pFullFileSystem->WriteFile( filename, "DEFAULT_WRITE_PATH", tempBuffer ); +#endif + if ( bVertexShader ) + { + return g_pShaderDeviceDx11->CreateVertexShader( pShader->GetBufferPointer(), pShader->GetBufferSize() ); + } + else + { + return g_pShaderDeviceDx11->CreatePixelShader( pShader->GetBufferPointer(), pShader->GetBufferSize() ); // hack hack hack! need to get centroid info from the source + } + } + if ( pShader ) + { + pShader->Release(); + } + if ( pErrorMessages ) + { + pErrorMessages->Release(); + } +} +#endif + +#ifdef DYNAMIC_SHADER_COMPILE +bool CShaderManager::LoadAndCreateShaders_Dynamic( ShaderLookupDx11_t &lookup, bool bVertexShader ) +{ + const char *pName = m_ShaderSymbolTable.String( lookup.m_Name ); + const ShaderCombos_t *pCombos = FindOrCreateShaderCombos( pName ); + if ( !pCombos ) + { + return false; + } + + int numDynamicCombos = pCombos->GetNumDynamicCombos(); + lookup.m_ShaderStaticCombos.m_pHardwareShaders = new HardwareShader_t[numDynamicCombos]; + lookup.m_ShaderStaticCombos.m_nCount = numDynamicCombos; + lookup.m_ShaderStaticCombos.m_pCreationData = new ShaderStaticCombos_t::ShaderCreationData_t[numDynamicCombos]; + + int i; + for( i = 0; i < numDynamicCombos; i++ ) + { + lookup.m_ShaderStaticCombos.m_pHardwareShaders[i] = INVALID_HARDWARE_SHADER; + } + return true; +} +#endif + +//----------------------------------------------------------------------------- +// Open the shader file, optionally gets the header +//----------------------------------------------------------------------------- +FileHandle_t CShaderManager::OpenFileAndLoadHeader( const char *pFileName, ShaderHeader_t *pHeader ) +{ + //FileHandle_t fp = g_pFullFileSystem->Open( pFileName, "rb", "GAME" ); + FileHandle_t fp = g_pFullFileSystem->Open( pFileName, "rb", "CORE" ); + if ( fp == FILESYSTEM_INVALID_HANDLE ) + { + return FILESYSTEM_INVALID_HANDLE; + } + + if ( pHeader ) + { + // read the header + g_pFullFileSystem->Read( pHeader, sizeof( ShaderHeader_t ), fp ); + + switch ( pHeader->m_nVersion ) + { + case 4: + // version with combos done as diffs vs a reference combo + // vsh/psh or older fxc + break; + + case 5: + case 6: + // version with optimal dictionary and compressed combo block + break; + + default: + Assert( 0 ); + Warning( "Shader %s is the wrong version %d, expecting %d\n", pFileName, pHeader->m_nVersion, SHADER_VCS_VERSION_NUMBER ); + g_pFullFileSystem->Close( fp ); + return FILESYSTEM_INVALID_HANDLE; + } + } + + return fp; +} + +//----------------------------------------------------------------------------- +// Disassemble a shader for debugging. Writes .asm files. +//----------------------------------------------------------------------------- +void CShaderManager::DisassembleShader( ShaderLookupDx11_t *pLookup, ShaderIndex_t dynamicCombo, uint8 *pByteCode ) +{ +#if defined( WRITE_ASSEMBLY ) + const char *pName = m_ShaderSymbolTable.String( pLookup->m_Name ); + + ID3DXBuffer *pd3dxBuffer; + HRESULT hr; + hr = D3DXDisassembleShader( (DWORD*)pByteCode, false, NULL, &pd3dxBuffer ); + Assert( hr == D3D_OK ); + + CUtlBuffer tempBuffer; + tempBuffer.SetBufferType( true, false ); + tempBuffer.EnsureCapacity( pd3dxBuffer->GetBufferSize() ); + memcpy( ( char * )tempBuffer.Base(), pd3dxBuffer->GetBufferPointer(), pd3dxBuffer->GetBufferSize() ); + tempBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, pd3dxBuffer->GetBufferSize() ); + + char filename[MAX_PATH]; + sprintf( filename, "%s_%d_%d.asm", pName, pLookup->m_nStaticIndex, dynamicCombo ); + g_pFullFileSystem->WriteFile( filename, "DEFAULT_WRITE_PATH", tempBuffer ); +#endif +} + +//----------------------------------------------------------------------------- +// Create dynamic combos +//----------------------------------------------------------------------------- +bool CShaderManager::CreateDynamicCombos_Ver4( void *pContext, uint8 *pComboBuffer ) +{ + ShaderLookupDx11_t* pLookup = (ShaderLookupDx11_t *)pContext; + + ShaderFileCache_t *pFileCache = &m_ShaderFileCache[pLookup->m_hShaderFileCache]; + ShaderHeader_t *pHeader = &pFileCache->m_Header; + + int nReferenceComboSizeForDiffs = ((ShaderHeader_t_v4 *)pHeader)->m_nDiffReferenceSize; + + uint8 *pReferenceShader = NULL; + uint8 *pDiffOutputBuffer = NULL; + if ( nReferenceComboSizeForDiffs ) + { + // reference combo is *always* the largest combo, so safe worst case size for uncompression buffer + pReferenceShader = (uint8 *)pFileCache->m_ReferenceCombo.Base(); + pDiffOutputBuffer = (uint8 *)_alloca( nReferenceComboSizeForDiffs ); + } + + // build this shader's dynamic combos + bool bOK = true; + int nStartingOffset = 0; + for ( int i = 0; i < pHeader->m_nDynamicCombos; i++ ) + { + if ( pLookup->m_pComboDictionary[i].m_Offset == -1 ) + { + // skipped + continue; + } + + if ( !nStartingOffset ) + { + nStartingOffset = pLookup->m_pComboDictionary[i].m_Offset; + } + + // offsets better be sequentially ascending + Assert( nStartingOffset <= pLookup->m_pComboDictionary[i].m_Offset ); + + if ( pLookup->m_pComboDictionary[i].m_Size <= 0 ) + { + // skipped + continue; + } + + // get the right byte code from the monolithic buffer + uint8 *pByteCode = (uint8 *)pComboBuffer + pLookup->m_nDataOffset + pLookup->m_pComboDictionary[i].m_Offset - nStartingOffset; + int nByteCodeSize = pLookup->m_pComboDictionary[i].m_Size; + + if ( pReferenceShader ) + { + // reference combo better be the largest combo, otherwise memory corruption + Assert( nReferenceComboSizeForDiffs >= nByteCodeSize ); + + // use the differencing algorithm to recover the full shader + int nOriginalSize; + ApplyDiffs( + pReferenceShader, + pByteCode, + nReferenceComboSizeForDiffs, + nByteCodeSize, + nOriginalSize, + pDiffOutputBuffer, + nReferenceComboSizeForDiffs ); + + pByteCode = pDiffOutputBuffer; + nByteCodeSize = nOriginalSize; + } + +#if defined( WRITE_ASSEMBLY ) + DisassembleShader( pLookup, i, pByteCode ); +#endif + HardwareShader_t hardwareShader = INVALID_HARDWARE_SHADER; + + if ( IsPC() && m_bCreateShadersOnDemand ) + { + // cache the code off for later + pLookup->m_ShaderStaticCombos.m_pCreationData[i].ByteCode.SetSize( nByteCodeSize ); + V_memcpy( pLookup->m_ShaderStaticCombos.m_pCreationData[i].ByteCode.Base(), pByteCode, nByteCodeSize ); + pLookup->m_ShaderStaticCombos.m_pCreationData[i].iCentroidMask = pFileCache->m_bVertexShader ? 0 : pHeader->m_nCentroidMask; + } + else + { + if ( pFileCache->m_bVertexShader ) + { + hardwareShader = g_pShaderDeviceDx11->CreateVertexShader( reinterpret_cast< DWORD *>( pByteCode ), nByteCodeSize ); + } + else + { + hardwareShader = g_pShaderDeviceDx11->CreatePixelShader( reinterpret_cast< DWORD *>( pByteCode ), nByteCodeSize ); + } + if ( hardwareShader == INVALID_HARDWARE_SHADER ) + { + Assert( 0 ); + bOK = false; + break; + } + } + pLookup->m_ShaderStaticCombos.m_pHardwareShaders[i] = hardwareShader; + } + + delete [] pLookup->m_pComboDictionary; + pLookup->m_pComboDictionary = NULL; + + return bOK; +} + +//----------------------------------------------------------------------------- +// Create dynamic combos +//----------------------------------------------------------------------------- +static uint32 NextULONG( uint8 * &pData ) +{ + // handle unaligned read + uint32 nRet; + memcpy( &nRet, pData, sizeof( nRet ) ); + pData += sizeof( nRet ); + return nRet; +} +bool CShaderManager::CreateDynamicCombos_Ver5( void *pContext, uint8 *pComboBuffer ) +{ + ShaderLookupDx11_t* pLookup = (ShaderLookupDx11_t *)pContext; + ShaderFileCache_t *pFileCache = &m_ShaderFileCache[pLookup->m_hShaderFileCache]; + uint8 *pCompressedShaders = pComboBuffer + pLookup->m_nDataOffset; + + uint8 *pUnpackBuffer = new uint8[MAX_SHADER_UNPACKED_BLOCK_SIZE]; + + // now, loop through all blocks + bool bOK = true; + while ( bOK ) + { + uint32 nBlockSize = NextULONG( pCompressedShaders ); + if ( nBlockSize == 0xffffffff ) + { + // any more blocks? + break; + } + + switch( nBlockSize & 0xc0000000 ) + { + case 0: // bzip2 + { + // uncompress + uint32 nOutsize = MAX_SHADER_UNPACKED_BLOCK_SIZE; + int nRslt = BZ2_bzBuffToBuffDecompress( + reinterpret_cast( pUnpackBuffer ), + &nOutsize, + reinterpret_cast( pCompressedShaders ), + nBlockSize, 1, 0 ); + if ( nRslt < 0 ) + { + // errors are negative for bzip + Assert( 0 ); + Warning( "BZIP Error (%d) decompressing shader", nRslt ); + bOK = false; + } + + pCompressedShaders += nBlockSize; + nBlockSize = nOutsize; // how much data there is + } + break; + + case 0x80000000: // uncompressed + { + // not compressed, as is + nBlockSize &= 0x3fffffff; + memcpy( pUnpackBuffer, pCompressedShaders, nBlockSize ); + pCompressedShaders += nBlockSize; + } + break; + + case 0x40000000: // lzma compressed + { + CLZMA lzDecoder; + nBlockSize &= 0x3fffffff; + + size_t nOutsize = lzDecoder.Uncompress( + reinterpret_cast( pCompressedShaders ), + pUnpackBuffer ); + pCompressedShaders += nBlockSize; + nBlockSize = nOutsize; // how much data there is + } + break; + + default: + { + Assert( 0 ); + Error(" unrecognized shader compression type = file corrupt?"); + bOK = false; + } + } + + uint8 *pReadPtr = pUnpackBuffer; + while ( pReadPtr < pUnpackBuffer+nBlockSize ) + { + uint32 nCombo_ID = NextULONG( pReadPtr ); + uint32 nShaderSize = NextULONG( pReadPtr ); + +#if defined( WRITE_ASSEMBLY ) + DisassembleShader( pLookup, nCombo_ID, pReadPtr ); +#endif + HardwareShader_t hardwareShader = INVALID_HARDWARE_SHADER; + + int iIndex = nCombo_ID; + if ( iIndex >= pLookup->m_nStaticIndex ) + iIndex -= pLookup->m_nStaticIndex; // ver5 stores combos as full combo, ver6 as dynamic combo # only + if ( IsPC() && m_bCreateShadersOnDemand ) + { + // cache the code off for later + pLookup->m_ShaderStaticCombos.m_pCreationData[iIndex].ByteCode.SetSize( nShaderSize ); + V_memcpy( pLookup->m_ShaderStaticCombos.m_pCreationData[iIndex].ByteCode.Base(), pReadPtr, nShaderSize ); + pLookup->m_ShaderStaticCombos.m_pCreationData[iIndex].iCentroidMask = pFileCache->m_bVertexShader ? 0 : pFileCache->m_Header.m_nCentroidMask; + } + else + { + if ( pFileCache->m_bVertexShader ) + { + hardwareShader = g_pShaderDeviceDx11->CreateVertexShader( reinterpret_cast< DWORD *>( pReadPtr ), nShaderSize ); + } + else + { + hardwareShader = g_pShaderDeviceDx11->CreatePixelShader( reinterpret_cast< DWORD *>( pReadPtr ), nShaderSize ); + } + if ( hardwareShader == INVALID_HARDWARE_SHADER ) + { + Warning( "failed to create shader\n" ); + Assert( 0 ); + bOK = false; + break; + } + } + pLookup->m_ShaderStaticCombos.m_pHardwareShaders[iIndex] = hardwareShader; + pReadPtr += nShaderSize; + } + } + + delete[] pUnpackBuffer; + + return bOK; +} + +//----------------------------------------------------------------------------- +// Static method, called by thread, don't call anything non-threadsafe from handler!!! +//----------------------------------------------------------------------------- +void CShaderManager::QueuedLoaderCallback( void *pContext, void *pContext2, const void *pData, int nSize, LoaderError_t loaderError ) +{ + ShaderLookupDx11_t* pLookup = (ShaderLookupDx11_t *)pContext; + + bool bOK = ( loaderError == LOADERERROR_NONE ); + if ( bOK ) + { + if ( pContext2 ) + { + // presence denotes diff version + bOK = s_ShaderManager.CreateDynamicCombos_Ver4( pContext, (uint8 *)pData ); + } + else + { + bOK = s_ShaderManager.CreateDynamicCombos_Ver5( pContext, (uint8 *)pData ); + } + } + if ( !bOK ) + { + pLookup->m_Flags |= SHADER_FAILED_LOAD; + } +} + +//----------------------------------------------------------------------------- +// Loads all shaders +//----------------------------------------------------------------------------- +bool CShaderManager::LoadAndCreateShaders( ShaderLookupDx11_t &lookup, bool bVertexShader ) +{ +#ifdef DYNAMIC_SHADER_COMPILE + lookup.m_Flags &= ~SHADER_DYNAMIC_COMPILE_IS_HLSL; +#endif + const char *pName = m_ShaderSymbolTable.String( lookup.m_Name ); + + // find it in the cache + // a cache hit prevents costly i/o for static components, i.e. header, ref combo, etc. + ShaderFileCache_t fileCacheLookup; + fileCacheLookup.m_Name = lookup.m_Name; + fileCacheLookup.m_bVertexShader = bVertexShader; + int fileCacheIndex = m_ShaderFileCache.Find( fileCacheLookup ); + if ( fileCacheIndex == m_ShaderFileCache.InvalidIndex() ) + { + // not found, create a new entry + fileCacheIndex = m_ShaderFileCache.AddToTail(); + } + + lookup.m_hShaderFileCache = fileCacheIndex; + + // fetch from cache + ShaderFileCache_t *pFileCache = &m_ShaderFileCache[fileCacheIndex]; + ShaderHeader_t *pHeader = &pFileCache->m_Header; + + FileHandle_t hFile = FILESYSTEM_INVALID_HANDLE; + if ( pFileCache->IsValid() ) + { + // using cached header, just open file, no read of header needed + hFile = OpenFileAndLoadHeader( m_ShaderSymbolTable.String( pFileCache->m_Filename ), NULL ); + if ( hFile == FILESYSTEM_INVALID_HANDLE ) + { + // shouldn't happen + Assert( 0 ); + return false; + } + } + else + { + V_memset( pHeader, 0, sizeof( ShaderHeader_t ) ); + + // try the vsh/psh dir first + char filename[MAX_PATH]; + Q_snprintf( filename, MAX_PATH, "shaders\\%s\\%s" SHADER_FNAME_EXTENSION, bVertexShader ? "vsh" : "psh", pName ); + hFile = OpenFileAndLoadHeader( filename, pHeader ); + if ( hFile == FILESYSTEM_INVALID_HANDLE ) + { +#ifdef DYNAMIC_SHADER_COMPILE + // Dynamically compile if it's HLSL. + if ( LoadAndCreateShaders_Dynamic( lookup, bVertexShader ) ) + { + lookup.m_Flags |= SHADER_DYNAMIC_COMPILE_IS_HLSL; + return true; + } + else + { + return false; + } +#endif + // next, try the fxc dir + Q_snprintf( filename, MAX_PATH, "shaders\\fxc\\%s" SHADER_FNAME_EXTENSION, pName ); + hFile = OpenFileAndLoadHeader( filename, pHeader ); + if ( hFile == FILESYSTEM_INVALID_HANDLE ) + { + lookup.m_Flags |= SHADER_FAILED_LOAD; + Warning( "Couldn't load %s shader %s\n", bVertexShader ? "vertex" : "pixel", pName ); + return false; + } + } + + lookup.m_Flags = pHeader->m_nFlags; + + pFileCache->m_Name = lookup.m_Name; + pFileCache->m_Filename = m_ShaderSymbolTable.AddString( filename ); + pFileCache->m_bVertexShader = bVertexShader; + + if ( pFileCache->IsOldVersion() ) + { + int referenceComboSize = ((ShaderHeader_t_v4 *)pHeader)->m_nDiffReferenceSize; + if ( referenceComboSize ) + { + // cache the reference combo + pFileCache->m_ReferenceCombo.EnsureCapacity( referenceComboSize ); + g_pFullFileSystem->Read( pFileCache->m_ReferenceCombo.Base(), referenceComboSize, hFile ); + } + } + else + { + // cache the dictionary + pFileCache->m_StaticComboRecords.EnsureCount( pHeader->m_nNumStaticCombos ); + g_pFullFileSystem->Read( pFileCache->m_StaticComboRecords.Base(), pHeader->m_nNumStaticCombos * sizeof( StaticComboRecord_t ), hFile ); + if ( pFileCache->IsVersion6() ) + { + // read static combo alias records + int nNumDups; + g_pFullFileSystem->Read( &nNumDups, sizeof( nNumDups ), hFile ); + if ( nNumDups ) + { + pFileCache->m_StaticComboDupRecords.EnsureCount( nNumDups ); + g_pFullFileSystem->Read( pFileCache->m_StaticComboDupRecords.Base(), nNumDups * sizeof( StaticComboAliasRecord_t ), hFile ); + } + } + + } + } + + // FIXME: should make lookup and ShaderStaticCombos_t are pool allocated. + int i; + lookup.m_ShaderStaticCombos.m_nCount = pHeader->m_nDynamicCombos; + lookup.m_ShaderStaticCombos.m_pHardwareShaders = new HardwareShader_t[pHeader->m_nDynamicCombos]; + if ( IsPC() && m_bCreateShadersOnDemand ) + { + lookup.m_ShaderStaticCombos.m_pCreationData = new ShaderStaticCombos_t::ShaderCreationData_t[pHeader->m_nDynamicCombos]; + } + for ( i = 0; i < pHeader->m_nDynamicCombos; i++ ) + { + lookup.m_ShaderStaticCombos.m_pHardwareShaders[i] = INVALID_HARDWARE_SHADER; + } + + int nStartingOffset = 0; + int nEndingOffset = 0; + + if ( pFileCache->IsOldVersion() ) + { + int nDictionaryOffset = sizeof( ShaderHeader_t ) + ((ShaderHeader_t_v4 *)pHeader)->m_nDiffReferenceSize; + + // read in shader's dynamic combos directory + lookup.m_pComboDictionary = new ShaderDictionaryEntry_t[pHeader->m_nDynamicCombos]; + g_pFullFileSystem->Seek( hFile, nDictionaryOffset + lookup.m_nStaticIndex * sizeof( ShaderDictionaryEntry_t ), FILESYSTEM_SEEK_HEAD ); + g_pFullFileSystem->Read( lookup.m_pComboDictionary, pHeader->m_nDynamicCombos * sizeof( ShaderDictionaryEntry_t ), hFile ); + + // want single read of all this shader's dynamic combos into a target buffer + // shaders are written sequentially, determine starting offset and length + for ( i = 0; i < pHeader->m_nDynamicCombos; i++ ) + { + if ( lookup.m_pComboDictionary[i].m_Offset == -1 ) + { + // skipped + continue; + } + + // ensure offsets are in fact sequentially ascending + Assert( lookup.m_pComboDictionary[i].m_Offset >= nStartingOffset && lookup.m_pComboDictionary[i].m_Size >= 0 ); + + if ( !nStartingOffset ) + { + nStartingOffset = lookup.m_pComboDictionary[i].m_Offset; + } + nEndingOffset = lookup.m_pComboDictionary[i].m_Offset + lookup.m_pComboDictionary[i].m_Size; + } + if ( !nStartingOffset ) + { + g_pFullFileSystem->Close( hFile ); + Warning( "Shader '%s' - All dynamic combos skipped. This is bad!\n", m_ShaderSymbolTable.String( pFileCache->m_Filename ) ); + return false; + } + } + else + { + int nStaticComboIdx = pFileCache->FindCombo( lookup.m_nStaticIndex / pFileCache->m_Header.m_nDynamicCombos ); + if ( nStaticComboIdx == -1 ) + { + g_pFullFileSystem->Close( hFile ); + lookup.m_Flags |= SHADER_FAILED_LOAD; + Warning( "Shader '%s' - Couldn't load combo %d of shader (dyn=%d)\n", m_ShaderSymbolTable.String( pFileCache->m_Filename ), lookup.m_nStaticIndex, pFileCache->m_Header.m_nDynamicCombos ); + return false; + } + + nStartingOffset = pFileCache->m_StaticComboRecords[nStaticComboIdx].m_nFileOffset; + nEndingOffset = pFileCache->m_StaticComboRecords[nStaticComboIdx+1].m_nFileOffset; + } + + // align offsets for unbuffered optimal i/o - fastest i/o possible + unsigned nOffsetAlign, nSizeAlign, nBufferAlign; + g_pFullFileSystem->GetOptimalIOConstraints( hFile, &nOffsetAlign, &nSizeAlign, &nBufferAlign ); + unsigned int nAlignedOffset = AlignValue( ( nStartingOffset - nOffsetAlign ) + 1, nOffsetAlign ); + unsigned int nAlignedBytesToRead = AlignValue( nEndingOffset - nAlignedOffset, nSizeAlign ); + + // used for adjusting provided buffer to actual data + lookup.m_nDataOffset = nStartingOffset - nAlignedOffset; + + bool bOK = true; + if ( IsX360() && g_pQueuedLoader->IsMapLoading() ) + { + LoaderJob_t loaderJob; + loaderJob.m_pFilename = m_ShaderSymbolTable.String( pFileCache->m_Filename ); + loaderJob.m_pPathID = "GAME"; + loaderJob.m_pCallback = QueuedLoaderCallback; + loaderJob.m_pContext = (void *)&lookup; + loaderJob.m_pContext2 = (void *)pFileCache->IsOldVersion(); + loaderJob.m_Priority = LOADERPRIORITY_DURINGPRELOAD; + loaderJob.m_nBytesToRead = nAlignedBytesToRead; + loaderJob.m_nStartOffset = nAlignedOffset; + g_pQueuedLoader->AddJob( &loaderJob ); + } + else + { + // single optimal read of all dynamic combos into monolithic buffer + uint8 *pOptimalBuffer = (uint8 *)g_pFullFileSystem->AllocOptimalReadBuffer( hFile, nAlignedBytesToRead, nAlignedOffset ); + g_pFullFileSystem->Seek( hFile, nAlignedOffset, FILESYSTEM_SEEK_HEAD ); + g_pFullFileSystem->Read( pOptimalBuffer, nAlignedBytesToRead, hFile ); + + if ( pFileCache->IsOldVersion() ) + { + bOK = CreateDynamicCombos_Ver4( &lookup, pOptimalBuffer ); + } + else + { + bOK = CreateDynamicCombos_Ver5( &lookup, pOptimalBuffer ); + } + + g_pFullFileSystem->FreeOptimalReadBuffer( pOptimalBuffer ); + } + + g_pFullFileSystem->Close( hFile ); + + if ( !bOK ) + { + lookup.m_Flags |= SHADER_FAILED_LOAD; + } + + return bOK; +} + +//----------------------------------------------------------------------------- +// Creates and destroys vertex shaders +//----------------------------------------------------------------------------- +VertexShader_t CShaderManager::CreateVertexShader( const char *pFileName, ShaderIndex_t nStaticVshIndex ) +{ + MEM_ALLOC_CREDIT(); + + if ( !pFileName ) + { + return INVALID_SHADER; + } + + VertexShader_t shader; + ShaderLookupDx11_t lookup; + lookup.m_Name = m_ShaderSymbolTable.AddString( pFileName ); + lookup.m_nStaticIndex = nStaticVshIndex; + shader = m_VertexShaderDict.Find( lookup ); + if ( shader == m_VertexShaderDict.InvalidIndex() ) + { + shader = m_VertexShaderDict.AddToTail( lookup ); + if ( !LoadAndCreateShaders( m_VertexShaderDict[shader], true ) ) + { + return INVALID_SHADER; + } + } + m_VertexShaderDict[shader].IncRefCount(); + return shader; +} + +//----------------------------------------------------------------------------- +// Create pixel shader +//----------------------------------------------------------------------------- +PixelShader_t CShaderManager::CreatePixelShader( const char *pFileName, ShaderIndex_t nStaticPshIndex ) +{ + MEM_ALLOC_CREDIT(); + + if ( !pFileName ) + { + return INVALID_SHADER; + } + + PixelShader_t shader; + ShaderLookupDx11_t lookup; + lookup.m_Name = m_ShaderSymbolTable.AddString( pFileName ); + lookup.m_nStaticIndex = nStaticPshIndex; + shader = m_PixelShaderDict.Find( lookup ); + if ( shader == m_PixelShaderDict.InvalidIndex() ) + { + shader = m_PixelShaderDict.AddToTail( lookup ); + if ( !LoadAndCreateShaders( m_PixelShaderDict[shader], false ) ) + { + return INVALID_SHADER; + } + } + m_PixelShaderDict[shader].IncRefCount(); + return shader; +} + +//----------------------------------------------------------------------------- +// Clear the refCounts to zero +//----------------------------------------------------------------------------- +void CShaderManager::ClearVertexAndPixelShaderRefCounts() +{ + for ( VertexShader_t vshIndex = m_VertexShaderDict.Head(); + vshIndex != m_VertexShaderDict.InvalidIndex(); + vshIndex = m_VertexShaderDict.Next( vshIndex ) ) + { + m_VertexShaderDict[vshIndex].m_nRefCount = 0; + } + + for ( PixelShader_t pshIndex = m_PixelShaderDict.Head(); + pshIndex != m_PixelShaderDict.InvalidIndex(); + pshIndex = m_PixelShaderDict.Next( pshIndex ) ) + { + m_PixelShaderDict[pshIndex].m_nRefCount = 0; + } +} + +//----------------------------------------------------------------------------- +// Destroy all shaders that have no reference +//----------------------------------------------------------------------------- +void CShaderManager::PurgeUnusedVertexAndPixelShaders() +{ + return; // FIXME + + // iterate vertex shaders + for ( VertexShader_t vshIndex = m_VertexShaderDict.Head(); vshIndex != m_VertexShaderDict.InvalidIndex(); ) + { + Assert( m_VertexShaderDict[vshIndex].m_nRefCount >= 0 ); + + // Get the next one before we potentially delete the current one. + VertexShader_t next = m_VertexShaderDict.Next( vshIndex ); + if ( m_VertexShaderDict[vshIndex].m_nRefCount <= 0 ) + { + DestroyVertexShader( vshIndex ); + } + vshIndex = next; + } + + // iterate pixel shaders + for ( PixelShader_t pshIndex = m_PixelShaderDict.Head(); pshIndex != m_PixelShaderDict.InvalidIndex(); ) + { + Assert( m_PixelShaderDict[pshIndex].m_nRefCount >= 0 ); + + // Get the next one before we potentially delete the current one. + PixelShader_t next = m_PixelShaderDict.Next( pshIndex ); + if ( m_PixelShaderDict[pshIndex].m_nRefCount <= 0 ) + { + DestroyPixelShader( pshIndex ); + } + pshIndex = next; + } +} + + + +void* CShaderManager::GetCurrentVertexShader() +{ + return (void*)m_HardwareVertexShader; +} + +void* CShaderManager::GetCurrentPixelShader() +{ + return (void*)m_HardwarePixelShader; +} + + +//----------------------------------------------------------------------------- +// The low-level dx call to set the vertex shader state +//----------------------------------------------------------------------------- +void CShaderManager::SetVertexShaderState( HardwareShader_t shader, DataCacheHandle_t hCachedShader ) +{ +} + +void CShaderManager::BindVertexShader( VertexShaderHandle_t hVertexShader ) +{ + //if ( m_HardwareVertexShader != hVertexShader ) + //{ + g_pShaderAPIDx11->BindVertexShader( hVertexShader ); + //m_HardwareVertexShader = hVertexShader; + //} +} + + +//----------------------------------------------------------------------------- +// Sets a particular vertex shader as the current shader +//----------------------------------------------------------------------------- +void CShaderManager::SetVertexShader( VertexShader_t shader ) +{ + // Determine which vertex shader to use... + if ( shader == INVALID_SHADER ) + { + BindVertexShader( 0 ); + return; + } + + int vshIndex = m_nVertexShaderIndex; + Assert( vshIndex >= 0 ); + if( vshIndex < 0 ) + { + vshIndex = 0; + } + + //ShaderLookupDx11_t &tlookup = m_VertexShaderDict[shader]; + //Warning( "vsh: %s static: %d dynamic: %d\n", m_ShaderSymbolTable.String( tlookup.m_Name ), + // tlookup.m_nStaticIndex, m_nVertexShaderIndex ); + +#ifdef DYNAMIC_SHADER_COMPILE + HardwareShader_t &dxshader = m_VertexShaderDict[shader].m_ShaderStaticCombos.m_pHardwareShaders[vshIndex]; + if ( dxshader == INVALID_HARDWARE_SHADER ) + { + // compile it since we haven't already! + ShaderLookupDx11_t &vshLookup = m_VertexShaderDict[shader]; + dxshader = CompileShader( m_ShaderSymbolTable.String( vshLookup.m_Name ), + vshLookup.m_nStaticIndex, vshIndex, true ); + Assert( dxshader != INVALID_HARDWARE_SHADER ); + } +#else + CShaderManager::ShaderLookupDx11_t *lookup = (ShaderLookupDx11_t *)&m_VertexShaderDict[shader]; + if ( lookup->m_Flags & SHADER_FAILED_LOAD ) + { + Assert( 0 ); + return; + } +#ifdef _DEBUG + vshDebugIndex = (vshDebugIndex + 1) % MAX_SHADER_HISTORY; + Q_strncpy( vshDebugName[vshDebugIndex], m_ShaderSymbolTable.String( lookup->m_Name ), sizeof( vshDebugName[0] ) ); +#endif + HardwareShader_t dxshader = lookup->m_ShaderStaticCombos.m_pHardwareShaders[vshIndex]; +#endif + + if ( IsPC() && ( dxshader == INVALID_HARDWARE_SHADER ) && m_bCreateShadersOnDemand ) + { +#ifdef DYNAMIC_SHADER_COMPILE + ShaderStaticCombos_t::ShaderCreationData_t *pCreationData = &m_VertexShaderDict[shader].m_ShaderStaticCombos.m_pCreationData[vshIndex]; +#else + ShaderStaticCombos_t::ShaderCreationData_t *pCreationData = &lookup->m_ShaderStaticCombos.m_pCreationData[vshIndex]; +#endif + + dxshader = g_pShaderDeviceDx11->CreateVertexShader( ( DWORD * )pCreationData->ByteCode.Base(), pCreationData->ByteCode.Count() ); + +#ifdef DYNAMIC_SHADER_COMPILE + // copy the compiled shader handle back to wherever it's supposed to be stored + m_VertexShaderDict[shader].m_ShaderStaticCombos.m_pHardwareShaders[vshIndex] = dxshader; +#else + lookup->m_ShaderStaticCombos.m_pHardwareShaders[vshIndex] = dxshader; +#endif + } + + Assert( dxshader ); + +#ifndef DYNAMIC_SHADER_COMPILE + if( !dxshader ) + { + Error( "!!!!!Using invalid shader combo!!!!! Consult a programmer and tell them to build debug materialsystem.dll and stdshader*.dll. Run with \"mat_bufferprimitives 0\" and look for CMaterial in the call stack and see what m_pDebugName is. You are likely using a shader combo that has been skipped.\n" ); + } +#endif + + BindVertexShader( (VertexShaderHandle_t)dxshader ); +} + +//----------------------------------------------------------------------------- +// The low-level dx call to set the pixel shader state +//----------------------------------------------------------------------------- +void CShaderManager::SetPixelShaderState( HardwareShader_t shader, DataCacheHandle_t hCachedShader ) +{ +} + +void CShaderManager::BindPixelShader( PixelShaderHandle_t hPixelShader ) +{ + //if ( m_HardwarePixelShader != hPixelShader ) + //{ + g_pShaderAPIDx11->BindPixelShader( hPixelShader ); + // m_HardwarePixelShader = hPixelShader; + //} +} + + +//----------------------------------------------------------------------------- +// Sets a particular pixel shader as the current shader +//----------------------------------------------------------------------------- +void CShaderManager::SetPixelShader( PixelShader_t shader ) +{ + if ( shader == INVALID_SHADER ) + { + BindPixelShader( 0 ); + return; + } + + int pshIndex = m_nPixelShaderIndex; + Assert( pshIndex >= 0 ); + //ShaderLookupDx11_t &lookup = m_PixelShaderDict[shader]; + //Warning( "psh: %s static: %d dynamic: %d\n", m_ShaderSymbolTable.String( lookup.m_Name ), + // lookup.m_nStaticIndex, m_nPixelShaderIndex ); +#ifdef DYNAMIC_SHADER_COMPILE + HardwareShader_t &dxshader = m_PixelShaderDict[shader].m_ShaderStaticCombos.m_pHardwareShaders[pshIndex]; + if ( dxshader == INVALID_HARDWARE_SHADER ) + { + // compile it since we haven't already! + ShaderLookupDx11_t &vshLookup = m_PixelShaderDict[shader]; + dxshader = CompileShader( m_ShaderSymbolTable.String( vshLookup.m_Name ), + vshLookup.m_nStaticIndex, pshIndex, false ); +// Assert( dxshader != INVALID_HARDWARE_SHADER ); + + if( IsX360() ) + { + //360 does not respond well at all to bad shaders or Error() calls. So we're staying here until we get something that compiles + while( dxshader == INVALID_HARDWARE_SHADER ) + { + Warning( "A dynamically compiled pixel shader has failed to build. Pausing for 5 seconds and attempting rebuild.\n" ); + Sleep( 5000 ); + dxshader = CompileShader( m_ShaderSymbolTable.String( vshLookup.m_Name ), + vshLookup.m_nStaticIndex, pshIndex, false ); + } + } + } +#else + ShaderLookupDx11_t *lookup = (ShaderLookupDx11_t *)&m_PixelShaderDict[shader]; + if ( lookup->m_Flags & SHADER_FAILED_LOAD ) + { + Assert( 0 ); + return; + } +#ifdef _DEBUG + pshDebugIndex = (pshDebugIndex + 1) % MAX_SHADER_HISTORY; + Q_strncpy( pshDebugName[pshDebugIndex], m_ShaderSymbolTable.String( lookup->m_Name ), sizeof( pshDebugName[0] ) ); +#endif + HardwareShader_t dxshader = lookup->m_ShaderStaticCombos.m_pHardwareShaders[pshIndex]; +#endif + + if ( IsPC() && ( dxshader == INVALID_HARDWARE_SHADER ) && m_bCreateShadersOnDemand ) + { +#ifdef DYNAMIC_SHADER_COMPILE + ShaderStaticCombos_t::ShaderCreationData_t *pCreationData = &m_PixelShaderDict[shader].m_ShaderStaticCombos.m_pCreationData[pshIndex]; +#else + ShaderStaticCombos_t::ShaderCreationData_t *pCreationData = &lookup->m_ShaderStaticCombos.m_pCreationData[pshIndex]; +#endif + + dxshader = g_pShaderDeviceDx11->CreatePixelShader( ( DWORD * )pCreationData->ByteCode.Base(), pCreationData->ByteCode.Count() ); + +#ifdef DYNAMIC_SHADER_COMPILE + // copy the compiled shader handle back to wherever it's supposed to be stored + m_PixelShaderDict[shader].m_ShaderStaticCombos.m_pHardwareShaders[pshIndex] = dxshader; +#else + lookup->m_ShaderStaticCombos.m_pHardwareShaders[pshIndex] = dxshader; +#endif + } + + AssertMsg( dxshader != INVALID_HARDWARE_SHADER, "Failed to set pixel shader." ); + BindPixelShader( (PixelShaderHandle_t)dxshader ); +} + +//----------------------------------------------------------------------------- +// Resets the shader state +//----------------------------------------------------------------------------- +void CShaderManager::ResetShaderState() +{ + // This will force the calls to SetVertexShader + SetPixelShader to actually set the state + m_HardwareVertexShader = (HardwareShader_t)-1; + m_HardwarePixelShader = (HardwareShader_t)-1; + + BindVertexShader( VERTEX_SHADER_HANDLE_INVALID ); + BindPixelShader( PIXEL_SHADER_HANDLE_INVALID ); +} + +//----------------------------------------------------------------------------- +// Destroy a particular vertex shader +//----------------------------------------------------------------------------- +void CShaderManager::DestroyVertexShader( VertexShader_t shader ) +{ + ShaderStaticCombos_t &combos = m_VertexShaderDict[shader].m_ShaderStaticCombos; + int i; + for ( i = 0; i < combos.m_nCount; i++ ) + { + if ( combos.m_pHardwareShaders[i] != INVALID_HARDWARE_SHADER ) + { + ID3D11VertexShader* pShader = (ID3D11VertexShader* )combos.m_pHardwareShaders[i]; + UnregisterVS( pShader ); +#ifdef _DEBUG + int nRetVal = +#endif + pShader->Release(); + Assert( nRetVal == 0 ); + } + } + delete [] combos.m_pHardwareShaders; + combos.m_pHardwareShaders = NULL; + + if ( combos.m_pCreationData != NULL ) + { + delete [] combos.m_pCreationData; + combos.m_pCreationData = NULL; + } + + m_VertexShaderDict.Remove( shader ); +} + +//----------------------------------------------------------------------------- +// Destroy a particular pixel shader +//----------------------------------------------------------------------------- +void CShaderManager::DestroyPixelShader( PixelShader_t pixelShader ) +{ + ShaderStaticCombos_t &combos = m_PixelShaderDict[pixelShader].m_ShaderStaticCombos; + int i; + for ( i = 0; i < combos.m_nCount; i++ ) + { + if ( combos.m_pHardwareShaders[i] != INVALID_HARDWARE_SHADER ) + { + ID3D11PixelShader* pShader = ( ID3D11PixelShader * )combos.m_pHardwareShaders[i]; + UnregisterPS( pShader ); +#ifdef _DEBUG + int nRetVal = +#endif + pShader->Release(); + Assert( nRetVal == 0 ); + } + } + delete [] combos.m_pHardwareShaders; + combos.m_pHardwareShaders = NULL; + + if ( combos.m_pCreationData != NULL ) + { + delete [] combos.m_pCreationData; + combos.m_pCreationData = NULL; + } + + m_PixelShaderDict.Remove( pixelShader ); +} + + +//----------------------------------------------------------------------------- +// Destroys all shaders +//----------------------------------------------------------------------------- +void CShaderManager::DestroyAllShaders( void ) +{ + for ( VertexShader_t vshIndex = m_VertexShaderDict.Head(); + vshIndex != m_VertexShaderDict.InvalidIndex(); ) + { + Assert( m_VertexShaderDict[vshIndex].m_nRefCount >= 0 ); + VertexShader_t next = m_VertexShaderDict.Next( vshIndex ); + DestroyVertexShader( vshIndex ); + vshIndex = next; + } + + for ( PixelShader_t pshIndex = m_PixelShaderDict.Head(); + pshIndex != m_PixelShaderDict.InvalidIndex(); ) + { + Assert( m_PixelShaderDict[pshIndex].m_nRefCount >= 0 ); + PixelShader_t next = m_PixelShaderDict.Next( pshIndex ); + DestroyPixelShader( pshIndex ); + pshIndex = next; + } + + // invalidate the file cache + m_ShaderFileCache.Purge(); +} + +//----------------------------------------------------------------------------- +// print all vertex and pixel shaders along with refcounts to the console +//----------------------------------------------------------------------------- +void CShaderManager::SpewVertexAndPixelShaders( void ) +{ + // only spew a populated shader file cache + Msg( "\nShader File Cache:\n" ); + for ( int cacheIndex = m_ShaderFileCache.Head(); + cacheIndex != m_ShaderFileCache.InvalidIndex(); + cacheIndex = m_ShaderFileCache.Next( cacheIndex ) ) + { + ShaderFileCache_t *pCache = &m_ShaderFileCache[cacheIndex]; + Msg( "Total Combos:%9d Static:%9d Dynamic:%7d SeekTable:%7d Ver:%d '%s'\n", + pCache->m_Header.m_nTotalCombos, + pCache->m_Header.m_nTotalCombos/pCache->m_Header.m_nDynamicCombos, + pCache->m_Header.m_nDynamicCombos, + pCache->IsOldVersion() ? 0 : pCache->m_Header.m_nNumStaticCombos, + pCache->m_Header.m_nVersion, + m_ShaderSymbolTable.String( pCache->m_Filename ) ); + } + Msg( "\n" ); + + // spew vertex shader dictionary + int totalVertexShaders = 0; + int totalVertexShaderSets = 0; + for ( VertexShader_t vshIndex = m_VertexShaderDict.Head(); + vshIndex != m_VertexShaderDict.InvalidIndex(); + vshIndex = m_VertexShaderDict.Next( vshIndex ) ) + { + const auto &lookup = m_VertexShaderDict[vshIndex]; + const char *pName = m_ShaderSymbolTable.String( lookup.m_Name ); + Msg( "vsh 0x%8.8x: static combo:%9d dynamic combos:%6d refcount:%4d \"%s\"\n", vshIndex, + ( int )lookup.m_nStaticIndex, ( int )lookup.m_ShaderStaticCombos.m_nCount, + lookup.m_nRefCount, pName ); + totalVertexShaders += lookup.m_ShaderStaticCombos.m_nCount; + totalVertexShaderSets++; + } + + // spew pixel shader dictionary + int totalPixelShaders = 0; + int totalPixelShaderSets = 0; + for ( PixelShader_t pshIndex = m_PixelShaderDict.Head(); + pshIndex != m_PixelShaderDict.InvalidIndex(); + pshIndex = m_PixelShaderDict.Next( pshIndex ) ) + { + const auto &lookup = m_PixelShaderDict[pshIndex]; + const char *pName = m_ShaderSymbolTable.String( lookup.m_Name ); + Msg( "psh 0x%8.8x: static combo:%9d dynamic combos:%6d refcount:%4d \"%s\"\n", pshIndex, + ( int )lookup.m_nStaticIndex, ( int )lookup.m_ShaderStaticCombos.m_nCount, + lookup.m_nRefCount, pName ); + totalPixelShaders += lookup.m_ShaderStaticCombos.m_nCount; + totalPixelShaderSets++; + } + + Msg( "Total unique vertex shaders: %d\n", totalVertexShaders ); + Msg( "Total vertex shader sets: %d\n", totalVertexShaderSets ); + Msg( "Total unique pixel shaders: %d\n", totalPixelShaders ); + Msg( "Total pixel shader sets: %d\n", totalPixelShaderSets ); +} + +CON_COMMAND( mat_spewvertexandpixelshaders, "Print all vertex and pixel shaders currently loaded to the console" ) +{ + ( ( CShaderManager * )ShaderManager() )->SpewVertexAndPixelShaders(); +} + +const char *CShaderManager::GetActiveVertexShaderName() +{ +#if !defined( _DEBUG ) + return ""; +#else + if ( !m_HardwareVertexShader ) + { + return "NULL"; + } + return vshDebugName[vshDebugIndex]; +#endif +} + +const char *CShaderManager::GetActivePixelShaderName() +{ +#if !defined( _DEBUG ) + return ""; +#else + if ( !m_HardwarePixelShader ) + { + return "NULL"; + } + return pshDebugName[pshDebugIndex]; +#endif +} + +#ifdef DYNAMIC_SHADER_COMPILE +void CShaderManager::FlushShaders( void ) +{ + for( VertexShader_t shader = m_VertexShaderDict.Head(); + shader != m_VertexShaderDict.InvalidIndex(); + shader = m_VertexShaderDict.Next( shader ) ) + { + int i; + ShaderStaticCombos_t *combos = &m_VertexShaderDict[shader].m_ShaderStaticCombos; + if( !( m_VertexShaderDict[shader].m_Flags & SHADER_DYNAMIC_COMPILE_IS_HLSL ) ) + { + // don't nuke non-HLSL shaders since we don't dynamically compile them. + continue; + } + for( i = 0; i < combos->m_nCount; i++ ) + { + if( combos->m_pHardwareShaders[i] != INVALID_HARDWARE_SHADER ) + { +#ifdef _DEBUG + int nRetVal= +#endif + ( ( ID3D11VertexShader * )combos->m_pHardwareShaders[i] )->Release(); + Assert( nRetVal == 0 ); + } + combos->m_pHardwareShaders[i] = INVALID_HARDWARE_SHADER; + } + } + + for( PixelShader_t shader = m_PixelShaderDict.Head(); + shader != m_PixelShaderDict.InvalidIndex(); + shader = m_PixelShaderDict.Next( shader ) ) + { + int i; + ShaderStaticCombos_t &combos = m_PixelShaderDict[shader].m_ShaderStaticCombos; + if( !( m_PixelShaderDict[shader].m_Flags & SHADER_DYNAMIC_COMPILE_IS_HLSL ) ) + { + // don't nuke non-HLSL shaders since we don't dynamically compile them. + continue; + } + for( i = 0; i < combos.m_nCount; i++ ) + { + if( combos.m_pHardwareShaders[i] != INVALID_HARDWARE_SHADER ) + { +#ifdef _DEBUG + int nRetVal = +#endif + ( ( ID3D11PixelShader * )combos.m_pHardwareShaders[i] )->Release(); + Assert( nRetVal == 0 ); + } + combos.m_pHardwareShaders[i] = INVALID_HARDWARE_SHADER; + } + } + + // invalidate the file cache + m_ShaderFileCache.Purge(); +} +#endif + +#ifdef DYNAMIC_SHADER_COMPILE +CON_COMMAND( mat_flushshaders, "flush all hardware shaders when using DYNAMIC_SHADER_COMPILE" ) +{ + ( ( CShaderManager * )ShaderManager() )->FlushShaders(); +} +#endif \ No newline at end of file diff --git a/materialsystem/shaderapidx11/vertexshaderdx11.h b/materialsystem/shaderapidx11/vertexshaderdx11.h new file mode 100644 index 0000000..5012795 --- /dev/null +++ b/materialsystem/shaderapidx11/vertexshaderdx11.h @@ -0,0 +1,102 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef VERTEXSHADERDX11_H +#define VERTEXSHADERDX11_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderapi/ishaderapi.h" +#include "shaderapidx9/locald3dtypes.h" + +enum VertexShaderLightTypes_t +{ + LIGHT_NONE = -1, + LIGHT_SPOT = 0, + LIGHT_POINT = 1, + LIGHT_DIRECTIONAL = 2, + LIGHT_STATIC = 3, + LIGHT_AMBIENTCUBE = 4, +}; + +//----------------------------------------------------------------------------- +// Vertex + pixel shader manager +//----------------------------------------------------------------------------- +abstract_class IShaderManager +{ +protected: + + // The current vertex and pixel shader index + ShaderIndex_t m_nVertexShaderIndex; + ShaderIndex_t m_nPixelShaderIndex; + +public: + // Initialize, shutdown + virtual void Init() = 0; + virtual void Shutdown() = 0; + + // Compiles vertex shaders + virtual IShaderBuffer *CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion ) = 0; + + // New version of these methods [dx10 port] + virtual VertexShaderHandle_t CreateVertexShader( IShaderBuffer* pShaderBuffer ) = 0; + virtual void DestroyVertexShader( VertexShaderHandle_t hShader ) = 0; + virtual PixelShaderHandle_t CreatePixelShader( IShaderBuffer* pShaderBuffer ) = 0; + virtual void DestroyPixelShader( PixelShaderHandle_t hShader ) = 0; + + // Creates vertex, pixel shaders + virtual VertexShader_t CreateVertexShader( const char *pVertexShaderFile, ShaderIndex_t nStaticVshIndex = 0 ) = 0; + virtual PixelShader_t CreatePixelShader( const char *pPixelShaderFile, ShaderIndex_t nStaticPshIndex = 0 ) = 0; + + // Sets which dynamic version of the vertex + pixel shader to use + void SetVertexShaderIndex( ShaderIndex_t vshIndex ); + void SetPixelShaderIndex( ShaderIndex_t pshIndex ); + + // Sets the vertex + pixel shader render state + virtual void SetVertexShader( VertexShader_t shader ) = 0; + virtual void SetPixelShader( PixelShader_t shader ) = 0; + + // Resets the vertex + pixel shader state + virtual void ResetShaderState() = 0; + + // Returns the current vertex + pixel shaders + virtual void *GetCurrentVertexShader() = 0; + virtual void *GetCurrentPixelShader() = 0; + + virtual void ClearVertexAndPixelShaderRefCounts() = 0; + virtual void PurgeUnusedVertexAndPixelShaders() = 0; + + // The low-level dx call to set the vertex shader state + virtual void BindVertexShader( VertexShaderHandle_t shader ) = 0; + virtual void BindPixelShader( PixelShaderHandle_t shader ) = 0; +}; + +//----------------------------------------------------------------------------- +// +// Methods related to setting vertex + pixel shader state +// +//----------------------------------------------------------------------------- +FORCEINLINE void IShaderManager::SetVertexShaderIndex( ShaderIndex_t vshIndex ) +{ + m_nVertexShaderIndex = vshIndex; +} + +FORCEINLINE void IShaderManager::SetPixelShaderIndex( ShaderIndex_t pshIndex ) +{ + m_nPixelShaderIndex = pshIndex; +} + +extern IShaderManager *g_pShaderManagerDx11; +inline IShaderManager* ShaderManager() +{ + return g_pShaderManagerDx11; +} + +#endif // VERTEXSHADERDX11_H diff --git a/materialsystem/shaderapidx9/TransitionTable.cpp b/materialsystem/shaderapidx9/TransitionTable.cpp index ab12389..f309f82 100644 --- a/materialsystem/shaderapidx9/TransitionTable.cpp +++ b/materialsystem/shaderapidx9/TransitionTable.cpp @@ -1128,7 +1128,7 @@ int CTransitionTable::CreateNormalTransitions( const ShadowState_t& fromState, c } int nSamplerCount = HardwareConfig()->GetSamplerCount(); - for ( int i = 0; i < nSamplerCount; ++i ) + for ( i = 0; i < nSamplerCount; ++i ) { ADD_SAMPLER_STATE_TRANSITION( i, SRGBReadEnable ); ADD_SAMPLER_STATE_TRANSITION( i, Fetch4Enable ); diff --git a/materialsystem/shaderapidx9/locald3dtypes.h b/materialsystem/shaderapidx9/locald3dtypes.h index ad45355..64e7936 100644 --- a/materialsystem/shaderapidx9/locald3dtypes.h +++ b/materialsystem/shaderapidx9/locald3dtypes.h @@ -44,9 +44,18 @@ public: typedef ID3D10Device *LPDIRECT3DDEVICE; typedef ID3D10Buffer *LPDIRECT3DINDEXBUFFER; typedef ID3D10Buffer *LPDIRECT3DVERTEXBUFFER; -}; +}; -#endif // defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION ) +#elif defined(DX11) + +#include +#include +#include + +// Stupid typedef to avoid breaking API +typedef ID3D11Resource IDirect3DBaseTexture; + +#else #if !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION ) @@ -108,13 +117,16 @@ public: typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER; }; +#endif // defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION ) + typedef void *HardwareShader_t; //----------------------------------------------------------------------------- // The vertex and pixel shader type //----------------------------------------------------------------------------- typedef int VertexShader_t; -typedef int PixelShader_t; +typedef int PixelShader_t; +typedef int GeometryShader_t; //----------------------------------------------------------------------------- // Bitpattern for an invalid shader diff --git a/materialsystem/shaderapidx9/shaderapibase.h b/materialsystem/shaderapidx9/shaderapibase.h index fe8d928..b45869a 100644 --- a/materialsystem/shaderapidx9/shaderapibase.h +++ b/materialsystem/shaderapidx9/shaderapibase.h @@ -26,7 +26,11 @@ //----------------------------------------------------------------------------- // The Base implementation of the shader rendering interface //----------------------------------------------------------------------------- +#ifdef DX11 +class CShaderAPIBase : public IShaderAPIDX11 +#else class CShaderAPIBase : public IShaderAPI +#endif { public: // constructor, destructor diff --git a/materialsystem/shaderapidx9/shaderapidx8.cpp b/materialsystem/shaderapidx9/shaderapidx8.cpp index ba6d509..e6e2a86 100644 --- a/materialsystem/shaderapidx9/shaderapidx8.cpp +++ b/materialsystem/shaderapidx9/shaderapidx8.cpp @@ -7899,7 +7899,7 @@ void CShaderAPIDx8::SetRenderTargetEx( int nRenderTargetID, ShaderAPITextureHand } else { - HRESULT hr = ((IDirect3DTexture9*)tex.GetTexture())->GetSurfaceLevel( 0, &pZSurface ); + hr = ((IDirect3DTexture9*)tex.GetTexture())->GetSurfaceLevel( 0, &pZSurface ); } if ( !pZSurface ) @@ -7973,7 +7973,6 @@ void CShaderAPIDx8::SetRenderTargetEx( int nRenderTargetID, ShaderAPITextureHand if ( m_UsingTextureRenderTarget && nRenderTargetID == 0 ) { D3DSURFACE_DESC desc; - HRESULT hr; if ( !pZSurface ) { hr = pColorSurface->GetDesc( &desc ); diff --git a/materialsystem/shaderapidx9/shaderdevicebase.cpp b/materialsystem/shaderapidx9/shaderdevicebase.cpp index aef5996..822b956 100644 --- a/materialsystem/shaderapidx9/shaderdevicebase.cpp +++ b/materialsystem/shaderapidx9/shaderdevicebase.cpp @@ -845,7 +845,9 @@ int CShaderDeviceMgrBase::GetClosestActualDXLevel( int nDxLevel ) const return 98; if ( nDxLevel <= 99 ) return 95; - return 100; + if (nDxLevel <= 109) + return 100; + return 110; } diff --git a/materialsystem/shaderapidx9/shaderdevicebase.h b/materialsystem/shaderapidx9/shaderdevicebase.h index 37d7cc0..bd14f23 100644 --- a/materialsystem/shaderapidx9/shaderdevicebase.h +++ b/materialsystem/shaderapidx9/shaderdevicebase.h @@ -126,7 +126,11 @@ protected: //----------------------------------------------------------------------------- // The Base implementation of the shader device //----------------------------------------------------------------------------- +#ifdef DX11 +class CShaderDeviceBase : public IShaderDeviceDX11 +#else class CShaderDeviceBase : public IShaderDevice +#endif { public: enum IPCMessage_t diff --git a/materialsystem/shaderapidx9/vertexdecl.cpp b/materialsystem/shaderapidx9/vertexdecl.cpp index 3d70dbc..ba87ee1 100644 --- a/materialsystem/shaderapidx9/vertexdecl.cpp +++ b/materialsystem/shaderapidx9/vertexdecl.cpp @@ -434,7 +434,7 @@ void ComputeVertexSpec( VertexFormat_t fmt, D3DVERTEXELEMENT9 *pDecl, bool bStat pDecl[i].Type = bUseWrinkle ? D3DDECLTYPE_FLOAT4 : D3DDECLTYPE_FLOAT3; ++i; - int normalOffset = GetVertexElementSize( VERTEX_ELEMENT_POSITION, compressionType ); + normalOffset = GetVertexElementSize( VERTEX_ELEMENT_POSITION, compressionType ); if ( bUseWrinkle ) { normalOffset += GetVertexElementSize( VERTEX_ELEMENT_WRINKLE, compressionType ); diff --git a/materialsystem/shaderapidx9/wmi.cpp b/materialsystem/shaderapidx9/wmi.cpp index 1b0644f..c23fea7 100644 --- a/materialsystem/shaderapidx9/wmi.cpp +++ b/materialsystem/shaderapidx9/wmi.cpp @@ -140,7 +140,7 @@ uint64 GetVidMemBytes( void ) while ( pEnumerator ) { - HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if(0 == uReturn) { diff --git a/materialsystem/shaderlib_dx11/BaseShader.cpp b/materialsystem/shaderlib_dx11/BaseShader.cpp new file mode 100644 index 0000000..1580d94 --- /dev/null +++ b/materialsystem/shaderlib_dx11/BaseShader.cpp @@ -0,0 +1,1852 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "shaderapi/IShaderDevice.h" +#include "shaderapi/IShaderAPI.h" +#include "shaderlib_dx11/BaseShader.h" +#include "shaderlib_dx11/ShaderDLL.h" +#include "tier0/dbg.h" +#include "shaderDLL_Global.h" +#include "IShaderSystem.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/itexture.h" +#include "materialsystem/ishaderapi.h" +#include "materialsystem/materialsystem_config.h" +#include "shaderlib/cshader.h" +#include "mathlib/vmatrix.h" +#include "tier1/strtools.h" +#include "convar.h" +#include "tier0/vprof.h" + +// NOTE: This must be the last include file in a .cpp file! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +const char *CBaseShader::s_pTextureGroupName = NULL; +IMaterialVar **CBaseShader::s_ppParams; +IShaderShadowDX11 *CBaseShader::s_pShaderShadow; +IShaderAPIDX11 *CBaseShader::s_pShaderAPI; +IShaderInit *CBaseShader::s_pShaderInit; +int CBaseShader::s_nModulationFlags; +CMeshBuilder *CBaseShader::s_pMeshBuilder; +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +bool g_shaderConfigDumpEnable = false; //true; //DO NOT CHECK IN ENABLED FIXME + +//----------------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------------- +CBaseShader::CBaseShader() +{ + GetShaderDLL()->InsertShader( this ); +} + + +//----------------------------------------------------------------------------- +// Shader parameter info +//----------------------------------------------------------------------------- +// Look in BaseShader.h for the enumeration for these. +// Update there if you update here. +static ShaderParamInfo_t s_StandardParams[NUM_SHADER_MATERIAL_VARS] = +{ + { "$flags", "flags", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, + { "$flags_defined", "flags_defined", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, + { "$flags2", "flags2", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, + { "$flags_defined2", "flags2_defined", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, + { "$color", "color", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 }, + { "$alpha", "alpha", SHADER_PARAM_TYPE_FLOAT, "1.0", 0 }, + { "$basetexture", "Base Texture with lighting built in", SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", 0 }, + { "$frame", "Animation Frame", SHADER_PARAM_TYPE_INTEGER, "0", 0 }, + { "$basetexturetransform", "Base Texture Texcoord Transform",SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", 0 }, + { "$flashlighttexture", "flashlight spotlight shape texture", SHADER_PARAM_TYPE_TEXTURE, "effects/flashlight001", SHADER_PARAM_NOT_EDITABLE }, + { "$flashlighttextureframe", "Animation Frame for $flashlight", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, + { "$color2", "color2", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 }, + { "$srgbtint", "tint value to be applied when running on new-style srgb parts", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 }, +}; + + +//----------------------------------------------------------------------------- +// Gets the standard shader parameter names +// FIXME: Turn this into one function? +//----------------------------------------------------------------------------- +int CBaseShader::GetNumParams( ) const +{ + return NUM_SHADER_MATERIAL_VARS; +} + +char const* CBaseShader::GetParamName( int nParamIndex ) const +{ + Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); + return s_StandardParams[nParamIndex].m_pName; +} + +const char *CBaseShader::GetParamHelp( int nParamIndex ) const +{ + Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); + return s_StandardParams[nParamIndex].m_pHelp; +} + +ShaderParamType_t CBaseShader::GetParamType( int nParamIndex ) const +{ + Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); + return s_StandardParams[nParamIndex].m_Type; +} + +const char *CBaseShader::GetParamDefault( int nParamIndex ) const +{ + Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); + return s_StandardParams[nParamIndex].m_pDefaultValue; +} + +int CBaseShader::GetParamFlags( int nParamIndex ) const +{ + Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); + return s_StandardParams[nParamIndex].m_nFlags; +} + +//----------------------------------------------------------------------------- +// Necessary to snag ahold of some important data for the helper methods +//----------------------------------------------------------------------------- +void CBaseShader::InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ) +{ + // Re-entrancy check + Assert( !s_ppParams ); + + s_ppParams = ppParams; + + OnInitShaderParams( ppParams, pMaterialName ); + + s_ppParams = NULL; +} + +void CBaseShader::InitShader(IShaderDevice* pShaderDevice) +{ + OnInitShader(pShaderDevice); +} + +void CBaseShader::InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName ) +{ + // Re-entrancy check + Assert( !s_ppParams ); + + s_ppParams = ppParams; + s_pShaderInit = pShaderInit; + s_pTextureGroupName = pTextureGroupName; + + OnInitShaderInstance( ppParams, pShaderInit, pMaterialName ); + + s_pTextureGroupName = NULL; + s_ppParams = NULL; + s_pShaderInit = NULL; +} + +void CBaseShader::DrawElements( IMaterialVar **ppParams, int nModulationFlags, + IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) +{ + VPROF("CBaseShader::DrawElements"); + // Re-entrancy check + Assert( !s_ppParams ); + + s_ppParams = ppParams; + s_pShaderAPI = static_cast(pShaderAPI); + s_pShaderShadow = static_cast(pShaderShadow); + s_nModulationFlags = nModulationFlags; + s_pMeshBuilder = pShaderAPI ? pShaderAPI->GetVertexModifyBuilder() : NULL; + + if ( IsSnapshotting() ) + { + // Set up the shadow state + SetInitialShadowState( ); + } + + OnDrawElements( ppParams, pShaderShadow, pShaderAPI, vertexCompression, pContextDataPtr ); + + s_nModulationFlags = 0; + s_ppParams = NULL; + s_pShaderAPI = NULL; + s_pShaderShadow = NULL; + s_pMeshBuilder = NULL; +} + + +//----------------------------------------------------------------------------- +// Sets the default shadow state +//----------------------------------------------------------------------------- +void CBaseShader::SetInitialShadowState( ) +{ + // Set the default state + s_pShaderShadow->SetDefaultState(); + + // Init the standard states... + int flags = s_ppParams[FLAGS]->GetIntValue(); + if (flags & MATERIAL_VAR_IGNOREZ) + { + s_pShaderShadow->EnableDepthTest( false ); + s_pShaderShadow->EnableDepthWrites( false ); + } + + if (flags & MATERIAL_VAR_DECAL) + { + s_pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_DECAL ); + s_pShaderShadow->EnableDepthWrites( false ); + } + + if (flags & MATERIAL_VAR_NOCULL) + { + s_pShaderShadow->EnableCulling( false ); + } + + if (flags & MATERIAL_VAR_ZNEARER) + { + s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_NEARER ); + } + + if (flags & MATERIAL_VAR_WIREFRAME) + { + s_pShaderShadow->PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_LINE ); + } + + // Set alpha to coverage + if (flags & MATERIAL_VAR_ALLOWALPHATOCOVERAGE) + { + // Force the bit on and then check against alpha blend and test states in CShaderShadowDX8::ComputeAggregateShadowState() + s_pShaderShadow->EnableAlphaToCoverage( true ); + } +} + + +//----------------------------------------------------------------------------- +// Draws a snapshot +//----------------------------------------------------------------------------- +void CBaseShader::Draw( bool bMakeActualDrawCall ) +{ + if ( IsSnapshotting() ) + { + // Turn off transparency if we're asked to.... + if (g_pConfig->bNoTransparency && + ((s_ppParams[FLAGS]->GetIntValue() & MATERIAL_VAR_NO_DEBUG_OVERRIDE) == 0)) + { + s_pShaderShadow->EnableDepthWrites( true ); + s_pShaderShadow->EnableBlending( false ); + } + + GetShaderSystem()->TakeSnapshot(); + } + else + { + GetShaderSystem()->DrawSnapshot( bMakeActualDrawCall ); + } +} + + +//----------------------------------------------------------------------------- +// Finds a particular parameter (works because the lowest parameters match the shader) +//----------------------------------------------------------------------------- +int CBaseShader::FindParamIndex( const char *pName ) const +{ + int numParams = GetNumParams(); + for( int i = 0; i < numParams; i++ ) + { + if( Q_strnicmp( GetParamName( i ), pName, 64 ) == 0 ) + { + return i; + } + } + return -1; +} + + +//----------------------------------------------------------------------------- +// Are we using graphics? +//----------------------------------------------------------------------------- +bool CBaseShader::IsUsingGraphics() +{ + return GetShaderSystem()->IsUsingGraphics(); +} + + +//----------------------------------------------------------------------------- +// Are we using graphics? +//----------------------------------------------------------------------------- +bool CBaseShader::CanUseEditorMaterials() +{ + return GetShaderSystem()->CanUseEditorMaterials(); +} + + +//----------------------------------------------------------------------------- +// Gets the builder... +//----------------------------------------------------------------------------- +CMeshBuilder* CBaseShader::MeshBuilder() +{ + return s_pMeshBuilder; +} + + +//----------------------------------------------------------------------------- +// Loads a texture +//----------------------------------------------------------------------------- +void CBaseShader::LoadTexture( int nTextureVar, int nAdditionalCreationFlags /* = 0 */ ) +{ + if ((!s_ppParams) || (nTextureVar == -1)) + return; + + IMaterialVar* pNameVar = s_ppParams[nTextureVar]; + if( pNameVar && pNameVar->IsDefined() ) + { + s_pShaderInit->LoadTexture( pNameVar, s_pTextureGroupName, nAdditionalCreationFlags ); + } +} + + +//----------------------------------------------------------------------------- +// Loads a bumpmap +//----------------------------------------------------------------------------- +void CBaseShader::LoadBumpMap( int nTextureVar ) +{ + if ((!s_ppParams) || (nTextureVar == -1)) + return; + + IMaterialVar* pNameVar = s_ppParams[nTextureVar]; + if( pNameVar && pNameVar->IsDefined() ) + { + s_pShaderInit->LoadBumpMap( pNameVar, s_pTextureGroupName ); + } +} + + +//----------------------------------------------------------------------------- +// Loads a cubemap +//----------------------------------------------------------------------------- +void CBaseShader::LoadCubeMap( int nTextureVar, int nAdditionalCreationFlags /* = 0 */ ) +{ + if ((!s_ppParams) || (nTextureVar == -1)) + return; + + IMaterialVar* pNameVar = s_ppParams[nTextureVar]; + if( pNameVar && pNameVar->IsDefined() ) + { + s_pShaderInit->LoadCubeMap( s_ppParams, pNameVar, nAdditionalCreationFlags ); + } +} + + +ShaderAPITextureHandle_t CBaseShader::GetShaderAPITextureBindHandle( int nTextureVar, int nFrameVar, int nTextureChannel ) +{ +// Assert( !IsSnapshotting() ); + Assert( nTextureVar != -1 ); + Assert ( s_ppParams ); + + IMaterialVar* pTextureVar = s_ppParams[nTextureVar]; + IMaterialVar* pFrameVar = (nFrameVar != -1) ? s_ppParams[nFrameVar] : NULL; + int nFrame = pFrameVar ? pFrameVar->GetIntValue() : 0; + return GetShaderSystem()->GetShaderAPITextureBindHandle( pTextureVar->GetTextureValue(), nFrame, nTextureChannel ); +} + + +//----------------------------------------------------------------------------- +// Four different flavors of BindTexture(), handling the two-sampler +// case as well as ITexture* versus textureVar forms +//----------------------------------------------------------------------------- + +void CBaseShader::BindTexture( Sampler_t sampler1, int nTextureVar, int nFrameVar /* = -1 */ ) +{ + BindTexture( sampler1, (Sampler_t) -1, nTextureVar, nFrameVar ); +} + + +void CBaseShader::BindTexture( Sampler_t sampler1, Sampler_t sampler2, int nTextureVar, int nFrameVar /* = -1 */ ) +{ + Assert( !IsSnapshotting() ); + Assert( nTextureVar != -1 ); + Assert ( s_ppParams ); + + IMaterialVar* pTextureVar = s_ppParams[nTextureVar]; + IMaterialVar* pFrameVar = (nFrameVar != -1) ? s_ppParams[nFrameVar] : NULL; + if (pTextureVar) + { + int nFrame = pFrameVar ? pFrameVar->GetIntValue() : 0; + + if ( sampler2 == Sampler_t(-1) ) + { + GetShaderSystem()->BindTexture( sampler1, pTextureVar->GetTextureValue(), nFrame ); + } + else + { + GetShaderSystem()->BindTexture( sampler1, sampler2, pTextureVar->GetTextureValue(), nFrame ); + } + } +} + + +void CBaseShader::BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrame /* = 0 */ ) +{ + BindTexture( sampler1, (Sampler_t) -1, pTexture, nFrame ); +} + +void CBaseShader::BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrame /* = 0 */ ) +{ + Assert( !IsSnapshotting() ); + + if ( sampler2 == Sampler_t(-1 ) ) + { + GetShaderSystem()->BindTexture( sampler1, pTexture, nFrame ); + } + else + { + GetShaderSystem()->BindTexture( sampler1, sampler2, pTexture, nFrame ); + } +} + +void CBaseShader::GetTextureDimensions( float* pOutWidth, float* pOutHeight, int nTextureVar ) +{ + Assert( pOutWidth && pOutHeight ); // Outputs must be provided. + Assert( nTextureVar != -1 ); + + IMaterialVar* pTextureVar = s_ppParams[nTextureVar]; + + if (pTextureVar && pTextureVar->GetTextureValue()) + { + *pOutWidth = (float) (pTextureVar->GetTextureValue()->GetActualWidth()); + *pOutHeight = (float) (pTextureVar->GetTextureValue()->GetActualHeight()); + } +} + + +//----------------------------------------------------------------------------- +// Does the texture store translucency in its alpha channel? +//----------------------------------------------------------------------------- +bool CBaseShader::TextureIsTranslucent( int textureVar, bool isBaseTexture ) +{ + if (textureVar < 0) + return false; + + IMaterialVar** params = s_ppParams; + if (params[textureVar]->GetType() == MATERIAL_VAR_TYPE_TEXTURE) + { + if (!isBaseTexture) + { + return params[textureVar]->GetTextureValue()->IsTranslucent(); + } + else + { + // Override translucency settings if this flag is set. + if (IS_FLAG_SET(MATERIAL_VAR_OPAQUETEXTURE)) + return false; + + if ( (CurrentMaterialVarFlags() & (MATERIAL_VAR_SELFILLUM | MATERIAL_VAR_BASEALPHAENVMAPMASK)) == 0) + { + if ((CurrentMaterialVarFlags() & MATERIAL_VAR_TRANSLUCENT) || + (CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST)) + { + return params[textureVar]->GetTextureValue()->IsTranslucent(); + } + } + } + } + + return false; +} + + +//----------------------------------------------------------------------------- +// +// Helper methods for color modulation +// +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Are we alpha or color modulating? +//----------------------------------------------------------------------------- +bool CBaseShader::IsAlphaModulating() +{ + return (s_nModulationFlags & SHADER_USING_ALPHA_MODULATION) != 0; +} + +bool CBaseShader::IsColorModulating() +{ + return (s_nModulationFlags & SHADER_USING_COLOR_MODULATION) != 0; +} + + +void CBaseShader::GetColorParameter( IMaterialVar **params, float *pColorOut ) const +{ + float flColor2[3]; + params[COLOR]->GetVecValue( pColorOut, 3 ); + params[COLOR2]->GetVecValue( flColor2, 3 ); + + pColorOut[0] *= flColor2[0]; + pColorOut[1] *= flColor2[1]; + pColorOut[2] *= flColor2[2]; + + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + { + float flSRGBTint[3]; + params[SRGBTINT]->GetVecValue( flSRGBTint, 3 ); + + pColorOut[0] *= flSRGBTint[0]; + pColorOut[1] *= flSRGBTint[1]; + pColorOut[2] *= flSRGBTint[2]; + } + +} + +//----------------------------------------------------------------------------- +// FIXME: Figure out a better way to do this? +//----------------------------------------------------------------------------- +int CBaseShader::ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI ) +{ + s_pShaderAPI = static_cast( pShaderAPI); + + int mod = 0; + if ( GetAlpha(params) < 1.0f ) + { + mod |= SHADER_USING_ALPHA_MODULATION; + } + + float color[3]; + GetColorParameter( params, color ); + + if ((color[0] != 1.0) || (color[1] != 1.0) || (color[2] != 1.0)) + { + mod |= SHADER_USING_COLOR_MODULATION; + } + + if( UsingFlashlight(params) ) + { + mod |= SHADER_USING_FLASHLIGHT; + } + + if ( UsingEditor(params) ) + { + mod |= SHADER_USING_EDITOR; + } + + if( IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING ) ) + { + AssertOnce( IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ) ); + if( IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ) ) + { + mod |= SHADER_USING_FIXED_FUNCTION_BAKED_LIGHTING; + } + } + + s_pShaderAPI = NULL; + + return mod; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CBaseShader::NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const +{ + return CShader_IsFlag2Set( params, MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CBaseShader::NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const +{ + return CShader_IsFlag2Set( params, MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CBaseShader::IsTranslucent( IMaterialVar **params ) const +{ + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); +} + +//----------------------------------------------------------------------------- +// Returns the translucency... +//----------------------------------------------------------------------------- +float CBaseShader::GetAlpha( IMaterialVar** ppParams ) +{ + if ( !ppParams ) + { + ppParams = s_ppParams; + } + + if (!ppParams) + return 1.0f; + + if ( ppParams[FLAGS]->GetIntValue() & MATERIAL_VAR_NOALPHAMOD ) + return 1.0f; + + float flAlpha = ppParams[ALPHA]->GetFloatValue(); + return clamp( flAlpha, 0.0f, 1.0f ); +} + + +//----------------------------------------------------------------------------- +// Sets the color + transparency +//----------------------------------------------------------------------------- +void CBaseShader::SetColorState( int colorVar, bool setAlpha ) +{ + Assert( !IsSnapshotting() ); + if ( !s_ppParams ) + return; + + // Use tint instead of color if it was specified... + IMaterialVar* pColorVar = (colorVar != -1) ? s_ppParams[colorVar] : 0; + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + if (pColorVar) + { + if (pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pColorVar->GetVecValue( color, 3 ); + } + else + { + color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); + } + + if ( !g_pHardwareConfig->SupportsPixelShaders_1_4() ) // Clamp 0..1 for ps_1_1 and below + { + color[0] = clamp( color[0], 0.0f, 1.0f ); + color[1] = clamp( color[1], 0.0f, 1.0f ); + color[2] = clamp( color[2], 0.0f, 1.0f ); + } + else if ( !g_pHardwareConfig->SupportsPixelShaders_2_0() ) // Clamp 0..8 for ps_1_4 + { + color[0] = clamp( color[0], 0.0f, 8.0f ); + color[1] = clamp( color[1], 0.0f, 8.0f ); + color[2] = clamp( color[2], 0.0f, 8.0f ); + } + } + ApplyColor2Factor( color ); + color[3] = setAlpha ? GetAlpha() : 1.0f; + s_pShaderAPI->Color4fv( color ); +} + + +void CBaseShader::SetModulationShadowState( int tintVar ) +{ + // Have have no control over the tint var... + bool doModulation = (tintVar != -1); + + // We activate color modulating when we're alpha or color modulating + doModulation = doModulation || IsAlphaModulating() || IsColorModulating(); + + s_pShaderShadow->EnableConstantColor( doModulation ); +} + +void CBaseShader::SetModulationDynamicState( int tintVar ) +{ + if (tintVar != -1) + { + SetColorState( tintVar, true ); + } + else + { + SetColorState( COLOR, true ); + } +} + +void CBaseShader::ApplyColor2Factor( float *pColorOut ) const // (*pColorOut) *= COLOR2 +{ + IMaterialVar* pColor2Var = s_ppParams[COLOR2]; + if (pColor2Var->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + float flColor2[3]; + pColor2Var->GetVecValue( flColor2, 3 ); + + pColorOut[0] *= flColor2[0]; + pColorOut[1] *= flColor2[1]; + pColorOut[2] *= flColor2[2]; + } + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + { + IMaterialVar* pSRGBVar = s_ppParams[SRGBTINT]; + if (pSRGBVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + float flSRGB[3]; + pSRGBVar->GetVecValue( flSRGB, 3 ); + + pColorOut[0] *= flSRGB[0]; + pColorOut[1] *= flSRGB[1]; + pColorOut[2] *= flSRGB[2]; + } + } +} + +void CBaseShader::ComputeModulationColor( float* color ) +{ + Assert( !IsSnapshotting() ); + if (!s_ppParams) + return; + + IMaterialVar* pColorVar = s_ppParams[COLOR]; + if (pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pColorVar->GetVecValue( color, 3 ); + } + else + { + color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); + } + + ApplyColor2Factor( color ); + + if( !g_pConfig->bShowDiffuse ) + { + color[0] = color[1] = color[2] = 0.0f; + } + if( mat_fullbright.GetInt() == 2 ) + { + color[0] = color[1] = color[2] = 1.0f; + } + color[3] = GetAlpha(); +} + + +//----------------------------------------------------------------------------- +// +// Helper methods for alpha blending.... +// +//----------------------------------------------------------------------------- +void CBaseShader::EnableAlphaBlending( ShaderBlendFactor_t src, ShaderBlendFactor_t dst ) +{ + Assert( IsSnapshotting() ); + s_pShaderShadow->EnableBlending( true ); + s_pShaderShadow->BlendFunc( src, dst ); + s_pShaderShadow->EnableDepthWrites(false); +} + +void CBaseShader::DisableAlphaBlending() +{ + Assert( IsSnapshotting() ); + s_pShaderShadow->EnableBlending( false ); +} + +void CBaseShader::SetNormalBlendingShadowState( int textureVar, bool isBaseTexture ) +{ + Assert( IsSnapshotting() ); + + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a vertex alpha + isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); + + // Or we've got a texture alpha + isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && + !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); + + if (isTranslucent) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + DisableAlphaBlending(); + } +} + +//ConVar mat_debug_flashlight_only( "mat_debug_flashlight_only", "0" ); +void CBaseShader::SetAdditiveBlendingShadowState( int textureVar, bool isBaseTexture ) +{ + Assert( IsSnapshotting() ); + + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a vertex alpha + isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); + + // Or we've got a texture alpha + isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && + !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); + + /* + if ( mat_debug_flashlight_only.GetBool() ) + { + if (isTranslucent) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA); + //s_pShaderShadow->EnableAlphaTest( true ); + //s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.99f ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ZERO); + } + } + else + */ + { + if (isTranslucent) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + } +} + +void CBaseShader::SetDefaultBlendingShadowState( int textureVar, bool isBaseTexture ) +{ + if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) + { + SetAdditiveBlendingShadowState( textureVar, isBaseTexture ); + } + else + { + SetNormalBlendingShadowState( textureVar, isBaseTexture ); + } +} + +void CBaseShader::SetBlendingShadowState( BlendType_t nMode ) +{ + switch ( nMode ) + { + case BT_NONE: + DisableAlphaBlending(); + break; + + case BT_BLEND: + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + break; + + case BT_ADD: + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + break; + + case BT_BLENDADD: + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + break; + } +} + + + +//----------------------------------------------------------------------------- +// Sets lightmap blending mode for single texturing +//----------------------------------------------------------------------------- +void CBaseShader::SingleTextureLightmapBlendMode( ) +{ + Assert( IsSnapshotting() ); + + s_pShaderShadow->EnableBlending( true ); + s_pShaderShadow->BlendFunc( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); +} + + +//----------------------------------------------------------------------------- +// Loads the identity transform into a matrix +//----------------------------------------------------------------------------- +void CBaseShader::LoadIdentity( MaterialMatrixMode_t matrixMode ) +{ + Assert( !IsSnapshotting() ); + + s_pShaderAPI->MatrixMode( matrixMode ); + s_pShaderAPI->LoadIdentity( ); +} + + +//----------------------------------------------------------------------------- +// Loads the camera to world transform into a matrix +//----------------------------------------------------------------------------- +void CBaseShader::LoadCameraToWorldTransform( MaterialMatrixMode_t matrixMode ) +{ + s_pShaderAPI->MatrixMode( matrixMode ); + s_pShaderAPI->LoadCameraToWorld(); +} + +void CBaseShader::LoadCameraSpaceSphereMapTransform( MaterialMatrixMode_t matrixMode ) +{ + static float mat[4][4] = + { + { 0.5f, 0.0f, 0.0f, 0.0f }, + { 0.0f, -0.5f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.5f, -0.5f, 0.0f, 1.0f }, + }; + + s_pShaderAPI->MatrixMode( matrixMode ); + s_pShaderAPI->LoadMatrix( (float*)mat ); +} + + +//----------------------------------------------------------------------------- +// +// Sets a texture translation transform +// +//----------------------------------------------------------------------------- +void CBaseShader::SetFixedFunctionTextureTranslation( MaterialMatrixMode_t textureTransform, int translationVar ) +{ + Assert( !IsSnapshotting() ); + + // handle scrolling of base texture + Vector2D vDelta( 0, 0 ); + + if (translationVar != -1) + { + s_ppParams[translationVar]->GetVecValue( vDelta.Base(), 2 ); + } + + if( vDelta[0] != 0.0f || vDelta[1] != 0.0f ) + { + s_pShaderAPI->MatrixMode( textureTransform ); + + // only do the upper 3x3 since this is a 2D matrix + float mat[16]; + mat[0] = 1.0f; mat[1] = 0.0f; mat[2] = 0.0f; + mat[4] = 0.0f; mat[5] = 1.0f; mat[6] = 0.0f; + mat[8] = vDelta[0]; mat[9] = vDelta[1]; mat[10] = 1.0f; + + // Better set the stuff we don't set with some sort of value! + mat[3] = mat[7] = mat[11] = 0; + mat[12] = mat[13] = mat[14] = 0; + mat[15] = 1; + + s_pShaderAPI->LoadMatrix( mat ); + } + else + { + LoadIdentity( textureTransform ); + } +} + +void CBaseShader::SetFixedFunctionTextureScale( MaterialMatrixMode_t textureTransform, int scaleVar ) +{ + Assert( !IsSnapshotting() ); + + // handle scrolling of base texture + Vector2D vScale; + s_ppParams[scaleVar]->GetVecValue( vScale.Base(), 2 ); + if( vScale[0] != 0.0f || vScale[1] != 0.0f ) + { + s_pShaderAPI->MatrixMode( textureTransform ); + + // only do the upper 3x3 since this is a 2D matrix + float mat[16]; + mat[0] = vScale[0]; mat[1] = 0.0f; mat[2] = 0.0f; + mat[4] = 0.0f; mat[5] = vScale[1]; mat[6] = 0.0f; + mat[8] = 0.0f; mat[9] = 0.0f; mat[10] = 1.0f; + + // Better set the stuff we don't set with some sort of value! + mat[3] = mat[7] = mat[11] = 0; + mat[12] = mat[13] = mat[14] = 0; + mat[15] = 1; + + s_pShaderAPI->LoadMatrix( mat ); + } + else + { + LoadIdentity( textureTransform ); + } +} + +void CBaseShader::SetFixedFunctionTextureTransform( MaterialMatrixMode_t textureTransform, int transformVar ) +{ + Assert( !IsSnapshotting() ); + + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + s_pShaderAPI->MatrixMode( textureTransform ); + + const VMatrix &transformation = pTransformationVar->GetMatrixValue(); + + // only do the upper 3x3 since this is a 2D matrix + float mat[16]; + mat[0] = transformation[0][0]; mat[1] = transformation[1][0]; mat[2] = transformation[3][0]; + mat[4] = transformation[0][1]; mat[5] = transformation[1][1]; mat[6] = transformation[3][1]; + mat[8] = transformation[0][3]; mat[9] = transformation[1][3]; mat[10] = transformation[3][3]; + + // Better set the stuff we don't set with some sort of value! + mat[3] = mat[7] = mat[11] = 0; + mat[12] = mat[13] = mat[14] = 0; + mat[15] = 1; + + s_pShaderAPI->LoadMatrix( mat ); + } + else + { + LoadIdentity( textureTransform ); + } +} + +void CBaseShader::SetFixedFunctionTextureScaledTransform( MaterialMatrixMode_t textureTransform, + int transformVar, int scaleVar ) +{ + Assert( !IsSnapshotting() ); + + float mat[16]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + Vector2D scale( 1, 1 ); + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale.Base(), 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + s_pShaderAPI->MatrixMode( textureTransform ); + + const VMatrix &transformation = pTransformationVar->GetMatrixValue(); + + // only do the upper 3x3 since this is a 2D matrix + mat[0] = transformation[0][0] * scale[0]; mat[1] = transformation[1][0] * scale[0]; mat[2] = transformation[3][0] * scale[0]; + mat[4] = transformation[0][1] * scale[1]; mat[5] = transformation[1][1] * scale[1]; mat[6] = transformation[3][1] * scale[1]; + mat[8] = transformation[0][3]; mat[9] = transformation[1][3]; mat[10] = transformation[3][3]; + + // Better set the stuff we don't set with some sort of value! + mat[3] = mat[7] = mat[11] = 0; + mat[12] = mat[13] = mat[14] = 0; + mat[15] = 1; + + s_pShaderAPI->LoadMatrix( mat ); + } + else + { + SetFixedFunctionTextureScale( textureTransform, scaleVar ); + } +} + + +//----------------------------------------------------------------------------- +// +// Helper methods for fog +// +//----------------------------------------------------------------------------- +void CBaseShader::FogToOOOverbright( void ) +{ + Assert( IsSnapshotting() ); + if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_OO_OVERBRIGHT ); + } + else + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + } +} + +void CBaseShader::FogToWhite( void ) +{ + Assert( IsSnapshotting() ); + if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_WHITE ); + } + else + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + } +} +void CBaseShader::FogToBlack( void ) +{ + Assert( IsSnapshotting() ); + if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_BLACK ); + } + else + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + } +} + +void CBaseShader::FogToGrey( void ) +{ + Assert( IsSnapshotting() ); + if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_GREY ); + } + else + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + } +} + +void CBaseShader::FogToFogColor( void ) +{ + Assert( IsSnapshotting() ); + if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_FOGCOLOR ); + } + else + { + s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + } +} + +void CBaseShader::DisableFog( void ) +{ + Assert( IsSnapshotting() ); + s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); +} + +void CBaseShader::DefaultFog( void ) +{ + if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) + { + FogToBlack(); + } + else + { + FogToFogColor(); + } +} + + +//----------------------------------------------------------------------------- +// Fixed function multiply by detail texture pass +//----------------------------------------------------------------------------- +void CBaseShader::FixedFunctionMultiplyByDetailPass( int baseTextureVar, int frameVar, + int textureTransformVar, int detailVar, int detailScaleVar ) +{ + IMaterialVar** params = s_ppParams; + + if (!params[detailVar]->IsDefined()) + return; + + if (IsSnapshotting()) + { + SetInitialShadowState(); + + s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + bool translucentTexture = TextureIsTranslucent( baseTextureVar, true ) || + IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); + + // Mod 2x blend here + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); + + s_pShaderShadow->EnableCustomPixelPipe( true ); + s_pShaderShadow->CustomTextureStages( 2 ); + + // We need to blend towards grey based on alpha... + // We can never get the perfect alpha (vertex alpha * cc alpha * texture alpha) + // so we'll just choose to use cc alpha * texture alpha + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1; + + // Compute alpha, stage 0 is used, stage 1 isn't. + if ( translucentTexture ) + { + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + flags |= SHADER_DRAW_TEXCOORD0; + } + else + { + bool hasVertexAlpha = (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA) != 0; + if (hasVertexAlpha) + { + flags |= SHADER_DRAW_COLOR; + } + + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, hasVertexAlpha ? SHADER_TEXOP_MODULATE : SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_VERTEXCOLOR ); + } + + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + + // This here will perform color = vertex light * alpha + 0.5f * (1 - alpha) + // Stage 0 really doesn't do anything + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + s_pShaderShadow->DrawFlags( flags ); + FogToGrey(); + Draw( ); + + s_pShaderShadow->EnableCustomPixelPipe( false ); + DisableAlphaBlending(); + } + else + { + if (TextureIsTranslucent( baseTextureVar, true ) ) + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, textureTransformVar ); + BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); + } + else + { + // Unnecessary... but we get strange colors if we don't put something on stage 0 + BindTexture( SHADER_SAMPLER0, detailVar, frameVar ); + } + + BindTexture( SHADER_SAMPLER1, detailVar, frameVar ); + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, textureTransformVar, detailScaleVar ); + float alpha = GetAlpha(); + s_pShaderAPI->Color4ub( 128, 128, 128, 255 * alpha ); + + Draw( ); + } +} + + +//----------------------------------------------------------------------------- +// Multiply by lightmap pass +//----------------------------------------------------------------------------- +void CBaseShader::FixedFunctionMultiplyByLightmapPass( int baseTextureVar, + int frameVar, int baseTextureTransformVar, float alphaOverride ) +{ + if (IsSnapshotting()) + { + SetInitialShadowState(); + + s_pShaderShadow->EnableAlphaTest( false ); + + s_pShaderShadow->EnableBlending( true ); + SingleTextureLightmapBlendMode(); + + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); + + s_pShaderShadow->EnableCustomPixelPipe( true ); + s_pShaderShadow->CustomTextureStages( 2 ); + + // Stage zero color is not used, this op doesn't matter + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); + + // This here will perform color = lightmap * (cc alpha) + 1 * (1- cc alpha) + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD1; + + // Multiply the constant alpha by the texture alpha for total alpha + if (TextureIsTranslucent(baseTextureVar, true)) + { + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + flags |= SHADER_DRAW_TEXCOORD0; + } + else + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG2, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + } + + // Alpha isn't used, it doesn't matter what we set it to. + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + + s_pShaderShadow->DrawFlags( flags ); + + FogToOOOverbright(); + Draw(); + + s_pShaderShadow->EnableCustomPixelPipe( false ); + } + else + { + s_pShaderAPI->SetDefaultState(); + + // Put the alpha in the color channel to modulate the color down.... + float alpha = (alphaOverride < 0) ? GetAlpha() : alphaOverride; + + // NOTE: 128 is a more exact OO_OVERBRIGHT; it prevents some artifacts +// s_pShaderAPI->Color4f( OO_OVERBRIGHT, OO_OVERBRIGHT, OO_OVERBRIGHT, alpha ); + s_pShaderAPI->Color4ub( 128, 128, 128, (int)(alpha * 255)); + + if (TextureIsTranslucent(baseTextureVar, true)) + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, baseTextureTransformVar ); + BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); + } + + LoadIdentity( MATERIAL_TEXTURE1 ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + Draw(); + } +} + + +//----------------------------------------------------------------------------- +// Fixed function Self illumination pass +//----------------------------------------------------------------------------- +void CBaseShader::FixedFunctionSelfIlluminationPass( Sampler_t sampler, + int baseTextureVar, int frameVar, int baseTextureTransformVar, int selfIllumTintVar ) +{ +// IMaterialVar** params = s_ppParams; + + if ( IsSnapshotting() ) + { + SetInitialShadowState(); + + // A little setup for self illum here... + SetModulationShadowState( selfIllumTintVar ); + + s_pShaderShadow->EnableTexture( sampler, true ); + + // No overbrighting + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); + + // Don't bother with z writes here... + s_pShaderShadow->EnableDepthWrites( false ); + + // We're always blending + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + int flags = SHADER_DRAW_POSITION; + if ( sampler == SHADER_SAMPLER0 ) + flags |= SHADER_DRAW_TEXCOORD0; + else + flags |= SHADER_DRAW_TEXCOORD1; + + s_pShaderShadow->DrawFlags( flags ); + FogToFogColor(); + } + else + { + s_pShaderAPI->SetDefaultState(); + + SetFixedFunctionTextureTransform( + (sampler == SHADER_SAMPLER0) ? MATERIAL_TEXTURE0 : MATERIAL_TEXTURE1, + baseTextureTransformVar ); + BindTexture( sampler, baseTextureVar, frameVar ); + + // NOTE: Texture + texture offset are set from BaseTimesLightmap + SetModulationDynamicState( selfIllumTintVar ); + } + Draw(); +} + + +//----------------------------------------------------------------------------- +// Fixed function Base * detail pass +//----------------------------------------------------------------------------- +void CBaseShader::FixedFunctionBaseTimesDetailPass( int baseTextureVar, + int frameVar, int baseTextureTransformVar, int detailVar, int detailScaleVar ) +{ + IMaterialVar** params = s_ppParams; + + // We can't do this one one pass if CC and VC are both active... + bool hasDetail = (detailVar != -1) && params[detailVar]->IsDefined(); + bool detailInSecondPass = hasDetail && IsColorModulating() && + (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) || IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA)); + + if (IsSnapshotting()) + { + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); + + // alpha test + s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // Alpha blending + SetDefaultBlendingShadowState( baseTextureVar, true ); + + // independently configure alpha and color + s_pShaderShadow->EnableAlphaPipe( true ); + + // Here's the color states (NOTE: SHADER_DRAW_COLOR == use Vertex Color) + s_pShaderShadow->EnableConstantColor( IsColorModulating() ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0; + + // Detail texture.. + if (hasDetail && (!detailInSecondPass)) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // Force mod2x + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f ); + + flags |= SHADER_DRAW_TEXCOORD1; + } + + // Here's the alpha states + s_pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + s_pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); + s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, TextureIsTranslucent(baseTextureVar, true) ); + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + s_pShaderShadow->DrawFlags( flags ); + + DefaultFog(); + + Draw(); + + s_pShaderShadow->EnableAlphaPipe( false ); + } + else + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, baseTextureTransformVar ); + BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); + + // Detail texture.. + if (hasDetail && (!detailInSecondPass)) + { + BindTexture( SHADER_SAMPLER1, detailVar, frameVar ); + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, baseTextureTransformVar, detailScaleVar ); + } + + SetModulationDynamicState(); + + Draw(); + } + + if (detailInSecondPass) + { + FixedFunctionMultiplyByDetailPass( baseTextureVar, frameVar, baseTextureTransformVar, detailVar, detailScaleVar ); + } +} + + +//----------------------------------------------------------------------------- +// Helpers for environment mapping... +//----------------------------------------------------------------------------- +int CBaseShader::SetShadowEnvMappingState( int envMapMaskVar, int tintVar ) +{ + Assert( IsSnapshotting() ); + IMaterialVar** params = s_ppParams; + + int varFlags = params[FLAGS]->GetIntValue(); + + s_pShaderShadow->EnableAlphaTest( false ); + + // envmap on stage 0 + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); + if ( (varFlags & MATERIAL_VAR_ENVMAPSPHERE) == 0 ) + s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_CAMERASPACEREFLECTIONVECTOR ); + else + s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_SPHERE_MAP ); + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_NORMAL; + + // mask on stage 1 + if (params[envMapMaskVar]->IsDefined() || (varFlags & MATERIAL_VAR_BASEALPHAENVMAPMASK)) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + flags |= SHADER_DRAW_TEXCOORD1; + } + else + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); + } + + if (varFlags & MATERIAL_VAR_BASEALPHAENVMAPMASK) + { + s_pShaderShadow->EnableCustomPixelPipe( true ); + s_pShaderShadow->CustomTextureStages( 2 ); + + // Color = base texture * envmaptint * (1 - mask alpha) + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_INVTEXTUREALPHA ); + + // Use alpha modulation * vertex alpha * env map alpha + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_TEXTURE ); + s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + s_pShaderShadow->EnableAlphaPipe( true ); + + // Color = base texture * envmaptint * mask + s_pShaderShadow->EnableConstantColor( tintVar >= 0 ); + + // Alpha = vertex alpha * constant alpha * env map alpha * mask alpha (only if it's not a base alpha mask) + s_pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + s_pShaderShadow->EnableVertexAlpha( (varFlags & MATERIAL_VAR_VERTEXALPHA) != 0 ); + s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, true ); + s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, params[envMapMaskVar]->IsTexture() ); + } + + return flags; +} + +void CBaseShader::SetDynamicEnvMappingState( int envMapVar, int envMapMaskVar, + int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, int frameVar, + int maskOffsetVar, int maskScaleVar, int tintVar ) +{ + Assert( !IsSnapshotting() ); + + IMaterialVar** params = s_ppParams; + int varFlags = params[FLAGS]->GetIntValue(); + + if( (varFlags & MATERIAL_VAR_ENVMAPSPHERE) == 0 ) + { + if ( (varFlags & MATERIAL_VAR_ENVMAPCAMERASPACE) == 0 ) + { + LoadCameraToWorldTransform( MATERIAL_TEXTURE0 ); + } + else + { + LoadIdentity( MATERIAL_TEXTURE0 ); + } + } + else + { + LoadCameraSpaceSphereMapTransform( MATERIAL_TEXTURE0 ); + } + + BindTexture( SHADER_SAMPLER0, envMapVar, envMapFrameVar ); + + if (params[envMapMaskVar]->IsTexture()) + { + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, + maskOffsetVar, maskScaleVar ); + BindTexture( SHADER_SAMPLER1, envMapMaskVar, envMapMaskFrameVar ); + } + else if (varFlags & MATERIAL_VAR_BASEALPHAENVMAPMASK) + { + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, + maskOffsetVar, maskScaleVar ); + BindTexture( SHADER_SAMPLER1, baseTextureVar, frameVar ); + } + + SetModulationDynamicState( tintVar ); +} + + +//----------------------------------------------------------------------------- +// Masked environment map +//----------------------------------------------------------------------------- +void CBaseShader::FixedFunctionMaskedEnvmapPass( int envMapVar, int envMapMaskVar, + int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, + int frameVar, int maskOffsetVar, int maskScaleVar, int envMapTintVar ) +{ +// IMaterialVar** params = ShaderState().m_ppParams; + + if (IsSnapshotting()) + { + // Alpha blending + SetDefaultBlendingShadowState( envMapMaskVar, false ); + + // Disable overbright + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); + + int flags = SetShadowEnvMappingState( envMapMaskVar, envMapTintVar ); + s_pShaderShadow->DrawFlags( flags ); + + DefaultFog(); + Draw(); + + s_pShaderShadow->EnableCustomPixelPipe( false ); + s_pShaderShadow->EnableAlphaPipe( false ); + } + else + { + SetDynamicEnvMappingState( envMapVar, envMapMaskVar, baseTextureVar, + envMapFrameVar, envMapMaskFrameVar, frameVar, + maskOffsetVar, maskScaleVar, envMapTintVar ); + + Draw(); + } +} + + +//----------------------------------------------------------------------------- +// Add masked environment map +//----------------------------------------------------------------------------- +void CBaseShader::FixedFunctionAdditiveMaskedEnvmapPass( int envMapVar, int envMapMaskVar, + int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, + int frameVar, int maskOffsetVar, int maskScaleVar, int envMapTintVar ) +{ +// IMaterialVar** params = ShaderState().m_ppParams; + + if (IsSnapshotting()) + { + SetInitialShadowState(); + + // Alpha blending + SetAdditiveBlendingShadowState( envMapMaskVar, false ); + + // Disable overbright + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); + s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); + + // Don't bother with z writes here... + s_pShaderShadow->EnableDepthWrites( false ); + + int flags = SetShadowEnvMappingState( envMapMaskVar, envMapTintVar ); + s_pShaderShadow->DrawFlags( flags ); + + FogToBlack(); + Draw(); + + s_pShaderShadow->EnableCustomPixelPipe( false ); + s_pShaderShadow->EnableAlphaPipe( false ); + } + else + { + SetDynamicEnvMappingState( envMapVar, envMapMaskVar, baseTextureVar, + envMapFrameVar, envMapMaskFrameVar, frameVar, + maskOffsetVar, maskScaleVar, envMapTintVar ); + + Draw(); + } +} + + +void CBaseShader::CleanupDynamicStateFixedFunction( ) +{ + Assert( !IsSnapshotting() ); + LoadIdentity( MATERIAL_TEXTURE0 ); +} + +bool CBaseShader::UsingFlashlight( IMaterialVar **params ) const +{ + if( IsSnapshotting() ) + { + return CShader_IsFlag2Set( params, MATERIAL_VAR2_USE_FLASHLIGHT ); + } + else + { + return s_pShaderAPI->InFlashlightMode(); + } +} + +bool CBaseShader::UsingEditor( IMaterialVar **params ) const +{ + if( IsSnapshotting() ) + { + return CShader_IsFlag2Set( params, MATERIAL_VAR2_USE_EDITOR ); + } + else + { + return s_pShaderAPI->InEditorMode(); + } +} + +void CBaseShader::DrawFlashlight_dx70( + IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + int flashlightTextureVar, int flashlightTextureFrameVar, + bool suppress_lighting ) +{ + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + // Alpha test +// pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + s_pShaderShadow->EnableAlphaTest( false ); + s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + + // Alpha blend + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; + pShaderShadow->DrawFlags( flags ); + FogToBlack(); + + if ( !suppress_lighting ) + pShaderShadow->EnableLighting( true ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + // color stage 0 + // projected texture * vertex color (lighting) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_VERTEXCOLOR ); + + // color stage 1 + // * base texture + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); + + // alpha stage 0 + // get alpha from constant alpha + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); + + // alpha stage 1 + // get alpha from $basetexture + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // Shove the view position into texcoord 0 before the texture matrix. + pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); + pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); + } + DYNAMIC_STATE + { + SetFlashlightFixedFunctionTextureTransform( MATERIAL_TEXTURE0 ); + + // NOTE: This has to come after the loadmatrix since the loadmatrix screws with the + // transform flags!!!!!! + // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. + // NOTE Tried to divide XY by Z, but doesn't work. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 3, true ); + + BindTexture( SHADER_SAMPLER0, flashlightTextureVar, flashlightTextureFrameVar ); + if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + + SetModulationDynamicState(); + } + Draw(); +} + +void CBaseShader::SetFlashlightFixedFunctionTextureTransform( MaterialMatrixMode_t matrix ) +{ + VMatrix worldToTexture; + s_pShaderAPI->GetFlashlightState( worldToTexture ); + + VMatrix worldToView, viewToWorld, viewToTexture; + s_pShaderAPI->GetMatrix( MATERIAL_VIEW, &worldToView[0][0] ); + // The matrix that we get back from the shader api is transposed. . . yuck. + MatrixTranspose( worldToView, worldToView ); + MatrixInverseGeneral( worldToView, viewToWorld ); + MatrixMultiply( worldToTexture, viewToWorld, viewToTexture ); + + s_pShaderAPI->MatrixMode( matrix ); + // tranpose before going into the shaderapi. . . suck + MatrixTranspose( viewToTexture, viewToTexture ); + s_pShaderAPI->LoadMatrix( &viewToTexture[0][0] ); +} + +bool CBaseShader::IsHDREnabled( void ) +{ + // HDRFIXME! Need to fix this for vgui materials + HDRType_t hdr_mode=g_pHardwareConfig->GetHDRType(); + switch(hdr_mode) + { + case HDR_TYPE_NONE: + return false; + + case HDR_TYPE_INTEGER: + return true; + + case HDR_TYPE_FLOAT: + { + ITexture *pRT = s_pShaderAPI->GetRenderTargetEx( 0 ); + if( pRT && pRT->GetImageFormat() == IMAGE_FORMAT_RGBA16161616F ) + { + return true; + } + } + } + return false; +} + +// +// Called from SHADOW_STATE +// + +void CBaseShader::SetInternalVertexShaderConstantBuffers() +{ + SetVertexShaderConstantBuffer(0, SHADER_CONSTANTBUFFER_PERMODEL); + SetVertexShaderConstantBuffer(1, SHADER_CONSTANTBUFFER_PERFRAME); + SetVertexShaderConstantBuffer(2, SHADER_CONSTANTBUFFER_PERSCENE); + SetVertexShaderConstantBuffer(3, SHADER_CONSTANTBUFFER_SKINNING); +} + +void CBaseShader::SetInternalVertexShaderConstantBuffersNoSkinning() +{ + SetVertexShaderConstantBuffer(0, SHADER_CONSTANTBUFFER_PERMODEL); + SetVertexShaderConstantBuffer(1, SHADER_CONSTANTBUFFER_PERFRAME); + SetVertexShaderConstantBuffer(2, SHADER_CONSTANTBUFFER_PERSCENE); +} + +void CBaseShader::SetInternalPixelShaderConstantBuffers() +{ + SetPixelShaderConstantBuffer(0, SHADER_CONSTANTBUFFER_PERMODEL); + SetPixelShaderConstantBuffer(1, SHADER_CONSTANTBUFFER_PERFRAME); + SetPixelShaderConstantBuffer(2, SHADER_CONSTANTBUFFER_PERSCENE); +} + +void CBaseShader::SetPixelShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer) +{ + Assert(s_pShaderShadow); + s_pShaderShadow->SetPixelShaderConstantBuffer(slot, cbuffer); +} + +void CBaseShader::SetVertexShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer) +{ + Assert(s_pShaderShadow); + s_pShaderShadow->SetVertexShaderConstantBuffer(slot, cbuffer); +} + +void CBaseShader::SetPixelShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer) +{ + s_pShaderShadow->SetPixelShaderConstantBuffer(slot, cbuffer); +} + +void CBaseShader::SetVertexShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer) +{ + s_pShaderShadow->SetVertexShaderConstantBuffer(slot, cbuffer); +} + +// Called from DYNAMIC_STATE +void CBaseShader::UpdateConstantBuffer(ConstantBufferHandle_t cbuffer, void* pNewData) +{ + Assert(s_pShaderAPI); + s_pShaderAPI->UpdateConstantBuffer(cbuffer, pNewData); +} \ No newline at end of file diff --git a/materialsystem/shaderlib_dx11/ShaderDLL.cpp b/materialsystem/shaderlib_dx11/ShaderDLL.cpp new file mode 100644 index 0000000..bc266ff --- /dev/null +++ b/materialsystem/shaderlib_dx11/ShaderDLL.cpp @@ -0,0 +1,169 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "shaderlib_dx11/ShaderDLL.h" +#include "materialsystem/IShader.h" +#include "tier1/utlvector.h" +#include "tier0/dbg.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "materialsystem/materialsystem_config.h" +#include "IShaderSystem.h" +#include "materialsystem/ishaderapi.h" +#include "shaderlib_cvar.h" +#include "mathlib/mathlib.h" +#include "tier1/tier1.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// The standard implementation of CShaderDLL +//----------------------------------------------------------------------------- +class CShaderDLL : public IShaderDLLInternal, public IShaderDLL +{ +public: + CShaderDLL(); + + // methods of IShaderDLL + virtual bool Connect( CreateInterfaceFn factory ); + virtual void Disconnect(); + virtual int ShaderCount() const; + virtual IShader *GetShader( int nShader ); + + // methods of IShaderDLLInternal + virtual bool Connect( CreateInterfaceFn factory, bool bIsMaterialSystem ); + virtual void Disconnect( bool bIsMaterialSystem ); + virtual void InsertShader( IShader *pShader ); + +private: + CUtlVector< IShader * > m_ShaderList; +}; + + +//----------------------------------------------------------------------------- +// Global interfaces/structures +//----------------------------------------------------------------------------- +IMaterialSystemHardwareConfig* g_pHardwareConfig; +const MaterialSystem_Config_t *g_pConfig; + + +//----------------------------------------------------------------------------- +// Interfaces/structures local to shaderlib +//----------------------------------------------------------------------------- +IShaderSystem* g_pSLShaderSystem; + + +// Pattern necessary because shaders register themselves in global constructors +static CShaderDLL *s_pShaderDLL; + + +//----------------------------------------------------------------------------- +// Global accessor +//----------------------------------------------------------------------------- +IShaderDLL *GetShaderDLL() +{ + // Pattern necessary because shaders register themselves in global constructors + if ( !s_pShaderDLL ) + { + s_pShaderDLL = new CShaderDLL; + } + + return s_pShaderDLL; +} + +IShaderDLLInternal *GetShaderDLLInternal() +{ + // Pattern necessary because shaders register themselves in global constructors + if ( !s_pShaderDLL ) + { + s_pShaderDLL = new CShaderDLL; + } + + return static_cast( s_pShaderDLL ); +} + +//----------------------------------------------------------------------------- +// Singleton interface +//----------------------------------------------------------------------------- +EXPOSE_INTERFACE_FN( (InstantiateInterfaceFn)GetShaderDLLInternal, IShaderDLLInternal, SHADER_DLL_INTERFACE_VERSION ); + +//----------------------------------------------------------------------------- +// Connect, disconnect... +//----------------------------------------------------------------------------- +CShaderDLL::CShaderDLL() +{ + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); +} + + +//----------------------------------------------------------------------------- +// Connect, disconnect... +//----------------------------------------------------------------------------- +bool CShaderDLL::Connect( CreateInterfaceFn factory, bool bIsMaterialSystem ) +{ + g_pHardwareConfig = (IMaterialSystemHardwareConfig*)factory( MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, NULL ); + g_pConfig = (const MaterialSystem_Config_t*)factory( MATERIALSYSTEM_CONFIG_VERSION, NULL ); + g_pSLShaderSystem = (IShaderSystem*)factory( SHADERSYSTEM_INTERFACE_VERSION, NULL ); + + if ( !bIsMaterialSystem ) + { + ConnectTier1Libraries( &factory, 1 ); + InitShaderLibCVars( factory ); + } + + return ( g_pConfig != NULL ) && (g_pHardwareConfig != NULL) && ( g_pSLShaderSystem != NULL ); +} + +void CShaderDLL::Disconnect( bool bIsMaterialSystem ) +{ + if ( !bIsMaterialSystem ) + { + ConVar_Unregister(); + DisconnectTier1Libraries(); + } + + g_pHardwareConfig = NULL; + g_pConfig = NULL; + g_pSLShaderSystem = NULL; +} + +bool CShaderDLL::Connect( CreateInterfaceFn factory ) +{ + return Connect( factory, false ); +} + +void CShaderDLL::Disconnect() +{ + Disconnect( false ); +} + + +//----------------------------------------------------------------------------- +// Iterates over all shaders +//----------------------------------------------------------------------------- +int CShaderDLL::ShaderCount() const +{ + return m_ShaderList.Count(); +} + +IShader *CShaderDLL::GetShader( int nShader ) +{ + if ( ( nShader < 0 ) || ( nShader >= m_ShaderList.Count() ) ) + return NULL; + + return m_ShaderList[nShader]; +} + + +//----------------------------------------------------------------------------- +// Adds to the shader lists +//----------------------------------------------------------------------------- +void CShaderDLL::InsertShader( IShader *pShader ) +{ + Assert( pShader ); + m_ShaderList.AddToTail( pShader ); +} + diff --git a/materialsystem/shaderlib_dx11/shaderDLL_Global.h b/materialsystem/shaderlib_dx11/shaderDLL_Global.h new file mode 100644 index 0000000..ae1ff0b --- /dev/null +++ b/materialsystem/shaderlib_dx11/shaderDLL_Global.h @@ -0,0 +1,33 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef SHADERDLL_GLOBAL_H +#define SHADERDLL_GLOBAL_H + +#ifdef _WIN32 +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IShaderSystem; + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +inline IShaderSystem *GetShaderSystem() +{ + extern IShaderSystem* g_pSLShaderSystem; + return g_pSLShaderSystem; +} + + +#endif // SHADERDLL_GLOBAL_H \ No newline at end of file diff --git a/materialsystem/shaderlib_dx11/shaderlib.vpc b/materialsystem/shaderlib_dx11/shaderlib.vpc new file mode 100644 index 0000000..1f7f265 --- /dev/null +++ b/materialsystem/shaderlib_dx11/shaderlib.vpc @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// SHADERLIB.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR "..\.." +$include "$SRCDIR\vpc_scripts\source_lib_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;..\" + $PreprocessorDefinitions "$BASE;FAST_MATERIALVAR_ACCESS" + $PreprocessorDefinitions "$BASE;fopen=dont_use_fopen" [$WINDOWS] + } +} + + +$Project "shaderlib_dx11" +{ + $Folder "Source Files" + { + $File "BaseShader.cpp" + $File "ShaderDLL.cpp" + $File "shaderlib_cvar.cpp" + } + + $Folder "Header Files" + { + $File "shaderDLL_Global.h" + $File "shaderlib_cvar.h" + $File "$SRCDIR\public\shaderlib_dx11\BaseShader.h" + $File "$SRCDIR\public\tier0\basetypes.h" + $File "$SRCDIR\public\tier0\commonmacros.h" + $File "$SRCDIR\public\shaderlib_dx11\cshader.h" + $File "$SRCDIR\public\tier0\dbg.h" + $File "$SRCDIR\public\tier0\fasttimer.h" + $File "$SRCDIR\public\appframework\IAppSystem.h" + $File "$SRCDIR\public\tier0\icommandline.h" + $File "$SRCDIR\public\icvar.h" + $File "$SRCDIR\public\materialsystem\imaterial.h" + $File "$SRCDIR\public\materialsystem\imaterialsystem.h" + $File "$SRCDIR\public\materialsystem\imaterialsystemhardwareconfig.h" + $File "$SRCDIR\public\materialsystem\imaterialvar.h" + $File "$SRCDIR\public\materialsystem\imesh.h" + $File "$SRCDIR\public\materialsystem\IShader.h" + $File "$SRCDIR\public\materialsystem\ishaderapi.h" + $File "..\IShaderSystem.h" + $File "$SRCDIR\public\materialsystem\itexture.h" + $File "$SRCDIR\public\materialsystem\materialsystem_config.h" + $File "$SRCDIR\public\mathlib\mathlib.h" + $File "$SRCDIR\public\tier0\memdbgoff.h" + $File "$SRCDIR\public\tier0\memdbgon.h" + $File "$SRCDIR\public\tier0\platform.h" + $File "$SRCDIR\public\tier0\protected_things.h" + $File "$SRCDIR\public\shaderlib_dx11\ShaderDLL.h" + $File "$SRCDIR\public\string_t.h" + $File "$SRCDIR\public\tier1\strtools.h" + $File "$SRCDIR\public\tier1\utlmemory.h" + $File "$SRCDIR\public\tier1\utlvector.h" + $File "$SRCDIR\public\mathlib\vector.h" + $File "$SRCDIR\public\mathlib\vector2d.h" + $File "$SRCDIR\public\mathlib\vector4d.h" + $File "$SRCDIR\public\mathlib\vmatrix.h" + $File "$SRCDIR\public\mathlib\vplane.h" + $File "$SRCDIR\public\vstdlib\vstdlib.h" + } +} diff --git a/materialsystem/shaderlib_dx11/shaderlib_cvar.cpp b/materialsystem/shaderlib_dx11/shaderlib_cvar.cpp new file mode 100644 index 0000000..e84d6fe --- /dev/null +++ b/materialsystem/shaderlib_dx11/shaderlib_cvar.cpp @@ -0,0 +1,42 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "icvar.h" +#include "tier1/tier1.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// ------------------------------------------------------------------------------------------- // +// ConVar stuff. +// ------------------------------------------------------------------------------------------- // +class CShaderLibConVarAccessor : public IConCommandBaseAccessor +{ +public: + virtual bool RegisterConCommandBase( ConCommandBase *pCommand ) + { + // Link to engine's list instead + g_pCVar->RegisterConCommand( pCommand ); + + char const *pValue = g_pCVar->GetCommandLineValue( pCommand->GetName() ); + if( pValue && !pCommand->IsCommand() ) + { + ( ( ConVar * )pCommand )->SetValue( pValue ); + } + return true; + } +}; + +CShaderLibConVarAccessor g_ConVarAccessor; + + +void InitShaderLibCVars( CreateInterfaceFn cvarFactory ) +{ + if ( g_pCVar ) + { + ConVar_Register( FCVAR_MATERIAL_SYSTEM_THREAD, &g_ConVarAccessor ); + } +} diff --git a/materialsystem/shaderlib_dx11/shaderlib_cvar.h b/materialsystem/shaderlib_dx11/shaderlib_cvar.h new file mode 100644 index 0000000..4416aba --- /dev/null +++ b/materialsystem/shaderlib_dx11/shaderlib_cvar.h @@ -0,0 +1,20 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef SHADERLIB_CVAR_H +#define SHADERLIB_CVAR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "interface.h" + + +void InitShaderLibCVars( CreateInterfaceFn cvarFactory ); + + +#endif // SHADERLIB_CVAR_H diff --git a/materialsystem/shadersystem.cpp b/materialsystem/shadersystem.cpp index 7d53060..5f43501 100644 --- a/materialsystem/shadersystem.cpp +++ b/materialsystem/shadersystem.cpp @@ -222,7 +222,7 @@ const char *CShaderSystem::s_pDebugShaderName[MATERIAL_DEBUG_COUNT] = "DebugDrawEnvmapMask", "DebugDepth", "DebugDepth", - "Wireframe_DX9" + "Wireframe" }; //----------------------------------------------------------------------------- @@ -326,10 +326,21 @@ void CShaderSystem::LoadAllShaderDLLs( ) // 360 only supports its dx9 dll int dxStart = IsX360() ? 9 : 6; char buf[32]; - for ( i = dxStart; i <= dxSupportLevel; ++i ) + + // DX11FIXME: older shaders are not supported in DX11 + if (CommandLine()->ParmValue("-dxlevel", 90) >= 110) { - Q_snprintf( buf, sizeof( buf ), "stdshader_dx%d%s", i, DLL_EXT_STRING ); - LoadShaderDLL( buf ); + char buf[32]; + Q_snprintf(buf, sizeof(buf), "stdshader_dx%d%s", 11, DLL_EXT_STRING); + LoadShaderDLL(buf); + } + else + { + for (i = dxStart; i <= dxSupportLevel; ++i) + { + Q_snprintf(buf, sizeof(buf), "stdshader_dx%d%s", i, DLL_EXT_STRING); + LoadShaderDLL(buf); + } } const char *pShaderName = NULL; @@ -700,7 +711,8 @@ void CShaderSystem::SetupShaderDictionary( int nShaderDLLIndex ) { if ( pTestDLL->m_ShaderDict.Find( pShaderName ) != pTestDLL->m_ShaderDict.InvalidIndex() ) { - Error( "Game shader '%s' trying to override a base shader '%s'.", info.m_pFileName, pShaderName ); + pTestDLL->m_ShaderDict.Remove(pShaderName); + Warning( "Game shader '%s' trying to override a base shader '%s'.", info.m_pFileName, pShaderName ); } } } diff --git a/materialsystem/stdshaders/buildhl2mpshaders.bat b/materialsystem/stdshaders/buildhl2mpshaders.bat index 902292d..ed77e93 100644 --- a/materialsystem/stdshaders/buildhl2mpshaders.bat +++ b/materialsystem/stdshaders/buildhl2mpshaders.bat @@ -8,7 +8,7 @@ rem == Set the absolute path to your mod's game directory here == set GAMEDIR=%cd%\..\..\..\game\mod_hl2mp rem == Set the relative or absolute path to Source SDK Base 2013 Singleplayer\bin == -set SDKBINDIR=C:\SteamBetaLibrary\SteamApps\common\Source SDK Base 2013 Singleplayer\bin +set SDKBINDIR=%cd%\..\..\..\game\bin rem == Set the Path to your mod's root source code == rem This should already be correct, accepts relative paths only! diff --git a/materialsystem/stdshadersdx11/BaseVSShader.cpp b/materialsystem/stdshadersdx11/BaseVSShader.cpp new file mode 100644 index 0000000..3e3d1b2 --- /dev/null +++ b/materialsystem/stdshadersdx11/BaseVSShader.cpp @@ -0,0 +1,586 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all vs/ps (dx8+) shaders inherit from. +//===========================================================================// +#if !defined(_STATIC_LINKED) || defined(STDSHADER_DX9_DLL_EXPORT) + +#include "basevsshader.h" +#include "mathlib/vmatrix.h" +#include "mathlib/bumpvects.h" +#include "ConVar.h" + +// what is this +#ifdef HDR +#include "vertexlit_and_unlit_generic_hdr_ps20.inc" +#include "vertexlit_and_unlit_generic_hdr_ps20b.inc" +#endif + +//#include "lightmappedgeneric_flashlight_vs30.inc" +//#include "vertexlitgeneric_flashlight_vs30.inc" +//#include "flashlight_ps30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +// These functions are to be called from the shaders. + +//----------------------------------------------------------------------------- +// Helper methods for pixel shader overbrighting +//----------------------------------------------------------------------------- +void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ) +{ + // can't have other overbright values with pixel shaders as it stands. + float v[4]; + if( bEnable ) + { + v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT; + } + else + { + v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f; + } + s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 ); +} + + +//----------------------------------------------------------------------------- +// Helper for dealing with modulation +//----------------------------------------------------------------------------- +void CBaseVSShader::SetModulationDynamicState( Vector4D &output ) +{ + ComputeModulationColor( output.Base() ); +} + +void CBaseVSShader::SetModulationDynamicState_LinearColorSpace( Vector4D &output ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); + color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); + color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); + + output.Init( color[0], color[1], color[2], color[3] ); +} + +void CBaseVSShader::SetModulationDynamicState_LinearColorSpace_LinearScale( Vector4D &output, float flScale ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + color[0] = ( color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ) ) * flScale; + color[1] = ( color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ) ) * flScale; + color[2] = ( color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ) ) * flScale; + + output.Init( color[0], color[1], color[2], color[3] ); +} + + +//----------------------------------------------------------------------------- +// Converts a color + alpha into a vector4 +//----------------------------------------------------------------------------- +void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ) +{ + color.Init( 1.0, 1.0, 1.0, 1.0 ); + if ( colorVar != -1 ) + { + IMaterialVar* pColorVar = s_ppParams[colorVar]; + if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR ) + { + pColorVar->GetVecValue( color.Base(), 3 ); + } + else + { + color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); + } + } + if ( alphaVar != -1 ) + { + float flAlpha = s_ppParams[alphaVar]->GetFloatValue(); + color[3] = clamp( flAlpha, 0.0f, 1.0f ); + } +} + +#ifdef _DEBUG +ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" ); +ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" ); +#endif + +//----------------------------------------------------------------------------- +// Helpers for dealing with envmap tint +//----------------------------------------------------------------------------- +// set alphaVar to -1 to ignore it. +void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear ) +{ + float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 ) + { + IMaterialVar* pAlphaVar = NULL; + if( alphaVar >= 0 ) + { + pAlphaVar = s_ppParams[alphaVar]; + } + if( pAlphaVar ) + { + color[3] = pAlphaVar->GetFloatValue(); + } + + IMaterialVar* pTintVar = s_ppParams[tintVar]; +#ifdef _DEBUG + pTintVar->GetVecValue( color, 3 ); + + float envmapTintOverride = mat_envmaptintoverride.GetFloat(); + float envmapTintScaleOverride = mat_envmaptintscale.GetFloat(); + + if( envmapTintOverride != -1.0f ) + { + color[0] = color[1] = color[2] = envmapTintOverride; + } + if( envmapTintScaleOverride != -1.0f ) + { + color[0] *= envmapTintScaleOverride; + color[1] *= envmapTintScaleOverride; + color[2] *= envmapTintScaleOverride; + } + + if( bConvertFromGammaToLinear ) + { + color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); + color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); + color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); + } +#else + if( bConvertFromGammaToLinear ) + { + pTintVar->GetLinearVecValue( color, 3 ); + } + else + { + pTintVar->GetVecValue( color, 3 ); + } +#endif + } + else + { + color[0] = color[1] = color[2] = color[3] = 0.0f; + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 ); +} + +void CBaseVSShader::SetAmbientCubeDynamicStateVertexShader( ) +{ + s_pShaderAPI->SetVertexShaderStateAmbientLightCube(); +} + +float CBaseVSShader::GetAmbientLightCubeLuminance( ) +{ + return s_pShaderAPI->GetAmbientLightCubeLuminance(); +} + +//----------------------------------------------------------------------------- +// Sets up hw morphing state for the vertex shader +//----------------------------------------------------------------------------- +void CBaseVSShader::SetHWMorphVertexShaderState( Vector4D &dimensions, Vector4D &subrect, VertexTextureSampler_t morphSampler ) +{ + if ( !s_pShaderAPI->IsHWMorphingEnabled() ) + return; + + int nMorphWidth, nMorphHeight; + s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR ); + + int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT ); + float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f }; + dimensions.Init( pMorphAccumSize[0], pMorphAccumSize[1], pMorphAccumSize[2], pMorphAccumSize[3] ); + + int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET ); + int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET ); + int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH ); + int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT ); + float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight }; + subrect.Init( pMorphAccumSubrect[0], pMorphAccumSubrect[1], pMorphAccumSubrect[2], pMorphAccumSubrect[3] ); + + s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR ); +} + +//----------------------------------------------------------------------------- +// GR - translucency query +//----------------------------------------------------------------------------- +BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture, + int detailTextureVar ) +{ + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a vertex alpha + isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); + + // Or we've got a texture alpha (for blending or alpha test) + isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && + !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); + + if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) ) + { + isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture ); + } + + if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) + { + return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive + } + else + { + return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending + } +} + +#if 0//#ifdef STDSHADER_DX11_DLL_EXPORT +void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ) +{ + // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric + if( !vars.m_bLightmappedGeneric ) + { + vars.m_bBump = false; + } + bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture(); + bool bSeamless = vars.m_fSeamlessScale != 0.0; + bool bDetail = vars.m_bLightmappedGeneric && (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1); + + int nDetailBlendMode = 0; + if ( bDetail ) + { + nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params ); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + } + + if( pShaderShadow ) + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + // Alpha blend + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() ); + } + + // Spot sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // Base sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + // Normalizing cubemap sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // Normalizing cubemap sampler2 or normal map sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + // RandomRotation sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + // Flashlight depth sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); + + if( vars.m_bWorldVertexTransition ) + { + // $basetexture2 + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if( bBump2 ) + { + // Normalmap2 sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + } + if( bDetail ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + if( vars.m_bLightmappedGeneric ) + { + lightmappedgeneric_flashlight_vs30_Static_Index vshIndex; + vshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); + vshIndex.SetNORMALMAP( vars.m_bBump ); + vshIndex.SetSEAMLESS( bSeamless ); + vshIndex.SetDETAIL( bDetail ); + pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs30", vshIndex.GetIndex() ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + if( vars.m_bBump ) + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + int numTexCoords = 1; + if( vars.m_bWorldVertexTransition ) + { + flags |= VERTEX_COLOR; + numTexCoords = 2; // need lightmap texcoords to get alpha. + } + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + } + else + { + /*vertexlitgeneric_flashlight_vs30_Static_Index vshIndex; + vshIndex.SetTEETH( vars.m_bTeeth ); + pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs30", vshIndex.GetIndex() );*/ + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlitgeneric_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( vertexlitgeneric_flashlight_vs30 ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int numTexCoords = 1; + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, vars.m_bBump ? 4 : 0 ); + } + + int nBumpMapVariant = 0; + if ( vars.m_bBump ) + { + nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1; + } + + // disabled at the moment, need to make this a convar anyway + int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); + + flashlight_ps30_Static_Index pshIndex; + pshIndex.SetNORMALMAP( nBumpMapVariant ); + pshIndex.SetNORMALMAP2( bBump2 ); + pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); + pshIndex.SetSEAMLESS( bSeamless ); + pshIndex.SetDETAILTEXTURE( bDetail ); + pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); + pshIndex.SetFLASHLIGHTDEPTHFILTERMODE( nShadowFilterMode ); + pShaderShadow->SetPixelShader( "flashlight_ps30", pshIndex.GetIndex() ); + + FogToBlack(); + } + else + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + if ( pFlashlightDepthTexture == NULL ) + { + const int iFlashlightShadowIndex = ( flashlightState.m_nShadowQuality >> 16 ) - 1; + + if ( iFlashlightShadowIndex >= 0 + && iFlashlightShadowIndex <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) + { + pFlashlightDepthTexture = (ITexture*)pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); + } + } + + float flFlashlightPos[4] = { XYZ( flashlightState.m_vecLightOrigin ) }; + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, flFlashlightPos ); + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1920.0f / 32.0f, 1080.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + + if( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + if( vars.m_bWorldVertexTransition ) + { + Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 ); + BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + if( vars.m_bBump ) + { + BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + } + + if( bDetail ) + { + BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar ); + } + + if( vars.m_bWorldVertexTransition ) + { + if( bBump2 ) + { + BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame ); + } + } + + if( vars.m_bLightmappedGeneric ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 ); + if ( bSeamless ) + { + float const0[4]={ vars.m_fSeamlessScale,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 ); + } + + if ( bDetail ) + { + float vDetailConstants[4] = {1,1,1,1}; + + if ( vars.m_nDetailTint != -1 ) + { + params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 ); + } + + if ( vars.m_nDetailTextureBlendFactor != -1 ) + { + vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 ); + } + } + else + { + //vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex; + vertexlitgeneric_flashlight_vs30_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( vars.m_bTeeth ) + { + Assert( vars.m_nTeethForwardVar >= 0 ); + Assert( vars.m_nTeethIllumFactorVar >= 0 ); + Vector4D lighting; + params[vars.m_nTeethForwardVar]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[vars.m_nTeethIllumFactorVar]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); + } + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + //pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + //i don't remember what this is from + vEyePos_SpecExponent[0] = flashlightState.m_vecLightOrigin[0]; + vEyePos_SpecExponent[1] = flashlightState.m_vecLightOrigin[1]; + vEyePos_SpecExponent[2] = flashlightState.m_vecLightOrigin[2]; + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, flashlightState.m_bUberlight ); + SET_DYNAMIC_PIXEL_SHADER( flashlight_ps30 ); + + // SetupUberlightFromState( pShaderAPI, flashlightState ); + + float atten[4]; // Set the flashlight attenuation factors + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + s_pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true ); + } + Draw(); +} + +// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering... +void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ) +{ + const int nTexRes = 32; + int nSeed = fmod (fJitterSeed, 1.0f) * nTexRes * nTexRes; + + int nRow = nSeed / nTexRes; + int nCol = nSeed % nTexRes; + + // Div and mod to get an individual texel in the fTexRes x fTexRes grid + *fU = nRow / (float) nTexRes; // Row + *fV = nCol / (float) nTexRes; // Column +} +#endif + +#endif // !_STATIC_LINKED || STDSHADER_DX8_DLL_EXPORT + +void CBaseVSShader::DrawEqualDepthToDestAlpha( void ) +{ +#ifdef STDSHADER_DX11_DLL_EXPORT +// if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + bool bMakeActualDrawCall = false; + if( s_pShaderShadow ) + { + s_pShaderShadow->EnableColorWrites( false ); + s_pShaderShadow->EnableAlphaWrites( true ); + s_pShaderShadow->EnableDepthWrites( false ); + s_pShaderShadow->EnableAlphaTest( false ); + s_pShaderShadow->EnableBlending( false ); + + s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + + SetVertexShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERMODEL ); + SetVertexShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 2, SHADER_CONSTANTBUFFER_PERSCENE ); + + s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs40", 0 ); + s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps40", 0 ); + } + if( s_pShaderAPI ) + { + s_pShaderAPI->SetVertexShaderIndex( 0 ); + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha(); + } + Draw( bMakeActualDrawCall ); + } +#else + Assert( 0 ); //probably just needs a shader update to the latest +#endif +} \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/BaseVSShader.h b/materialsystem/stdshadersdx11/BaseVSShader.h new file mode 100644 index 0000000..0363a82 --- /dev/null +++ b/materialsystem/stdshadersdx11/BaseVSShader.h @@ -0,0 +1,328 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all vs/ps (dx8+) shaders inherit from. +//===========================================================================// + +#ifndef BASEVSSHADER_H +#define BASEVSSHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderlib_dx11/cshader.h" +#include "shaderlib_dx11/baseshader.h" +#include "shader_register_map.h" +#include "ConVar.h" +#include + +#define SUPPORT_DX8 0 +#define SUPPORT_DX7 0 +//----------------------------------------------------------------------------- +// Helper macro for vertex shaders +//----------------------------------------------------------------------------- +#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags ) +#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 ) + + +// useful parameter initialization macro +#define INIT_FLOAT_PARM( parm, value ) \ + if ( !params[(parm)]->IsDefined() ) \ + { \ + params[(parm)]->SetFloatValue( (value) ); \ + } + + +//----------------------------------------------------------------------------- +// Base class for shaders, contains helper methods. +//----------------------------------------------------------------------------- +class CBaseVSShader : public CBaseShader +{ +public: + + // Sets up ambient light cube... + void SetAmbientCubeDynamicStateVertexShader( ); + float GetAmbientLightCubeLuminance( ); + + // Helpers for dealing with envmaptint + void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false ); + + // Helper methods for pixel shader overbrighting + void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ); + + // Helper for dealing with modulation + void SetModulationDynamicState( Vector4D &output ); + void SetModulationDynamicState_LinearColorSpace( Vector4D &output ); + void SetModulationDynamicState_LinearColorSpace_LinearScale( Vector4D &output, float flScale ); + + // + // Standard shader passes! + // + + void InitParamsUnlitGeneric_DX8( + int baseTextureVar, + int detailScaleVar, + int envmapOptionalVar, + int envmapVar, + int envmapTintVar, + int envmapMaskScaleVar, + int nDetailBlendMode ); + + void InitUnlitGeneric_DX8( + int baseTextureVar, + int detailVar, + int envmapVar, + int envmapMaskVar ); + + // Dx8 Unlit Generic pass + void VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar, + int baseTextureTransformVar, + int detailVar, int detailTransform, bool bDetailTransformIsScale, + int envmapVar, int envMapFrameVar, int envmapMaskVar, + int envmapMaskFrameVar, int envmapMaskScaleVar, int envmapTintVar, + int alphaTestReferenceVar, + int nDetailBlendModeVar, + int nOutlineVar, + int nOutlineColorVar, + int nOutlineStartVar, + int nOutlineEndVar, + int nSeparateDetailUVsVar + ); + + // Helpers for drawing world bump mapped stuff. + void DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar, + int envMapVar, int envMapVarFrame, + int envMapTintVar, int alphaVar, + int envMapContrastVar, int envMapSaturationVar, + int bumpTransformVar, + bool bBlendSpecular, bool bNoWriteZ = false ); + void DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar, + int bumpFrameVar, int envmapFrameVar, + int envmapTintVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, + int bumpTransformVar, int fresnelReflectionVar, + bool bBlend, bool bNoWriteZ = false ); + + const char *UnlitGeneric_ComputeVertexShaderName( bool bMask, + bool bEnvmap, + bool bBaseTexture, + bool bBaseAlphaEnvmapMask, + bool bDetail, + bool bVertexColor, + bool bEnvmapCameraSpace, + bool bEnvmapSphere ); + + const char *UnlitGeneric_ComputePixelShaderName( bool bMask, + bool bEnvmap, + bool bBaseTexture, + bool bBaseAlphaEnvmapMask, + bool bDetail, + bool bMultiplyDetail, + bool bMaskBaseByDetailAlpha ); + + void DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, int frameVar, int colorVar, int alphaVar ); + void DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, bool bMultiply, bool bSSBump ); + void DrawWorldBumpedSpecularLighting( int envmapMaskVar, int envmapMaskFrame, + int bumpmapVar, int envmapVar, + int bumpFrameVar, int envmapFrameVar, + int envmapTintVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, + int bumpTransformVar, int fresnelReflectionVar, + bool bBlend ); + void DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar, + int baseTextureFrameVar, + int baseTexture2Var, int baseTextureTransform2Var, + int baseTextureFrame2Var, int colorVar, int alphaVar ); + void DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, int baseTextureVar, int baseTextureTransformVar, int frameVar ); + void DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, int bumpTransformVar, + int baseTextureVar, int baseTextureTransformVar, int baseTextureFrameVar, + int baseTexture2Var, int baseTextureTransform2Var, int baseTextureFrame2Var); + /*void DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar, + int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, + int envmapMaskVar, int envmapMaskFrame, + int envmapVar, + int envmapFrameVar, + int envmapTintVar, int colorVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, int frameVar, int fresnelReflectionVar, + bool doBaseTexture2, + int baseTexture2Var, + int baseTextureTransform2Var, + int baseTextureFrame2Var, + bool bSSBump + );*/ + + // Sets up hw morphing state for the vertex shader + void SetHWMorphVertexShaderState( Vector4D &dimensions, Vector4D &subrect, VertexTextureSampler_t morphSampler ); + + // Computes the shader index for vertex lit materials + int ComputeVertexLitShaderIndex( bool bVertexLitGeneric, bool hasBump, bool hasEnvmap, bool hasVertexColor, bool bHasNormal ) const; + + BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 ); + + struct DrawFlashlight_dx90_Vars_t + { + DrawFlashlight_dx90_Vars_t() + { + // set all ints to -1 + memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) ); + // set all bools to a default value. + m_bBump = false; + m_bLightmappedGeneric = false; + m_bWorldVertexTransition = false; + m_bTeeth = false; + m_bSSBump = false; + m_fSeamlessScale = 0.0; + } + bool m_bBump; + bool m_bLightmappedGeneric; + bool m_bWorldVertexTransition; + bool m_bTeeth; + int m_nBumpmapVar; + int m_nBumpmapFrame; + int m_nBumpTransform; + int m_nFlashlightTextureVar; + int m_nFlashlightTextureFrameVar; + int m_nBaseTexture2Var; + int m_nBaseTexture2FrameVar; + int m_nBumpmap2Var; + int m_nBumpmap2Frame; + int m_nBump2Transform; + int m_nDetailVar; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + int m_nTeethForwardVar; + int m_nTeethIllumFactorVar; + int m_nAlphaTestReference; + bool m_bSSBump; + float m_fSeamlessScale; // 0.0 = not seamless + }; + void DrawFlashlight_dx90( IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ); + + void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ); + + //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth. + //This pass fills in the areas that passed the alpha test with depth in dest alpha + //by writing only equal depth pixels and only if we should be writing depth to dest alpha + void DrawEqualDepthToDestAlpha( void ); + +private: + // Helper methods for VertexLitGenericPass +// void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin ); + void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar, + int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar, + int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar, + int envmapMaskScaleVar, int envmapTintVar ); + + // Converts a color + alpha into a vector4 + void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ); + +}; + +FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false ) +{ + // Old code + //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; + //float flFlashlightScale = 1.0f / flToneMapScale; + + // Fix to old code to keep flashlight from ever getting brighter than 1.0 + //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; + //if ( flToneMapScale < 1.0f ) + // flToneMapScale = 1.0f; + //float flFlashlightScale = 1.0f / flToneMapScale; + + // Force flashlight to 25% bright always + float flFlashlightScale = 0.25f; + + if ( !g_pHardwareConfig->GetHDREnabled() ) + { + // Non-HDR path requires 2.0 flashlight + flFlashlightScale = 2.0f; + } + + // DX10 requires some hackery due to sRGB/blend ordering change from DX9 + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + { + flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800 + } + + // Generate pixel shader constant + float const *pFlashlightColor = state.m_Color; + float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] }; + vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term + + // Red flashlight for testing + //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f; + + pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst ); +} + +FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state ) +{ + // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + return state.m_flShadowAtten * 0.1f; // magic number + + return state.m_flShadowAtten; +} + +FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state ) +{ + return state.m_flShadowFilterSize / state.m_flShadowMapResolution; +} + +// convenient material variable access functions for helpers to use. +FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params ) +{ + return ( nVar != -1 ) && ( params[nVar]->IsTexture() ); +} + +FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params ) +{ + return ( nVar != -1 ) && ( params[nVar]->GetIntValue() ); +} + +FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 ) +{ + return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue; +} + +FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 ) +{ + return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue; +} + +FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue ) +{ + if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) + { + params[nIndex]->SetFloatValue( flValue ); + } +} + +FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue ) +{ + if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) + { + params[nIndex]->SetIntValue( nValue ); + } +} + + +class ConVar; + +#ifdef _DEBUG +extern ConVar mat_envmaptintoverride; +extern ConVar mat_envmaptintscale; +#endif + + +#endif // BASEVSSHADER_H diff --git a/materialsystem/stdshadersdx11/_clean.bat b/materialsystem/stdshadersdx11/_clean.bat new file mode 100644 index 0000000..29f8298 --- /dev/null +++ b/materialsystem/stdshadersdx11/_clean.bat @@ -0,0 +1,43 @@ +@echo off +setlocal + +if /i "%1" == "-game" goto CleanGameDir + +rem Clean out hl2 +if exist ..\..\..\game\hl2\shaders rd /s /q ..\..\..\game\hl2\shaders +goto CleanOtherStuff + +:CleanGameDir +set __GameDir=%~2 +if not exist "%__GameDir%\gameinfo.txt" goto MissingGameInfo +if exist "%__GameDir%\shaders" rd /s /q "%2\shaders" +goto CleanOtherStuff + +:CleanOtherStuff +if exist debug_dx9 rd /s /q debug_dx9 + +if exist fxctmp9 rd /s /q fxctmp9 +if exist vshtmp9 rd /s /q vshtmp9 +if exist pshtmp9 rd /s /q pshtmp9 + +if exist fxctmp9_360 rd /s /q fxctmp9_360 +if exist vshtmp9_360 rd /s /q vshtmp9_360 +if exist pshtmp9_360 rd /s /q pshtmp9_360 + +if exist fxctmp9_tmp rd /s /q fxctmp9_tmp +if exist vshtmp9_tmp rd /s /q vshtmp9_tmp +if exist pshtmp9_tmp rd /s /q pshtmp9_tmp + +if exist fxctmp9_360_tmp rd /s /q fxctmp9_360_tmp +if exist vshtmp9_360_tmp rd /s /q vshtmp9_360_tmp +if exist pshtmp9_360_tmp rd /s /q pshtmp9_360_tmp + +if exist shaders rd /s /q shaders +goto end + +:MissingGameInfo +echo Invalid -game parameter specified (no "%__GameDir%\gameinfo.txt" exists). +goto end + + +:end \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/_cleantemps.bat b/materialsystem/stdshadersdx11/_cleantemps.bat new file mode 100644 index 0000000..7055aaf --- /dev/null +++ b/materialsystem/stdshadersdx11/_cleantemps.bat @@ -0,0 +1,12 @@ +@echo off +setlocal + +if exist fxctmp9_tmp rd /s /q fxctmp9_tmp +if exist vshtmp9_tmp rd /s /q vshtmp9_tmp +if exist pshtmp9_tmp rd /s /q pshtmp9_tmp + +if exist fxctmp9_360_tmp rd /s /q fxctmp9_360_tmp +if exist vshtmp9_360_tmp rd /s /q vshtmp9_360_tmp +if exist pshtmp9_360_tmp rd /s /q pshtmp9_360_tmp + +if exist shaders rd /s /q shaders diff --git a/materialsystem/stdshadersdx11/_kill_shadercompiler.bat b/materialsystem/stdshadersdx11/_kill_shadercompiler.bat new file mode 100644 index 0000000..a4bce87 --- /dev/null +++ b/materialsystem/stdshadersdx11/_kill_shadercompiler.bat @@ -0,0 +1,8 @@ +@echo off + +tasklist /FI "IMAGENAME eq shadercompile.exe" 2>NUL | find /I /N "shadercompile.exe">NUL + +if "%ERRORLEVEL%"=="0" ( + echo Shadercompile is running still, killing + taskkill /f /im shadercompile.exe >nul +) \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/_shaderlist_dx11.txt b/materialsystem/stdshadersdx11/_shaderlist_dx11.txt new file mode 100644 index 0000000..cf070ef --- /dev/null +++ b/materialsystem/stdshadersdx11/_shaderlist_dx11.txt @@ -0,0 +1,42 @@ +// vs 4.0 ps 4.0 shaders collection + +//test_ps40.fxc +//test_vs40.fxc + +bik_vs40.fxc +bik_ps40.fxc + +unlitgeneric_vs40.fxc +unlitgeneric_ps40.fxc + +white_ps40.fxc +writez_vs40.fxc + +modulate_ps40.fxc +modulate_vs40.fxc + +splinecard_vs40.fxc +spritecard_vs40.fxc +spritecard_ps40.fxc + +sprite_ps40.fxc +sprite_vs40.fxc + +sky_vs40.fxc +sky_ps40.fxc +sky_hdr_compressed_rgbs_ps40.fxc +sky_hdr_compressed_ps40.fxc + +decalmodulate_ps40.fxc + +vertexlit_and_unlit_generic_vs40.fxc +vertexlit_and_unlit_generic_ps40.fxc + +depthtodestalpha_vs40.fxc +depthtodestalpha_ps40.fxc + +wireframe_ps40.fxc +wireframe_vs40.fxc + +lightmappedgeneric_ps40.fxc +lightmappedgeneric_vs40.fxc \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/bik_dx11.cpp b/materialsystem/stdshadersdx11/bik_dx11.cpp new file mode 100644 index 0000000..947218c --- /dev/null +++ b/materialsystem/stdshadersdx11/bik_dx11.cpp @@ -0,0 +1,90 @@ +#if 1 +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "bik_ps40.inc" +#include "bik_vs40.inc" + +BEGIN_VS_SHADER( Bik, "Help for Bik" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( YTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Y Bink Texture" ) + SHADER_PARAM( CRTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Cr Bink Texture" ) + SHADER_PARAM( CBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Cb Bink Texture" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + DECLARE_CONSTANT_BUFFER(BikTest) + + SHADER_INIT + { + if ( params[YTEXTURE]->IsDefined() ) + { + LoadTexture( YTEXTURE ); + } + if ( params[CRTEXTURE]->IsDefined() ) + { + LoadTexture( CRTEXTURE ); + } + if ( params[CBTEXTURE]->IsDefined() ) + { + LoadTexture( CBTEXTURE ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + unsigned int flags = VERTEX_POSITION; + int numTexCoords = 1; + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + SetVertexShaderConstantBuffer(1, SHADER_CONSTANTBUFFER_PERFRAME); + SetVertexShaderConstantBuffer(2, SHADER_CONSTANTBUFFER_PERSCENE); + + DECLARE_STATIC_VERTEX_SHADER( bik_vs40 ); + SET_STATIC_VERTEX_SHADER( bik_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER(bik_ps40); + SET_STATIC_PIXEL_SHADER(bik_ps40); + + pShaderShadow->EnableSRGBWrite( false ); + + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, YTEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CRTEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER2, CBTEXTURE, FRAME ); + + DECLARE_DYNAMIC_VERTEX_SHADER( bik_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, 0 ); + SET_DYNAMIC_VERTEX_SHADER( bik_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( bik_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, 0 ); + SET_DYNAMIC_PIXEL_SHADER( bik_ps40 ); + } + Draw(); + } +END_SHADER +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/bik_ps40.fxc b/materialsystem/stdshadersdx11/bik_ps40.fxc new file mode 100644 index 0000000..5105956 --- /dev/null +++ b/materialsystem/stdshadersdx11/bik_ps40.fxc @@ -0,0 +1,48 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..0" + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] + +#include "common_ps_fxc.h" + +Texture2D YTexture : register(t0); +SamplerState YSampler : register( s0 ); + +Texture2D cRTexture : register(t1); +SamplerState cRSampler : register( s1 ); + +Texture2D cBTexture : register(t2); +SamplerState cBSampler : register( s2 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; + //HALF4 worldPos_projPosZ : TEXCOORD1; + //float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + half y, cR, cB; + y = YTexture.Sample( YSampler, i.baseTexCoord.xy ); + cR = cRTexture.Sample( cRSampler, i.baseTexCoord.xy ); + cB = cBTexture.Sample( cBSampler, i.baseTexCoord.xy ); + + HALF4 c; + c = float4( y, cR, cB, 1.0f ); + + float4 tor = float4( 1.164123535f, 1.595794678f, 0.0f, -0.87065506f ); + float4 tog = float4( 1.164123535f, -0.813476563f, -0.391448975f, 0.529705048f ); + float4 tob = float4( 1.164123535f, 0.0f, 2.017822266f, -1.081668854f ); + + HALF4 rgba; + + rgba.r = dot( c, tor ); + rgba.g = dot( c, tog ); + rgba.b = dot( c, tob ); + rgba.a = 1.0f; + + //float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + float4 result = rgba; + + return result; +} diff --git a/materialsystem/stdshadersdx11/bik_vs40.fxc b/materialsystem/stdshadersdx11/bik_vs40.fxc new file mode 100644 index 0000000..05ddc7a --- /dev/null +++ b/materialsystem/stdshadersdx11/bik_vs40.fxc @@ -0,0 +1,41 @@ +// DYNAMIC: "DOWATERFOG" "0..0" + +#include "common_vs_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_PERFRAME(register(b1)) +CBUFFER_PERSCENE(register(b2)) + + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + //float fog : FOG; + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + //float4 worldPos_projPosZ : TEXCOORD1; // Necessary for water fog dest alpha + //float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4x4 viewProj = mul(cViewMatrix, cProjMatrix); + + // Transform into projection space + float4 projPos = mul(float4(v.vPos.xyz, 1), viewProj); + o.projPos = projPos; + + o.baseTexCoord.xy = v.vTexCoord0; + return o; +} + + diff --git a/materialsystem/stdshadersdx11/buildhl2mpshaders.bat b/materialsystem/stdshadersdx11/buildhl2mpshaders.bat new file mode 100644 index 0000000..7cdbafa --- /dev/null +++ b/materialsystem/stdshadersdx11/buildhl2mpshaders.bat @@ -0,0 +1,21 @@ +@echo off +setlocal + +rem ================================ +rem ==== MOD PATH CONFIGURATIONS === + +rem == Set the absolute path to your mod's game directory here == +set GAMEDIR=%cd%\..\..\..\game\mod_episodic + +rem == Set the relative or absolute path to Source SDK Base 2013 Singleplayer\bin == +set SDKBINDIR=%cd%\..\..\..\game\bin + +rem == Set the Path to your mod's root source code == +rem This should already be correct, accepts relative paths only! +set SOURCEDIR=..\.. + +rem ==== MOD PATH CONFIGURATIONS END === +rem ==================================== + + +call buildsdkshaders.bat diff --git a/materialsystem/stdshadersdx11/buildsdkshaders.bat b/materialsystem/stdshadersdx11/buildsdkshaders.bat new file mode 100644 index 0000000..11761c5 --- /dev/null +++ b/materialsystem/stdshadersdx11/buildsdkshaders.bat @@ -0,0 +1,39 @@ +@echo off +setlocal + +rem Use dynamic shaders to build .inc files only +set dynamic_shaders=1 +rem == Setup path to nmake.exe, from vc 2005 common tools directory == +call "%VS100COMNTOOLS%vsvars32.bat" + + +set TTEXE=..\..\devtools\bin\timeprecise.exe +if not exist %TTEXE% goto no_ttexe +goto no_ttexe_end + +:no_ttexe +set TTEXE=time /t +:no_ttexe_end + + +rem echo. +rem echo ~~~~~~ buildsdkshaders %* ~~~~~~ +%TTEXE% -cur-Q +set tt_all_start=%ERRORLEVEL% +set tt_all_chkpt=%tt_start% + +set BUILD_SHADER=call buildshaders.bat +set ARG_EXTRA= + +%BUILD_SHADER% _shaderlist_dx11 -game %GAMEDIR% -source %SOURCEDIR% -dx9_30 -force30 + + +rem echo. +if not "%dynamic_shaders%" == "1" ( + rem echo Finished full buildallshaders %* +) else ( + rem echo Finished dynamic buildallshaders %* +) + +rem %TTEXE% -diff %tt_all_start% -cur +rem echo. diff --git a/materialsystem/stdshadersdx11/buildshaders.bat b/materialsystem/stdshadersdx11/buildshaders.bat new file mode 100644 index 0000000..ad9b185 --- /dev/null +++ b/materialsystem/stdshadersdx11/buildshaders.bat @@ -0,0 +1,209 @@ +@echo off + +set TTEXE=..\..\devtools\bin\timeprecise.exe +if not exist %TTEXE% goto no_ttexe +goto no_ttexe_end + +:no_ttexe +set TTEXE=time /t +:no_ttexe_end + +echo. +echo ==================== buildshaders %* ================== +%TTEXE% -cur-Q +set tt_start=%ERRORLEVEL% +set tt_chkpt=%tt_start% + + +REM **************** +REM usage: buildshaders +REM **************** + +setlocal +set arg_filename=%1 +set shadercompilecommand=shadercompile.exe +set targetdir=shaders +set SrcDirBase=..\.. +set shaderDir=shaders +set SDKArgs= +set SHADERINCPATH=vshtmp9/... fxctmp9/... + + +if "%1" == "" goto usage +set inputbase=%1 + +set DIRECTX_SDK_VER=pc09.00 +set DIRECTX_SDK_BIN_DIR=dx9sdk\utilities + +if /i "%6" == "-dx9_30" goto dx_sdk_dx9_30 +goto dx_sdk_end +:dx_sdk_dx9_30 + set DIRECTX_SDK_VER=pc09.30 + set DIRECTX_SDK_BIN_DIR=dx10sdk\utilities\dx9_30 + goto dx_sdk_end +:dx_sdk_end + +if /i "%7" == "-force30" goto set_force30_arg +goto set_force_end +:set_force30_arg + set DIRECTX_FORCE_MODEL=30 + goto set_force_end +:set_force_end + +if /i "%2" == "-game" goto set_mod_args +goto build_shaders + +REM **************** +REM USAGE +REM **************** +:usage +echo. +echo "usage: buildshaders [-game] [gameDir if -game was specified] [-source sourceDir]" +echo " gameDir is where gameinfo.txt is (where it will store the compiled shaders)." +echo " sourceDir is where the source code is (where it will find scripts and compilers)." +echo "ex : buildshaders myshaders" +echo "ex : buildshaders myshaders -game c:\steam\steamapps\sourcemods\mymod -source c:\mymod\src" +goto :end + +REM **************** +REM MOD ARGS - look for -game or the vproject environment variable +REM **************** +:set_mod_args + +if not exist "%SDKBINDIR%\shadercompile.exe" goto NoShaderCompile +set ChangeToDir=%SDKBINDIR% + +if /i "%4" NEQ "-source" goto NoSourceDirSpecified +set SrcDirBase=%~5 + +REM ** use the -game parameter to tell us where to put the files +set targetdir=%~3\shaders +set SDKArgs=-nompi -nop4 -game "%~3" + +if not exist "%~3\gameinfo.txt" goto InvalidGameDirectory +goto build_shaders + +REM **************** +REM ERRORS +REM **************** +:InvalidGameDirectory +echo - +echo Error: "%~3" is not a valid game directory. +echo (The -game directory must have a gameinfo.txt file) +echo - +goto end + +:NoSourceDirSpecified +echo ERROR: If you specify -game on the command line, you must specify -source. +goto usage +goto end + +:NoShaderCompile +echo - +echo - ERROR: shadercompile.exe doesn't exist in %SDKBINDIR% +echo - +goto end + +REM **************** +REM BUILD SHADERS +REM **************** +:build_shaders + +rem echo -------------------------------- +rem echo %inputbase% +rem echo -------------------------------- +REM make sure that target dirs exist +REM files will be built in these targets and copied to their final destination +if not exist %shaderDir% mkdir %shaderDir% +if not exist %shaderDir%\fxc mkdir %shaderDir%\fxc +if not exist %shaderDir%\vsh mkdir %shaderDir%\vsh +if not exist %shaderDir%\psh mkdir %shaderDir%\psh +REM Nuke some files that we will add to later. +if exist filelist.txt del /f /q filelist.txt +if exist filestocopy.txt del /f /q filestocopy.txt +if exist filelistgen.txt del /f /q filelistgen.txt +if exist inclist.txt del /f /q inclist.txt +if exist vcslist.txt del /f /q vcslist.txt + +REM **************** +REM Generate a makefile for the shader project +REM **************** +perl "%SrcDirBase%\devtools\bin\updateshaders.pl" -source "%SrcDirBase%" %inputbase% + + +REM **************** +REM Run the makefile, generating minimal work/build list for fxc files, go ahead and compile vsh and psh files. +REM **************** +rem nmake /S /C -f makefile.%inputbase% clean > clean.txt 2>&1 +echo Building inc files, asm vcs files, and VMPI worklist for %inputbase%... +nmake /S /C -f makefile.%inputbase% + +REM **************** +REM Copy the inc files to their target +REM **************** +if exist "inclist.txt" ( + echo Publishing shader inc files to target... + perl %SrcDirBase%\devtools\bin\copyshaderincfiles.pl inclist.txt +) + +REM **************** +REM Add the executables to the worklist. +REM **************** +if /i "%DIRECTX_SDK_VER%" == "pc09.00" ( + rem echo "Copy extra files for dx 9 std +) +if /i "%DIRECTX_SDK_VER%" == "pc09.30" ( + echo %SrcDirBase%\devtools\bin\d3dx9_33.dll >> filestocopy.txt +) + +echo %SrcDirBase%\%DIRECTX_SDK_BIN_DIR%\dx_proxy.dll >> filestocopy.txt + +echo %SDKBINDIR%\shadercompile.exe >> filestocopy.txt +echo %SDKBINDIR%\shadercompile_dll.dll >> filestocopy.txt +echo %SDKBINDIR%\vstdlib.dll >> filestocopy.txt +echo %SDKBINDIR%\tier0.dll >> filestocopy.txt + +REM **************** +REM Cull duplicate entries in work/build list +REM **************** +if exist filestocopy.txt type filestocopy.txt | perl "%SrcDirBase%\devtools\bin\uniqifylist.pl" > uniquefilestocopy.txt +if exist filelistgen.txt if not "%dynamic_shaders%" == "1" ( + echo Generating action list... + copy filelistgen.txt filelist.txt >nul +) + +REM **************** +REM Execute distributed process on work/build list +REM **************** + +set shader_path_cd=%cd% +if exist "filelist.txt" if exist "uniquefilestocopy.txt" if not "%dynamic_shaders%" == "1" ( + echo Running distributed shader compilation... + + cd /D %ChangeToDir% + echo %shadercompilecommand% %SDKArgs% -shaderpath "%shader_path_cd:/=\%" -allowdebug + %shadercompilecommand% %SDKArgs% -shaderpath "%shader_path_cd:/=\%" -allowdebug + cd /D %shader_path_cd% +) + +REM **************** +REM PC Shader copy +REM Publish the generated files to the output dir using XCOPY +REM This batch file may have been invoked standalone or slaved (master does final smart mirror copy) +REM **************** +:DoXCopy +if not "%dynamic_shaders%" == "1" ( +if not exist "%targetdir%" md "%targetdir%" +if not "%targetdir%"=="%shaderDir%" xcopy %shaderDir%\*.* "%targetdir%" /e /y +) +goto end + +REM **************** +REM END +REM **************** +:end + + +%TTEXE% -diff %tt_start% +echo. + diff --git a/materialsystem/stdshadersdx11/common_cbuffers_def_fxc.h b/materialsystem/stdshadersdx11/common_cbuffers_def_fxc.h new file mode 100644 index 0000000..ff329dc --- /dev/null +++ b/materialsystem/stdshadersdx11/common_cbuffers_def_fxc.h @@ -0,0 +1,13 @@ +#ifndef COMMON_CBUFFERS_DEF_H_ +#define COMMON_CBUFFERS_DEF_H_ + +// Convenience include if you need all the internal cbuffers + +#include "common_cbuffers_fxc.h" + +CBUFFER_PERMODEL( INTERNAL_CBUFFER_REG_0 ) +CBUFFER_PERFRAME( INTERNAL_CBUFFER_REG_1 ) +CBUFFER_PERSCENE( INTERNAL_CBUFFER_REG_2 ) +CBUFFER_SKINNING( INTERNAL_CBUFFER_REG_3 ) + +#endif // COMMON_CBUFFERS_DEF_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/common_cbuffers_def_noskinning_fxc.h b/materialsystem/stdshadersdx11/common_cbuffers_def_noskinning_fxc.h new file mode 100644 index 0000000..41f5199 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_cbuffers_def_noskinning_fxc.h @@ -0,0 +1,12 @@ +#ifndef COMMON_CBUFFERS_DEF_H_ +#define COMMON_CBUFFERS_DEF_H_ + +// Convenience include if you need all the internal cbuffers + +#include "common_cbuffers_fxc.h" + +CBUFFER_PERMODEL( register( b0 ) ) +CBUFFER_PERFRAME( register( b1 ) ) +CBUFFER_PERSCENE( register( b2 ) ) + +#endif // COMMON_CBUFFERS_DEF_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/common_cbuffers_fxc.h b/materialsystem/stdshadersdx11/common_cbuffers_fxc.h new file mode 100644 index 0000000..608de62 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_cbuffers_fxc.h @@ -0,0 +1,50 @@ +#ifndef COMMON_CBUFFERS_H_ +#define COMMON_CBUFFERS_H_ + +#include "shader_register_map.h" +#include "lightinfo_fxc.h" + +#define CBUFFER_PERMODEL( reg ) \ +cbuffer PerModel_t : reg \ +{ \ + float4x4 cModelMatrix; \ + LightInfo cLightInfo[MAX_NUM_LIGHTS]; \ + int4 cLightCount; \ + float3 cAmbientCube[6]; \ +}; + +#define CBUFFER_SKINNING( reg )\ +cbuffer Skinning_t : reg \ +{ \ + float4x3 cModel[53]; \ +}; + +#define CBUFFER_FLEX( reg )\ +cbuffer Flex_t : reg \ +{ \ + float4 cFlexWeights[512]; \ +}; + +#define CBUFFER_PERFRAME( reg ) \ +cbuffer PerFrame_t : reg \ +{ \ + float4x4 cViewMatrix; \ + float4 cEyePos; \ + float4 cToneMappingScale; \ + float4 cFlashlightPos; \ +}; + +#define CBUFFER_PERSCENE( reg ) \ +cbuffer PerScene_t : reg \ +{ \ + float4x4 cProjMatrix; \ + float4x4 cFlashlightWorldToTexture; \ + float4 cFlashlightScreenScale; \ + float4 cFlashlightColor; \ + float4 cFlashlightAttenuationFactors; \ + float4 cShadowTweaks; \ + float4 cConstants; \ + float4 cFlexScale; \ +}; + +#endif // COMMON_CBUFFERS_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/common_flashlight_fxc.h b/materialsystem/stdshadersdx11/common_flashlight_fxc.h new file mode 100644 index 0000000..7c92547 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_flashlight_fxc.h @@ -0,0 +1,532 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Common pixel shader code specific to flashlights +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FLASHLIGHT_FXC_H_ +#define COMMON_FLASHLIGHT_FXC_H_ + +#include "common_ps_fxc.h" + +#if SHADER_MODEL_PS_3_0 +// Superellipse soft clipping +// +// Input: +// - Point Q on the x-y plane +// - The equations of two superellipses (with major/minor axes given by +// a,b and A,B for the inner and outer ellipses, respectively) +// - This is changed a bit from the original RenderMan code to be better vectorized +// +// Return value: +// - 0 if Q was inside the inner ellipse +// - 1 if Q was outside the outer ellipse +// - smoothly varying from 0 to 1 in between +float2 ClipSuperellipse( float2 Q, // Point on the xy plane + float4 aAbB, // Dimensions of superellipses + float2 rounds ) // Same roundness for both ellipses +{ + float2 qr, Qabs = abs(Q); // Project to +x +y quadrant + + float2 bx_Bx = Qabs.x * aAbB.zw; + float2 ay_Ay = Qabs.y * aAbB.xy; + + qr.x = pow( pow(bx_Bx.x, rounds.x) + pow(ay_Ay.x, rounds.x), rounds.y ); // rounds.x = 2 / roundness + qr.y = pow( pow(bx_Bx.y, rounds.x) + pow(ay_Ay.y, rounds.x), rounds.y ); // rounds.y = -roundness/2 + + return qr * aAbB.xy * aAbB.zw; +} + +// Volumetric light shaping +// +// Inputs: +// - the point being shaded, in the local light space +// - all information about the light shaping, including z smooth depth +// clipping, superellipse xy shaping, and distance falloff. +// Return value: +// - attenuation factor based on the falloff and shaping +float uberlight(float3 PL, // Point in light space + + float3 smoothEdge0, // edge0 for three smooth steps + float3 smoothEdge1, // edge1 for three smooth steps + float3 smoothOneOverWidth, // width of three smooth steps + + float2 shear, // shear in X and Y + float4 aAbB, // Superellipse dimensions + float2 rounds ) // two functions of roundness packed together +{ + float2 qr = ClipSuperellipse( (PL / PL.z) - shear, aAbB, rounds ); + + smoothEdge0.x = qr.x; // Fill in the dynamic parts of the smoothsteps + smoothEdge1.x = qr.y; // The other components are pre-computed outside of the shader + smoothOneOverWidth.x = 1.0f / ( qr.y - qr.x ); + float3 x = float3( 1, PL.z, PL.z ); + + float3 atten3 = smoothstep3( smoothEdge0, smoothEdge1, smoothOneOverWidth, x ); + + // Modulate the three resulting attenuations (flipping the sense of the attenuation from the superellipse and the far clip) + return (1.0f - atten3.x) * atten3.y * (1.0f - atten3.z); +} + +#endif + +// JasonM - TODO: remove this simpleton version +float DoShadow( Texture2D DepthTex, SamplerState DepthSampler, float4 texCoord ) +{ + const float g_flShadowBias = 0.0005f; + float2 uoffset = float2( 0.5f/512.f, 0.0f ); + float2 voffset = float2( 0.0f, 0.5f/512.f ); + float3 projTexCoord = texCoord.xyz / texCoord.w; + float4 flashlightDepth = float4( DepthTex.Sample( DepthSampler, projTexCoord.xy + uoffset + voffset ).x, + DepthTex.Sample( DepthSampler, projTexCoord.xy + uoffset - voffset ).x, + DepthTex.Sample( DepthSampler, projTexCoord.xy - uoffset + voffset ).x, + DepthTex.Sample( DepthSampler, projTexCoord.xy - uoffset - voffset ).x ); + +# if ( defined( REVERSE_DEPTH_ON_X360 ) ) + { + flashlightDepth = 1.0f - flashlightDepth; + } +# endif + + float shadowed = 0.0f; + float z = texCoord.z/texCoord.w; + float4 dz = float4(z,z,z,z) - (flashlightDepth + float4( g_flShadowBias, g_flShadowBias, g_flShadowBias, g_flShadowBias)); + float4 shadow = float4(0.25f,0.25f,0.25f,0.25f); + + if( dz.x <= 0.0f ) + shadowed += shadow.x; + if( dz.y <= 0.0f ) + shadowed += shadow.y; + if( dz.z <= 0.0f ) + shadowed += shadow.z; + if( dz.w <= 0.0f ) + shadowed += shadow.w; + + return shadowed; +} + + +float DoShadowNvidiaRAWZOneTap( Texture2D DepthTex, SamplerState DepthSampler, const float4 shadowMapPos ) +{ + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float fDepth = dot(DepthTex.Sample(DepthSampler, shadowMapCenter).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + + return fDepth > objDepth; +} + + +float DoShadowNvidiaRAWZ( Texture2D DepthTex, SamplerState DepthSampler, const float4 shadowMapPos ) +{ + float fE = 1.0f / 512.0f; // Epsilon + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vDepths; + vDepths.x = dot(DepthTex.Sample(DepthSampler, shadowMapCenter + float2( fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.y = dot( DepthTex.Sample(DepthSampler, shadowMapCenter + float2( -fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.z = dot( DepthTex.Sample(DepthSampler, shadowMapCenter + float2( fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.w = dot( DepthTex.Sample(DepthSampler, shadowMapCenter + float2( -fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + + return dot(vDepths > objDepth.xxxx, float4(0.25, 0.25, 0.25, 0.25)); +} + + +float DoShadowNvidiaCheap( Texture2D DepthTex, SamplerState DepthSampler, const float4 shadowMapPos ) +{ + float fTexelEpsilon = 1.0f / 1024.0f; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vTaps; + vTaps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon)).x ); + vTaps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon)).x ); + vTaps.z = step( objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon ) ).x ); + vTaps.w = step( objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon ) ).x ); + + return dot(vTaps, float4(0.25, 0.25, 0.25, 0.25)); +} + +float DoShadowNvidiaPCF3x3Box( Texture2D DepthTex, SamplerState DepthSampler, const float3 shadowMapPos, const float4 vShadowTweaks ) +{ + float fTexelEpsilon = vShadowTweaks.x; + + float3 shadowMapCenter_objDepth = shadowMapPos.xyz; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vOneTaps; + vOneTaps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon )).x ); + vOneTaps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon )).x ); + vOneTaps.z = step( objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon ) ).x ); + vOneTaps.w = step( objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon )).x ); + float flOneTaps = dot( vOneTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); + + float4 vTwoTaps; + vTwoTaps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTexelEpsilon, 0 )).x ); + vTwoTaps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTexelEpsilon, 0 )).x ); + vTwoTaps.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( 0, -fTexelEpsilon )).x ); + vTwoTaps.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( 0, -fTexelEpsilon )).x ); + float flTwoTaps = dot( vTwoTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); + + float flCenterTap = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter).x ) * (1.0f / 9.0f); + + // Sum all 9 Taps + return flOneTaps + flTwoTaps + flCenterTap; +} + + +// +// 1 4 7 4 1 +// 4 20 33 20 4 +// 7 33 55 33 7 +// 4 20 33 20 4 +// 1 4 7 4 1 +// +float DoShadowNvidiaPCF5x5Gaussian( Texture2D DepthTex, SamplerState DepthSampler, const float3 shadowMapPos, const float4 vShadowTweaks ) +{ + float fEpsilonX = vShadowTweaks; + float fTwoEpsilonX = 2.0f * fEpsilonX; + float fEpsilonY = vShadowTweaks; + float fTwoEpsilonY = 2.0f * fEpsilonY; + + float3 shadowMapCenter_objDepth = shadowMapPos; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vOneTaps; + vOneTaps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTwoEpsilonX, fTwoEpsilonY )).x ); + vOneTaps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTwoEpsilonX, fTwoEpsilonY )).x ); + vOneTaps.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTwoEpsilonX, -fTwoEpsilonY )).x ); + vOneTaps.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTwoEpsilonX, -fTwoEpsilonY )).x ); + float flOneTaps = dot( vOneTaps, float4(1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f)); + + float4 vSevenTaps; + vSevenTaps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTwoEpsilonX, 0 )).x ); + vSevenTaps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTwoEpsilonX, 0 )).x ); + vSevenTaps.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( 0, fTwoEpsilonY )).x ); + vSevenTaps.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( 0, -fTwoEpsilonY )).x ); + float flSevenTaps = dot( vSevenTaps, float4( 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f ) ); + + float4 vFourTapsA, vFourTapsB; + vFourTapsA.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTwoEpsilonX, fEpsilonY )).x ); + vFourTapsA.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fEpsilonX, fTwoEpsilonY )).x ); + vFourTapsA.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fEpsilonX, fTwoEpsilonY )).x ); + vFourTapsA.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTwoEpsilonX, fEpsilonY )).x ); + vFourTapsB.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fTwoEpsilonX, -fEpsilonY )).x ); + vFourTapsB.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fEpsilonX, -fTwoEpsilonY )).x ); + vFourTapsB.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fEpsilonX, -fTwoEpsilonY )).x ); + vFourTapsB.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fTwoEpsilonX, -fEpsilonY )).x ); + float flFourTapsA = dot( vFourTapsA, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); + float flFourTapsB = dot( vFourTapsB, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); + + float4 v20Taps; + v20Taps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fEpsilonX, fEpsilonY )).x ); + v20Taps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fEpsilonX, fEpsilonY )).x ); + v20Taps.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fEpsilonX, -fEpsilonY )).x ); + v20Taps.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fEpsilonX, -fEpsilonY )).x ); + float fl20Taps = dot( v20Taps, float4(20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f)); + + float4 v33Taps; + v33Taps.x = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( fEpsilonX, 0 )).x ); + v33Taps.y = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( -fEpsilonX, 0 )).x ); + v33Taps.z = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( 0, fEpsilonY )).x ); + v33Taps.w = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter + float2( 0, -fEpsilonY )).x ); + float fl33Taps = dot( v33Taps, float4(33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f)); + + float flCenterTap = step(objDepth, DepthTex.Sample( DepthSampler, shadowMapCenter).x ) * (55.0f / 331.0f); + + // Sum all 25 Taps + return flOneTaps + flSevenTaps + flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap; +} + + +float DoShadowATICheap( Texture2D DepthTex, SamplerState DepthSampler, const float4 shadowMapPos ) +{ + float2 shadowMapCenter = shadowMapPos.xy/shadowMapPos.w; + float objDepth = shadowMapPos.z / shadowMapPos.w; + float fSampleDepth = DepthTex.Sample( DepthSampler, shadowMapCenter ).x; + + objDepth = min( objDepth, 0.99999 ); //HACKHACK: On 360, surfaces at or past the far flashlight plane have an abrupt cutoff. This is temp until a smooth falloff is implemented + + return fSampleDepth > objDepth; +} + + +// Poisson disc, randomly rotated at different UVs +float DoShadowPoisson16Sample( Texture2D DepthTex, SamplerState DepthSampler, Texture2D RandomRotationTex, SamplerState RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks, bool bNvidiaHardwarePCF, bool bFetch4 ) +{ + float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), float2( 0.8806f, 0.3430f ), float2( -0.0041f, -0.6197f ), float2( 0.0472f, 0.4964f ), + float2( -0.3730f, 0.0874f ), float2( -0.9217f, -0.3177f ), float2( -0.6289f, 0.7388f ), float2( 0.5744f, -0.7741f ) }; + + float flScaleOverMapSize = vShadowTweaks.x * 2; // Tweak parameters to shader + float2 vNoiseOffset = vShadowTweaks.zw; + float4 vLightDepths = 0, accum = 0.0f; + float2 rotOffset = 0; + + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + + // 2D Rotation Matrix setup + float3 RMatTop = 0, RMatBottom = 0; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) + RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5) + vNoiseOffset).xy * 2.0 - 1.0; + RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple +#endif + + RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution + RMatBottom *= flScaleOverMapSize; + + RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below + RMatBottom.z = shadowMapCenter.y; + + float fResult = 0.0f; + + if ( bNvidiaHardwarePCF ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; + vLightDepths.x += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; + vLightDepths.y += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; + vLightDepths.z += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; + vLightDepths.w += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; + vLightDepths.x += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; + vLightDepths.y += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; + vLightDepths.z += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; + vLightDepths.w += step( objDepth, DepthTex.Sample(DepthSampler, rotOffset).x ); + + // First, search for blockers + return dot( vLightDepths, float4( 0.25, 0.25, 0.25, 0.25) ); + } + else if ( bFetch4 ) + { + for( int i=0; i<8; i++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[i].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[i].xy) + RMatBottom.z; + vLightDepths = DepthTex.Sample( DepthSampler, rotOffset.xy ); + accum += (vLightDepths > objDepth.xxxx); + } + + return dot( accum, float4( 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f) ); + } + else // ATI vanilla hardware shadow mapping + { + for( int i=0; i<2; i++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+0].xy) + RMatBottom.z; + vLightDepths.x = DepthTex.Sample( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+1].xy) + RMatBottom.z; + vLightDepths.y = DepthTex.Sample( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+2].xy) + RMatBottom.z; + vLightDepths.z = DepthTex.Sample( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+3].xy) + RMatBottom.z; + vLightDepths.w = DepthTex.Sample( DepthSampler, rotOffset.xy ).x; + + accum += (vLightDepths > objDepth.xxxx); + } + + return dot( accum, float4( 0.125, 0.125, 0.125, 0.125 ) ); + } +} + +float DoFlashlightShadow( Texture2D DepthTex, SamplerState DepthSampler, /*sampler RandomRotationSampler,*/ float3 vProjCoords, float2 vScreenPos, int nShadowLevel, float4 vShadowTweaks, bool bAllowHighQuality, bool bForceSimple = false ) +{ + float flShadow = 1.0f; + + //if( nShadowLevel == NVIDIA_PCF_POISSON ) +#if defined( SHADER_MODEL_PS_3_0 ) || defined(SHADER_MODEL_PS_4_0) + flShadow = DoShadowNvidiaPCF5x5Gaussian( DepthTex, DepthSampler, vProjCoords, vShadowTweaks ); +#else + flShadow = DoShadowNvidiaPCF3x3Box( DepthTex, DepthSampler, vProjCoords, vShadowTweaks ); +#endif + /*else if( nShadowLevel == ATI_NOPCF ) + flShadow = DoShadowPoisson16Sample( DepthTex, DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, false ); + else if( nShadowLevel == ATI_NO_PCF_FETCH4 ) + flShadow = DoShadowPoisson16Sample( DepthTex, DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, true );*/ + + return flShadow; +} + +float3 SpecularLight( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, const bool bDoSpecularWarp, in Texture2D specularWarpTex, in SamplerState specularWarpSampler, float fFresnel ) +{ + float3 result = float3(0.0f, 0.0f, 0.0f); + + float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal + float3 vSpecular = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + vSpecular = pow( vSpecular.x, fSpecularExponent ); // Raise to specular power + + // Optionally warp as function of scalar specular and fresnel + if ( bDoSpecularWarp ) + vSpecular *= specularWarpTex.Sample( specularWarpSampler, float2(vSpecular.x, fFresnel) ).xyz; // Sample at { (L.R)^k, fresnel } + + return vSpecular; +} + +void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, + float3 attenuationFactors, float farZ, Texture2D FlashlightTex, SamplerState FlashlightSampler, + Texture2D FlashlightDepthTex, SamplerState FlashlightDepthSampler, + Texture2D RandomRotationTex, SamplerState RandomRotationSampler, + int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, const float2 vScreenPos, const float fSpecularExponent, const float3 vEyeDir, + const bool bDoSpecularWarp, Texture2D specularWarpTex, SamplerState specularWarpSampler, float fFresnel, float4 vShadowTweaks, + + // Outputs of this shader...separate shadowed diffuse and specular from the flashlight + out float3 diffuseLighting, out float3 specularLighting ) +{ + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = FlashlightTex.Sample( FlashlightSampler, vProjCoords.xy ).xyz; + +#if defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) + flashlightColor *= flashlightSpacePosition.w > 0; // Catch back projection (PC-only, ps2b and up) +#endif + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) + flashlightColor *= cFlashlightColor.xyz; // Flashlight color +#endif + + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + + // Shadowing and coloring terms +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0)) + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthTex, FlashlightDepthSampler, /*RandomRotationSampler,*/ vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } +#endif + + diffuseLighting = fAtten; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) + diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) + flFlashlightNoLambertValue ); // Lambertian term +#else + diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) ); // Lambertian (not Half-Lambert) term +#endif + diffuseLighting *= flashlightColor; + diffuseLighting *= endFalloffFactor; + + // Specular term (masked by diffuse) + specularLighting = diffuseLighting * SpecularLight ( worldNormal, L, fSpecularExponent, vEyeDir, bDoSpecularWarp, + specularWarpTex, specularWarpSampler, fFresnel ); +} + +// Diffuse only version +float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, + float3 attenuationFactors, float farZ, Texture2D FlashlightTex, SamplerState FlashlightSampler, + Texture2D FlashlightDepthTex, SamplerState FlashlightDepthSampler, + int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, + const float2 vScreenPos, bool bClip, float4 vShadowTweaks = float4(1/4096.0f, 0.00001f, 0.0f, 0.0f), bool bHasNormal = true ) +{ + if ( flashlightSpacePosition.w < 0 ) + { + return float3(0,0,0); + } + else + { + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = FlashlightDepthTex.Sample( FlashlightSampler, vProjCoords.xy ).xyz; + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) + flashlightColor *= cFlashlightColor.xyz; // Flashlight color +#endif + + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + + // Shadowing and coloring terms +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0)) + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthTex, FlashlightDepthSampler, /*RandomRotationSampler,*/ vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( saturate( flShadow ), 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } +#endif + + float3 diffuseLighting = fAtten; + + float flLDotWorldNormal; + if ( bHasNormal ) + { + flLDotWorldNormal = dot( L.xyz, worldNormal.xyz ); + } + else + { + flLDotWorldNormal = 1.0f; + } + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) + diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term +#else + diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term +#endif + + diffuseLighting *= flashlightColor; + diffuseLighting *= endFalloffFactor; + + return diffuseLighting; + } +} + +#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_ diff --git a/materialsystem/stdshadersdx11/common_fxc.h b/materialsystem/stdshadersdx11/common_fxc.h new file mode 100644 index 0000000..a452e13 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_fxc.h @@ -0,0 +1,316 @@ +//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FXC_H_ +#define COMMON_FXC_H_ + +#include "common_pragmas.h" +#include "common_hlsl_cpp_consts.h" +#include "shader_register_map.h" +#include "lightinfo_fxc.h" + +#ifdef NV3X +# define HALF half +# define HALF2 half2 +# define HALF3 half3 +# define HALF4 half4 +# define HALF3x3 half3x3 +# define HALF3x4 half3x4 +# define HALF4x3 half4x3 +# define HALF_CONSTANT( _constant ) ((HALF)_constant) +#else +# define HALF float +# define HALF2 float2 +# define HALF3 float3 +# define HALF4 float4 +# define HALF3x3 float3x3 +# define HALF3x4 float3x4 +# define HALF4x3 float4x3 +# define HALF_CONSTANT( _constant ) _constant +#endif + +// This is where all common code for both vertex and pixel shaders. +#define OO_SQRT_3 0.57735025882720947f +static const HALF3 bumpBasis[3] = { + HALF3( 0.81649661064147949f, 0.0f, OO_SQRT_3 ), + HALF3( -0.40824833512306213f, 0.70710676908493042f, OO_SQRT_3 ), + HALF3( -0.40824821591377258f, -0.7071068286895752f, OO_SQRT_3 ) +}; +static const HALF3 bumpBasisTranspose[3] = { + HALF3( 0.81649661064147949f, -0.40824833512306213f, -0.40824833512306213f ), + HALF3( 0.0f, 0.70710676908493042f, -0.7071068286895752f ), + HALF3( OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 ) +}; + +#if defined( _X360 ) +#define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in public/shaderapi/shareddefs.h +//Note that the reversal happens in the viewport. So ONLY reading back from a depth texture should be affected. Projected math is unaffected. +#endif + +HALF3 CalcReflectionVectorNormalized( HALF3 normal, HALF3 eyeVector ) +{ + // FIXME: might be better of normalizing with a normalizing cube map and + // get rid of the dot( normal, normal ) + // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v + return 2.0 * ( dot( normal, eyeVector ) / dot( normal, normal ) ) * normal - eyeVector; +} + +HALF3 CalcReflectionVectorUnnormalized( HALF3 normal, HALF3 eyeVector ) +{ + // FIXME: might be better of normalizing with a normalizing cube map and + // get rid of the dot( normal, normal ) + // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v + // multiply all values through by N.N. uniformly scaling reflection vector won't affect result + // since it is used in a cubemap lookup + return (2.0*(dot( normal, eyeVector ))*normal) - (dot( normal, normal )*eyeVector); +} + +float3 HuePreservingColorClamp( float3 c ) +{ + // Get the max of all of the color components and a specified maximum amount + float maximum = max( max( c.x, c.y ), max( c.z, 1.0f ) ); + + return (c / maximum); +} + +HALF3 HuePreservingColorClamp( HALF3 c, HALF maxVal ) +{ + // Get the max of all of the color components and a specified maximum amount + float maximum = max( max( c.x, c.y ), max( c.z, maxVal ) ); + return (c * ( maxVal / maximum ) ); +} + +#if (AA_CLAMP==1) +HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) +{ + HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; + result += Lightmap3Coord; + return result; +} + +void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, + out HALF2 bumpCoord1, + out HALF2 bumpCoord2, + out HALF2 bumpCoord3 ) +{ + HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; + result += Lightmap3Coord; + bumpCoord1 = result + HALF2(Lightmap1and2Coord.z, 0); + bumpCoord2 = result + 2*HALF2(Lightmap1and2Coord.z, 0); + bumpCoord3 = result + 3*HALF2(Lightmap1and2Coord.z, 0); +} +#else +HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) +{ + return Lightmap1and2Coord.xy; +} + +void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, + out HALF2 bumpCoord1, + out HALF2 bumpCoord2, + out HALF2 bumpCoord3 ) +{ + bumpCoord1 = Lightmap1and2Coord.xy; + bumpCoord2 = Lightmap1and2Coord.wz; // reversed order!!! + bumpCoord3 = Lightmap3Coord.xy; +} +#endif + +// Versions of matrix multiply functions which force HLSL compiler to explictly use DOTs, +// not giving it the option of using MAD expansion. In a perfect world, the compiler would +// always pick the best strategy, and these shouldn't be needed.. but.. well.. umm.. +// +// lorenmcq + +float3 mul3x3(float3 v, float3x3 m) +{ + return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); +} + +float3 mul4x3(float4 v, float4x3 m) +{ + return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); +} + +float3 DecompressHDR( float4 input ) +{ + return input.rgb * input.a * MAX_HDR_OVERBRIGHT; +} + +float4 CompressHDR( float3 input ) +{ + // FIXME: want to use min so that we clamp to white, but what happens if we + // have an albedo component that's less than 1/MAX_HDR_OVERBRIGHT? + // float fMax = max( max( color.r, color.g ), color.b ); + float4 output; + float fMax = min( min( input.r, input.g ), input.b ); + if( fMax > 1.0f ) + { + float oofMax = 1.0f / fMax; + output.rgb = oofMax * input.rgb; + output.a = min( fMax / MAX_HDR_OVERBRIGHT, 1.0f ); + } + else + { + output.rgb = input.rgb; + output.a = 0.0f; + } + return output; +} + + +float3 LinearToGamma( const float3 f3linear ) +{ + return pow( f3linear, 1.0f / 2.2f ); +} + +float4 LinearToGamma( const float4 f4linear ) +{ + return float4( pow( f4linear.xyz, 1.0f / 2.2f ), f4linear.w ); +} + +float LinearToGamma( const float f1linear ) +{ + return pow( f1linear, 1.0f / 2.2f ); +} + +float3 GammaToLinear( const float3 gamma ) +{ + return pow( gamma, 2.2f ); +} + +float4 GammaToLinear( const float4 gamma ) +{ + return float4( pow( gamma.xyz, 2.2f ), gamma.w ); +} + +float GammaToLinear( const float gamma ) +{ + return pow( gamma, 2.2f ); +} + +// These two functions use the actual sRGB math +float SrgbGammaToLinear( float flSrgbGammaValue ) +{ + float x = saturate( flSrgbGammaValue ); + return ( x <= 0.04045f ) ? ( x / 12.92f ) : ( pow( ( x + 0.055f ) / 1.055f, 2.4f ) ); +} + +float SrgbLinearToGamma( float flLinearValue ) +{ + float x = saturate( flLinearValue ); + return ( x <= 0.0031308f ) ? ( x * 12.92f ) : ( 1.055f * pow( x, ( 1.0f / 2.4f ) ) ) - 0.055f; +} + +float3 Vec3WorldToTangent( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + float3 vTangentVector; + vTangentVector.x = dot( iWorldVector.xyz, iWorldTangent.xyz ); + vTangentVector.y = dot( iWorldVector.xyz, iWorldBinormal.xyz ); + vTangentVector.z = dot( iWorldVector.xyz, iWorldNormal.xyz ); + return vTangentVector.xyz; // Return without normalizing +} + +float3 Vec3WorldToTangentNormalized( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + return normalize( Vec3WorldToTangent( iWorldVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); +} + +float3 Vec3TangentToWorld( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + float3 vWorldVector; + vWorldVector.xyz = iTangentVector.x * iWorldTangent.xyz; + vWorldVector.xyz += iTangentVector.y * iWorldBinormal.xyz; + vWorldVector.xyz += iTangentVector.z * iWorldNormal.xyz; + return vWorldVector.xyz; // Return without normalizing +} + +float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); +} + +//----------------------------------------------------------------- +// These functions were moved here from common_vs_fxc.h to support +// full pixel shader lighting. +//----------------------------------------------------------------- + +// The following "internal" routines are called "privately" by other routines in this file which +// handle the particular flavor of vs20 control flow appropriate to the original caller +float LightAttenInternal( const float3 worldPos, int lightNum, LightInfo lightInfo[4] ) +{ + float result = 0.0f; + + // Get light direction + float3 lightDir = lightInfo[lightNum].pos - worldPos; + + // Get light distance squared. + float lightDistSquared = dot( lightDir, lightDir ); + + // Get 1/lightDistance + float ooLightDist = rsqrt( lightDistSquared ); + + // Normalize light direction + lightDir *= ooLightDist; + + float3 vDist = dst( lightDistSquared, ooLightDist ); + + float flDistanceAtten = 1.0f / dot( lightInfo[lightNum].atten.xyz, vDist ); + + // Spot attenuation + float flCosTheta = dot( lightInfo[lightNum].dir.xyz, -lightDir ); + float flSpotAtten = ( flCosTheta - lightInfo[lightNum].spotParams.z ) * lightInfo[lightNum].spotParams.w; + flSpotAtten = max( 0.0001f, flSpotAtten ); + flSpotAtten = pow( flSpotAtten, lightInfo[lightNum].spotParams.x ); + flSpotAtten = saturate( flSpotAtten ); + + // Select between point and spot + float flAtten = lerp( flDistanceAtten, flDistanceAtten * flSpotAtten, lightInfo[lightNum].dir.w ); + + // Select between above and directional (no attenuation) + result = lerp( flAtten, 1.0f, lightInfo[lightNum].color.w ); + + return result; +} + +// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file +float GetAttenForLight( const float3 worldPos, int lightNum, LightInfo lightInfo[4] ) +{ + float result = 0.0f; + result = LightAttenInternal( worldPos, lightNum, lightInfo ); + + return result; +} + +matrix ComputeMVP( const matrix model, const matrix view, const matrix proj ) +{ + matrix mvp = mul( model, view ); + mvp = mul( mvp, proj ); + return mvp; +} + +float4 ComputeProjPos( const float3 vPos, const matrix model, const matrix view, const matrix proj ) +{ + float4 projPos; + projPos = mul( float4( vPos, 1.0f ), model ); + projPos = mul( projPos, view ); + projPos = mul( projPos, proj ); + return projPos; +} + +float4 ComputeEyeSpacePos( const float3 vPos, const matrix view, const matrix model ) +{ + matrix viewModel = mul( view, model ); + return mul( float4( vPos, 1 ), viewModel ); +} + +float4 WorldToEye( const float3 worldPos, const matrix view ) +{ + return mul( float4( worldPos, 1 ), view ); +} + +#endif //#ifndef COMMON_FXC_H_ diff --git a/materialsystem/stdshadersdx11/common_hlsl_cpp_consts.h b/materialsystem/stdshadersdx11/common_hlsl_cpp_consts.h new file mode 100644 index 0000000..5989e2b --- /dev/null +++ b/materialsystem/stdshadersdx11/common_hlsl_cpp_consts.h @@ -0,0 +1,27 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_HLSL_CONSTS_H_ +#define COMMON_HLSL_CONSTS_H_ + +#ifdef NV3X + #define PSHADER_VECT_SCALE 20.0 + #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) +#else + #define PSHADER_VECT_SCALE 1.0 + #define VSHADER_VECT_SCALE 1.0 +#endif + +// GR - HDR luminance maps to 0..n range +// IMPORTANT: Keep the same value as in materialsystem_global.h +// HDRFIXME: Make this a pixel shader constant? +#define MAX_HDR_OVERBRIGHT 16.0f + +#define LINEAR_FOG_COLOR 29 +#define TONE_MAPPING_SCALE_PSH_CONSTANT 30 + +#endif //#ifndef COMMON_HLSL_CONSTS_H_ diff --git a/materialsystem/stdshadersdx11/common_lightmappedgeneric_fxc.h b/materialsystem/stdshadersdx11/common_lightmappedgeneric_fxc.h new file mode 100644 index 0000000..6571312 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_lightmappedgeneric_fxc.h @@ -0,0 +1,153 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +void GetBaseTextureAndNormal( Texture2D basetex, SamplerState base, Texture2D basetex2, SamplerState base2, Texture2D bumptex, SamplerState bump, + bool bBase2, bool bBump, float3 coords, float3 vWeights, + out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) +{ + vResultBase = 0; + vResultBase2 = 0; + vResultBump = 0; + + if ( !bBump ) + { + vResultBump = float4(0, 0, 1, 1); + } + +#if SEAMLESS + + vResultBase += vWeights.x * basetex.Sample( base, coords.zy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.x * basetex2.Sample( base2, coords.zy ); + } + if ( bBump ) + { + vResultBump += vWeights.x * bumptex.Sample( bump, coords.zy ); + } + + vResultBase += vWeights.y * basetex.Sample( base, coords.xz ); + if ( bBase2 ) + { + vResultBase2 += vWeights.y * basetex2.Sample( base2, coords.xz ); + } + if ( bBump ) + { + vResultBump += vWeights.y * bumptex.Sample( bump, coords.xz ); + } + + vResultBase += vWeights.z * basetex.Sample( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.z * basetex2.Sample( base2, coords.xy ); + } + if ( bBump ) + { + vResultBump += vWeights.z * bumptex.Sample( bump, coords.xy ); + } + +#else // not seamless + + vResultBase = basetex.Sample( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 = basetex2.Sample( base2, coords.xy ); + } + if ( bBump ) + { + vResultBump = bumptex.Sample( bump, coords.xy ); + } +#endif + +} + +float4 Cubic( float v ) +{ + float4 n = float4( 1.0f, 2.0f, 3.0f, 4.0f ) - v; + float4 s = n * n * n; + float x = s.x; + float y = s.y - 4.0f * s.x; + float z = s.z - 4.0f * s.y + 6.0f * s.x; + float w = 6.0 - x - y - z; + return float4( x, y, z, w ) * ( 1.0f / 6.0f ); +} + +float4 SampleBicubic( Texture2D tex, SamplerState samp, float2 coords ) +{ + uint width, height, levels; + tex.GetDimensions( 0, width, height, levels ); + float2 texSize = float2( width, height ); + float2 invTexSize = 1.0f / texSize; + + coords = coords * texSize - 0.5f; + + float2 fxy = frac( coords ); + coords -= fxy; + + float4 xcubic = Cubic( fxy.x ); + float4 ycubic = Cubic( fxy.y ); + + float4 c = coords.xxyy + float2( -0.5f, 1.0f ).xyxy; + + float4 s = float4( xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw ); + float4 offset = c + float4( xcubic.yw, ycubic.yw ) / s; + + float4 sample0 = tex.Sample( samp, offset.xz ); + float4 sample1 = tex.Sample( samp, offset.yz ); + float4 sample2 = tex.Sample( samp, offset.xw ); + float4 sample3 = tex.Sample( samp, offset.yw ); + + float sx = s.x / ( s.x + s.y ); + float sy = s.z / ( s.z + s.w ); + + return lerp( lerp( sample3, sample2, sx ), lerp( sample1, sample0, sx ), sy ); +} + + +float3 LightMapSample( Texture2D LightmapTex, SamplerState LightmapSampler, float2 vTexCoord ) +{ +# if ( !defined( _X360 ) || !defined( USE_32BIT_LIGHTMAPS_ON_360 ) ) + { + float3 sample = LightmapTex.Sample( LightmapSampler, vTexCoord ).xyz; + //float3 sample = SampleBicubic( LightmapTex, LightmapSampler, vTexCoord ).xyz; + + return sample; + } +# else + { +# if 0 //1 for cheap sampling, 0 for accurate scaling from the individual samples + { + float4 sample = LightmapTex.Sample( LightmapSampler, vTexCoord ); + + return sample.rgb * sample.a; + } +# else + { + float4 Weights; + float4 samples_0; //no arrays allowed in inline assembly + float4 samples_1; + float4 samples_2; + float4 samples_3; + + asm { + tfetch2D samples_0, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_1, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_2, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_3, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + + getWeights2D Weights, vTexCoord.xy, LightmapSampler + }; + + Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); + + float3 result; + result.rgb = samples_0.rgb * (samples_0.a * Weights.x); + result.rgb += samples_1.rgb * (samples_1.a * Weights.y); + result.rgb += samples_2.rgb * (samples_2.a * Weights.z); + result.rgb += samples_3.rgb * (samples_3.a * Weights.w); + + return result; + } +# endif + } +# endif +} \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/common_pragmas.h b/materialsystem/stdshadersdx11/common_pragmas.h new file mode 100644 index 0000000..d2cf3e1 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_pragmas.h @@ -0,0 +1,38 @@ +//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// +// +// Purpose: Common shader compiler pragmas +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_PRAGMAS_H_ +#define COMMON_PRAGMAS_H_ + +// +// Validated shader models: +// +// SHADER_MODEL_VS_1_1 +// SHADER_MODEL_VS_2_0 +// SHADER_MODEL_VS_3_0 +// +// SHADER_MODEL_PS_1_1 +// SHADER_MODEL_PS_1_4 +// SHADER_MODEL_PS_2_0 +// SHADER_MODEL_PS_2_B +// SHADER_MODEL_PS_3_0 +// +// +// +// Platforms: +// +// PC +// _X360 +// + +// Special pragmas silencing common warnings +#pragma warning ( disable : 3557 ) // warning X3557: Loop only executes for N iteration(s), forcing loop to unroll +#pragma warning ( disable : 3595 ) // warning X3595: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused +#pragma warning ( disable : 3596 ) // warning X3596: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused +#pragma warning ( disable : 4702 ) // warning X4702: complement opportunity missed because input result WAS clamped from 0 to 1 + +#endif //#ifndef COMMON_PRAGMAS_H_ diff --git a/materialsystem/stdshadersdx11/common_ps_fxc.h b/materialsystem/stdshadersdx11/common_ps_fxc.h new file mode 100644 index 0000000..0d1cf65 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_ps_fxc.h @@ -0,0 +1,837 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +// Purpose: Common pixel shader code +// +// NOTE: This file expects that you have included common_cbuffers_fxc.h and +// defined the lighting cbuffer before including this file! +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_PS_FXC_H_ +#define COMMON_PS_FXC_H_ + +#include "common_fxc.h" + +// Put global skip commands here. . make sure and check that the appropriate vars are defined +// so these aren't used on the wrong shaders! + +// -------------------------------------------------------------------------------- +// HDR should never be enabled if we don't aren't running in float or integer HDR mode. +// SKIP: defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// -------------------------------------------------------------------------------- +// We don't ever write water fog to dest alpha if we aren't doing water fog. +// SKIP: defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// -------------------------------------------------------------------------------- +// We don't need fog in the pixel shader if we aren't in float fog mode2 +// NOSKIP: defined $HDRTYPE && defined $HDRENABLED && defined $PIXELFOGTYPE && $HDRTYPE != HDR_TYPE_FLOAT && $FOGTYPE != 0 +// -------------------------------------------------------------------------------- +// We don't do HDR and LIGHTING_PREVIEW at the same time since it's running LDR in hammer. +// SKIP: defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// -------------------------------------------------------------------------------- +// Ditch all fastpath attempts if we are doing LIGHTING_PREVIEW. +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// -------------------------------------------------------------------------------- +// Ditch flashlight depth when flashlight is disabled +// SKIP: ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// -------------------------------------------------------------------------------- + +// System defined pixel shader constants + +#define sampler SamplerState + +// NOTE: w == 1.0f / (Dest alpha compressed depth range). +#define OO_DESTALPHA_DEPTH_RANGE (cLinearFogColor.w) + +// Linear and gamma light scale values +#define LINEAR_LIGHT_SCALE cToneMappingScale.x +#define LIGHT_MAP_SCALE cToneMappingScale.y +#define ENV_MAP_SCALE cToneMappingScale.z +#define GAMMA_LIGHT_SCALE cToneMappingScale.w + +// Flashlight constants +#define flFlashlightNoLambertValue cFlashlightColor.w // This is either 0.0 or 2.0 + +#define HDR_INPUT_MAP_SCALE 16.0f + +#define TONEMAP_SCALE_NONE 0 +#define TONEMAP_SCALE_LINEAR 1 +#define TONEMAP_SCALE_GAMMA 2 + +#define PIXEL_FOG_TYPE_NONE -1 //MATERIAL_FOG_NONE is handled by PIXEL_FOG_TYPE_RANGE, this is for explicitly disabling fog in the shader +#define PIXEL_FOG_TYPE_RANGE 0 //range+none packed together in ps2b. Simply none in ps20 (instruction limits) +#define PIXEL_FOG_TYPE_HEIGHT 1 + +// If you change these, make the corresponding change in hardwareconfig.cpp +#define NVIDIA_PCF_POISSON 0 +#define ATI_NOPCF 1 +#define ATI_NO_PCF_FETCH4 2 +#define NVIDIA_GAUSSIAN 3 +#define NVIDIA_BOX_3X 4 +#define NVIDIA_RAWZ 5 +#define NVIDIA_RAWZ_ONETAP 6 +#define TEST 7 + +/* +// unused +HALF Luminance( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.30f), HALF_CONSTANT(0.59f), HALF_CONSTANT(0.11f) ) ); +} +*/ + +/* +// unused +HALF LuminanceScaled( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.30f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.59f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.11f) / MAX_HDR_OVERBRIGHT ) ); +} +*/ + +/* +// unused +HALF AvgColor( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); +} +*/ + +/* +// unused +HALF4 DiffuseBump( sampler lightmapSampler, + float2 lightmapTexCoord1, + float2 lightmapTexCoord2, + float2 lightmapTexCoord3, + HALF3 normal ) +{ + HALF3 lightmapColor1 = tex2D( lightmapSampler, lightmapTexCoord1 ); + HALF3 lightmapColor2 = tex2D( lightmapSampler, lightmapTexCoord2 ); + HALF3 lightmapColor3 = tex2D( lightmapSampler, lightmapTexCoord3 ); + + HALF3 diffuseLighting; + diffuseLighting = saturate( dot( normal, bumpBasis[0] ) ) * lightmapColor1 + + saturate( dot( normal, bumpBasis[1] ) ) * lightmapColor2 + + saturate( dot( normal, bumpBasis[2] ) ) * lightmapColor3; + + return HALF4( diffuseLighting, LuminanceScaled( diffuseLighting ) ); +} +*/ + + +/* +// unused +HALF Fresnel( HALF3 normal, + HALF3 eye, + HALF2 scaleBias ) +{ + HALF fresnel = HALF_CONSTANT(1.0f) - dot( normal, eye ); + fresnel = pow( fresnel, HALF_CONSTANT(5.0f) ); + + return fresnel * scaleBias.x + scaleBias.y; +} +*/ + +/* +// unused +HALF4 GetNormal( sampler normalSampler, + float2 normalTexCoord ) +{ + HALF4 normal = tex2D( normalSampler, normalTexCoord ); + normal.rgb = HALF_CONSTANT(2.0f) * normal.rgb - HALF_CONSTANT(1.0f); + + return normal; +} +*/ + +// Needs to match NormalDecodeMode_t enum in imaterialsystem.h +#define NORM_DECODE_NONE 0 +#define NORM_DECODE_ATI2N 1 +#define NORM_DECODE_ATI2N_ALPHA 2 + +float4 DecompressNormal( Texture2D NormalTex, SamplerState NormalSampler, float2 tc, int nDecompressionMode, Texture2D AlphaTexture, SamplerState AlphaSampler ) +{ + float4 normalTexel = NormalTex.Sample( NormalSampler, tc ); + float4 result; + + if ( nDecompressionMode == NORM_DECODE_NONE ) + { + result = float4(normalTexel.xyz * 2.0f - 1.0f, normalTexel.a ); + } + else if ( nDecompressionMode == NORM_DECODE_ATI2N ) + { + result.xy = normalTexel.xy * 2.0f - 1.0f; + result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); + result.a = 1.0f; + } + else // ATI2N plus ATI1N for alpha + { + result.xy = normalTexel.xy * 2.0f - 1.0f; + result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); + result.a = AlphaTexture.Sample( AlphaSampler, tc ).x; // Note that this comes in on the X channel + } + + return result; +} + +float4 DecompressNormal( Texture2D NormalTex, SamplerState NormalSampler, float2 tc, int nDecompressionMode ) +{ + return DecompressNormal( NormalTex, NormalSampler, tc, nDecompressionMode, NormalTex, NormalSampler ); +} + + +HALF3 NormalizeWithCubemap( TextureCube normalizeTexture, SamplerState normalizeSampler, HALF3 input ) +{ +// return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f; + return normalizeTexture.Sample( normalizeSampler, input ); +} + +/* +HALF4 EnvReflect( sampler envmapSampler, + sampler normalizeSampler, + HALF3 normal, + float3 eye, + HALF2 fresnelScaleBias ) +{ + HALF3 normEye = NormalizeWithCubemap( normalizeSampler, eye ); + HALF fresnel = Fresnel( normal, normEye, fresnelScaleBias ); + HALF3 reflect = CalcReflectionVectorUnnormalized( normal, eye ); + return texCUBE( envmapSampler, reflect ); +} +*/ + +// Vectorized smoothstep for doing three smoothsteps at once. Used by uberlight +float3 smoothstep3( float3 edge0, float3 edge1, float3 OneOverWidth, float3 x ) +{ + x = saturate((x - edge0) * OneOverWidth); // Scale, bias and saturate x to the range of zero to one + return x*x*(3-2*x); // Evaluate polynomial +} + +float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange ) +{ +#if 0 + // This version is what you use if you want a line-integral through the water for water fog. +// float flDepthFromWater = flWaterZ - flWorldPosZ + 2.0f; // hackity hack . .this is for the DF_FUDGE_UP in view_scene.cpp + float flDepthFromWater = flWaterZ - flWorldPosZ; + + // if flDepthFromWater < 0, then set it to 0 + // This is the equivalent of moving the vert to the water surface if it's above the water surface + // We'll do this with the saturate at the end instead. +// flDepthFromWater = max( 0.0f, flDepthFromWater ); + + // Calculate the ratio of water fog to regular fog (ie. how much of the distance from the viewer + // to the vert is actually underwater. + float flDepthFromEye = flEyePosZ - flWorldPosZ; + //float f = (flDepthFromWater / flDepthFromEye) * flProjPosZ; + float f = saturate(flDepthFromWater * (1.0/flDepthFromEye)); + + // $tmp.w is now the distance that we see through water. + //return saturate( f * flFogOORange ); + return saturate(f * flProjPosZ * flFogOORange); +#else + // This version is simply using the depth of the water to determine fog factor, + // which is cheaper than doing the line integral and also fixes some problems with having + // a hard line on the shore when the water surface is viewed tangentially. + // hackity hack . .the 2.0 is for the DF_FUDGE_UP in view_scene.cpp + return saturate( ( flWaterZ - flWorldPosZ - 2.0f ) * flFogOORange ); +#endif +} + +float CalcRangeFog( const float flEyeDist, const float flFogStart, const float flFogEnd, const float flFogMaxDensity ) +{ + return min( flFogMaxDensity, ( flFogEnd - flEyeDist ) / ( flFogEnd - flFogStart ) ); +} + +float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flEyeDist ) +{ + float retVal; + if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + { + retVal = 0.0f; + } + if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //range fog, or no fog depending on fog parameters + { + retVal = CalcRangeFog( flEyeDist, fogParams.x, fogParams.y, fogParams.z ); + } + else if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) //height fog + { + retVal = CalcWaterFogAlpha( fogParams.w, flEyePosZ, flWorldPosZ, flEyeDist, fogParams.x ); + } + + return retVal; +} + +//g_FogParams not defined by default, but this is the same layout for every shader that does define it +#define g_FogStart c.g_FogParams.x +#define g_FogEnd c.g_FogParams.y +#define g_FogMaxDensity c.g_FogParams.z +#define g_WaterZ c.g_FogParams.w + +float3 BlendPixelFog( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, const int iPIXELFOGTYPE ) +{ + if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //either range fog or no fog depending on fog parameters and whether this is ps20 or ps2b + { +# if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + pixelFogFactor = saturate( pixelFogFactor ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog +# else + return vShaderColor; +# endif + } + else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + { + return lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + } + else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + { + return vShaderColor; + } +} + +#if 0 +// i have NO CLUE why shader model 2.0b doesn't like result.g here +// because this is the EXACT SAME in other branches (ASW and Source 2013) +// and it works PERFECTLY FINE in those, so kill me now please +// actually it might also be the damn dx_proxy +//#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) && ( CONVERT_TO_SRGB != 0 ) ) +#if ( defined(SHADER_MODEL_PS_3_0) && ( CONVERT_TO_SRGB != 0 ) ) +sampler1D GammaTableSampler : register( s15 ); + +float3 SRGBOutput( const float3 vShaderColor ) +{ + //On ps2b capable hardware we always have the linear->gamma conversion table texture in sampler s15. + float3 result; + result.r = tex1D( GammaTableSampler, vShaderColor.r ).r; + result.g = tex1D( GammaTableSampler, vShaderColor.g ).r; + result.b = tex1D( GammaTableSampler, vShaderColor.b ).r; + return result; +} + +#else +#endif +#endif + +float3 SRGBOutput( const float3 vShaderColor ) +{ + return vShaderColor; //ps 1.1, 1.4, and 2.0 never do srgb conversion in the pixel shader // maybe 2.0b as well? +} + +//#endif + + +float SoftParticleDepth( float flDepth ) +{ + return 0.0f; + //return flDepth * OO_DESTALPHA_DEPTH_RANGE; +} + + +float DepthToDestAlpha( const float flProjZ ) +{ +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + return SoftParticleDepth( flProjZ ); +#else + return 1.0f; +#endif +} + + +float4 FinalOutput( const float4 vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, float4 pixelFogColor, + const int iTONEMAP_SCALE_TYPE, float4 toneMappingScale = float4(1, 1, 1, 1), const bool bWriteDepthToDestAlpha = false, const float flProjZ = 1.0f ) +{ + float4 result; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb = vShaderColor.rgb * toneMappingScale.x; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb = vShaderColor.rgb * toneMappingScale.w; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_NONE ) + { + result.rgb = vShaderColor.rgb; + } + + if( bWriteDepthToDestAlpha ) + result.a = DepthToDestAlpha( flProjZ ); + else + result.a = vShaderColor.a; + + result.rgb = BlendPixelFog( result.rgb, pixelFogFactor, pixelFogColor.rgb, iPIXELFOGTYPE ); + +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion +#endif + + return result; +} + +struct LPREVIEW_PS_OUT +{ + float4 color : COLOR0; + float4 normal : COLOR1; + float4 position : COLOR2; + float4 flags : COLOR3; +}; + +LPREVIEW_PS_OUT FinalOutput( const LPREVIEW_PS_OUT vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, float4 fogColor, const int iTONEMAP_SCALE_TYPE ) +{ + LPREVIEW_PS_OUT result; + result.color = FinalOutput( vShaderColor.color, pixelFogFactor, iPIXELFOGTYPE, fogColor, iTONEMAP_SCALE_TYPE ); + result.normal.rgb = SRGBOutput( vShaderColor.normal.rgb ); + result.normal.a = vShaderColor.normal.a; + + result.position.rgb = SRGBOutput( vShaderColor.position.rgb ); + result.position.a = vShaderColor.position.a; + + result.flags.rgb = SRGBOutput( vShaderColor.flags.rgb ); + result.flags.a = vShaderColor.flags.a; + + return result; +} + + + + +float RemapValClamped( float val, float A, float B, float C, float D) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + + return C + (D - C) * cVal; +} + + +//===================================================================================// +// This is based on Natasha Tatarchuk's Parallax Occlusion Mapping (ATI) +//===================================================================================// +// INPUT: +// inTexCoord: +// the texcoord for the height/displacement map before parallaxing +// +// vParallax: +// Compute initial parallax displacement direction: +// float2 vParallaxDirection = normalize( vViewTS.xy ); +// float fLength = length( vViewTS ); +// float fParallaxLength = sqrt( fLength * fLength - vViewTS.z * vViewTS.z ) / vViewTS.z; +// Out.vParallax = vParallaxDirection * fParallaxLength * fProjectedBumpHeight; +// +// vNormal: +// tangent space normal +// +// vViewW: +// float3 vViewW = /*normalize*/(mul( matViewInverse, float4( 0, 0, 0, 1)) - inPosition ); +// +// OUTPUT: +// the new texcoord after parallaxing +float2 CalcParallaxedTexCoord( float2 inTexCoord, float2 vParallax, float3 vNormal, + float3 vViewW, Texture2D HeightMapTex, SamplerState HeightMapSampler ) +{ + const int nMinSamples = 8; + const int nMaxSamples = 50; + + // Normalize the incoming view vector to avoid artifacts: +// vView = normalize( vView ); + vViewW = normalize( vViewW ); +// vLight = normalize( vLight ); + + // Change the number of samples per ray depending on the viewing angle + // for the surface. Oblique angles require smaller step sizes to achieve + // more accurate precision + int nNumSteps = (int) lerp( nMaxSamples, nMinSamples, dot( vViewW, vNormal ) ); + + float4 cResultColor = float4( 0, 0, 0, 1 ); + + //===============================================// + // Parallax occlusion mapping offset computation // + //===============================================// + float fCurrHeight = 0.0; + float fStepSize = 1.0 / (float) nNumSteps; + float fPrevHeight = 1.0; + float fNextHeight = 0.0; + + int nStepIndex = 0; +// bool bCondition = true; + + float2 dx = ddx( inTexCoord ); + float2 dy = ddy( inTexCoord ); + + float2 vTexOffsetPerStep = fStepSize * vParallax; + + float2 vTexCurrentOffset = inTexCoord; + float fCurrentBound = 1.0; + + float x = 0; + float y = 0; + float xh = 0; + float yh = 0; + + float2 texOffset2 = 0; + + bool bCondition = true; + while ( bCondition == true && nStepIndex < nNumSteps ) + { + vTexCurrentOffset -= vTexOffsetPerStep; + + fCurrHeight = HeightMapTex.SampleGrad( HeightMapSampler, vTexCurrentOffset, dx, dy ).r; + + fCurrentBound -= fStepSize; + + if ( fCurrHeight > fCurrentBound ) + { + x = fCurrentBound; + y = fCurrentBound + fStepSize; + xh = fCurrHeight; + yh = fPrevHeight; + + texOffset2 = vTexCurrentOffset - vTexOffsetPerStep; + + bCondition = false; + } + else + { + nStepIndex++; + fPrevHeight = fCurrHeight; + } + + } // End of while ( bCondition == true && nStepIndex > -1 )#else + + fCurrentBound -= fStepSize; + + float fParallaxAmount; + float numerator = (x * (y - yh) - y * (x - xh)); + float denomenator = ((y - yh) - (x - xh)); + // avoid NaN generation + if( ( numerator == 0.0f ) && ( denomenator == 0.0f ) ) + { + fParallaxAmount = 0.0f; + } + else + { + fParallaxAmount = numerator / denomenator; + } + + float2 vParallaxOffset = vParallax * (1 - fParallaxAmount ); + + // Sample the height at the next possible step: + fNextHeight = HeightMapTex.SampleGrad( HeightMapSampler, texOffset2, dx, dy ).r; + + // Original offset: + float2 texSampleBase = inTexCoord - vParallaxOffset; + + return texSampleBase; + +#if 0 + cResultColor.rgb = ComputeDiffuseColor( texSampleBase, vLight ); + + float fBound = 1.0 - fStepSize * nStepIndex; + if ( fNextHeight < fCurrentBound ) +// if( 0 ) + { + //void DoIteration( in float2 vParallaxJittered, in float3 vLight, inout float4 cResultColor ) + //cResultColor.rgb = float3(1,0,0); + DoIteration( vParallax + vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + DoIteration( vParallax - vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + DoIteration( vParallax + float2( -vPixelSize.x, vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + DoIteration( vParallax + float2( vPixelSize.x, -vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + + cResultColor.rgb /= 5; +// cResultColor.rgb = float3( 1.0f, 0.0f, 0.0f ); + } // End of if ( fNextHeight < fCurrentBound ) + +#if DOSHADOWS + { + //============================================// + // Soft shadow and self-occlusion computation // + //============================================// + // Compute the blurry shadows (note that this computation takes into + // account self-occlusion for shadow computation): + float sh0 = tex2D( sNormalMap, texSampleBase).w; + float shA = (tex2D( sNormalMap, texSampleBase + inXY * 0.88 ).w - sh0 - 0.88 ) * 1 * fShadowSoftening; + float sh9 = (tex2D( sNormalMap, texSampleBase + inXY * 0.77 ).w - sh0 - 0.77 ) * 2 * fShadowSoftening; + float sh8 = (tex2D( sNormalMap, texSampleBase + inXY * 0.66 ).w - sh0 - 0.66 ) * 4 * fShadowSoftening; + float sh7 = (tex2D( sNormalMap, texSampleBase + inXY * 0.55 ).w - sh0 - 0.55 ) * 6 * fShadowSoftening; + float sh6 = (tex2D( sNormalMap, texSampleBase + inXY * 0.44 ).w - sh0 - 0.44 ) * 8 * fShadowSoftening; + float sh5 = (tex2D( sNormalMap, texSampleBase + inXY * 0.33 ).w - sh0 - 0.33 ) * 10 * fShadowSoftening; + float sh4 = (tex2D( sNormalMap, texSampleBase + inXY * 0.22 ).w - sh0 - 0.22 ) * 12 * fShadowSoftening; + + // Compute the actual shadow strength: + float fShadow = 1 - max( max( max( max( max( max( shA, sh9 ), sh8 ), sh7 ), sh6 ), sh5 ), sh4 ); + + cResultColor.rgb *= fShadow * 0.6 + 0.4; + } +#endif + + return cResultColor; +#endif +} + + +//======================================// +// HSL Color space conversion routines // +//======================================// + +#define HUE 0 +#define SATURATION 1 +#define LIGHTNESS 2 + +// Convert from RGB to HSL color space +float4 RGBtoHSL( float4 inColor ) +{ + float h, s; + float flMax = max( inColor.r, max( inColor.g, inColor.b ) ); + float flMin = min( inColor.r, min( inColor.g, inColor.b ) ); + + float l = (flMax + flMin) / 2.0f; + + if (flMax == flMin) // achromatic case + { + s = h = 0; + } + else // chromatic case + { + // Next, calculate the hue + float delta = flMax - flMin; + + // First, calculate the saturation + if (l < 0.5f) // If we're in the lower hexcone + { + s = delta/(flMax + flMin); + } + else + { + s = delta/(2 - flMax - flMin); + } + + if ( inColor.r == flMax ) + { + h = (inColor.g - inColor.b)/delta; // color between yellow and magenta + } + else if ( inColor.g == flMax ) + { + h = 2 + (inColor.b - inColor.r)/delta; // color between cyan and yellow + } + else // blue must be max + { + h = 4 + (inColor.r - inColor.g)/delta; // color between magenta and cyan + } + + h *= 60.0f; + + if (h < 0.0f) + { + h += 360.0f; + } + + h /= 360.0f; + } + + return float4 (h, s, l, 1.0f); +} + +float HueToRGB( float v1, float v2, float vH ) +{ + float fResult = v1; + + vH = fmod (vH + 1.0f, 1.0f); + + if ( ( 6.0f * vH ) < 1.0f ) + { + fResult = ( v1 + ( v2 - v1 ) * 6.0f * vH ); + } + else if ( ( 2.0f * vH ) < 1.0f ) + { + fResult = ( v2 ); + } + else if ( ( 3.0f * vH ) < 2.0f ) + { + fResult = ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3.0f ) - vH ) * 6.0f ); + } + + return fResult; +} + +// Convert from HSL to RGB color space +float4 HSLtoRGB( float4 hsl ) +{ + float r, g, b; + float h = hsl[HUE]; + float s = hsl[SATURATION]; + float l = hsl[LIGHTNESS]; + + if ( s == 0 ) + { + r = g = b = l; + } + else + { + float v1, v2; + + if ( l < 0.5f ) + v2 = l * ( 1.0f + s ); + else + v2 = ( l + s ) - ( s * l ); + + v1 = 2 * l - v2; + + r = HueToRGB( v1, v2, h + ( 1.0f / 3.0f ) ); + g = HueToRGB( v1, v2, h ); + b = HueToRGB( v1, v2, h - ( 1.0f / 3.0f ) ); + } + + return float4( r, g, b, 1.0f ); +} + + +// texture combining modes for combining base and detail/basetexture2 +#define TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2 0 // original mode +#define TCOMBINE_RGB_ADDITIVE 1 // base.rgb+detail.rgb*fblend +#define TCOMBINE_DETAIL_OVER_BASE 2 +#define TCOMBINE_FADE 3 // straight fade between base and detail. +#define TCOMBINE_BASE_OVER_DETAIL 4 // use base alpha for blend over detail +#define TCOMBINE_RGB_ADDITIVE_SELFILLUM 5 // add detail color post lighting +#define TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6 +#define TCOMBINE_MOD2X_SELECT_TWO_PATTERNS 7 // use alpha channel of base to select between mod2x channels in r+a of detail +#define TCOMBINE_MULTIPLY 8 +#define TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA 9 // use alpha channel of detail to mask base +#define TCOMBINE_SSBUMP_BUMP 10 // use detail to modulate lighting as an ssbump +#define TCOMBINE_SSBUMP_NOBUMP 11 // detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11 + +float4 TextureCombine( float4 baseColor, float4 detailColor, int combine_mode, + float fBlendFactor ) +{ + if ( combine_mode == TCOMBINE_MOD2X_SELECT_TWO_PATTERNS) + { + float3 dc=lerp(detailColor.r,detailColor.a, baseColor.a); + baseColor.rgb*=lerp(float3(1,1,1),2.0*dc,fBlendFactor); + } + if ( combine_mode == TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2) + baseColor.rgb*=lerp(float3(1,1,1),2.0*detailColor.rgb,fBlendFactor); + if ( combine_mode == TCOMBINE_RGB_ADDITIVE ) + baseColor.rgb += fBlendFactor * detailColor.rgb; + if ( combine_mode == TCOMBINE_DETAIL_OVER_BASE ) + { + float fblend=fBlendFactor * detailColor.a; + baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend); + } + if ( combine_mode == TCOMBINE_FADE ) + { + baseColor = lerp( baseColor, detailColor, fBlendFactor); + } + if ( combine_mode == TCOMBINE_BASE_OVER_DETAIL ) + { + float fblend=fBlendFactor * (1-baseColor.a); + baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend ); + baseColor.a = detailColor.a; + } + if ( combine_mode == TCOMBINE_MULTIPLY ) + { + baseColor = lerp( baseColor, baseColor*detailColor, fBlendFactor); + } + + if (combine_mode == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA ) + { + baseColor.a = lerp( baseColor.a, baseColor.a*detailColor.a, fBlendFactor ); + } + if ( combine_mode == TCOMBINE_SSBUMP_NOBUMP ) + { + baseColor.rgb = baseColor.rgb * dot( detailColor.rgb, 2.0/3.0 ); + } + return baseColor; +} + +bool GreaterEqualAlphaTest( float alpha, float ref ) +{ + return alpha >= ref; +} + +bool GreaterAlphaTest( float alpha, float ref ) +{ + return alpha > ref; +} + +float3 lerp5(float3 f1, float3 f2, float i1, float i2, float x) +{ + return f1+(f2-f1)*(x-i1)/(i2-i1); +} + +float3 TextureCombinePostLighting( float3 lit_baseColor, float4 detailColor, int combine_mode, + float fBlendFactor ) +{ + if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM ) + lit_baseColor += fBlendFactor * detailColor.rgb; + if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE ) + { + // fade in an unusual way - instead of fading out color, remap an increasing band of it from + // 0..1 + //if (fBlendFactor > 0.5) + // lit_baseColor += min(1, (1.0/fBlendFactor)*max(0, detailColor.rgb-(1-fBlendFactor) ) ); + //else + // lit_baseColor += 2*fBlendFactor*2*max(0, detailColor.rgb-.5); + + float f = fBlendFactor - 0.5; + float fMult = (f >= 0) ? 1.0/fBlendFactor : 4*fBlendFactor; + float fAdd = (f >= 0) ? 1.0-fMult : -0.5*fMult; + lit_baseColor += saturate(fMult * detailColor.rgb + fAdd); + } + return lit_baseColor; +} + +//NOTE: On X360. fProjZ is expected to be pre-reversed for cheaper math here in the pixel shader +float DepthFeathering( Texture2D DepthTex, SamplerState DepthSampler, const float2 vScreenPos, float fProjZ, float fProjW, float4 vDepthBlendConstants ) +{ +# if ( !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) ) //minimum requirement of ps2b + { + float flFeatheredAlpha; + float2 flDepths; +#define flSceneDepth flDepths.x +#define flSpriteDepth flDepths.y + +# if ( defined( _X360 ) ) + { + //Get depth from the depth texture. Need to sample with the offset of (0.5, 0.5) to fix rounding errors + asm { + tfetch2D flDepths.x___, vScreenPos, DepthSampler, OffsetX=0.5, OffsetY=0.5, MinFilter=point, MagFilter=point, MipFilter=point + }; + +# if( !defined( REVERSE_DEPTH_ON_X360 ) ) + flSceneDepth = 1.0f - flSceneDepth; +# endif + + //get the sprite depth into the same range as the texture depth + flSpriteDepth = fProjZ / fProjW; + + //unproject to get at the pre-projection z. This value is much more linear than depth + flDepths = vDepthBlendConstants.z / flDepths; + flDepths = vDepthBlendConstants.y - flDepths; + + flFeatheredAlpha = flSceneDepth - flSpriteDepth; + flFeatheredAlpha *= vDepthBlendConstants.x; + flFeatheredAlpha = saturate( flFeatheredAlpha ); + } +# else + { + flSceneDepth = DepthTex.Sample( DepthSampler, vScreenPos ).a; // PC uses dest alpha of the frame buffer + flSpriteDepth = SoftParticleDepth( fProjZ ); + + flFeatheredAlpha = abs(flSceneDepth - flSpriteDepth) * vDepthBlendConstants.x; + flFeatheredAlpha = max( smoothstep( 0.75f, 1.0f, flSceneDepth ), flFeatheredAlpha ); //as the sprite approaches the edge of our compressed depth space, the math stops working. So as the sprite approaches the far depth, smoothly remove feathering. + flFeatheredAlpha = saturate( flFeatheredAlpha ); + } +# endif + +#undef flSceneDepth +#undef flSpriteDepth + + return flFeatheredAlpha; + } +# else + { + return 1.0f; + } +# endif +} + +#endif //#ifndef COMMON_PS_FXC_H_ diff --git a/materialsystem/stdshadersdx11/common_sky_fxc.h b/materialsystem/stdshadersdx11/common_sky_fxc.h new file mode 100644 index 0000000..874842e --- /dev/null +++ b/materialsystem/stdshadersdx11/common_sky_fxc.h @@ -0,0 +1,21 @@ +//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_SKY_FXC_H_ +#define COMMON_SKY_FXC_H_ + +struct Sky_t +{ + // Vertex shader + float4 vTextureSizeInfo; + float4 mBaseTexCoordTransform[2]; + + // Pixel shader + float4 InputScale; +}; + +#endif //#ifndef COMMON_SKY_FXC_H_ diff --git a/materialsystem/stdshadersdx11/common_vertexlitgeneric_dx11.h b/materialsystem/stdshadersdx11/common_vertexlitgeneric_dx11.h new file mode 100644 index 0000000..9af4482 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_vertexlitgeneric_dx11.h @@ -0,0 +1,420 @@ +#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ +#define COMMON_VERTEXLITGENERIC_DX9_H_ + +#include "common_ps_fxc.h" + +#define cOverbright 2.0f +#define cOOOverbright 0.5f + +#define LIGHTTYPE_NONE 0 +#define LIGHTTYPE_SPOT 1 +#define LIGHTTYPE_POINT 2 +#define LIGHTTYPE_DIRECTIONAL 3 + +// Better suited to Pixel shader models, 11 instructions in pixel shader +float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 linearColor, nSquared = worldNormal * worldNormal; + //float3 isNegative = ( worldNormal >= 0.0 ) ? 0 : nSquared; + //float3 isPositive = ( worldNormal >= 0.0 ) ? nSquared : 0; + + float3 isNegative = ( worldNormal < 0.0 ); + float3 isPositive = 1-isNegative; + + isNegative *= nSquared; + isPositive *= nSquared; + + linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] + + isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] + + isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5]; + + return linearColor; +} + +// Better suited to Vertex shader models +// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad) +float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + float3 linearColor; + linearColor = nSquared.x * cAmbientCube[isNegative.x] + + nSquared.y * cAmbientCube[isNegative.y+2] + + nSquared.z * cAmbientCube[isNegative.z+4]; + return linearColor; +} + +float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ +#if defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) || defined(SHADER_MODEL_PS_4_0) + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#else + return PixelShaderAmbientLight( worldNormal, cAmbientCube ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Compute scalar diffuse term with various optional tweaks such as +// Half Lambert and ambient occlusion +//----------------------------------------------------------------------------- +float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in Texture2D lightWarpTexture, in sampler lightWarpSampler ) +{ + float fResult; + + float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range) + + if ( bHalfLambert ) + { + fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range + + if ( !bDoLightingWarp ) + { + fResult *= fResult; // Square + } + } + else + { + fResult = saturate( NDotL ); // Saturate pure Lambertian term + } + + if ( bDoAmbientOcclusion ) + { + // Raise to higher powers for darker AO values +// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion ); +// result *= pow( NDotL * 0.5 + 0.5, fAOPower ); + fResult *= fAmbientOcclusion; + } + + float3 fOut = float3( fResult, fResult, fResult ); + if ( bDoLightingWarp ) + { + fOut = 2.0f * lightWarpTexture.Sample( lightWarpSampler, fResult ).x; + } + + return fOut; +} + +float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal, + in Texture2D NormalizeTexture, in sampler NormalizeSampler, + const float3 vPosition, const float3 vColor, const bool bHalfLambert, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in Texture2D lightWarpTexture, in sampler lightWarpSampler ) +{ +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0)) + float3 lightDir = normalize( vPosition - worldPos ); +#else + float3 lightDir = NormalizeWithCubemap( NormalizeTexture, NormalizeSampler, vPosition - worldPos ); +#endif + return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpTexture, lightWarpSampler ); +} + +float3 PixelShaderGetLightVector( const float3 worldPos, LightInfo lightInfo[4], int nLightIndex ) +{ + return normalize( lightInfo[nLightIndex].pos - worldPos ); +} + +float3 PixelShaderGetLightColor( LightInfo lightInfo[4], int nLightIndex ) +{ + return lightInfo[nLightIndex].color.rgb; +} + + +void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in Texture2D specularWarpTexture, + in sampler specularWarpSampler, const float fFresnel, + const float3 color, const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + rimLighting = float3(0.0f, 0.0f, 0.0f); + + float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal + float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent + + // Optionally warp as function of scalar specular and fresnel + if ( bDoSpecularWarp ) + specularLighting *= specularWarpTexture.Sample( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } + + specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + specularLighting *= color; // Modulate with light color + + if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion + specularLighting *= fAmbientOcclusion; + + if ( bDoRimLighting ) // Optionally do rim lighting + { + rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent + rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + rimLighting *= color; // Modulate with light color + } +} + +// Traditional fresnel term approximation +float Fresnel( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = 1-saturate( dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + return fresnel * fresnel; // Square for a more subtle look +} + +// Traditional fresnel term approximation which uses 4th power (square twice) +float Fresnel4( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = 1-saturate( dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + fresnel = fresnel * fresnel; // Square + return fresnel * fresnel; // Square again for a more subtle look +} + + +// +// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function +// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between +// low and mid while the 0.5 to 1 range blends between mid and high +// +// | +// | . M . . . H +// | . +// L +// | +// +---------------- +// 0 1 +// +float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges ) +{ + float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel + + if ( f > 0.5f ) + result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values + else + result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values + + return result; +} + +void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float fAtten, const float3 vLightColor, const float3 vLightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in Texture2D specularWarpTexture, + in sampler specularWarpSampler, float fFresnel, + const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + // Compute Specular and rim terms + SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent, + vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpTexture, specularWarpSampler, fFresnel, vLightColor * fAtten, + bDoRimLighting, fRimExponent, specularLighting, rimLighting ); +} + +float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + in Texture2D NormalizeTexture, in sampler NormalizeSampler, const int nNumLights, LightInfo lightInfo[4], + const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in Texture2D lightWarpTexture, in sampler lightWarpSampler ) +{ + float3 linearColor = 0.0f; + + if ( bStaticLight ) + { + // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright + // need to get it into + // linear space so that we can do adds. + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if ( bAmbientLight ) + { + float3 ambient = AmbientLight( worldNormal, cAmbientCube ); + + if ( bDoAmbientOcclusion ) + ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring... + + linearColor += ambient; + } + + if ( nNumLights > 0 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeTexture, NormalizeSampler, + lightInfo[0].pos, lightInfo[0].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpTexture, lightWarpSampler ); + if ( nNumLights > 1 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeTexture, NormalizeSampler, + lightInfo[1].pos, lightInfo[1].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpTexture, lightWarpSampler ); + if ( nNumLights > 2 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeTexture, NormalizeSampler, + lightInfo[2].pos, lightInfo[2].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpTexture, lightWarpSampler ); + if ( nNumLights > 3 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, NormalizeTexture, NormalizeSampler, + lightInfo[3].pos, lightInfo[3].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpTexture, lightWarpSampler ); + } + } + } + } + + return linearColor; +} + +void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float4 lightAtten, const int nNumLights, LightInfo lightInfo[4], + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in Texture2D specularWarpTexture, + in sampler specularWarpSampler, float fFresnel, + const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + specularLighting = rimLighting = float3( 0.0f, 0.0f, 0.0f ); + float3 localSpecularTerm, localRimTerm; + + if( nNumLights > 0 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.x, PixelShaderGetLightColor( lightInfo, 0 ), + PixelShaderGetLightVector( worldPos, lightInfo, 0 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpTexture, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + if( nNumLights > 1 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.y, PixelShaderGetLightColor( lightInfo, 1 ), + PixelShaderGetLightVector( worldPos, lightInfo, 1 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpTexture, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + + if( nNumLights > 2 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.z, PixelShaderGetLightColor( lightInfo, 2 ), + PixelShaderGetLightVector( worldPos, lightInfo, 2 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpTexture, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + if( nNumLights > 3 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.w, PixelShaderGetLightColor( lightInfo, 3 ), + PixelShaderGetLightVector( worldPos, lightInfo, 3 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpTexture, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + +} + +float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel ) +{ + float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal + + return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube ); +} + +// Called directly by newer shaders or through the following wrapper for older shaders +float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + in Texture2D NormalizeTexture, in sampler NormalizeSampler, const int nNumLights, LightInfo lightInfo[4], + const bool bHalfLambert, + + // New optional/experimental parameters + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in Texture2D lightWarpTexture, in sampler lightWarpSampler ) +{ + float3 returnColor; + + // special case for no lighting + if( !bStaticLight && !bAmbientLight ) + { + returnColor = float3( 0.0f, 0.0f, 0.0f ); + } + else if( bStaticLight && !bAmbientLight ) + { + // special case for static lighting only + returnColor = GammaToLinear( staticLightingColor ); + } + else + { + float3 linearColor; + + linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor, + bStaticLight, bAmbientLight, lightAtten, + cAmbientCube, NormalizeTexture, NormalizeSampler, nNumLights, lightInfo, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpTexture, lightWarpSampler ); + + // go ahead and clamp to the linear space equivalent of overbright 2 so that we match + // everything else. +// returnColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) ); + returnColor = linearColor; + } + + return returnColor; +} + +// Returns per-pixel attenuation for all four lights +float4 PixelShaderDoLightAtten( const float3 worldPos, const int nNumLights, LightInfo lightInfo[MAX_NUM_LIGHTS] ) +{ + float4 atten = 0; + if ( nNumLights > 0 ) + { + atten.x = GetAttenForLight( worldPos, 0, lightInfo ); + if ( nNumLights > 1 ) + { + atten.y = GetAttenForLight( worldPos, 1, lightInfo ); + if ( nNumLights > 2 ) + { + atten.z = GetAttenForLight( worldPos, 2, lightInfo ); + if ( nNumLights > 3 ) + { + atten.w = GetAttenForLight( worldPos, 3, lightInfo ); + } + } + } + } + + return atten; +} + +#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ diff --git a/materialsystem/stdshadersdx11/common_vs_fxc.h b/materialsystem/stdshadersdx11/common_vs_fxc.h new file mode 100644 index 0000000..662c000 --- /dev/null +++ b/materialsystem/stdshadersdx11/common_vs_fxc.h @@ -0,0 +1,785 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: This is where all common code for vertex shaders go. +// +// NOTE: This file expects that you have included common_cbuffers_fxc.h and +// defined the transform, skinning, lighting, and misc buffers before +// including this file! +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef COMMON_VS_FXC_H_ +#define COMMON_VS_FXC_H_ + +#include "common_fxc.h" + +#define NUM_MODEL_TRANSFORMS 53 + +// Put global skip commands here. . make sure and check that the appropriate vars are defined +// so these aren't used on the wrong shaders! +// -------------------------------------------------------------------------------- +// Ditch all fastpath attemps if we are doing LIGHTING_PREVIEW. +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// -------------------------------------------------------------------------------- + + +#ifndef COMPRESSED_VERTS +// Default to no vertex compression +#define COMPRESSED_VERTS 0 +#endif + +#if ( !defined( SHADER_MODEL_VS_2_0 ) && !defined( SHADER_MODEL_VS_3_0 ) && !defined(SHADER_MODEL_VS_4_0) ) +#if COMPRESSED_VERTS == 1 +#error "Vertex compression is only for DX9 and up!" +#endif +#endif + +// We're testing 2 normal compression methods +// One compressed normals+tangents into a SHORT2 each (8 bytes total) +// The other compresses them together, into a single UBYTE4 (4 bytes total) +// FIXME: pick one or the other, compare lighting quality in important cases +#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0 +#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1 +//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 +#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 + + +#define FOGTYPE_RANGE 0 +#define FOGTYPE_HEIGHT 1 + +#define COMPILE_ERROR ( 1/0; ) + +// ---------------------------------------------------------------------- +// CONSTANT BUFFERS +// NOTE: These need to match the structs defined in ShaderDeviceDx11.h!!! +// ---------------------------------------------------------------------- + +#define cOOGamma cConstants1.x +#define cOverbright 2.0f +#define cOneThird cConstants1.z +#define cOOOverbright ( 1.0f / 2.0f ) + +#define g_nLightCount cLightCountRegister.x + +#define cFogEndOverFogRange cFogParams.x +#define cFogOne cFogParams.y +#define cFogMaxDensity cFogParams.z +#define cOOFogRange cFogParams.w + +//======================================================================================= +// Methods to decompress vertex normals +//======================================================================================= + +//----------------------------------------------------------------------------------- +// Decompress a normal from two-component compressed format +// We expect this data to come from a signed SHORT2 stream in the range of -32768..32767 +// +// -32678 and 0 are invalid encodings +// w contains the sign to use in the cross product when generating a binormal +void _DecompressShort2Tangent( float2 inputTangent, out float4 outputTangent ) +{ + float2 ztSigns = sign( inputTangent ); // sign bits for z and tangent (+1 or -1) + float2 xyAbs = abs( inputTangent ); // 1..32767 + outputTangent.xy = (xyAbs - 16384.0f) / 16384.0f; // x and y + outputTangent.z = ztSigns.x * sqrt( saturate( 1.0f - dot( outputTangent.xy, outputTangent.xy ) ) ); + outputTangent.w = ztSigns.y; +} + +//----------------------------------------------------------------------------------- +// Same code as _DecompressShort2Tangent, just one returns a float4, one a float3 +void _DecompressShort2Normal( float2 inputNormal, out float3 outputNormal ) +{ + float4 result; + _DecompressShort2Tangent( inputNormal, result ); + outputNormal = result.xyz; +} + +//----------------------------------------------------------------------------------- +// Decompress normal+tangent together +void _DecompressShort2NormalTangent( float2 inputNormal, float2 inputTangent, out float3 outputNormal, out float4 outputTangent ) +{ + // FIXME: if we end up sticking with the SHORT2 format, pack the normal and tangent into a single SHORT4 element + // (that would make unpacking normal+tangent here together much cheaper than the sum of their parts) + _DecompressShort2Normal( inputNormal, outputNormal ); + _DecompressShort2Tangent( inputTangent, outputTangent ); +} + +//======================================================================================= +// Decompress a normal and tangent from four-component compressed format +// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 +// The final vTangent.w contains the sign to use in the cross product when generating a binormal +void _DecompressUByte4NormalTangent( float4 inputNormal, + out float3 outputNormal, // {nX, nY, nZ} + out float4 outputTangent ) // {tX, tY, tZ, sign of binormal} +{ + float fOne = 1.0f; + + float4 ztztSignBits = ( inputNormal - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction + float4 xyxyAbs = abs( inputNormal - 128.0f ) - ztztSignBits; // 0..127 + float4 xyxySignBits = ( xyxyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) + float4 normTan = (abs( xyxyAbs - 64.0f ) - xyxySignBits) / 63.0f; // abs({nX, nY, tX, tY}) + outputNormal.xy = normTan.xy; // abs({nX, nY, __, __}) + outputTangent.xy = normTan.zw; // abs({tX, tY, __, __}) + + float4 xyxySigns = 1 - 2*xyxySignBits; // Convert sign bits to signs + float4 ztztSigns = 1 - 2*ztztSignBits; // ( [1,0] -> [-1,+1] ) + + outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 + outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere + outputNormal.xy *= xyxySigns.xy; // Restore x and y signs + outputNormal.z *= ztztSigns.x; // Restore z sign + + outputTangent.z = 1.0f - outputTangent.x - outputTangent.y; // Project onto x+y+z=1 + outputTangent.xyz = normalize( outputTangent.xyz ); // Normalize onto unit sphere + outputTangent.xy *= xyxySigns.zw; // Restore x and y signs + outputTangent.z *= ztztSigns.z; // Restore z sign + outputTangent.w = ztztSigns.w; // Binormal sign +} + + +//----------------------------------------------------------------------------------- +// Decompress just a normal from four-component compressed format (same as above) +// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 +// [ When compiled, this works out to approximately 17 asm instructions ] +void _DecompressUByte4Normal( float4 inputNormal, + out float3 outputNormal) // {nX, nY, nZ} +{ + float fOne = 1.0f; + + float2 ztSigns = ( inputNormal.xy - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction + float2 xyAbs = abs( inputNormal.xy - 128.0f ) - ztSigns; // 0..127 + float2 xySigns = ( xyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) + outputNormal.xy = ( abs( xyAbs - 64.0f ) - xySigns ) / 63.0f; // abs({nX, nY}) + + outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 + outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere + + outputNormal.xy *= lerp( fOne.xx, -fOne.xx, xySigns ); // Restore x and y signs + outputNormal.z *= lerp( fOne.x, -fOne.x, ztSigns.x ); // Restore z sign +} + + +void DecompressVertex_Normal( float4 inputNormal, out float3 outputNormal ) +{ + if ( COMPRESSED_VERTS == 1 ) + { + if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + { + _DecompressShort2Normal( inputNormal.xy, outputNormal ); + } + else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + { + _DecompressUByte4Normal( inputNormal, outputNormal ); + } + } + else + { + outputNormal = inputNormal.xyz; + } +} + +void DecompressVertex_NormalTangent( float4 inputNormal, float4 inputTangent, out float3 outputNormal, out float4 outputTangent ) +{ + if ( COMPRESSED_VERTS == 1 ) + { + if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + { + _DecompressShort2NormalTangent( inputNormal.xy, inputTangent.xy, outputNormal, outputTangent ); + } + else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + { + _DecompressUByte4NormalTangent( inputNormal, outputNormal, outputTangent ); + } + } + else + { + outputNormal = inputNormal.xyz; + outputTangent = inputTangent; + } +} + + +#if defined(SHADER_MODEL_VS_3_0) || defined(SHADER_MODEL_VS_4_0) + +//----------------------------------------------------------------------------- +// Methods to sample morph data from a vertex texture +// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex +// For position + normal morph for example, there will be 2 fields. +//----------------------------------------------------------------------------- +float4 SampleMorphDelta( Texture2D vtt, SamplerState vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + return vtt.SampleLevel( vt, t.xy, t.z ); +} + +// Optimized version which reads 2 deltas +void SampleMorphDelta2( Texture2D vtt, SamplerState vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + delta1 = vtt.SampleLevel( vt, t.xy, t.z ); + t.x += 1.0f / vMorphTargetTextureDim.x; + delta2 = vtt.SampleLevel( vt, t.xy, t.z ); +} + +#endif // SHADER_MODEL_VS_3_0 + +//----------------------------------------------------------------------------- +// Method to apply morphs +//----------------------------------------------------------------------------- +bool ApplyMorph( float3 vPosFlex, float4 flexScale, inout float3 vPosition ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * flexScale.x; + vPosition.xyz += vPosDelta; + return true; +} + +bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, float4 flexScale, inout float3 vPosition, inout float3 vNormal ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * flexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * flexScale.x; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + return true; +} + +bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, float4 flexScale, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * flexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * flexScale.x; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + vTangent.xyz += vNormalDelta; + return true; +} + +bool ApplyMorph( float4 vPosFlex, float3 vNormalFlex, float4 flexScale, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * flexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * flexScale.x; + flWrinkle = vPosFlex.w * flexScale.y; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + vTangent.xyz += vNormalDelta; + return true; +} + +#if defined(SHADER_MODEL_VS_3_0) || defined(SHADER_MODEL_VS_4_0) +#pragma message "We have sm 3.0 or 4.0" + +bool ApplyMorph( Texture2D morphTexture, SamplerState morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition ) +{ +#if MORPHING + +#if !DECAL + // Flexes coming in from a separate stream + float4 vPosDelta = SampleMorphDelta( morphTexture, morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 ); + vPosition += vPosDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + return false; +#endif +} + +bool ApplyMorph( Texture2D morphTexture, SamplerState morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphTexture, morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + return false; +#endif +} + +bool ApplyMorph( Texture2D morphTexture, SamplerState morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphTexture, morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + return false; +#endif +} + +bool ApplyMorph( Texture2D morphTexture, SamplerState morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphTexture, morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; + flWrinkle = vPosDelta.w; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float4 vPosDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = morphTexture.SampleLevel( morphSampler, t.xy, t.z ); + + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; + flWrinkle = vPosDelta.w * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + flWrinkle = 0.0f; + return false; + +#endif +} + +#endif // SHADER_MODEL_VS_3_0 + + +float RangeFog( const float3 projPos, const float4 fogParams ) +{ + // cFogMaxDensity, cOOFogRange, cFogEndOverFogRange + return max( fogParams.z, ( -projPos.z * fogParams.w + fogParams.x ) ); +} + +float WaterFog( const float3 worldPos, const float3 projPos, const float3 eyePos, const float fogZ, const float4 fogParams ) +{ + float4 tmp; + + tmp.xy = float2( fogZ, eyePos.z) - worldPos.z; + + // tmp.x is the distance from the water surface to the vert + // tmp.y is the distance from the eye position to the vert + + // if $tmp.x < 0, then set it to 0 + // This is the equivalent of moving the vert to the water surface if it's above the water surface + + tmp.x = max( 0.0f, tmp.x ); + + // $tmp.w = $tmp.x / $tmp.y + tmp.w = tmp.x / tmp.y; + + tmp.w *= projPos.z; + + // $tmp.w is now the distance that we see through water. + + return max( fogParams.z, ( -tmp.w * fogParams.w + fogParams.y ) ); +} + +float CalcFog( const float3 worldPos, const float3 projPos, const float3 eyePos, const int fogType, const float fogZ, const float4 fogParams ) +{ +#if defined( _X360 ) + // 360 only does pixel fog + return 1.0f; +#endif + + if( fogType == FOGTYPE_RANGE ) + { + return RangeFog( projPos, fogParams ); + } + else + { +#if SHADERMODEL_VS_2_0 == 1 + // We do this work in the pixel shader in dx9, so don't do any fog here. + return 1.0f; +#else + return WaterFog( worldPos, projPos, eyePos, fogZ, fogParams ); +#endif + } +} + +float CalcFog( const float3 worldPos, const float3 projPos, const float3 eyePos, const bool bWaterFog, const float fogZ, const float4 fogParams ) +{ +#if defined( _X360 ) + // 360 only does pixel fog + return 1.0f; +#endif + + float flFog; + if( !bWaterFog ) + { + flFog = RangeFog( projPos, fogParams ); + } + else + { +#if SHADERMODEL_VS_2_0 == 1 + // We do this work in the pixel shader in dx9, so don't do any fog here. + flFog = 1.0f; +#else + flFog = WaterFog( worldPos, projPos, eyePos, fogZ, fogParams ); +#endif + } + + return flFog; +} + +float4 DecompressBoneWeights( const float4 weights ) +{ + float4 result = weights; + + if ( COMPRESSED_VERTS ) + { + // Decompress from SHORT2 to float. In our case, [-1, +32767] -> [0, +1] + // NOTE: we add 1 here so we can divide by 32768 - which is exact (divide by 32767 is not). + // This avoids cracking between meshes with different numbers of bone weights. + // We use SHORT2 instead of SHORT2N for a similar reason - the GPU's conversion + // from [-32768,+32767] to [-1,+1] is imprecise in the same way. + result += 1; + result /= 32768; + } + + return result; +} + + +void SkinPosition( bool bSkinning, const float4 modelPos, + const float4 boneWeights, uint4 boneIndices, + float4x3 model[NUM_MODEL_TRANSFORMS], + out float3 worldPos ) +{ + + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, (float4x3)model[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = (float4x3)model[boneIndices[0]]; + float4x3 mat2 = (float4x3)model[boneIndices[1]]; + float4x3 mat3 = (float4x3)model[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + } + } +} + +void SkinPositionAndNormal( bool bSkinning, const float4 modelPos, const float3 modelNormal, + const float4 boneWeights, uint4 boneIndices, + float4x3 model[NUM_MODEL_TRANSFORMS], + out float3 worldPos, out float3 worldNormal ) +{ + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, (float4x3)model[0] ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )model[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = (float4x3)model[boneIndices[0]]; + float4x3 mat2 = (float4x3)model[boneIndices[1]]; + float4x3 mat3 = (float4x3)model[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix ); + } + + } // end [isolate] +} + +// Is it worth keeping SkinPosition and SkinPositionAndNormal around since the optimizer +// gets rid of anything that isn't used? +void SkinPositionNormalAndTangentSpace( + bool bSkinning, + const float4 modelPos, const float3 modelNormal, + const float4 modelTangentS, + const float4 boneWeights, uint4 boneIndices, + float4x3 model[NUM_MODEL_TRANSFORMS], + out float3 worldPos, out float3 worldNormal, + out float3 worldTangentS, out float3 worldTangentT ) +{ + + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, (float4x3)model[0] ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )model[0] ); + worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )model[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = (float4x3)model[boneIndices[0]]; + float4x3 mat2 = (float4x3)model[boneIndices[1]]; + float4x3 mat3 = (float4x3)model[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )blendMatrix ); + worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix ); + } + worldTangentT = cross( worldNormal, worldTangentS ) * modelTangentS.w; + } +} + + +//----------------------------------------------------------------------------- +// Lighting helper functions +//----------------------------------------------------------------------------- + +float3 AmbientLight( const float3 worldNormal, const float3 ambientCube[6] ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + int3 isPositive = 1 - isNegative; + isNegative *= nSquared; + isPositive *= nSquared; + float3 linearColor; + linearColor = isPositive.x * ambientCube[0] + isNegative.x * ambientCube[1] + + isPositive.y * ambientCube[2] + isNegative.y * ambientCube[3] + + isPositive.z * ambientCube[4] + isNegative.z * ambientCube[5]; + return linearColor; +} + +float CosineTermInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert, LightInfo lightInfo[MAX_NUM_LIGHTS] ) +{ + // Calculate light direction assuming this is a point or spot + float3 lightDir = normalize( lightInfo[lightNum].pos - worldPos ); + + // Select the above direction or the one in the structure, based upon light type + lightDir = lerp( lightDir, -lightInfo[lightNum].dir, lightInfo[lightNum].color.w ); + + // compute N dot L + float NDotL = dot( worldNormal, lightDir ); + + if ( !bHalfLambert ) + { + NDotL = max( 0.0f, NDotL ); + } + else // Half-Lambert + { + NDotL = NDotL * 0.5 + 0.5; + NDotL = NDotL * NDotL; + } + return NDotL; +} + +// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file +float CosineTerm( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert, + int4 lightEnabled[MAX_NUM_LIGHTS], LightInfo lightInfo[MAX_NUM_LIGHTS] ) +{ + float flResult = 0.0f; + //if ( lightEnabled[lightNum] != 0 ) + { + flResult = CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert, lightInfo ); + } + + return flResult; +} + + +float3 DoLightInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert, + LightInfo lightInfo[MAX_NUM_LIGHTS] ) +{ + return lightInfo[lightNum].color * + CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert, lightInfo ) * + LightAttenInternal( worldPos, lightNum, lightInfo ); +} + + +#if 0 +// This routine +float3 DoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bDynamicLight, bool bHalfLambert, LightInfo lightInfo[MAX_NUM_LIGHTS], + float3 ambientCube[6]) +{ + float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); + + if( bStaticLight ) // Static light + { + float3 col = staticLightingColor * cOverbright; +#if defined ( _X360 ) + linearColor += col * col; +#else + linearColor += GammaToLinear( col ); +#endif + } + + if( bDynamicLight ) // Dynamic light + { + for (int i = 0; i < g_nLightCount; i++) + { + linearColor += DoLightInternal( worldPos, worldNormal, i, bHalfLambert, lightInfo ); + } + } + + if( bDynamicLight ) + { + linearColor += AmbientLight( worldNormal, ambientCube ); //ambient light is already remapped + } + + return linearColor; +} + +#endif + + +float3 DoLightingUnrolled( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bDynamicLight, bool bHalfLambert, const int nNumLights, + LightInfo lightInfo[MAX_NUM_LIGHTS], float3 ambientCube[6]) +{ + float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); + + if( bStaticLight ) // Static light + { + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if( bDynamicLight ) // Ambient light + { + if ( nNumLights >= 1 ) + linearColor += DoLightInternal( worldPos, worldNormal, 0, bHalfLambert, lightInfo ); + if ( nNumLights >= 2 ) + linearColor += DoLightInternal( worldPos, worldNormal, 1, bHalfLambert, lightInfo ); + if ( nNumLights >= 3 ) + linearColor += DoLightInternal( worldPos, worldNormal, 2, bHalfLambert, lightInfo ); + if ( nNumLights >= 4 ) + linearColor += DoLightInternal( worldPos, worldNormal, 3, bHalfLambert, lightInfo ); + } + + if( bDynamicLight ) + { + linearColor += AmbientLight( worldNormal, ambientCube ); //ambient light is already remapped + } + + return linearColor; +} + +int4 FloatToInt( in float4 floats ) +{ + return D3DCOLORtoUBYTE4( floats.zyxw / 255.001953125 ); +} + + +float2 ComputeSphereMapTexCoords( in float3 reflectionVector, float4x4 viewModel ) +{ + // transform reflection vector into view space + reflectionVector = mul( reflectionVector, ( float3x3 )viewModel ); + + // generate + float3 tmp = float3( reflectionVector.x, reflectionVector.y, reflectionVector.z + 1.0f ); + + // find 1 / len + float ooLen = dot( tmp, tmp ); + ooLen = 1.0f / sqrt( ooLen ); + + // tmp = tmp/|tmp| + 1 + tmp.xy = ooLen * tmp.xy + 1.0f; + + return tmp.xy * 0.5f; +} + + +#define DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE 1 + // minxyz.minsoftness / maxxyz.maxsoftness +float3 ApplyDeformation( float3 worldpos, int deftype, float4 defparms0, float4 defparms1, + float4 defparms2, float4 defparms3 ) +{ + float3 ret = worldpos; + if ( deftype == DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE ) + { + ret=max( ret, defparms2.xyz ); + ret=min( ret, defparms3.xyz ); + } + + return ret; +} + + +#endif //#ifndef COMMON_VS_FXC_H_ diff --git a/materialsystem/stdshadersdx11/decalmodulate_dx11.cpp b/materialsystem/stdshadersdx11/decalmodulate_dx11.cpp new file mode 100644 index 0000000..8cf6e67 --- /dev/null +++ b/materialsystem/stdshadersdx11/decalmodulate_dx11.cpp @@ -0,0 +1,161 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "shader_register_map.h" +#include "vertexlitgeneric_dx11_helper.h" + +#include "vertexlit_and_unlit_generic_vs40.inc" +#include "decalmodulate_ps40.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( DecalModulate, DecalModulate_DX11 ) + +//extern ConVar r_flashlight_version2; + +BEGIN_VS_SHADER( DecalModulate_dx11, + "Help for DecalModulate_dx11" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_FALLBACK +{ + return 0; +} + +DECLARE_CONSTANT_BUFFER( VertexLitGeneric ) + +SHADER_INIT_PARAMS() +{ + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + +#ifndef _X360 + if ( g_pHardwareConfig->HasFastVertexTextures() ) + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } +#endif +} + +SHADER_INIT +{ + LoadTexture( BASETEXTURE ); +} + +SHADER_INIT_GLOBAL +{ + INIT_CONSTANT_BUFFER( VertexLitGeneric ); +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_DECAL ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + SetInternalVertexShaderConstantBuffers(); + SetVertexShaderConstantBuffer( USER_CBUFFER_REG_0, CONSTANT_BUFFER( VertexLitGeneric ) ); + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERSCENE ); + SetPixelShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERFRAME ); + SetPixelShaderConstantBuffer( 2, CONSTANT_BUFFER( VertexLitGeneric ) ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); + pShaderShadow->DisableFogGammaCorrection( true ); //fog should stay exactly middle grey + FogToGrey(); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, false ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, false ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, false ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, false ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, false ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, false ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, true ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, false ); + SET_STATIC_VERTEX_SHADER_COMBO( WRINKLEMAP, false ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( decalmodulate_ps40 ); + SET_STATIC_PIXEL_SHADER( decalmodulate_ps40 ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; +#ifndef _X360 + // The VS30 shader offsets decals along the normal (for morphed geom) + flags |= g_pHardwareConfig->HasFastVertexTextures() ? VERTEX_NORMAL : 0; +#endif + int pTexCoordDim[3] = { 2, 0, 3 }; + int nTexCoordCount = 1; + int userDataSize = 0; + +#ifndef _X360 + if ( g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + } + DYNAMIC_STATE + { + //if ( pShaderAPI->InFlashlightMode() && ( !IsX360() && ( r_flashlight_version2.GetInt() == 0 ) ) ) + //{ + // // Don't draw anything for the flashlight pass + // Draw( false ); + // return; + //} + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + VertexLitGeneric_CBuffer_t constants; + memset( &constants, 0, sizeof( VertexLitGeneric_CBuffer_t ) ); + constants.cBaseTextureTransform[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + constants.cBaseTextureTransform[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + SetHWMorphVertexShaderState( constants.cMorphDimensions, constants.cMorphSubrect, SHADER_VERTEXTEXTURE_SAMPLER0 ); + pShaderAPI->GetFogParamsAndColor( constants.g_FogParams.Base(), constants.g_FogColor.Base() ); + UPDATE_CONSTANT_BUFFER( VertexLitGeneric, constants ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, 0 ); // Use simplest possible vertex lighting, since ps is so simple + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, 0 ); // + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FLASHLIGHT, false ); + SET_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( decalmodulate_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( decalmodulate_ps40 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } + Draw(); +} +END_SHADER diff --git a/materialsystem/stdshadersdx11/decalmodulate_ps40.fxc b/materialsystem/stdshadersdx11/decalmodulate_ps40.fxc new file mode 100644 index 0000000..a3d8c6b --- /dev/null +++ b/materialsystem/stdshadersdx11/decalmodulate_ps40.fxc @@ -0,0 +1,51 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_cbuffers_fxc.h" + +CBUFFER_PERSCENE( register( b0 ) ) +CBUFFER_PERFRAME( register( b1 ) ) + +#include "common_ps_fxc.h" + +#include "vertexlitgeneric_dx11_shared.h" + +cbuffer DecalModulate_CBuffer : register( b2 ) +{ + VertexLitAndUnlitGeneric_t c; +}; + +Texture2D Tex : register( t0 ); +sampler TexSampler : register( s0 ); + +#define g_EyePos cEyePos + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + + HALF2 detailTexCoord : TEXCOORD1; + float4 color : TEXCOORD2; + float3 worldVertToEyeVector : TEXCOORD3; + float3 worldSpaceNormal : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; // Necessary for pixel fog + + float3 eyeSpacePos : COLOR0; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + float4 result = Tex.Sample( TexSampler, i.baseTexCoord ); + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, c.g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, length( i.eyeSpacePos ) ); + + // Since we're blending with a mod2x, we need to compensate with this hack + // NOTE: If the fog color (not fog density) is extremely dark, this can makes some decals seem + // a little transparent, but it's better than not doing this + fogFactor = pow( saturate( fogFactor ), 0.4f ); + + return FinalOutput( result, fogFactor, PIXELFOGTYPE, c.g_FogColor, TONEMAP_SCALE_NONE ); +} diff --git a/materialsystem/stdshadersdx11/depthtodestalpha_ps40.fxc b/materialsystem/stdshadersdx11/depthtodestalpha_ps40.fxc new file mode 100644 index 0000000..e92d7d8 --- /dev/null +++ b/materialsystem/stdshadersdx11/depthtodestalpha_ps40.fxc @@ -0,0 +1,13 @@ +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 vProjPos : SV_POSITION; + float projPosZ : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + return FinalOutput( float4( 0, 0, 0, 1.0f ), 0.0f, PIXEL_FOG_TYPE_NONE, float4(0, 0, 0, 1), + TONEMAP_SCALE_NONE, float4(1, 1, 1, 1), true, i.projPosZ ); +} diff --git a/materialsystem/stdshadersdx11/depthtodestalpha_vs40.fxc b/materialsystem/stdshadersdx11/depthtodestalpha_vs40.fxc new file mode 100644 index 0000000..abc73a1 --- /dev/null +++ b/materialsystem/stdshadersdx11/depthtodestalpha_vs40.fxc @@ -0,0 +1,28 @@ +#include "common_cbuffers_fxc.h" +CBUFFER_PERMODEL(register(b0)) // model matrix +CBUFFER_PERFRAME(register(b1)) // view matrix +CBUFFER_PERSCENE(register(b2)) // proj matrix + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : SV_POSITION; + float projPosZ : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.vProjPos = ComputeProjPos(v.vPos.xyz, cModelMatrix, cViewMatrix, cProjMatrix); + o.projPosZ = o.vProjPos.z; + + return o; +} diff --git a/materialsystem/stdshadersdx11/filestocopy.txt b/materialsystem/stdshadersdx11/filestocopy.txt new file mode 100644 index 0000000..eeb1469 --- /dev/null +++ b/materialsystem/stdshadersdx11/filestocopy.txt @@ -0,0 +1,6 @@ +..\..\devtools\bin\d3dx9_33.dll +..\..\dx10sdk\utilities\dx9_30\dx_proxy.dll +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\shadercompile.exe +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\shadercompile_dll.dll +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\vstdlib.dll +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\tier0.dll diff --git a/materialsystem/stdshadersdx11/fxctmp9/bik_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/bik_ps40.inc new file mode 100644 index 0000000..c4a38ee --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/bik_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class bik_ps40_Static_Index +{ +public: + bik_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_bik_ps40 0 +class bik_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + bik_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_bik_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/bik_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/bik_vs40.inc new file mode 100644 index 0000000..75ab72d --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/bik_vs40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class bik_vs40_Static_Index +{ +public: + bik_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_bik_vs40 0 +class bik_vs40_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + bik_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_bik_vs40 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/decalmodulate_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/decalmodulate_ps40.inc new file mode 100644 index 0000000..9337b1e --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/decalmodulate_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class decalmodulate_ps40_Static_Index +{ +public: + decalmodulate_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_decalmodulate_ps40 0 +class decalmodulate_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + decalmodulate_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_decalmodulate_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/depthtodestalpha_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/depthtodestalpha_ps40.inc new file mode 100644 index 0000000..ee0ed72 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/depthtodestalpha_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depthtodestalpha_ps40_Static_Index +{ +public: + depthtodestalpha_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depthtodestalpha_ps40 0 +class depthtodestalpha_ps40_Dynamic_Index +{ +public: + depthtodestalpha_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depthtodestalpha_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/depthtodestalpha_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/depthtodestalpha_vs40.inc new file mode 100644 index 0000000..1ecc31b --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/depthtodestalpha_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depthtodestalpha_vs40_Static_Index +{ +public: + depthtodestalpha_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depthtodestalpha_vs40 0 +class depthtodestalpha_vs40_Dynamic_Index +{ +public: + depthtodestalpha_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depthtodestalpha_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/lightmappedgeneric_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/lightmappedgeneric_ps40.inc new file mode 100644 index 0000000..9adef7f --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/lightmappedgeneric_ps40.inc @@ -0,0 +1,612 @@ +#include "shaderlib/cshader.h" +class lightmappedgeneric_ps40_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nALPHATEST; +#ifdef _DEBUG + bool m_bALPHATEST; +#endif +public: + void SetALPHATEST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHATEST = i; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } + void SetALPHATEST( bool i ) + { + m_nALPHATEST = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } +public: + lightmappedgeneric_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bALPHATEST = false; +#endif // _DEBUG + m_nALPHATEST = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK && m_bALPHATEST; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 32 * m_nMASKEDBLENDING ) + ( 64 * m_nBASETEXTURE2 ) + ( 128 * m_nDETAILTEXTURE ) + ( 256 * m_nBUMPMAP ) + ( 768 * m_nBUMPMAP2 ) + ( 1536 * m_nCUBEMAP ) + ( 3072 * m_nENVMAPMASK ) + ( 6144 * m_nBASEALPHAENVMAPMASK ) + ( 12288 * m_nSELFILLUM ) + ( 24576 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 49152 * m_nDIFFUSEBUMPMAP ) + ( 98304 * m_nBASETEXTURENOENVMAP ) + ( 196608 * m_nBASETEXTURE2NOENVMAP ) + ( 393216 * m_nWARPLIGHTING ) + ( 786432 * m_nFANCY_BLENDING ) + ( 1572864 * m_nSEAMLESS ) + ( 3145728 * m_nBUMPMASK ) + ( 6291456 * m_nALPHATEST ) + 0; + } +}; +#define shaderStaticTest_lightmappedgeneric_ps40 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_ALPHATEST + 0 +class lightmappedgeneric_ps40_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + lightmappedgeneric_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_lightmappedgeneric_ps40 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/lightmappedgeneric_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/lightmappedgeneric_vs40.inc new file mode 100644 index 0000000..e19cbdf --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/lightmappedgeneric_vs40.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class lightmappedgeneric_vs40_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +private: + int m_nTANGENTSPACE; +#ifdef _DEBUG + bool m_bTANGENTSPACE; +#endif +public: + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } + void SetTANGENTSPACE( bool i ) + { + m_nTANGENTSPACE = i ? 1 : 0; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nVERTEXALPHATEXBLENDFACTOR; +#ifdef _DEBUG + bool m_bVERTEXALPHATEXBLENDFACTOR; +#endif +public: + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } + void SetVERTEXALPHATEXBLENDFACTOR( bool i ) + { + m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +public: + lightmappedgeneric_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bTANGENTSPACE = false; +#endif // _DEBUG + m_nTANGENTSPACE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS && m_bBUMPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nENVMAP_MASK ) + ( 8 * m_nTANGENTSPACE ) + ( 16 * m_nBUMPMAP ) + ( 32 * m_nDIFFUSEBUMPMAP ) + ( 64 * m_nVERTEXCOLOR ) + ( 128 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 256 * m_nSEAMLESS ) + ( 512 * m_nBUMPMASK ) + 0; + } +}; +#define shaderStaticTest_lightmappedgeneric_vs40 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + 0 +class lightmappedgeneric_vs40_Dynamic_Index +{ +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + lightmappedgeneric_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_lightmappedgeneric_vs40 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/modulate_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/modulate_ps40.inc new file mode 100644 index 0000000..59a8de7 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/modulate_ps40.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class modulate_ps40_Static_Index +{ +public: + modulate_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_modulate_ps40 0 +class modulate_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + modulate_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_modulate_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/modulate_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/modulate_vs40.inc new file mode 100644 index 0000000..9f27c7e --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/modulate_vs40.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class modulate_vs40_Static_Index +{ +public: + modulate_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_modulate_vs40 0 +class modulate_vs40_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + modulate_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_modulate_vs40 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/sky_hdr_compressed_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/sky_hdr_compressed_ps40.inc new file mode 100644 index 0000000..19dceb4 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/sky_hdr_compressed_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sky_hdr_compressed_ps40_Static_Index +{ +public: + sky_hdr_compressed_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_hdr_compressed_ps40 0 +class sky_hdr_compressed_ps40_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sky_hdr_compressed_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sky_hdr_compressed_ps40 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/sky_hdr_compressed_rgbs_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/sky_hdr_compressed_rgbs_ps40.inc new file mode 100644 index 0000000..0e7a7e2 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/sky_hdr_compressed_rgbs_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sky_hdr_compressed_rgbs_ps40_Static_Index +{ +public: + sky_hdr_compressed_rgbs_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_hdr_compressed_rgbs_ps40 0 +class sky_hdr_compressed_rgbs_ps40_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sky_hdr_compressed_rgbs_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sky_hdr_compressed_rgbs_ps40 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/sky_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/sky_ps40.inc new file mode 100644 index 0000000..ee44c77 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/sky_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sky_ps40_Static_Index +{ +public: + sky_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_ps40 0 +class sky_ps40_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sky_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sky_ps40 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/sky_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/sky_vs40.inc new file mode 100644 index 0000000..6115dd3 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/sky_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sky_vs40_Static_Index +{ +public: + sky_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_vs40 0 +class sky_vs40_Dynamic_Index +{ +public: + sky_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sky_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/splinecard_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/splinecard_vs40.inc new file mode 100644 index 0000000..08fc757 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/splinecard_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class splinecard_vs40_Static_Index +{ +public: + splinecard_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_splinecard_vs40 0 +class splinecard_vs40_Dynamic_Index +{ +public: + splinecard_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_splinecard_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/sprite_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/sprite_ps40.inc new file mode 100644 index 0000000..3f5d3d5 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/sprite_ps40.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sprite_ps40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCONSTANTCOLOR; +#ifdef _DEBUG + bool m_bCONSTANTCOLOR; +#endif +public: + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } + void SetCONSTANTCOLOR( bool i ) + { + m_nCONSTANTCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sprite_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = false; +#endif // _DEBUG + m_nCONSTANTCOLOR = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nCONSTANTCOLOR ) + ( 16 * m_nHDRTYPE ) + ( 48 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sprite_ps40 psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + 0 +class sprite_ps40_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sprite_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sprite_ps40 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/sprite_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/sprite_vs40.inc new file mode 100644 index 0000000..1d93508 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/sprite_vs40.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sprite_vs40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sprite_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nVERTEXCOLOR ) + ( 4 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sprite_vs40 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_SRGB + 0 +class sprite_vs40_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sprite_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sprite_vs40 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/spritecard_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/spritecard_ps40.inc new file mode 100644 index 0000000..04d0df6 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/spritecard_ps40.inc @@ -0,0 +1,310 @@ +#include "shaderlib/cshader.h" +class spritecard_ps40_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +private: + int m_nSEQUENCE_BLEND_MODE; +#ifdef _DEBUG + bool m_bSEQUENCE_BLEND_MODE; +#endif +public: + void SetSEQUENCE_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nSEQUENCE_BLEND_MODE = i; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } + void SetSEQUENCE_BLEND_MODE( bool i ) + { + m_nSEQUENCE_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } +private: + int m_nADDBASETEXTURE2; +#ifdef _DEBUG + bool m_bADDBASETEXTURE2; +#endif +public: + void SetADDBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDBASETEXTURE2 = i; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } + void SetADDBASETEXTURE2( bool i ) + { + m_nADDBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND1; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND1; +#endif +public: + void SetMAXLUMFRAMEBLEND1( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND1 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } + void SetMAXLUMFRAMEBLEND1( bool i ) + { + m_nMAXLUMFRAMEBLEND1 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND2; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND2; +#endif +public: + void SetMAXLUMFRAMEBLEND2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND2 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } + void SetMAXLUMFRAMEBLEND2( bool i ) + { + m_nMAXLUMFRAMEBLEND2 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } +private: + int m_nEXTRACTGREENALPHA; +#ifdef _DEBUG + bool m_bEXTRACTGREENALPHA; +#endif +public: + void SetEXTRACTGREENALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nEXTRACTGREENALPHA = i; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } + void SetEXTRACTGREENALPHA( bool i ) + { + m_nEXTRACTGREENALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } +private: + int m_nCOLORRAMP; +#ifdef _DEBUG + bool m_bCOLORRAMP; +#endif +public: + void SetCOLORRAMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORRAMP = i; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } + void SetCOLORRAMP( bool i ) + { + m_nCOLORRAMP = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } +private: + int m_nANIMBLEND; +#ifdef _DEBUG + bool m_bANIMBLEND; +#endif +public: + void SetANIMBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nANIMBLEND = i; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } + void SetANIMBLEND( bool i ) + { + m_nANIMBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } +private: + int m_nADDSELF; +#ifdef _DEBUG + bool m_bADDSELF; +#endif +public: + void SetADDSELF( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDSELF = i; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } + void SetADDSELF( bool i ) + { + m_nADDSELF = i ? 1 : 0; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } +private: + int m_nALPHATEST; +#ifdef _DEBUG + bool m_bALPHATEST; +#endif +public: + void SetALPHATEST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHATEST = i; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } + void SetALPHATEST( bool i ) + { + m_nALPHATEST = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +public: + spritecard_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = false; +#endif // _DEBUG + m_nSEQUENCE_BLEND_MODE = 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = false; +#endif // _DEBUG + m_nADDBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND1 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND2 = 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = false; +#endif // _DEBUG + m_nEXTRACTGREENALPHA = 0; +#ifdef _DEBUG + m_bCOLORRAMP = false; +#endif // _DEBUG + m_nCOLORRAMP = 0; +#ifdef _DEBUG + m_bANIMBLEND = false; +#endif // _DEBUG + m_nANIMBLEND = 0; +#ifdef _DEBUG + m_bADDSELF = false; +#endif // _DEBUG + m_nADDSELF = 0; +#ifdef _DEBUG + m_bALPHATEST = false; +#endif // _DEBUG + m_nALPHATEST = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE && m_bSEQUENCE_BLEND_MODE && m_bADDBASETEXTURE2 && m_bMAXLUMFRAMEBLEND1 && m_bMAXLUMFRAMEBLEND2 && m_bEXTRACTGREENALPHA && m_bCOLORRAMP && m_bANIMBLEND && m_bADDSELF && m_bALPHATEST && m_bDEPTHBLEND; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDUALSEQUENCE ) + ( 2 * m_nSEQUENCE_BLEND_MODE ) + ( 6 * m_nADDBASETEXTURE2 ) + ( 12 * m_nMAXLUMFRAMEBLEND1 ) + ( 24 * m_nMAXLUMFRAMEBLEND2 ) + ( 48 * m_nEXTRACTGREENALPHA ) + ( 96 * m_nCOLORRAMP ) + ( 192 * m_nANIMBLEND ) + ( 384 * m_nADDSELF ) + ( 768 * m_nALPHATEST ) + ( 1536 * m_nDEPTHBLEND ) + 0; + } +}; +#define shaderStaticTest_spritecard_ps40 psh_forgot_to_set_static_DUALSEQUENCE + psh_forgot_to_set_static_SEQUENCE_BLEND_MODE + psh_forgot_to_set_static_ADDBASETEXTURE2 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND1 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND2 + psh_forgot_to_set_static_EXTRACTGREENALPHA + psh_forgot_to_set_static_COLORRAMP + psh_forgot_to_set_static_ANIMBLEND + psh_forgot_to_set_static_ADDSELF + psh_forgot_to_set_static_ALPHATEST + psh_forgot_to_set_static_DEPTHBLEND + 0 +class spritecard_ps40_Dynamic_Index +{ +public: + spritecard_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_spritecard_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/spritecard_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/spritecard_vs40.inc new file mode 100644 index 0000000..df95fe5 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/spritecard_vs40.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class spritecard_vs40_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +public: + spritecard_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 3 * m_nDUALSEQUENCE ) + 0; + } +}; +#define shaderStaticTest_spritecard_vs40 vsh_forgot_to_set_static_DUALSEQUENCE + 0 +class spritecard_vs40_Dynamic_Index +{ +private: + int m_nORIENTATION; +#ifdef _DEBUG + bool m_bORIENTATION; +#endif +public: + void SetORIENTATION( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nORIENTATION = i; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } + void SetORIENTATION( bool i ) + { + m_nORIENTATION = i ? 1 : 0; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } +public: + spritecard_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bORIENTATION = false; +#endif // _DEBUG + m_nORIENTATION = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bORIENTATION; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nORIENTATION ) + 0; + } +}; +#define shaderDynamicTest_spritecard_vs40 vsh_forgot_to_set_dynamic_ORIENTATION + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/unlitgeneric_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/unlitgeneric_ps40.inc new file mode 100644 index 0000000..b438207 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/unlitgeneric_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class unlitgeneric_ps40_Static_Index +{ +public: + unlitgeneric_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_unlitgeneric_ps40 0 +class unlitgeneric_ps40_Dynamic_Index +{ +public: + unlitgeneric_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_unlitgeneric_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/unlitgeneric_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/unlitgeneric_vs40.inc new file mode 100644 index 0000000..5bad5b4 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/unlitgeneric_vs40.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class unlitgeneric_vs40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nMODEL; +#ifdef _DEBUG + bool m_bMODEL; +#endif +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } + void SetMODEL( bool i ) + { + m_nMODEL = i ? 1 : 0; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } +public: + unlitgeneric_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + m_nMODEL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bMODEL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nVERTEXCOLOR ) + ( 2 * m_nMODEL ) + 0; + } +}; +#define shaderStaticTest_unlitgeneric_vs40 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_MODEL + 0 +class unlitgeneric_vs40_Dynamic_Index +{ +public: + unlitgeneric_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_unlitgeneric_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/unlittwotexture_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/unlittwotexture_ps40.inc new file mode 100644 index 0000000..39b03eb --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/unlittwotexture_ps40.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class unlittwotexture_ps40_Static_Index +{ +public: + unlittwotexture_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_unlittwotexture_ps40 0 +class unlittwotexture_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + unlittwotexture_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_unlittwotexture_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/unlittwotexture_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/unlittwotexture_vs40.inc new file mode 100644 index 0000000..7283871 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/unlittwotexture_vs40.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class unlittwotexture_vs40_Static_Index +{ +public: + unlittwotexture_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_unlittwotexture_vs40 0 +class unlittwotexture_vs40_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + unlittwotexture_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_unlittwotexture_vs40 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/vertexlit_and_unlit_generic_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/vertexlit_and_unlit_generic_ps40.inc new file mode 100644 index 0000000..579dda2 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/vertexlit_and_unlit_generic_ps40.inc @@ -0,0 +1,837 @@ +#include "shaderlib/cshader.h" +class vertexlit_and_unlit_generic_ps40_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMMASK; +#ifdef _DEBUG + bool m_bSELFILLUMMASK; +#endif +public: + void SetSELFILLUMMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMMASK = i; +#ifdef _DEBUG + m_bSELFILLUMMASK = true; +#endif + } + void SetSELFILLUMMASK( bool i ) + { + m_nSELFILLUMMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMMASK = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +private: + int m_nALPHATEST; +#ifdef _DEBUG + bool m_bALPHATEST; +#endif +public: + void SetALPHATEST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHATEST = i; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } + void SetALPHATEST( bool i ) + { + m_nALPHATEST = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +public: + vertexlit_and_unlit_generic_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMMASK = false; +#endif // _DEBUG + m_nSELFILLUMMASK = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; +#ifdef _DEBUG + m_bALPHATEST = false; +#endif // _DEBUG + m_nALPHATEST = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bBUMPMAP && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bSELFILLUMMASK && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bLIGHTWARPTEXTURE && m_bVERTEXCOLOR && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bDEPTHBLEND && m_bALPHATEST && m_bBLENDTINTBYBASEALPHA; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 384 * m_nDETAILTEXTURE ) + ( 768 * m_nBUMPMAP ) + ( 1536 * m_nCUBEMAP ) + ( 3072 * m_nDIFFUSELIGHTING ) + ( 6144 * m_nENVMAPMASK ) + ( 12288 * m_nBASEALPHAENVMAPMASK ) + ( 24576 * m_nSELFILLUM ) + ( 49152 * m_nSELFILLUMMASK ) + ( 98304 * m_nSELFILLUMFRESNEL ) + ( 196608 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 393216 * m_nHALFLAMBERT ) + ( 786432 * m_nLIGHTWARPTEXTURE ) + ( 1572864 * m_nVERTEXCOLOR ) + ( 3145728 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 6291456 * m_nSEAMLESS_BASE ) + ( 12582912 * m_nSEAMLESS_DETAIL ) + ( 25165824 * m_nDISTANCEALPHA ) + ( 50331648 * m_nDISTANCEALPHAFROMDETAIL ) + ( 100663296 * m_nSOFT_MASK ) + ( 201326592 * m_nOUTLINE ) + ( 402653184 * m_nOUTER_GLOW ) + ( 805306368 * m_nDEPTHBLEND ) + ( 1610612736 * m_nALPHATEST ) + ( 3221225472 * m_nBLENDTINTBYBASEALPHA ) + 0; + } +}; +#define shaderStaticTest_vertexlit_and_unlit_generic_ps40 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMMASK + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_ALPHATEST + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + 0 +class vertexlit_and_unlit_generic_ps40_Dynamic_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nPHONGWARPTEXTURE; +#ifdef _DEBUG + bool m_bPHONGWARPTEXTURE; +#endif +public: + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } + void SetPHONGWARPTEXTURE( bool i ) + { + m_nPHONGWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } +private: + int m_nRIMLIGHT; +#ifdef _DEBUG + bool m_bRIMLIGHT; +#endif +public: + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } + void SetRIMLIGHT( bool i ) + { + m_nRIMLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } +public: + vertexlit_and_unlit_generic_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = false; +#endif // _DEBUG + m_nPHONGWARPTEXTURE = 0; +#ifdef _DEBUG + m_bRIMLIGHT = false; +#endif // _DEBUG + m_nRIMLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFLASHLIGHTSHADOWS && m_bAMBIENT_LIGHT && m_bPHONG && m_bWRINKLEMAP && m_bPHONGWARPTEXTURE && m_bRIMLIGHT; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFLASHLIGHT ) + ( 2 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 6 * m_nFLASHLIGHTSHADOWS ) + ( 12 * m_nAMBIENT_LIGHT ) + ( 24 * m_nPHONG ) + ( 48 * m_nWRINKLEMAP ) + ( 96 * m_nPHONGWARPTEXTURE ) + ( 192 * m_nRIMLIGHT ) + 0; + } +}; +#define shaderDynamicTest_vertexlit_and_unlit_generic_ps40 psh_forgot_to_set_dynamic_FLASHLIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_PHONG + psh_forgot_to_set_dynamic_WRINKLEMAP + psh_forgot_to_set_dynamic_PHONGWARPTEXTURE + psh_forgot_to_set_dynamic_RIMLIGHT + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/vertexlit_and_unlit_generic_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/vertexlit_and_unlit_generic_vs40.inc new file mode 100644 index 0000000..4f99016 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/vertexlit_and_unlit_generic_vs40.inc @@ -0,0 +1,462 @@ +#include "shaderlib/cshader.h" +class vertexlit_and_unlit_generic_vs40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nSEPARATE_DETAIL_UVS; +#ifdef _DEBUG + bool m_bSEPARATE_DETAIL_UVS; +#endif +public: + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } + void SetSEPARATE_DETAIL_UVS( bool i ) + { + m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +public: + vertexlit_and_unlit_generic_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = false; +#endif // _DEBUG + m_nSEPARATE_DETAIL_UVS = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bBUMPMAP && m_bWRINKLEMAP && m_bDECAL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 256 * m_nVERTEXCOLOR ) + ( 512 * m_nCUBEMAP ) + ( 1024 * m_nHALFLAMBERT ) + ( 2048 * m_nSEAMLESS_BASE ) + ( 4096 * m_nSEAMLESS_DETAIL ) + ( 8192 * m_nSEPARATE_DETAIL_UVS ) + ( 16384 * m_nBUMPMAP ) + ( 32768 * m_nWRINKLEMAP ) + ( 65536 * m_nDECAL ) + 0; + } +}; +#define shaderStaticTest_vertexlit_and_unlit_generic_vs40 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_WRINKLEMAP + vsh_forgot_to_set_static_DECAL + 0 +class vertexlit_and_unlit_generic_vs40_Dynamic_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + vertexlit_and_unlit_generic_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFLASHLIGHT && m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFLASHLIGHT ) + ( 2 * m_nCOMPRESSED_VERTS ) + ( 4 * m_nDYNAMIC_LIGHT ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nDOWATERFOG ) + ( 32 * m_nSKINNING ) + ( 64 * m_nLIGHTING_PREVIEW ) + ( 128 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_vertexlit_and_unlit_generic_vs40 vsh_forgot_to_set_dynamic_FLASHLIGHT + vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/white_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/white_ps40.inc new file mode 100644 index 0000000..4ba6a6a --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/white_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class white_ps40_Static_Index +{ +public: + white_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_white_ps40 0 +class white_ps40_Dynamic_Index +{ +public: + white_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_white_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/wireframe_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9/wireframe_ps40.inc new file mode 100644 index 0000000..823da81 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/wireframe_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class wireframe_ps40_Static_Index +{ +public: + wireframe_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_wireframe_ps40 0 +class wireframe_ps40_Dynamic_Index +{ +public: + wireframe_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_wireframe_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/wireframe_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/wireframe_vs40.inc new file mode 100644 index 0000000..542fe67 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/wireframe_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class wireframe_vs40_Static_Index +{ +public: + wireframe_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_wireframe_vs40 0 +class wireframe_vs40_Dynamic_Index +{ +public: + wireframe_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_wireframe_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9/writez_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9/writez_vs40.inc new file mode 100644 index 0000000..43dea1b --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9/writez_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class writez_vs40_Static_Index +{ +public: + writez_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_writez_vs40 0 +class writez_vs40_Dynamic_Index +{ +public: + writez_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_writez_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/bik_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/bik_ps40.inc new file mode 100644 index 0000000..c4a38ee --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/bik_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class bik_ps40_Static_Index +{ +public: + bik_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_bik_ps40 0 +class bik_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + bik_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_bik_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/bik_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/bik_vs40.inc new file mode 100644 index 0000000..75ab72d --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/bik_vs40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class bik_vs40_Static_Index +{ +public: + bik_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_bik_vs40 0 +class bik_vs40_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + bik_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_bik_vs40 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/decalmodulate_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/decalmodulate_ps40.inc new file mode 100644 index 0000000..9337b1e --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/decalmodulate_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class decalmodulate_ps40_Static_Index +{ +public: + decalmodulate_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_decalmodulate_ps40 0 +class decalmodulate_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + decalmodulate_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_decalmodulate_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/depthtodestalpha_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/depthtodestalpha_ps40.inc new file mode 100644 index 0000000..ee0ed72 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/depthtodestalpha_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depthtodestalpha_ps40_Static_Index +{ +public: + depthtodestalpha_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depthtodestalpha_ps40 0 +class depthtodestalpha_ps40_Dynamic_Index +{ +public: + depthtodestalpha_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depthtodestalpha_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/depthtodestalpha_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/depthtodestalpha_vs40.inc new file mode 100644 index 0000000..1ecc31b --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/depthtodestalpha_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depthtodestalpha_vs40_Static_Index +{ +public: + depthtodestalpha_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depthtodestalpha_vs40 0 +class depthtodestalpha_vs40_Dynamic_Index +{ +public: + depthtodestalpha_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depthtodestalpha_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/lightmappedgeneric_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/lightmappedgeneric_ps40.inc new file mode 100644 index 0000000..9adef7f --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/lightmappedgeneric_ps40.inc @@ -0,0 +1,612 @@ +#include "shaderlib/cshader.h" +class lightmappedgeneric_ps40_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nALPHATEST; +#ifdef _DEBUG + bool m_bALPHATEST; +#endif +public: + void SetALPHATEST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHATEST = i; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } + void SetALPHATEST( bool i ) + { + m_nALPHATEST = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } +public: + lightmappedgeneric_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bALPHATEST = false; +#endif // _DEBUG + m_nALPHATEST = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK && m_bALPHATEST; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 32 * m_nMASKEDBLENDING ) + ( 64 * m_nBASETEXTURE2 ) + ( 128 * m_nDETAILTEXTURE ) + ( 256 * m_nBUMPMAP ) + ( 768 * m_nBUMPMAP2 ) + ( 1536 * m_nCUBEMAP ) + ( 3072 * m_nENVMAPMASK ) + ( 6144 * m_nBASEALPHAENVMAPMASK ) + ( 12288 * m_nSELFILLUM ) + ( 24576 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 49152 * m_nDIFFUSEBUMPMAP ) + ( 98304 * m_nBASETEXTURENOENVMAP ) + ( 196608 * m_nBASETEXTURE2NOENVMAP ) + ( 393216 * m_nWARPLIGHTING ) + ( 786432 * m_nFANCY_BLENDING ) + ( 1572864 * m_nSEAMLESS ) + ( 3145728 * m_nBUMPMASK ) + ( 6291456 * m_nALPHATEST ) + 0; + } +}; +#define shaderStaticTest_lightmappedgeneric_ps40 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_ALPHATEST + 0 +class lightmappedgeneric_ps40_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + lightmappedgeneric_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_lightmappedgeneric_ps40 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/lightmappedgeneric_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/lightmappedgeneric_vs40.inc new file mode 100644 index 0000000..e19cbdf --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/lightmappedgeneric_vs40.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class lightmappedgeneric_vs40_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +private: + int m_nTANGENTSPACE; +#ifdef _DEBUG + bool m_bTANGENTSPACE; +#endif +public: + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } + void SetTANGENTSPACE( bool i ) + { + m_nTANGENTSPACE = i ? 1 : 0; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nVERTEXALPHATEXBLENDFACTOR; +#ifdef _DEBUG + bool m_bVERTEXALPHATEXBLENDFACTOR; +#endif +public: + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } + void SetVERTEXALPHATEXBLENDFACTOR( bool i ) + { + m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +public: + lightmappedgeneric_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bTANGENTSPACE = false; +#endif // _DEBUG + m_nTANGENTSPACE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS && m_bBUMPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nENVMAP_MASK ) + ( 8 * m_nTANGENTSPACE ) + ( 16 * m_nBUMPMAP ) + ( 32 * m_nDIFFUSEBUMPMAP ) + ( 64 * m_nVERTEXCOLOR ) + ( 128 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 256 * m_nSEAMLESS ) + ( 512 * m_nBUMPMASK ) + 0; + } +}; +#define shaderStaticTest_lightmappedgeneric_vs40 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + 0 +class lightmappedgeneric_vs40_Dynamic_Index +{ +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + lightmappedgeneric_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_lightmappedgeneric_vs40 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/modulate_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/modulate_ps40.inc new file mode 100644 index 0000000..59a8de7 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/modulate_ps40.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class modulate_ps40_Static_Index +{ +public: + modulate_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_modulate_ps40 0 +class modulate_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + modulate_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_modulate_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/modulate_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/modulate_vs40.inc new file mode 100644 index 0000000..9f27c7e --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/modulate_vs40.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class modulate_vs40_Static_Index +{ +public: + modulate_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_modulate_vs40 0 +class modulate_vs40_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + modulate_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_modulate_vs40 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_hdr_compressed_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_hdr_compressed_ps40.inc new file mode 100644 index 0000000..19dceb4 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_hdr_compressed_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sky_hdr_compressed_ps40_Static_Index +{ +public: + sky_hdr_compressed_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_hdr_compressed_ps40 0 +class sky_hdr_compressed_ps40_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sky_hdr_compressed_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sky_hdr_compressed_ps40 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_hdr_compressed_rgbs_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_hdr_compressed_rgbs_ps40.inc new file mode 100644 index 0000000..0e7a7e2 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_hdr_compressed_rgbs_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sky_hdr_compressed_rgbs_ps40_Static_Index +{ +public: + sky_hdr_compressed_rgbs_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_hdr_compressed_rgbs_ps40 0 +class sky_hdr_compressed_rgbs_ps40_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sky_hdr_compressed_rgbs_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sky_hdr_compressed_rgbs_ps40 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_ps40.inc new file mode 100644 index 0000000..ee44c77 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_ps40.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sky_ps40_Static_Index +{ +public: + sky_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_ps40 0 +class sky_ps40_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sky_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sky_ps40 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_vs40.inc new file mode 100644 index 0000000..6115dd3 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/sky_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sky_vs40_Static_Index +{ +public: + sky_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sky_vs40 0 +class sky_vs40_Dynamic_Index +{ +public: + sky_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sky_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/splinecard_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/splinecard_vs40.inc new file mode 100644 index 0000000..08fc757 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/splinecard_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class splinecard_vs40_Static_Index +{ +public: + splinecard_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_splinecard_vs40 0 +class splinecard_vs40_Dynamic_Index +{ +public: + splinecard_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_splinecard_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/sprite_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/sprite_ps40.inc new file mode 100644 index 0000000..3f5d3d5 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/sprite_ps40.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sprite_ps40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCONSTANTCOLOR; +#ifdef _DEBUG + bool m_bCONSTANTCOLOR; +#endif +public: + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } + void SetCONSTANTCOLOR( bool i ) + { + m_nCONSTANTCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sprite_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = false; +#endif // _DEBUG + m_nCONSTANTCOLOR = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nCONSTANTCOLOR ) + ( 16 * m_nHDRTYPE ) + ( 48 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sprite_ps40 psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + 0 +class sprite_ps40_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sprite_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sprite_ps40 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/sprite_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/sprite_vs40.inc new file mode 100644 index 0000000..1d93508 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/sprite_vs40.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sprite_vs40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sprite_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nVERTEXCOLOR ) + ( 4 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sprite_vs40 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_SRGB + 0 +class sprite_vs40_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sprite_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sprite_vs40 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/spritecard_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/spritecard_ps40.inc new file mode 100644 index 0000000..04d0df6 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/spritecard_ps40.inc @@ -0,0 +1,310 @@ +#include "shaderlib/cshader.h" +class spritecard_ps40_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +private: + int m_nSEQUENCE_BLEND_MODE; +#ifdef _DEBUG + bool m_bSEQUENCE_BLEND_MODE; +#endif +public: + void SetSEQUENCE_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nSEQUENCE_BLEND_MODE = i; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } + void SetSEQUENCE_BLEND_MODE( bool i ) + { + m_nSEQUENCE_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } +private: + int m_nADDBASETEXTURE2; +#ifdef _DEBUG + bool m_bADDBASETEXTURE2; +#endif +public: + void SetADDBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDBASETEXTURE2 = i; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } + void SetADDBASETEXTURE2( bool i ) + { + m_nADDBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND1; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND1; +#endif +public: + void SetMAXLUMFRAMEBLEND1( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND1 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } + void SetMAXLUMFRAMEBLEND1( bool i ) + { + m_nMAXLUMFRAMEBLEND1 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND2; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND2; +#endif +public: + void SetMAXLUMFRAMEBLEND2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND2 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } + void SetMAXLUMFRAMEBLEND2( bool i ) + { + m_nMAXLUMFRAMEBLEND2 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } +private: + int m_nEXTRACTGREENALPHA; +#ifdef _DEBUG + bool m_bEXTRACTGREENALPHA; +#endif +public: + void SetEXTRACTGREENALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nEXTRACTGREENALPHA = i; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } + void SetEXTRACTGREENALPHA( bool i ) + { + m_nEXTRACTGREENALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } +private: + int m_nCOLORRAMP; +#ifdef _DEBUG + bool m_bCOLORRAMP; +#endif +public: + void SetCOLORRAMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORRAMP = i; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } + void SetCOLORRAMP( bool i ) + { + m_nCOLORRAMP = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } +private: + int m_nANIMBLEND; +#ifdef _DEBUG + bool m_bANIMBLEND; +#endif +public: + void SetANIMBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nANIMBLEND = i; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } + void SetANIMBLEND( bool i ) + { + m_nANIMBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } +private: + int m_nADDSELF; +#ifdef _DEBUG + bool m_bADDSELF; +#endif +public: + void SetADDSELF( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDSELF = i; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } + void SetADDSELF( bool i ) + { + m_nADDSELF = i ? 1 : 0; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } +private: + int m_nALPHATEST; +#ifdef _DEBUG + bool m_bALPHATEST; +#endif +public: + void SetALPHATEST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHATEST = i; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } + void SetALPHATEST( bool i ) + { + m_nALPHATEST = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +public: + spritecard_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = false; +#endif // _DEBUG + m_nSEQUENCE_BLEND_MODE = 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = false; +#endif // _DEBUG + m_nADDBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND1 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND2 = 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = false; +#endif // _DEBUG + m_nEXTRACTGREENALPHA = 0; +#ifdef _DEBUG + m_bCOLORRAMP = false; +#endif // _DEBUG + m_nCOLORRAMP = 0; +#ifdef _DEBUG + m_bANIMBLEND = false; +#endif // _DEBUG + m_nANIMBLEND = 0; +#ifdef _DEBUG + m_bADDSELF = false; +#endif // _DEBUG + m_nADDSELF = 0; +#ifdef _DEBUG + m_bALPHATEST = false; +#endif // _DEBUG + m_nALPHATEST = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE && m_bSEQUENCE_BLEND_MODE && m_bADDBASETEXTURE2 && m_bMAXLUMFRAMEBLEND1 && m_bMAXLUMFRAMEBLEND2 && m_bEXTRACTGREENALPHA && m_bCOLORRAMP && m_bANIMBLEND && m_bADDSELF && m_bALPHATEST && m_bDEPTHBLEND; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDUALSEQUENCE ) + ( 2 * m_nSEQUENCE_BLEND_MODE ) + ( 6 * m_nADDBASETEXTURE2 ) + ( 12 * m_nMAXLUMFRAMEBLEND1 ) + ( 24 * m_nMAXLUMFRAMEBLEND2 ) + ( 48 * m_nEXTRACTGREENALPHA ) + ( 96 * m_nCOLORRAMP ) + ( 192 * m_nANIMBLEND ) + ( 384 * m_nADDSELF ) + ( 768 * m_nALPHATEST ) + ( 1536 * m_nDEPTHBLEND ) + 0; + } +}; +#define shaderStaticTest_spritecard_ps40 psh_forgot_to_set_static_DUALSEQUENCE + psh_forgot_to_set_static_SEQUENCE_BLEND_MODE + psh_forgot_to_set_static_ADDBASETEXTURE2 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND1 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND2 + psh_forgot_to_set_static_EXTRACTGREENALPHA + psh_forgot_to_set_static_COLORRAMP + psh_forgot_to_set_static_ANIMBLEND + psh_forgot_to_set_static_ADDSELF + psh_forgot_to_set_static_ALPHATEST + psh_forgot_to_set_static_DEPTHBLEND + 0 +class spritecard_ps40_Dynamic_Index +{ +public: + spritecard_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_spritecard_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/spritecard_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/spritecard_vs40.inc new file mode 100644 index 0000000..df95fe5 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/spritecard_vs40.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class spritecard_vs40_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +public: + spritecard_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 3 * m_nDUALSEQUENCE ) + 0; + } +}; +#define shaderStaticTest_spritecard_vs40 vsh_forgot_to_set_static_DUALSEQUENCE + 0 +class spritecard_vs40_Dynamic_Index +{ +private: + int m_nORIENTATION; +#ifdef _DEBUG + bool m_bORIENTATION; +#endif +public: + void SetORIENTATION( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nORIENTATION = i; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } + void SetORIENTATION( bool i ) + { + m_nORIENTATION = i ? 1 : 0; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } +public: + spritecard_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bORIENTATION = false; +#endif // _DEBUG + m_nORIENTATION = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bORIENTATION; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nORIENTATION ) + 0; + } +}; +#define shaderDynamicTest_spritecard_vs40 vsh_forgot_to_set_dynamic_ORIENTATION + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/unlitgeneric_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlitgeneric_ps40.inc new file mode 100644 index 0000000..b438207 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlitgeneric_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class unlitgeneric_ps40_Static_Index +{ +public: + unlitgeneric_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_unlitgeneric_ps40 0 +class unlitgeneric_ps40_Dynamic_Index +{ +public: + unlitgeneric_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_unlitgeneric_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/unlitgeneric_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlitgeneric_vs40.inc new file mode 100644 index 0000000..5bad5b4 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlitgeneric_vs40.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class unlitgeneric_vs40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nMODEL; +#ifdef _DEBUG + bool m_bMODEL; +#endif +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } + void SetMODEL( bool i ) + { + m_nMODEL = i ? 1 : 0; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } +public: + unlitgeneric_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + m_nMODEL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bMODEL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nVERTEXCOLOR ) + ( 2 * m_nMODEL ) + 0; + } +}; +#define shaderStaticTest_unlitgeneric_vs40 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_MODEL + 0 +class unlitgeneric_vs40_Dynamic_Index +{ +public: + unlitgeneric_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_unlitgeneric_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/unlittwotexture_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlittwotexture_ps40.inc new file mode 100644 index 0000000..39b03eb --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlittwotexture_ps40.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class unlittwotexture_ps40_Static_Index +{ +public: + unlittwotexture_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_unlittwotexture_ps40 0 +class unlittwotexture_ps40_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + unlittwotexture_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_unlittwotexture_ps40 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/unlittwotexture_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlittwotexture_vs40.inc new file mode 100644 index 0000000..7283871 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/unlittwotexture_vs40.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class unlittwotexture_vs40_Static_Index +{ +public: + unlittwotexture_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_unlittwotexture_vs40 0 +class unlittwotexture_vs40_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + unlittwotexture_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_unlittwotexture_vs40 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/vertexlit_and_unlit_generic_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/vertexlit_and_unlit_generic_ps40.inc new file mode 100644 index 0000000..579dda2 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/vertexlit_and_unlit_generic_ps40.inc @@ -0,0 +1,837 @@ +#include "shaderlib/cshader.h" +class vertexlit_and_unlit_generic_ps40_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMMASK; +#ifdef _DEBUG + bool m_bSELFILLUMMASK; +#endif +public: + void SetSELFILLUMMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMMASK = i; +#ifdef _DEBUG + m_bSELFILLUMMASK = true; +#endif + } + void SetSELFILLUMMASK( bool i ) + { + m_nSELFILLUMMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMMASK = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +private: + int m_nALPHATEST; +#ifdef _DEBUG + bool m_bALPHATEST; +#endif +public: + void SetALPHATEST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHATEST = i; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } + void SetALPHATEST( bool i ) + { + m_nALPHATEST = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHATEST = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +public: + vertexlit_and_unlit_generic_ps40_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMMASK = false; +#endif // _DEBUG + m_nSELFILLUMMASK = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; +#ifdef _DEBUG + m_bALPHATEST = false; +#endif // _DEBUG + m_nALPHATEST = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bBUMPMAP && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bSELFILLUMMASK && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bLIGHTWARPTEXTURE && m_bVERTEXCOLOR && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bDEPTHBLEND && m_bALPHATEST && m_bBLENDTINTBYBASEALPHA; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 384 * m_nDETAILTEXTURE ) + ( 768 * m_nBUMPMAP ) + ( 1536 * m_nCUBEMAP ) + ( 3072 * m_nDIFFUSELIGHTING ) + ( 6144 * m_nENVMAPMASK ) + ( 12288 * m_nBASEALPHAENVMAPMASK ) + ( 24576 * m_nSELFILLUM ) + ( 49152 * m_nSELFILLUMMASK ) + ( 98304 * m_nSELFILLUMFRESNEL ) + ( 196608 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 393216 * m_nHALFLAMBERT ) + ( 786432 * m_nLIGHTWARPTEXTURE ) + ( 1572864 * m_nVERTEXCOLOR ) + ( 3145728 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 6291456 * m_nSEAMLESS_BASE ) + ( 12582912 * m_nSEAMLESS_DETAIL ) + ( 25165824 * m_nDISTANCEALPHA ) + ( 50331648 * m_nDISTANCEALPHAFROMDETAIL ) + ( 100663296 * m_nSOFT_MASK ) + ( 201326592 * m_nOUTLINE ) + ( 402653184 * m_nOUTER_GLOW ) + ( 805306368 * m_nDEPTHBLEND ) + ( 1610612736 * m_nALPHATEST ) + ( 3221225472 * m_nBLENDTINTBYBASEALPHA ) + 0; + } +}; +#define shaderStaticTest_vertexlit_and_unlit_generic_ps40 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMMASK + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_ALPHATEST + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + 0 +class vertexlit_and_unlit_generic_ps40_Dynamic_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nPHONGWARPTEXTURE; +#ifdef _DEBUG + bool m_bPHONGWARPTEXTURE; +#endif +public: + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } + void SetPHONGWARPTEXTURE( bool i ) + { + m_nPHONGWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } +private: + int m_nRIMLIGHT; +#ifdef _DEBUG + bool m_bRIMLIGHT; +#endif +public: + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } + void SetRIMLIGHT( bool i ) + { + m_nRIMLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } +public: + vertexlit_and_unlit_generic_ps40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = false; +#endif // _DEBUG + m_nPHONGWARPTEXTURE = 0; +#ifdef _DEBUG + m_bRIMLIGHT = false; +#endif // _DEBUG + m_nRIMLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFLASHLIGHTSHADOWS && m_bAMBIENT_LIGHT && m_bPHONG && m_bWRINKLEMAP && m_bPHONGWARPTEXTURE && m_bRIMLIGHT; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFLASHLIGHT ) + ( 2 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 6 * m_nFLASHLIGHTSHADOWS ) + ( 12 * m_nAMBIENT_LIGHT ) + ( 24 * m_nPHONG ) + ( 48 * m_nWRINKLEMAP ) + ( 96 * m_nPHONGWARPTEXTURE ) + ( 192 * m_nRIMLIGHT ) + 0; + } +}; +#define shaderDynamicTest_vertexlit_and_unlit_generic_ps40 psh_forgot_to_set_dynamic_FLASHLIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_PHONG + psh_forgot_to_set_dynamic_WRINKLEMAP + psh_forgot_to_set_dynamic_PHONGWARPTEXTURE + psh_forgot_to_set_dynamic_RIMLIGHT + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/vertexlit_and_unlit_generic_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/vertexlit_and_unlit_generic_vs40.inc new file mode 100644 index 0000000..4f99016 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/vertexlit_and_unlit_generic_vs40.inc @@ -0,0 +1,462 @@ +#include "shaderlib/cshader.h" +class vertexlit_and_unlit_generic_vs40_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nSEPARATE_DETAIL_UVS; +#ifdef _DEBUG + bool m_bSEPARATE_DETAIL_UVS; +#endif +public: + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } + void SetSEPARATE_DETAIL_UVS( bool i ) + { + m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +public: + vertexlit_and_unlit_generic_vs40_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = false; +#endif // _DEBUG + m_nSEPARATE_DETAIL_UVS = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bBUMPMAP && m_bWRINKLEMAP && m_bDECAL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 256 * m_nVERTEXCOLOR ) + ( 512 * m_nCUBEMAP ) + ( 1024 * m_nHALFLAMBERT ) + ( 2048 * m_nSEAMLESS_BASE ) + ( 4096 * m_nSEAMLESS_DETAIL ) + ( 8192 * m_nSEPARATE_DETAIL_UVS ) + ( 16384 * m_nBUMPMAP ) + ( 32768 * m_nWRINKLEMAP ) + ( 65536 * m_nDECAL ) + 0; + } +}; +#define shaderStaticTest_vertexlit_and_unlit_generic_vs40 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_WRINKLEMAP + vsh_forgot_to_set_static_DECAL + 0 +class vertexlit_and_unlit_generic_vs40_Dynamic_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + vertexlit_and_unlit_generic_vs40_Dynamic_Index() + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFLASHLIGHT && m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFLASHLIGHT ) + ( 2 * m_nCOMPRESSED_VERTS ) + ( 4 * m_nDYNAMIC_LIGHT ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nDOWATERFOG ) + ( 32 * m_nSKINNING ) + ( 64 * m_nLIGHTING_PREVIEW ) + ( 128 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_vertexlit_and_unlit_generic_vs40 vsh_forgot_to_set_dynamic_FLASHLIGHT + vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/white_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/white_ps40.inc new file mode 100644 index 0000000..4ba6a6a --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/white_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class white_ps40_Static_Index +{ +public: + white_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_white_ps40 0 +class white_ps40_Dynamic_Index +{ +public: + white_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_white_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/wireframe_ps40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/wireframe_ps40.inc new file mode 100644 index 0000000..823da81 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/wireframe_ps40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class wireframe_ps40_Static_Index +{ +public: + wireframe_ps40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_wireframe_ps40 0 +class wireframe_ps40_Dynamic_Index +{ +public: + wireframe_ps40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_wireframe_ps40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/wireframe_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/wireframe_vs40.inc new file mode 100644 index 0000000..542fe67 --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/wireframe_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class wireframe_vs40_Static_Index +{ +public: + wireframe_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_wireframe_vs40 0 +class wireframe_vs40_Dynamic_Index +{ +public: + wireframe_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_wireframe_vs40 0 diff --git a/materialsystem/stdshadersdx11/fxctmp9_tmp/writez_vs40.inc b/materialsystem/stdshadersdx11/fxctmp9_tmp/writez_vs40.inc new file mode 100644 index 0000000..43dea1b --- /dev/null +++ b/materialsystem/stdshadersdx11/fxctmp9_tmp/writez_vs40.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class writez_vs40_Static_Index +{ +public: + writez_vs40_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_writez_vs40 0 +class writez_vs40_Dynamic_Index +{ +public: + writez_vs40_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_writez_vs40 0 diff --git a/materialsystem/stdshadersdx11/genwaterloop.pl b/materialsystem/stdshadersdx11/genwaterloop.pl new file mode 100644 index 0000000..64ad065 --- /dev/null +++ b/materialsystem/stdshadersdx11/genwaterloop.pl @@ -0,0 +1,9 @@ +for($ix=-2;$ix<=2;$ix++) +{ + for($iy=-2;$iy<=2;$iy++) + { + print "vRefractColor += tex2D( RefractSampler, vRefractTexCoord + $ix * ddx1 + $iy * ddy1 );\n"; + $sumweights+=1; + } +} +print "float sumweights = $sumweights;\n"; diff --git a/materialsystem/stdshadersdx11/inclist.txt b/materialsystem/stdshadersdx11/inclist.txt new file mode 100644 index 0000000..93224d1 --- /dev/null +++ b/materialsystem/stdshadersdx11/inclist.txt @@ -0,0 +1,26 @@ +fxctmp9_tmp\bik_vs40.inc +fxctmp9_tmp\bik_ps40.inc +fxctmp9_tmp\unlitgeneric_vs40.inc +fxctmp9_tmp\unlitgeneric_ps40.inc +fxctmp9_tmp\white_ps40.inc +fxctmp9_tmp\writez_vs40.inc +fxctmp9_tmp\modulate_ps40.inc +fxctmp9_tmp\modulate_vs40.inc +fxctmp9_tmp\splinecard_vs40.inc +fxctmp9_tmp\spritecard_vs40.inc +fxctmp9_tmp\spritecard_ps40.inc +fxctmp9_tmp\sprite_ps40.inc +fxctmp9_tmp\sprite_vs40.inc +fxctmp9_tmp\sky_vs40.inc +fxctmp9_tmp\sky_ps40.inc +fxctmp9_tmp\sky_hdr_compressed_rgbs_ps40.inc +fxctmp9_tmp\sky_hdr_compressed_ps40.inc +fxctmp9_tmp\decalmodulate_ps40.inc +fxctmp9_tmp\vertexlit_and_unlit_generic_vs40.inc +fxctmp9_tmp\vertexlit_and_unlit_generic_ps40.inc +fxctmp9_tmp\depthtodestalpha_vs40.inc +fxctmp9_tmp\depthtodestalpha_ps40.inc +fxctmp9_tmp\wireframe_ps40.inc +fxctmp9_tmp\wireframe_vs40.inc +fxctmp9_tmp\lightmappedgeneric_ps40.inc +fxctmp9_tmp\lightmappedgeneric_vs40.inc diff --git a/materialsystem/stdshadersdx11/lightinfo_fxc.h b/materialsystem/stdshadersdx11/lightinfo_fxc.h new file mode 100644 index 0000000..05fe0ca --- /dev/null +++ b/materialsystem/stdshadersdx11/lightinfo_fxc.h @@ -0,0 +1,19 @@ +#ifndef LIGHTINFO_FXC_H +#define LIGHTINFO_FXC_H + +// w components of color and dir indicate light type: +// 1x - directional +// 01 - spot +// 00 - point +struct LightInfo +{ + float4 color; // {xyz} is color w is light type code (see comment below) + float4 dir; // {xyz} is dir w is light type code + float4 pos; + float4 spotParams; + float4 atten; +}; + +#define MAX_NUM_LIGHTS 4 + +#endif // LIGHTINFO_FXC_H \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_dx11.cpp b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11.cpp new file mode 100644 index 0000000..ea9780c --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11.cpp @@ -0,0 +1,184 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#if 1 +#include "BaseVSShader.h" +#include "convar.h" +#include "lightmappedgeneric_dx11_helper.h" + +static LightmappedGeneric_DX11_Vars_t s_info; + +BEGIN_VS_SHADER( LightmappedGeneric, + "Help for LightmappedGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + + SHADER_PARAM( ALPHA2, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "Blended texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) + SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures." ) + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha." ); +SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha." ); + +SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures." ) +SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) +SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline" ) +SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline" ) +SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline" ) +SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline" ) +SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline" ) + +SHADER_PARAM( ENVMAPPARALLAX, SHADER_PARAM_TYPE_MATRIX, "[1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1]", "" ) +SHADER_PARAM( ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "The world space position of the env_cubemap being corrected" ) + +SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) +SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) +SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) +SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) +END_SHADER_PARAMS + +void SetupVars( LightmappedGeneric_DX11_Vars_t &info ) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nAlpha2 = ALPHA2; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + + info.m_nEnvmapParallax = ENVMAPPARALLAX; + info.m_nEnvmapOrigin = ENVMAPORIGIN; + + info.m_nPhong = PHONG; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhongExponent = PHONGEXPONENT; +} + +SHADER_FALLBACK +{ + return 0; +} + +// Set up anything that is necessary to make decisions in SHADER_FALLBACK. +SHADER_INIT_PARAMS() +{ + SetupVars( s_info ); + InitParamsLightmappedGeneric_DX11( this, params, pMaterialName, s_info ); +} + +SHADER_INIT_GLOBAL +{ + g_hLightmappedGeneric_CBuffer = pShaderDevice->CreateConstantBuffer( sizeof( LightmappedGeneric_CBuffer_t ) ); +} + +SHADER_INIT +{ + SetupVars( s_info ); + InitLightmappedGeneric_DX11( this, params, s_info ); +} + +SHADER_DRAW +{ + DrawLightmappedGeneric_DX11( this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr ); +} +END_SHADER + +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_helper.cpp b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_helper.cpp new file mode 100644 index 0000000..819aeab --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_helper.cpp @@ -0,0 +1,1235 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//============================================================================= + +#include "lightmappedgeneric_dx11_helper.h" +#include "BaseVSShader.h" +#include "../stdshaders/commandbuilder.h" +#include "convar.h" +#include "tier0/vprof.h" + +#include + +#include "lightmappedgeneric_ps40.inc" +#include "lightmappedgeneric_vs40.inc" + +//#include "lightmappedadv_flashlight_ps30.inc" +//#include "lightmappedadv_flashlight_vs30.inc" + +#include "tier0/memdbgon.h" + +ConVar mat_disable_lightwarp( "mat_disable_lightwarp", "0" ); +ConVar mat_disable_fancy_blending( "mat_disable_fancy_blending", "0" ); +ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_csm_blend_tweak( "r_csm_blend_tweak", "16" ); + +ConVar mat_enable_lightmapped_phong( "mat_enable_lightmapped_phong", "1", FCVAR_ARCHIVE, "If 1, allow phong on world brushes. If 0, disallow. mat_force_lightmapped_phong does not work if this value is 0." ); +ConVar mat_force_lightmapped_phong( "mat_force_lightmapped_phong", "1", FCVAR_CHEAT, "Forces the use of phong on all LightmappedAdv textures, regardless of setting in VMT." ); +ConVar mat_force_lightmapped_phong_boost( "mat_force_lightmapped_phong_boost", "5.0", FCVAR_CHEAT ); +ConVar mat_force_lightmapped_phong_exp( "mat_force_lightmapped_phong_exp", "50.0", FCVAR_CHEAT ); + +static ALIGN16 LightmappedGeneric_CBuffer_t s_LightmappedGeneric_CBuffer; +ConstantBufferHandle_t g_hLightmappedGeneric_CBuffer; + +// The idea behind the context is to only query the material parameters and calculate stuff +// on shadow state or when the material's parameters have changed. This way, in dynamic state, +// we can update constants and bind stuff as quickly as possible. +class CLightmappedGeneric_DX11_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + bool m_bVertexShaderFastPath; + bool m_bPixelShaderFastPath; + bool m_bPixelShaderForceFastPathBecauseOutline; + bool m_bFullyOpaque; + bool m_bFullyOpaqueWithoutAlphaTest; + bool m_bSeamlessMapping; + bool m_bHasBlendMaskTransform; + bool m_bHasTextureTransform; + bool m_bHasEnvmapMask; + bool m_bHasBump; + bool m_bHasBump2; + bool m_bHasDetailTexture; + bool m_bHasEnvmap; + bool m_bHasOutline; + bool m_bHasSoftEdges; + + LightmappedGeneric_CBuffer_t m_Constants; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CLightmappedGeneric_DX11_Context( void ) + { + m_pStaticCmds = NULL; + m_bSeamlessMapping = false; + m_bHasBlendMaskTransform = false; + m_bHasTextureTransform = false; + m_bHasEnvmapMask = false; + m_bHasBump = false; + m_bHasBump2 = false; + m_bHasDetailTexture = false; + m_bHasOutline = false; + m_bHasSoftEdges = false; + } + + ~CLightmappedGeneric_DX11_Context( void ) + { + ResetStaticCmds(); + } + +}; + +void DrawLightmappedAdvFlashlight_DX11_Internal( CBaseVSShader *pShader, IMaterialVar **params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow *pShaderShadow, const LightmappedAdvFlashlight_DX11_Vars_t &vars ) +{ +#if 0 + Assert( vars.m_bLightmappedGeneric ); + + bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture(); + bool bSeamless = vars.m_fSeamlessScale != 0.0; + bool bDetail = ( vars.m_nDetailVar != -1 ) && params[vars.m_nDetailVar]->IsDefined() && ( vars.m_nDetailScale != -1 ); + bool bPhong = params[vars.m_nPhong]->GetIntValue() != 0; + + int nDetailBlendMode = 0; + if ( bDetail ) + { +// nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params ); +// nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + } + + PhongMaskVariant_t nPhongMaskVariant = PHONGMASK_NONE; + if ( bPhong ) + { + if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + nPhongMaskVariant = PHONGMASK_BASEALPHA; + } + else if ( IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) ) + { + nPhongMaskVariant = PHONGMASK_NORMALALPHA; + } + else if ( params[vars.m_nPhongMask]->IsDefined() ) + { + nPhongMaskVariant = PHONGMASK_STANDALONE; + } + } + + if ( pShaderShadow ) + { + pShader->SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + // Alpha blend + pShader->SetAdditiveBlendingShadowState( BASETEXTURE, true ); + + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() ); + } + + // Spot sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // Base sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + // Normalizing cubemap sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // Normalizing cubemap sampler2 or normal map sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + // RandomRotation sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + // Flashlight depth sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); + + if ( vars.m_bWorldVertexTransition ) + { + // $basetexture2 + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if ( bBump2 ) + { + // Normalmap2 sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + } + if ( bDetail ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + if ( nPhongMaskVariant == PHONGMASK_STANDALONE ) + { + // phong mask sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedadv_flashlight_vs40 ); + SET_STATIC_VERTEX_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); + SET_STATIC_VERTEX_SHADER_COMBO( NORMALMAP, vars.m_bBump ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_VERTEX_SHADER_COMBO( DETAIL, bDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( PHONG, bPhong ); + SET_STATIC_VERTEX_SHADER( lightmappedadv_flashlight_vs40 ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + if ( vars.m_bBump ) + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + int numTexCoords = 1; + if ( vars.m_bWorldVertexTransition ) + { + flags |= VERTEX_COLOR; + numTexCoords = 2; // need lightmap texcoords to get alpha. + } + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + int nBumpMapVariant = 0; + if ( vars.m_bBump ) + { + nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1; + } + + DECLARE_STATIC_PIXEL_SHADER( lightmappedadv_flashlight_ps40 ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONG, bPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGMASK, nPhongMaskVariant ); + SET_STATIC_PIXEL_SHADER( lightmappedadv_flashlight_ps40 ); + + pShader->FogToBlack(); + } + else + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + if ( pFlashlightDepthTexture == NULL ) + { + const int iFlashlightShadowIndex = ( flashlightState.m_nShadowQuality >> 16 ) & 0xFF; + + if ( iFlashlightShadowIndex >= 0 + && iFlashlightShadowIndex <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) + { + pFlashlightDepthTexture = (ITexture *)pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); + } + } + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + pShader->BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if ( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = { 1280.0f / 32.0f, 720.0f / 32.0f, 0, 0 }; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = static_cast( nWidth ) / 32.0f; + vScreenScale[1] = static_cast( nHeight ) / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + + if ( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 ) + { + pShader->BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + if ( vars.m_bWorldVertexTransition ) + { + Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 ); + pShader->BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + if ( vars.m_bBump ) + { + pShader->BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + } + + if ( bDetail ) + { + pShader->BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar ); + } + + if ( bBump2 ) + { + pShader->BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame ); + } + + if ( nPhongMaskVariant == PHONGMASK_STANDALONE ) + { + pShader->BindTexture( SHADER_SAMPLER9, vars.m_nPhongMask, vars.m_nPhongMaskFrame ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedadv_flashlight_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( lightmappedadv_flashlight_vs40 ); + + if ( bSeamless ) + { + float const0[4] = { vars.m_fSeamlessScale,0,0,0 }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 ); + } + + if ( bDetail ) + { + float vDetailConstants[4] = { 1,1,1,1 }; + + if ( vars.m_nDetailTint != -1 ) + { + params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 ); + } + + if ( vars.m_nDetailTextureBlendFactor != -1 ) + { + vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 ); + } + + if ( bPhong ) + { + float vEyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + vEyePos[3] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, vEyePos ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = params[vars.m_nPhongExponent]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + static IShaderDynamicAPI *shaderAPI; + shaderAPI = pShaderAPI; + + auto func = []( int var, const float *pVec, int nConsts ) + { + shaderAPI->SetPixelShaderConstant( var, pVec, nConsts ); + }; + + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedadv_flashlight_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, flashlightState.m_bUberlight ); + SET_DYNAMIC_PIXEL_SHADER( lightmappedadv_flashlight_ps40 ); + + float atten[4]; // Set the flashlight attenuation factors + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + float lightPos[4]; + lightPos[0] = flashlightState.m_vecLightOrigin[0]; + lightPos[1] = flashlightState.m_vecLightOrigin[1]; + lightPos[2] = flashlightState.m_vecLightOrigin[2]; + lightPos[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 1, lightPos, 1 ); + + float specParams[4]; + params[vars.m_nPhongFresnelRanges]->GetVecValue( specParams, 3 ); + specParams[3] = params[vars.m_nPhongBoost]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, specParams, 1 ); + + pShader->SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true ); + } + pShader->Draw(); +#endif +} + +void InitParamsLightmappedGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, const char *pMaterialName, LightmappedGeneric_DX11_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() && + !( params[info.m_nNoDiffuseBumpLighting]->IsDefined() && params[info.m_nNoDiffuseBumpLighting]->GetIntValue() ) ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + if ( pShader->IsUsingGraphics() && params[info.m_nEnvmap]->IsDefined() && !pShader->CanUseEditorMaterials() ) + { + if ( stricmp( params[info.m_nEnvmap]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + if ( ( mat_disable_lightwarp.GetBool() ) && + ( info.m_nLightWarpTexture != -1 ) ) + { + params[info.m_nLightWarpTexture]->SetUndefined(); + } + if ( ( mat_disable_fancy_blending.GetBool() ) && + ( info.m_nBlendModulateTexture != -1 ) ) + { + params[info.m_nBlendModulateTexture]->SetUndefined(); + } + + if ( !params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if ( !params[info.m_nNoDiffuseBumpLighting]->IsDefined() ) + params[info.m_nNoDiffuseBumpLighting]->SetIntValue( 0 ); + + if ( !params[info.m_nSelfIllumTint]->IsDefined() ) + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if ( !params[info.m_nDetailScale]->IsDefined() ) + params[info.m_nDetailScale]->SetFloatValue( 4.0f ); + + if ( !params[info.m_nDetailTint]->IsDefined() ) + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f, 1.0f ); + + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nDetailTextureCombineMode, params, 0 ); + + if ( !params[info.m_nFresnelReflection]->IsDefined() ) + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + + if ( !params[info.m_nEnvmapMaskFrame]->IsDefined() ) + params[info.m_nEnvmapMaskFrame]->SetIntValue( 0 ); + + if ( !params[info.m_nEnvmapFrame]->IsDefined() ) + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + + if ( !params[info.m_nBumpFrame]->IsDefined() ) + params[info.m_nBumpFrame]->SetIntValue( 0 ); + + if ( !params[info.m_nDetailFrame]->IsDefined() ) + params[info.m_nDetailFrame]->SetIntValue( 0 ); + + if ( !params[info.m_nEnvmapContrast]->IsDefined() ) + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + + if ( !params[info.m_nEnvmapSaturation]->IsDefined() ) + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // If in decal mode, no debug override... + if ( IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && ( params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0 ) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + // If mat_specular 0, then get rid of envmap + if ( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + if ( !params[info.m_nBaseTextureNoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTextureNoEnvmap]->SetIntValue( 0 ); + } + if ( !params[info.m_nBaseTexture2NoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTexture2NoEnvmap]->SetIntValue( 0 ); + } + + if ( ( info.m_nSelfShadowedBumpFlag != -1 ) && + ( !params[info.m_nSelfShadowedBumpFlag]->IsDefined() ) + ) + { + params[info.m_nSelfShadowedBumpFlag]->SetIntValue( 0 ); + } + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); + + if ( !params[info.m_nPhong]->IsDefined() || !mat_enable_lightmapped_phong.GetBool() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + if ( !params[info.m_nPhongBoost]->IsDefined() ) + { + params[info.m_nPhongBoost]->SetFloatValue( 1.0 ); + } + if ( !params[info.m_nPhongFresnelRanges]->IsDefined() ) + { + params[info.m_nPhongFresnelRanges]->SetVecValue( 0.0, 0.5, 1.0 ); + } + if ( !params[info.m_nPhongExponent]->IsDefined() ) + { + params[info.m_nPhongExponent]->SetFloatValue( 5.0 ); + } + + if ( params[info.m_nPhong]->GetIntValue() && mat_enable_lightmapped_phong.GetBool() ) + { + if ( pShader->CanUseEditorMaterials() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + else if ( !params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ) + { + Warning( "Warning! material %s: $envmapmasktransform and $phong are mutial exclusive. Disabling phong..\n", pMaterialName ); + params[info.m_nPhong]->SetIntValue( 0 ); + } + } + else if ( mat_force_lightmapped_phong.GetBool() && mat_enable_lightmapped_phong.GetBool() && + params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ) + { + params[info.m_nPhong]->SetIntValue( 1 ); + params[info.m_nPhongBoost]->SetFloatValue( mat_force_lightmapped_phong_boost.GetFloat() ); + params[info.m_nPhongFresnelRanges]->SetVecValue( 0.0, 0.5, 1.0 ); + params[info.m_nPhongExponent]->SetFloatValue( mat_force_lightmapped_phong_exp.GetFloat() ); + } + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); +} + +void InitLightmappedGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, LightmappedGeneric_DX11_Vars_t &info ) +{ + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap2 ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpMask]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpMask ); + } + + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture ); + + if ( !params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if ( params[info.m_nBaseTexture2]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2 ); + } + + if ( params[info.m_nLightWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nLightWarpTexture ); + } + + if ( ( info.m_nBlendModulateTexture != -1 ) && + ( params[info.m_nBlendModulateTexture]->IsDefined() ) ) + { + pShader->LoadTexture( info.m_nBlendModulateTexture ); + } + + if ( params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + + pShader->LoadTexture( info.m_nDetail/*, nDetailBlendMode != 0 ? TEXTUREFLAGS_SRGB : 0*/ ); + } + + pShader->LoadTexture( info.m_nFlashlightTexture ); + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) || IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if ( params[info.m_nEnvmap]->IsDefined() ) + { + if ( !IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ) + { + pShader->LoadCubeMap( info.m_nEnvmap/*, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0*/ ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if ( params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + } + else + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // We always need this because of the flashlight. + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); +} + +void DrawLightmappedGeneric_DX11_Internal( CBaseVSShader *pShader, IMaterialVar **params, bool hasFlashlight, + IShaderDynamicAPI *pShaderAPI, IShaderShadow *pShaderShadow, + LightmappedGeneric_DX11_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr +) +{ + VPROF_BUDGET( "DrawLightmappedGeneric_DX11", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + CLightmappedGeneric_DX11_Context *pContextData = reinterpret_cast ( *pContextDataPtr ); + if ( pShaderShadow || ( !pContextData ) || pContextData->m_bMaterialVarsChanged || hasFlashlight ) + { + bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); + int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask; + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bFullyOpaqueWithoutAlphaTest = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && ( !hasFlashlight || IsX360() ); //dest alpha is free for special use + bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested; + bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; + + if ( !pContextData ) // make sure allocated + { + pContextData = new CLightmappedGeneric_DX11_Context; + *pContextDataPtr = pContextData; + } + + pContextData->m_bHasBump = ( params[info.m_nBumpmap]->IsTexture() ) && ( !g_pHardwareConfig->PreferReducedFillrate() ); + bool hasSSBump = pContextData->m_bHasBump && ( info.m_nSelfShadowedBumpFlag != -1 ) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() ); + bool hasBaseTexture2 = hasBaseTexture && params[info.m_nBaseTexture2]->IsTexture(); + bool hasLightWarpTexture = params[info.m_nLightWarpTexture]->IsTexture(); + pContextData->m_bHasBump2 = pContextData->m_bHasBump && params[info.m_nBumpmap2]->IsTexture(); + bool hasDetailTexture = params[info.m_nDetail]->IsTexture(); + pContextData->m_bHasDetailTexture = hasDetailTexture; + bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool hasBumpMask = pContextData->m_bHasBump && pContextData->m_bHasBump2 && params[info.m_nBumpMask]->IsTexture() && !hasSelfIllum && + !hasDetailTexture && !hasBaseTexture2 && ( params[info.m_nBaseTextureNoEnvmap]->GetIntValue() == 0 ); + bool bHasBlendModulateTexture = + ( info.m_nBlendModulateTexture != -1 ) && + ( params[info.m_nBlendModulateTexture]->IsTexture() ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + if ( hasFlashlight && !IsX360() ) + { + // !!speed!! do this in the caller so we don't build struct every time + LightmappedAdvFlashlight_DX11_Vars_t vars; + vars.m_bBump = pContextData->m_bHasBump; + vars.m_nBumpmapVar = info.m_nBumpmap; + vars.m_nBumpmapFrame = info.m_nBumpFrame; + vars.m_nBumpTransform = info.m_nBumpTransform; + vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture; + vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame; + vars.m_bLightmappedGeneric = true; + vars.m_bWorldVertexTransition = hasBaseTexture2; + vars.m_nBaseTexture2Var = info.m_nBaseTexture2; + vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame; + vars.m_nBumpmap2Var = info.m_nBumpmap2; + vars.m_nBumpmap2Frame = info.m_nBumpFrame2; + vars.m_nBump2Transform = info.m_nBumpTransform2; + vars.m_nAlphaTestReference = info.m_nAlphaTestReference; + vars.m_bSSBump = hasSSBump; + vars.m_nDetailVar = info.m_nDetail; + vars.m_nDetailScale = info.m_nDetailScale; + vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode; + vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; + vars.m_nDetailTint = info.m_nDetailTint; + + if ( ( info.m_nSeamlessMappingScale != -1 ) ) + vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); + else + vars.m_fSeamlessScale = 0.0; + + vars.m_nPhong = info.m_nPhong; + vars.m_nPhongBoost = info.m_nPhongBoost; + vars.m_nPhongFresnelRanges = info.m_nPhongFresnelRanges; + vars.m_nPhongExponent = info.m_nPhongExponent; + vars.m_nPhongMask = info.m_nEnvmapMask; + vars.m_nPhongMaskFrame = info.m_nEnvmapMaskFrame; + + DrawLightmappedAdvFlashlight_DX11_Internal( pShader, params, pShaderAPI, pShaderShadow, vars ); + return; + } + + pContextData->m_bFullyOpaque = bFullyOpaque; + pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest; + + bool bHasOutline = IsBoolSet( info.m_nOutline, params ); + pContextData->m_bHasOutline = bHasOutline; + pContextData->m_bPixelShaderForceFastPathBecauseOutline = bHasOutline; + bool bHasSoftEdges = IsBoolSet( info.m_nSoftEdges, params ); + pContextData->m_bHasSoftEdges = bHasSoftEdges; + pContextData->m_bHasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + + float fDetailBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool hasDiffuseBumpmap = pContextData->m_bHasBump && ( params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0 ); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + pContextData->m_bHasEnvmap = hasEnvmap; + + if ( bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + + if ( !hasBaseTexture ) + { + if ( hasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + pContextData->m_bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + + if ( pContextData->m_bSeamlessMapping ) + { + pContextData->m_Constants.cSeamlessMappingScale.x = params[info.m_nSeamlessMappingScale]->GetFloatValue(); + } + + staticCmdsBuf.End(); + // now, copy buf + pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + if ( pShaderShadow ) + { + pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture ); + + // Bind em + + pShader->SetInternalVertexShaderConstantBuffersNoSkinning(); + pShader->SetVertexShaderConstantBuffer( 3, g_hLightmappedGeneric_CBuffer ); + + pShader->SetInternalPixelShaderConstantBuffers(); + pShader->SetPixelShaderConstantBuffer( 3, g_hLightmappedGeneric_CBuffer ); + + unsigned int flags = VERTEX_POSITION; + + if ( hasEnvmap ) + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; + } + + if ( hasVertexColor || hasBaseTexture2 || pContextData->m_bHasBump2 ) + { + flags |= VERTEX_COLOR; + } + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 2; + if ( pContextData->m_bHasBump ) + { + numTexCoords = 3; + } + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + // Pre-cache pixel shaders + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + + int bumpmap_variant = ( hasSSBump ) ? 2 : pContextData->m_bHasBump; + bool bMaskedBlending = ( ( info.m_nMaskedBlending != -1 ) && + ( params[info.m_nMaskedBlending]->GetIntValue() != 0 ) ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs40 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, pContextData->m_bHasEnvmapMask ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, pContextData->m_bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, pContextData->m_bHasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || pContextData->m_bHasBump2 ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, pContextData->m_bSeamlessMapping ); + SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs40 ); + + + DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps40 ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, pContextData->m_bHasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, pContextData->m_bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, pContextData->m_bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, pContextData->m_bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( ALPHATEST, bIsAlphaTested ); + SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps40 ); + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and writing depth to dest alpha + // But only do it if we're not using the alpha already for translucency + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + + //pShaderShadow->EnableSRGBWrite( true ); + + pShader->DefaultFog(); + + } // end shadow state + } // end shadow || regen display list + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + int nDetailBlendMode = 0; + if ( hasDetailTexture ) + { + nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params ); + ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue(); + if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP ) + { + if ( pContextData->m_bHasBump ) + nDetailBlendMode = 10; // ssbump + else + nDetailBlendMode = 11; // ssbump_nobump + } + } + pContextData->m_Constants.g_DetailBlendMode.x = nDetailBlendMode; + + pContextData->m_bHasBlendMaskTransform = ( + ( info.m_nBlendMaskTransform != -1 ) && + ( info.m_nMaskedBlending != -1 ) && + ( params[info.m_nMaskedBlending]->GetIntValue() ) && + ( !( params[info.m_nBumpTransform]->MatrixIsIdentity() ) ) ); + + // If we don't have a texture transform, we don't have + // to set vertex shader constants or run vertex shader instructions + // for the texture transform. + pContextData->m_bHasTextureTransform = + !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform2]->MatrixIsIdentity() && + params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ); + + pContextData->m_bHasTextureTransform |= pContextData->m_bHasBlendMaskTransform; + + pContextData->m_bVertexShaderFastPath = !pContextData->m_bHasTextureTransform; + + if ( params[info.m_nDetail]->IsTexture() ) + { + pContextData->m_bVertexShaderFastPath = false; + } + if ( pContextData->m_bHasBlendMaskTransform ) + { + pShader->StoreVertexShaderTextureTransform( pContextData->m_Constants.cBlendMaskTexCoordTransform, + info.m_nBlendMaskTransform ); + } + + if ( !pContextData->m_bVertexShaderFastPath ) + { + pContextData->m_bHasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + if ( !pContextData->m_bSeamlessMapping ) + pShader->StoreVertexShaderTextureTransform( pContextData->m_Constants.cBaseTexCoordTransform, info.m_nBaseTextureTransform ); + + // If we have a detail texture, then the bump texcoords are the same as the base texcoords. + if ( pContextData->m_bHasBump && !pContextData->m_bHasDetailTexture ) + { + pShader->StoreVertexShaderTextureTransform( pContextData->m_Constants.cDetailOrBumpTexCoordTransform, info.m_nBumpTransform ); + } + if ( pContextData->m_bHasEnvmapMask ) + { + pShader->StoreVertexShaderTextureTransform( pContextData->m_Constants.cEnvmapMaskOrBump2TexCoordTransform, info.m_nEnvmapMaskTransform ); + } + else if ( pContextData->m_bHasBump2 ) + { + pShader->StoreVertexShaderTextureTransform( pContextData->m_Constants.cEnvmapMaskOrBump2TexCoordTransform, info.m_nBumpTransform2 ); + + } + } + + pShader->StoreEnvmapTint( pContextData->m_Constants.g_EnvmapTint, info.m_nEnvmapTint ); + + // set up shader modulation color + pContextData->m_Constants.cModulationColor.Init( 1, 1, 1, 1 ); + pShader->ComputeModulationColor( pContextData->m_Constants.cModulationColor.Base() ); + float flLScale = pShaderAPI->GetLightMapScaleFactor(); + pContextData->m_Constants.cModulationColor[0] *= flLScale; + pContextData->m_Constants.cModulationColor[1] *= flLScale; + pContextData->m_Constants.cModulationColor[2] *= flLScale; + + pContextData->m_Constants.g_TintValuesAndLightmapScale = pContextData->m_Constants.cModulationColor; + pContextData->m_Constants.g_TintValuesAndLightmapScale[3] *= + ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[info.m_nAlpha2]->GetFloatValue() > 0.0f ) ? params[info.m_nAlpha2]->GetFloatValue() : 1.0f; + //pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color ); + //pContextData->m_TintValuesAndLightmapScale.Init( 0, 0, 1, 1 ); + + if ( pContextData->m_bHasDetailTexture ) + { + pContextData->m_Constants.g_DetailTint_and_BlendFactor.Init( 1, 1, 1, 1 ); + + if ( info.m_nDetailTint != -1 ) + { + params[info.m_nDetailTint]->GetVecValue( pContextData->m_Constants.g_DetailTint_and_BlendFactor.Base(), 3 ); + } + + pContextData->m_Constants.g_DetailTint_and_BlendFactor[3] = fDetailBlendFactor; + + } + + float selfIllumTintVal[4]; + params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 ); + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue(); + float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue(); + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + pContextData->m_bPixelShaderFastPath = true; + bool bUsingContrast = hasEnvmap && ( ( envmapContrast != 0.0f ) && ( envmapContrast != 1.0f ) ) && ( envmapSaturation != 1.0f ); + bool bUsingFresnel = hasEnvmap && ( fresnelReflection != 1.0f ); + bool bUsingSelfIllumTint = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f ); + if ( bUsingContrast || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular ) + { + pContextData->m_bPixelShaderFastPath = false; + } + if ( !pContextData->m_bPixelShaderFastPath ) + { + params[info.m_nEnvmapContrast]->GetVecValue( pContextData->m_Constants.g_EnvmapContrast.Base(), 3 ); + params[info.m_nEnvmapSaturation]->GetVecValue( pContextData->m_Constants.g_EnvmapSaturation.Base(), 3 ); + + float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue(); + // [ 0, 0, 1-R(0), R(0) ] + pContextData->m_Constants.g_FresnelReflectionReg.Init( 0, 0, 1.0 - flFresnel, flFresnel ); + + pContextData->m_Constants.g_SelfIllumTint = params[info.m_nSelfIllumTint]->GetVecValue(); + } + else + { + if ( bHasOutline ) + { + float flOutlineParms[8] = { GetFloatParam( info.m_nOutlineStart0, params ), + GetFloatParam( info.m_nOutlineStart1, params ), + GetFloatParam( info.m_nOutlineEnd0, params ), + GetFloatParam( info.m_nOutlineEnd1, params ), + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ) }; + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flOutlineParms + 4, 3 ); + } + + pContextData->m_Constants.g_OutlineParams[0] = &flOutlineParms[0]; + pContextData->m_Constants.g_OutlineParams[1] = &flOutlineParms[4]; + } + + if ( bHasSoftEdges ) + { + pContextData->m_Constants.g_SoftEdgeParams.Init( + GetFloatParam( info.m_nEdgeSoftnessStart, params ), + GetFloatParam( info.m_nEdgeSoftnessEnd, params ), + 0, 0 ); + } + } + + if ( bIsAlphaTested ) + { + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pContextData->m_Constants.g_AlphaTestRef = params[info.m_nAlphaTestReference]->GetFloatValue(); + } + } + + // texture binds + if ( hasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + // handle mat_fullbright 2 + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if ( bLightingOnly ) + { + // BASE TEXTURE + if ( hasSelfIllum ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // BASE TEXTURE 2 + if ( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_GREY ); + } + + // DETAIL TEXTURE + if ( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_GREY ); + } + + // disable color modulation + pContextData->m_Constants.cModulationColor.Init(); + + // turn off environment mapping + pContextData->m_Constants.g_EnvmapTint.Init(); + } + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + if ( hasDetailTexture ) + { + pShader->StoreVertexShaderTextureScaledTransform( pContextData->m_Constants.cDetailOrBumpTexCoordTransform, info.m_nBaseTextureTransform, info.m_nDetailScale ); + } + + if ( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER6, info.m_nBaseTexture2, info.m_nBaseTexture2Frame ); + } + + if ( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nDetail, info.m_nDetailFrame ); + } + + if ( pContextData->m_bHasBump || hasNormalMapAlphaEnvmapMask ) + { + if ( !g_pConfig->m_bFastNoBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + if ( pContextData->m_bHasBump2 ) + { + if ( !g_pConfig->m_bFastNoBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALMAP_FLAT ); + } + } + if ( hasBumpMask ) + { + if ( !g_pConfig->m_bFastNoBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nBumpMask, -1 ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_NORMALMAP_FLAT ); + } + } + + if ( pContextData->m_bHasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + if ( hasLightWarpTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, info.m_nLightWarpTexture, -1 ); + } + + if ( bHasBlendModulateTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nBlendModulateTexture, -1 ); + } + + pContextData->m_SemiStaticCmdsOut.End(); + } + } + DYNAMIC_STATE + { + static CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Reset(); + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + pShaderAPI->GetFogParamsAndColor( pContextData->m_Constants.g_FogParams.Base(), + pContextData->m_Constants.g_FogColor.Base() ); + + // Upload the constants to the gpu + pShaderAPI->UpdateConstantBuffer( g_hLightmappedGeneric_CBuffer, &pContextData->m_Constants ); + + if ( pContextData->m_bHasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); + + bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath; + + if ( nFixedLightingMode != 0 ) + { + if ( pContextData->m_bPixelShaderForceFastPathBecauseOutline ) + nFixedLightingMode = 0; + else + bVertexShaderFastPath = false; + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_vs40 ); + + bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath; + if ( nFixedLightingMode != 0 ) + { + bPixelShaderFastPath = false; + } + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if ( pContextData->m_bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + AssertMsg( !( bWriteDepthToAlpha && bWriteWaterFogToAlpha ), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && pContextData->m_Constants.g_EnvmapContrast[0] == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps40 ); + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + + pShader->Draw(); + + if ( IsPC() && ( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0 ) && pContextData->m_bFullyOpaqueWithoutAlphaTest ) + { + //Alpha testing makes it so we can't write to dest alpha + //Writing to depth makes it so later polygons can't write to dest alpha either + //This leads to situations with garbage in dest alpha. + + //Fix it now by converting depth to dest alpha for any pixels that just wrote. + pShader->DrawEqualDepthToDestAlpha(); + } +} + +void DrawLightmappedGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow *pShaderShadow, + LightmappedGeneric_DX11_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool hasFlashlight = pShader->UsingFlashlight( params ); + DrawLightmappedGeneric_DX11_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); +} diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_helper.h b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_helper.h new file mode 100644 index 0000000..e6e6868 --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_helper.h @@ -0,0 +1,166 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef LIGHTMAPPEDGENERIC_DX11_HELPER_H +#define LIGHTMAPPEDGENERIC_DX11_HELPER_H + +#include +#include "BaseVSShader.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +ALIGN16 struct LightmappedGeneric_CBuffer_t +{ + // Vertex shader + Vector4D cBaseTexCoordTransform[2]; + Vector4D cDetailOrBumpTexCoordTransform[2]; + Vector4D cEnvmapMaskOrBump2TexCoordTransform[2]; + Vector4D cBlendMaskTexCoordTransform[2]; + Vector4D cSeamlessMappingScale; + Vector4D cModulationColor; + + // Pixel shader + Vector4D g_OutlineParams[2]; + Vector4D g_EnvmapTint; + Vector4D g_FresnelReflectionReg; + Vector4D g_SelfIllumTint; + Vector4D g_DetailTint_and_BlendFactor; + Vector4D g_TintValuesAndLightmapScale; + Vector4D g_SoftEdgeParams; + Vector4D g_EnvmapContrast; + Vector4D g_EnvmapSaturation; + + IntVector4D g_DetailBlendMode; + + Vector4D g_FogParams; + Vector4D g_FogColor; + + float g_AlphaTestRef; +}; + +extern ALIGN16 ConstantBufferHandle_t g_hLightmappedGeneric_CBuffer; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct LightmappedGeneric_DX11_Vars_t +{ + LightmappedGeneric_DX11_Vars_t() + { + memset( this, 0xFF, sizeof( LightmappedGeneric_DX11_Vars_t ) ); + } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nSelfIllumTint; + + int m_nAlpha2; // Hack for DoD srgb blend issues on overlays + + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nFresnelReflection; + int m_nNoDiffuseBumpLighting; + int m_nBumpmap2; + int m_nBumpFrame2; + int m_nBumpTransform2; + int m_nBumpMask; + int m_nBaseTexture2; + int m_nBaseTexture2Frame; + int m_nBaseTextureNoEnvmap; + int m_nBaseTexture2NoEnvmap; + int m_nDetailAlphaMaskBaseTexture; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + int m_nLightWarpTexture; + int m_nBlendModulateTexture; + int m_nMaskedBlending; + int m_nBlendMaskTransform; + int m_nSelfShadowedBumpFlag; + int m_nSeamlessMappingScale; + int m_nAlphaTestReference; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + + int m_nEnvmapParallax; + int m_nEnvmapOrigin; + + int m_nPhong; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nPhongExponent; +}; + +enum PhongMaskVariant_t +{ + PHONGMASK_NONE, + PHONGMASK_BASEALPHA, + PHONGMASK_NORMALALPHA, + PHONGMASK_STANDALONE, +}; + +struct LightmappedAdvFlashlight_DX11_Vars_t : public CBaseVSShader::DrawFlashlight_dx90_Vars_t +{ + LightmappedAdvFlashlight_DX11_Vars_t() + : m_nPhong( -1 ) + , m_nPhongBoost( -1 ) + , m_nPhongFresnelRanges( -1 ) + , m_nPhongExponent( -1 ) + , m_nPhongMask( -1 ) + , m_nPhongMaskFrame( -1 ) + { + } + int m_nPhong; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nPhongExponent; + int m_nPhongMask; + int m_nPhongMaskFrame; +}; + +void InitParamsLightmappedGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, const char *pMaterialName, LightmappedGeneric_DX11_Vars_t &info ); +void InitLightmappedGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, LightmappedGeneric_DX11_Vars_t &info ); +void DrawLightmappedGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow *pShaderShadow, + LightmappedGeneric_DX11_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr ); + + +#endif // LIGHTMAPPEDGENERIC_DX11_HELPER_H \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_shared_fxc.h b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_shared_fxc.h new file mode 100644 index 0000000..39a7fd9 --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_dx11_shared_fxc.h @@ -0,0 +1,33 @@ +#ifndef LIGHTMAPPEDGENERIC_DX11_SHARED_FXC_H_ +#define LIGHTMAPPEDGENERIC_DX11_SHARED_FXC_H_ + +struct LightmappedGeneric_t +{ + // Vertex shader + float4 cBaseTexCoordTransform[2]; + float4 cDetailOrBumpTexCoordTransform[2]; + float4 cEnvmapMaskTexCoordTransform[2]; + float4 cBlendMaskTexCoordTransform[2]; + float4 cSeamlessScale; + float4 cModulationColor; + + // Pixel shader + float4 g_OutlineParamsAndColor[2]; + float4 g_EnvmapTint; + float4 cFresnelReflection; + float4 cSelfIllumTint; + float4 g_DetailTint_and_BlendFactor; + float4 g_TintValuesAndLightmapScale; + float4 g_EdgeSoftnessParms; + float4 cEnvmapContrast; + float4 cEnvmapSaturation; + + int4 g_DetailBlendMode; + + float4 g_FogParams; + float4 g_FogColor; + + float g_AlphaTestRef; +}; + +#endif // LIGHTMAPPEDGENERIC_DX11_SHARED_FXC_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.fxc b/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.fxc new file mode 100644 index 0000000..4ee7d8a --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.fxc @@ -0,0 +1,41 @@ +// STATIC: "MASKEDBLENDING" "0..1" +// STATIC: "BASETEXTURE2" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..2" +// STATIC: "BUMPMAP2" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "BASETEXTURENOENVMAP" "0..1" +// STATIC: "BASETEXTURE2NOENVMAP" "0..1" +// STATIC: "WARPLIGHTING" "0..1" +// STATIC: "FANCY_BLENDING" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "ALPHATEST" "0..1" + +#define NORMALMASK_DECODE_MODE 0 +#define NORMAL_DECODE_MODE 0 +#define RELIEF_MAPPING 0 + +// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +// _SKIP: $SEAMLESS && $RELIEF_MAPPING [ps20b] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// SKIP: ($DETAIL_BLEND_MODE == 2 ) || ($DETAIL_BLEND_MODE == 3 ) || ($DETAIL_BLEND_MODE == 4 ) +// SKIP: ($DETAIL_BLEND_MODE == 5 ) || ($DETAIL_BLEND_MODE == 6 ) || ($DETAIL_BLEND_MODE == 7 ) +// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 ) +// SKIP: ($DETAIL_BLEND_MODE == 10 ) && ($BUMPMAP == 0 ) +// SKIP: ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 ) + +#include "lightmappedgeneric_ps40.h" + diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.h b/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.h new file mode 100644 index 0000000..e4f1875 --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_ps40.h @@ -0,0 +1,544 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// SKIP: $BUMPMAP2 && $WARPLIGHTING +// SKIP: $WARPLIGHTING && $DETAILTEXTURE +// SKIP: $ENVMAPMASK && $BUMPMAP +// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK +// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST +// SKIP: !$FASTPATH && $FASTPATHENVMAPTINT +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: !$BUMPMAP && $BUMPMAP2 +// SKIP: $ENVMAPMASK && $BUMPMAP2 +// SKIP: $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// SKIP: $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// SKIP: $BASEALPHAENVMAPMASK && $BUMPMAP +// SKIP: $PARALLAXMAP && $DETAILTEXTURE +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $SEAMLESS && $DETAILTEXTURE +// SKIP: $SEAMLESS && $MASKEDBLENDING +// SKIP: $BUMPMASK && ( $SEAMLESS || $DETAILTEXTURE || $SELFILLUM || $BASETEXTURENOENVMAP || $BASETEXTURE2 ) +// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 1) +// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 2) +// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 1) +// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 2) +// NOSKIP: $FANCY_BLENDING && (!$FASTPATH) + +// debug crap: +// NOSKIP: $DETAILTEXTURE +// NOSKIP: $CUBEMAP +// NOSKIP: $ENVMAPMASK +// NOSKIP: $BASEALPHAENVMAPMASK +// NOSKIP: $SELFILLUM + +#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp + +// Define the common constant buffers we will use +#include "common_cbuffers_def_noskinning_fxc.h" + +#include "common_ps_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_lightmappedgeneric_fxc.h" +#include "lightmappedgeneric_dx11_shared_fxc.h" + +#if SEAMLESS +#define USE_FAST_PATH 1 +#else +#define USE_FAST_PATH FASTPATH +#endif + +cbuffer LightmappedGeneric_PS : register( b3 ) +{ + LightmappedGeneric_t c; +}; + +#define g_OutlineParams c.g_OutlineParamsAndColor[0] +#define g_OutlineColor c.g_OutlineParamsAndColor[1] + +#if USE_FAST_PATH == 1 + + #if FASTPATHENVMAPCONTRAST == 0 + static const float3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f }; + #else + static const float3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f }; + #endif + static const float3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f }; + static const float g_FresnelReflection = 1.0f; + static const float g_OneMinusFresnelReflection = 0.0f; + static const float4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f }; + #if OUTLINE + #define OUTLINE_MIN_VALUE0 g_OutlineParams.x + #define OUTLINE_MIN_VALUE1 g_OutlineParams.y + #define OUTLINE_MAX_VALUE0 g_OutlineParams.z + #define OUTLINE_MAX_VALUE1 g_OutlineParams.w + #define OUTLINE_COLOR g_OutlineColor + #endif + #if SOFTEDGES + #define SOFT_MASK_MIN g_EdgeSoftnessParms.x + #define SOFT_MASK_MAX g_EdgeSoftnessParms.y + #endif +#else +#define g_EnvmapContrast c.cEnvmapContrast.xyz +#define g_EnvmapSaturation c.cEnvmapSaturation.xyz +#define g_SelfIllumTint c.cSelfIllumTint +#define g_FresnelReflection c.cFresnelReflection.a +#define g_OneMinusFresnelReflection c.cFresnelReflection.b +#endif + +#define g_DetailTint (c.g_DetailTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (c.g_DetailTint_and_BlendFactor.w) + +#define g_flAlpha2 c.g_TintValuesAndLightmapScale.w +#define g_EyePos cEyePos.xyz + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); + +Texture2D LightmapTexture : register( t1 ); +sampler LightmapSampler : register( s1 ); + +#if CUBEMAP +TextureCube EnvmapTexture : register( t4 ); +sampler EnvmapSampler : register( s4 ); +#endif + +#if FANCY_BLENDING +Texture2D BlendModulationTexture : register( t8 ); +sampler BlendModulationSampler : register( s8 ); +#endif + +#if DETAILTEXTURE +Texture2D DetailTexture : register( t2 ); +sampler DetailSampler : register( s2 ); +#endif + +#if BUMPMAP +Texture2D BumpmapTexture : register( t3 ); +sampler BumpmapSampler : register( s3 ); +#else +#define BumpmapTexture BaseTexture +#define BumpmapSampler BaseTextureSampler +#endif + +#if BUMPMAP2 == 1 +Texture2D BumpmapTexture2 : register( t5 ); +sampler BumpmapSampler2 : register( s5 ); +#elif ENVMAPMASK == 1 +Texture2D EnvmapMaskTexture : register( t5 ); +sampler EnvmapMaskSampler : register( s5 ); +#endif + +#if WARPLIGHTING +Texture2D WarpLightingTexture : register( t7 ); +sampler WarpLightingSampler : register( s7 ); +#endif + +#if BASETEXTURE2 +Texture2D BaseTexture2 : register( t6 ); +sampler BaseTextureSampler2 : register( s6 ); +#else +#define BaseTexture2 BaseTexture +#define BaseTextureSampler2 BaseTextureSampler +#endif + +#if BUMPMASK == 1 +Texture2D BumpMaskTexture : register( t9 ); +sampler BumpMaskSampler : register( s9 ); +#endif + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + float4 vertexColor : COLOR; +#if SEAMLESS + float4 SeamlessTexCoord_VertexBlend : TEXCOORD0; // zy xz +#else + float3 baseTexCoord_VertexBlend : TEXCOORD0; +#endif + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; + float4 lightmapTexCoord1And2 : TEXCOORD2; + float4 lightmapTexCoord3 : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD4; + +#if CUBEMAP || (LIGHTING_PREVIEW) + float3x3 tangentSpaceTranspose : TEXCOORD5; + // tangentSpaceTranspose : TEXCOORD6 + // tangentSpaceTranspose : TEXCOORD7 +#endif + + float3 eyePos : COLOR1; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + bool bBaseTexture2 = BASETEXTURE2 ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBumpmap = BUMPMAP ? true : false; + bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bBaseTextureNoEnvmap = BASETEXTURENOENVMAP ? true : false; + bool bBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP ? true : false; + + float4 baseColor = 0.0f; + float4 baseColor2 = 0.0f; + float4 vNormal = float4( 0, 0, 1, 1 ); + float3 baseTexCoords = float3( 0,0,0 ); + +#if SEAMLESS + baseTexCoords = i.SeamlessTexCoord_VertexBlend.xyz; +#else + baseTexCoords.xy = i.baseTexCoord_VertexBlend.xy; +#endif + + GetBaseTextureAndNormal( BaseTexture, BaseTextureSampler, BaseTexture2, BaseTextureSampler2, + BumpmapTexture, BumpmapSampler, bBaseTexture2, bBumpmap || bNormalMapAlphaEnvmapMask, + baseTexCoords, i.vertexColor.rgb, baseColor, baseColor2, vNormal ); + +#if BUMPMAP == 1 // not ssbump + vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // make signed if we're not ssbump +#endif + + float3 lightmapColor1 = float3( 1.0f, 1.0f, 1.0f ); + float3 lightmapColor2 = float3( 1.0f, 1.0f, 1.0f ); + float3 lightmapColor3 = float3( 1.0f, 1.0f, 1.0f ); +#if LIGHTING_PREVIEW == 0 + if ( bBumpmap && bDiffuseBumpmap ) + { + float2 bumpCoord1; + float2 bumpCoord2; + float2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + lightmapColor1 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord1 ); + lightmapColor2 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord2 ); + lightmapColor3 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord3 ); + } + else + { + float2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + lightmapColor1 = LightMapSample( LightmapTexture, LightmapSampler, bumpCoord1 ); + } +#endif + +#if RELIEF_MAPPING + // in the parallax case, all texcoords must be the same in order to free + // up an iterator for the tangent space view vector + float2 detailTexCoord = i.baseTexCoord_VertexBlend.xy; + float2 bumpmapTexCoord = i.baseTexCoord_VertexBlend.xy; + float2 envmapMaskTexCoord = i.baseTexCoord_VertexBlend.xy; +#else + + #if ( DETAILTEXTURE == 1 ) + float2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + float2 bumpmapTexCoord = i.baseTexCoord_VertexBlend.xy; + #elif ( BUMPMASK == 1 ) + float2 detailTexCoord = 0.0f; + float2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + float2 bumpmap2TexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; + #else + float2 detailTexCoord = 0.0f; + float2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + #endif + + float2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; +#endif // !RELIEF_MAPPING + + float4 detailColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if DETAILTEXTURE + + detailColor = float4( g_DetailTint, 1.0f ) * DetailTexture.Sample( DetailSampler, detailTexCoord ); + +#endif + +#if ( OUTLINE || SOFTEDGES ) + float distAlphaMask = baseColor.a; + +# if OUTLINE + if ( ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && + ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + { + float oFactor = 1.0; + if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + { + oFactor = smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + } + else + { + oFactor = smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + } + baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + } +# endif +# if SOFTEDGES + baseColor.a *= smoothstep( SOFT_MASK_MAX, SOFT_MASK_MIN, distAlphaMask ); +# else + baseColor.a *= distAlphaMask >= 0.5; +# endif +#endif + + +//#if LIGHTING_PREVIEW == 2 +// baseColor.xyz = GammaToLinear( baseColor.xyz ); +//#endif + + float blendedAlpha = baseColor.a; + +#if MASKEDBLENDING + float blendfactor = 0.5; +#elif SEAMLESS + float blendfactor = i.SeamlessTexCoord_VertexBlend.w; +#else + float blendfactor = i.baseTexCoord_VertexBlend.z; +#endif + + if ( bBaseTexture2 ) + { +#if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING) + float4 modt = BlendModulationTexture.Sample( BlendModulationSampler,i.lightmapTexCoord3.zw ); +#if MASKEDBLENDING + // FXC is unable to optimize this, despite blendfactor=0.5 above + //float minb=modt.g-modt.r; + //float maxb=modt.g+modt.r; + //blendfactor=smoothstep(minb,maxb,blendfactor); + //blendfactor=modt.g; + float minb = modt.g - modt.r; + float maxb = modt.g + modt.r; +#else + float minb = max( 0,modt.g - modt.r ); + float maxb = min( 1,modt.g + modt.r ); + //float minb=saturate(modt.g-modt.r); + //float maxb=saturate(modt.g+modt.r); +#endif + blendfactor = smoothstep( minb,maxb,blendfactor ); +//#endif +#endif + //baseColor.rgb = lerp( baseColor.rgb, baseColor2.rgb, blendfactor ); + baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor ); + blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor ); + } + + float3 specularFactor = 1.0f; + float4 vNormalMask = float4( 0, 0, 1, 1 ); + if ( bBumpmap ) + { + if ( bBaseTextureNoEnvmap ) + { + vNormal.a = 0.0f; + } + +#if ( BUMPMAP2 == 1 ) + { + #if ( BUMPMASK == 1 ) + float2 b2TexCoord = bumpmap2TexCoord; + #else + float2 b2TexCoord = bumpmapTexCoord; + #endif + + float4 vNormal2; + if ( BUMPMAP == 2 ) + vNormal2 = BumpmapTexture2.Sample( BumpmapSampler2, b2TexCoord ); + else + vNormal2 = DecompressNormal( BumpmapTexture2, BumpmapSampler2, b2TexCoord, + NORMAL_DECODE_MODE, BumpmapTexture2, BumpmapSampler2 ); // Bump 2 coords + + if ( bBaseTexture2NoEnvmap ) + { + vNormal2.a = 0.0f; + } + + #if ( BUMPMASK == 1 ) + float3 vNormal1 = DecompressNormal( BumpmapTexture, BumpmapSampler, + i.detailOrBumpAndEnvmapMaskTexCoord.xy, + NORMALMASK_DECODE_MODE, BumpmapTexture, BumpmapSampler ); + + vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz ); + + // Third normal map...same coords as base + vNormalMask = DecompressNormal( BumpMaskTexture, BumpMaskSampler, i.baseTexCoord_VertexBlend.xy, + NORMALMASK_DECODE_MODE, BumpMaskTexture, BumpMaskSampler ); + + vNormal.xyz = lerp( vNormalMask.xyz, vNormal.xyz, vNormalMask.a ); // Mask out normals from vNormal + specularFactor = vNormalMask.a; + #else // BUMPMASK == 0 + if ( FANCY_BLENDING && bNormalMapAlphaEnvmapMask ) + { + vNormal = lerp( vNormal, vNormal2, blendfactor ); + } + else + { + vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor ); + } + + #endif + + } + +#endif // BUMPMAP2 == 1 + + if ( bNormalMapAlphaEnvmapMask ) + { + specularFactor *= vNormal.a; + } + } + else if ( bNormalMapAlphaEnvmapMask ) + { + specularFactor *= vNormal.a; + } + +#if ( BUMPMAP2 == 0 ) +#if ENVMAPMASK + { + specularFactor *= EnvmapMaskTexture.Sample( EnvmapMaskSampler, envmapMaskTexCoord ).xyz; + } +#endif +#endif + + if ( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - blendedAlpha; // Reversing alpha blows! + } + float4 albedo = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + albedo *= baseColor; + if ( !bBaseAlphaEnvmapMask && !bSelfIllum ) + { + alpha *= baseColor.a; + } + + if ( bDetailTexture ) + { + albedo = TextureCombine( albedo, detailColor, c.g_DetailBlendMode.x, g_DetailBlendFactor ); + } + + // The vertex color contains the modulation color + vertex color combined +#if ( SEAMLESS == 0 ) + albedo.xyz *= i.vertexColor.xyz; +#endif + alpha *= i.vertexColor.a * g_flAlpha2; // not sure about this one + + // Save this off for single-pass flashlight, since we'll still need the SSBump vector, not a real normal + float3 vSSBumpVector = vNormal.xyz; + + float3 diffuseLighting; + if ( bBumpmap && bDiffuseBumpmap ) + { +// ssbump +#if ( BUMPMAP == 2 ) + diffuseLighting = vNormal.x * lightmapColor1 + + vNormal.y * lightmapColor2 + + vNormal.z * lightmapColor3; + diffuseLighting *= c.g_TintValuesAndLightmapScale.rgb; + + // now, calculate vNormal for reflection purposes. if vNormal isn't needed, hopefully + // the compiler will eliminate these calculations + vNormal.xyz = normalize( bumpBasis[0] * vNormal.x + bumpBasis[1] * vNormal.y + bumpBasis[2] * vNormal.z ); +#else + float3 dp; + dp.x = saturate( dot( vNormal.xyz, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal.xyz, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal.xyz, bumpBasis[2] ) ); + dp *= dp; + + if ( c.g_DetailBlendMode.x == TCOMBINE_SSBUMP_BUMP ) + dp *= 2 * detailColor; + + diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= c.g_TintValuesAndLightmapScale.xyz / sum; +#endif + } + else + { + diffuseLighting = lightmapColor1 * c.g_TintValuesAndLightmapScale.xyz; + } + +#if WARPLIGHTING && ( SEAMLESS == 0 ) + float len = 0.5 * length( diffuseLighting ); + // FIXME: 8-bit lookup textures like this need a "nice filtering" VTF option, which converts + // them to 16-bit on load or does filtering in the shader (since most hardware - 360 + // included - interpolates 8-bit textures at 8-bit precision, which causes banding) + diffuseLighting *= 2.0 * WarpLightingTexture.Sample( WarpLightingSampler,float2( len,0 ) ); +#endif + +#if CUBEMAP || LIGHTING_PREVIEW + float3 worldSpaceNormal = mul( vNormal.xyz, i.tangentSpaceTranspose ); +#endif + float3 diffuseComponent = albedo.xyz * diffuseLighting; + //return float4( diffuseLighting, 1.0f ); + + if ( bSelfIllum ) + { + float3 selfIllumComponent = g_SelfIllumTint.xyz * albedo.xyz; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); +#if CUBEMAP + if ( bCubemap ) + { + float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz; + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector ); + //return float4( reflectVect, 1.0f ); + + // Calc Fresnel factor + half3 eyeVect = normalize( worldVertToEyeVector ); + float fresnel = 1.0 - dot( worldSpaceNormal, eyeVect ); + fresnel = pow( fresnel, 5.0 ); + fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection; + + //return float4( specularFactor, 1.0f ); + + specularLighting = ENV_MAP_SCALE * EnvmapTexture.Sample( EnvmapSampler, reflectVect ).rgb; + //return float4( specularLighting, 1.0f ); + specularLighting *= specularFactor; + + specularLighting *= c.g_EnvmapTint.rgb; + //return float4( c.g_EnvmapTint.rgb, 1.0f ); +#if FANCY_BLENDING == 0 + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + specularLighting *= fresnel; + + //return float4( specularLighting, 1.0f ); + } +#endif + + float3 result = diffuseComponent + specularLighting; + +#if ALPHATEST + if ( !GreaterEqualAlphaTest( alpha, c.g_AlphaTestRef ) ) + discard; +#endif + + bool bWriteDepthToAlpha = false; + + // ps_2_b and beyond +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) + bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, c.g_FogParams, cEyePos.z, i.worldPos_projPosZ.z, length( i.eyePos ) ); +#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; +#endif + +#if ALPHATEST + if ( !GreaterEqualAlphaTest( alpha, c.g_AlphaTestRef ) ) + discard; +#endif + + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, c.g_FogColor, + TONEMAP_SCALE_LINEAR, cToneMappingScale, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); +} + diff --git a/materialsystem/stdshadersdx11/lightmappedgeneric_vs40.fxc b/materialsystem/stdshadersdx11/lightmappedgeneric_vs40.fxc new file mode 100644 index 0000000..638f3e0 --- /dev/null +++ b/materialsystem/stdshadersdx11/lightmappedgeneric_vs40.fxc @@ -0,0 +1,212 @@ +// STATIC: "ENVMAP_MASK" "0..1" +// STATIC: "TANGENTSPACE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMASK" "0..1" + +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +// This should not be a combo since I'm a moron with the tangent space and the flashlight. +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $SEAMLESS +// SKIP: $CASCADED_SHADOW && $LIGHTING_PREVIEW + +#include "common_cbuffers_def_noskinning_fxc.h" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; +static const bool g_bTangentSpace = TANGENTSPACE; +static const bool g_bBumpmap = BUMPMAP; +static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP; +static const bool g_bVertexColor = VERTEXCOLOR; +static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; +static const bool g_BumpMask = BUMPMASK; + +#include "lightmappedgeneric_dx11_shared_fxc.h" + +cbuffer LightmappedGeneric_VS : register(b3) +{ + LightmappedGeneric_t c; +}; + +#define SEAMLESS_SCALE c.cSeamlessScale + +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vColor : COLOR; +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; + float4 vertexColor : COLOR; // in seamless, r g b = blend weights +#if SEAMLESS + float4 SeamlessTexCoord_VertexBlend : TEXCOORD0; // x y z +#else + float3 baseTexCoord_VertexBlend : TEXCOORD0; +#endif + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; + float4 lightmapTexCoord1And2 : TEXCOORD2; + float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale + float4 worldPos_projPosZ : TEXCOORD4; + +#if TANGENTSPACE || (LIGHTING_PREVIEW) + float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 +#endif + + float3 eyePos : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float3 worldPos = mul( float4( v.vPos, 1 ), cModelMatrix ).xyz; + + o.eyePos = mul(float4(worldPos, 1), cViewMatrix).xyz; + + float4 vProjPos = ComputeProjPos(v.vPos.xyz, cModelMatrix, cViewMatrix, cProjMatrix); + o.projPos = vProjPos; + + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModelMatrix ); + +#if TANGENTSPACE || (LIGHTING_PREVIEW) + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModelMatrix ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModelMatrix ); + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; +#endif + + //float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + +#if SEAMLESS + { + // we need to fill in the texture coordinate projections + o.SeamlessTexCoord_VertexBlend.xyz = SEAMLESS_SCALE*worldPos; + } +#else + { + if (FASTPATH) + { + o.baseTexCoord_VertexBlend.xy = v.vBaseTexCoord; + } + else + { + o.baseTexCoord_VertexBlend.x = dot( v.vBaseTexCoord, c.cBaseTexCoordTransform[0] ) + c.cBaseTexCoordTransform[0].w; + o.baseTexCoord_VertexBlend.y = dot( v.vBaseTexCoord, c.cBaseTexCoordTransform[1] ) + c.cBaseTexCoordTransform[1].w; + } +#if ( RELIEF_MAPPING == 0 ) + { + // calculate detailorbumptexcoord + if ( FASTPATH ) + o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy; + else + { + o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, c.cDetailOrBumpTexCoordTransform[0] ) + c.cDetailOrBumpTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, c.cDetailOrBumpTexCoordTransform[1] ) + c.cDetailOrBumpTexCoordTransform[1].w; + } + } +#endif + } +#endif + if ( FASTPATH ) + { + o.lightmapTexCoord3.zw = v.vBaseTexCoord; + } + else + { + o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, c.cBlendMaskTexCoordTransform[0] ) + c.cBlendMaskTexCoordTransform[0].w; + o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, c.cBlendMaskTexCoordTransform[1] ) + c.cBlendMaskTexCoordTransform[1].w; + } + + // compute lightmap coordinates + if( g_bBumpmap && g_bBumpmapDiffuseLighting ) + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; + } + else + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord; + } + +#if ( RELIEF_MAPPING == 0) + if( g_UseSeparateEnvmapMask || g_BumpMask ) + { + // reversed component order +# if FASTPATH + o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy; +# else + o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, c.cEnvmapMaskTexCoordTransform[0] ) + c.cEnvmapMaskTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, c.cEnvmapMaskTexCoordTransform[1] ) + c.cEnvmapMaskTexCoordTransform[1].w; +# endif + } +#endif + + if (!g_bVertexColor) + { + o.vertexColor = float4( 1.0f, 1.0f, 1.0f, c.cModulationColor.a ); + } + else + { +#if FASTPATH + o.vertexColor = v.vColor; +#else + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexColor.rgb = v.vColor.rgb; + o.vertexColor.a = c.cModulationColor.a; + } + else + { + o.vertexColor = v.vColor; + o.vertexColor.a *= c.cModulationColor.a; + } +#endif + } +#if SEAMLESS + // compute belnd weights in rgb + float3 vNormal=normalize( worldNormal ); + o.vertexColor.xyz = vNormal * vNormal; // sums to 1. +#endif + + if ( g_bVertexAlphaTexBlendFactor ) + { +#if SEAMLESS + o.SeamlessTexCoord_VertexBlend.w = v.vColor.a; +#else + o.baseTexCoord_VertexBlend.z = v.vColor.a; +#endif + } + + return o; +} diff --git a/materialsystem/stdshadersdx11/makefile._shaderlist_dx11 b/materialsystem/stdshadersdx11/makefile._shaderlist_dx11 new file mode 100644 index 0000000..9b9b20e --- /dev/null +++ b/materialsystem/stdshadersdx11/makefile._shaderlist_dx11 @@ -0,0 +1,80 @@ +default: fxctmp9_tmp\bik_vs40.inc fxctmp9_tmp\bik_ps40.inc fxctmp9_tmp\unlitgeneric_vs40.inc fxctmp9_tmp\unlitgeneric_ps40.inc fxctmp9_tmp\white_ps40.inc fxctmp9_tmp\writez_vs40.inc fxctmp9_tmp\modulate_ps40.inc fxctmp9_tmp\modulate_vs40.inc fxctmp9_tmp\splinecard_vs40.inc fxctmp9_tmp\spritecard_vs40.inc fxctmp9_tmp\spritecard_ps40.inc fxctmp9_tmp\sprite_ps40.inc fxctmp9_tmp\sprite_vs40.inc fxctmp9_tmp\sky_vs40.inc fxctmp9_tmp\sky_ps40.inc fxctmp9_tmp\sky_hdr_compressed_rgbs_ps40.inc fxctmp9_tmp\sky_hdr_compressed_ps40.inc fxctmp9_tmp\decalmodulate_ps40.inc fxctmp9_tmp\vertexlit_and_unlit_generic_vs40.inc fxctmp9_tmp\vertexlit_and_unlit_generic_ps40.inc fxctmp9_tmp\depthtodestalpha_vs40.inc fxctmp9_tmp\depthtodestalpha_ps40.inc fxctmp9_tmp\wireframe_ps40.inc fxctmp9_tmp\wireframe_vs40.inc fxctmp9_tmp\lightmappedgeneric_ps40.inc fxctmp9_tmp\lightmappedgeneric_vs40.inc + +fxctmp9_tmp\bik_vs40.inc : bik_vs40.fxc shader_register_map.h lightinfo_fxc.h common_vs_fxc.h common_pragmas.h common_hlsl_cpp_consts.h common_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." bik_vs40.fxc-----bik_vs40 + +fxctmp9_tmp\bik_ps40.inc : bik_ps40.fxc shader_register_map.h common_pragmas.h lightinfo_fxc.h common_ps_fxc.h common_hlsl_cpp_consts.h common_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." bik_ps40.fxc-----bik_ps40 + +fxctmp9_tmp\unlitgeneric_vs40.inc : unlitgeneric_vs40.fxc common_vs_fxc.h common_pragmas.h common_cbuffers_fxc.h shader_register_map.h common_fxc.h unlittwotexture_constants_fxc.h lightinfo_fxc.h common_hlsl_cpp_consts.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." unlitgeneric_vs40.fxc-----unlitgeneric_vs40 + +fxctmp9_tmp\unlitgeneric_ps40.inc : unlitgeneric_ps40.fxc common_ps_fxc.h common_hlsl_cpp_consts.h common_fxc.h common_cbuffers_fxc.h shader_register_map.h lightinfo_fxc.h common_pragmas.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." unlitgeneric_ps40.fxc-----unlitgeneric_ps40 + +fxctmp9_tmp\white_ps40.inc : white_ps40.fxc common_fxc.h common_hlsl_cpp_consts.h common_ps_fxc.h common_pragmas.h lightinfo_fxc.h shader_register_map.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." white_ps40.fxc-----white_ps40 + +fxctmp9_tmp\writez_vs40.inc : writez_vs40.fxc common_hlsl_cpp_consts.h common_fxc.h shader_register_map.h common_cbuffers_fxc.h common_vs_fxc.h common_pragmas.h lightinfo_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." writez_vs40.fxc-----writez_vs40 + +fxctmp9_tmp\modulate_ps40.inc : modulate_ps40.fxc common_fxc.h common_pragmas.h common_cbuffers_fxc.h shader_register_map.h common_ps_fxc.h common_hlsl_cpp_consts.h lightinfo_fxc.h modulate_constants_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." modulate_ps40.fxc-----modulate_ps40 + +fxctmp9_tmp\modulate_vs40.inc : modulate_vs40.fxc common_fxc.h shader_register_map.h common_cbuffers_fxc.h common_pragmas.h common_vs_fxc.h common_hlsl_cpp_consts.h modulate_constants_fxc.h lightinfo_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." modulate_vs40.fxc-----modulate_vs40 + +fxctmp9_tmp\splinecard_vs40.inc : splinecard_vs40.fxc shader_register_map.h common_cbuffers_fxc.h common_vs_fxc.h common_pragmas.h lightinfo_fxc.h common_hlsl_cpp_consts.h common_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." splinecard_vs40.fxc-----splinecard_vs40 + +fxctmp9_tmp\spritecard_vs40.inc : spritecard_vs40.fxc common_hlsl_cpp_consts.h lightinfo_fxc.h spritecard_constants_fxc.h common_fxc.h common_cbuffers_fxc.h shader_register_map.h common_pragmas.h common_vs_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." spritecard_vs40.fxc-----spritecard_vs40 + +fxctmp9_tmp\spritecard_ps40.inc : spritecard_ps40.fxc common_cbuffers_fxc.h shader_register_map.h common_pragmas.h common_fxc.h lightinfo_fxc.h spritecard_constants_fxc.h common_ps_fxc.h common_hlsl_cpp_consts.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." spritecard_ps40.fxc-----spritecard_ps40 + +fxctmp9_tmp\sprite_ps40.inc : sprite_ps40.fxc common_fxc.h common_hlsl_cpp_consts.h common_ps_fxc.h common_pragmas.h lightinfo_fxc.h shader_register_map.h common_cbuffers_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." sprite_ps40.fxc-----sprite_ps40 + +fxctmp9_tmp\sprite_vs40.inc : sprite_vs40.fxc common_hlsl_cpp_consts.h common_fxc.h shader_register_map.h common_cbuffers_fxc.h common_vs_fxc.h common_pragmas.h lightinfo_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." sprite_vs40.fxc-----sprite_vs40 + +fxctmp9_tmp\sky_vs40.inc : sky_vs40.fxc lightinfo_fxc.h common_sky_fxc.h common_hlsl_cpp_consts.h common_pragmas.h common_vs_fxc.h shader_register_map.h common_cbuffers_fxc.h common_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." sky_vs40.fxc-----sky_vs40 + +fxctmp9_tmp\sky_ps40.inc : sky_ps40.fxc lightinfo_fxc.h common_sky_fxc.h common_ps_fxc.h common_hlsl_cpp_consts.h common_pragmas.h shader_register_map.h common_cbuffers_fxc.h common_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." sky_ps40.fxc-----sky_ps40 + +fxctmp9_tmp\sky_hdr_compressed_rgbs_ps40.inc : sky_hdr_compressed_rgbs_ps40.fxc common_sky_fxc.h common_ps_fxc.h common_hlsl_cpp_consts.h lightinfo_fxc.h common_fxc.h common_pragmas.h shader_register_map.h common_cbuffers_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." sky_hdr_compressed_rgbs_ps40.fxc-----sky_hdr_compressed_rgbs_ps40 + +fxctmp9_tmp\sky_hdr_compressed_ps40.inc : sky_hdr_compressed_ps40.fxc common_cbuffers_fxc.h shader_register_map.h lightinfo_fxc.h common_pragmas.h common_hlsl_cpp_consts.h common_ps_fxc.h common_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." sky_hdr_compressed_ps40.fxc-----sky_hdr_compressed_ps40 + +fxctmp9_tmp\decalmodulate_ps40.inc : decalmodulate_ps40.fxc common_fxc.h common_pragmas.h shader_register_map.h common_cbuffers_fxc.h common_hlsl_cpp_consts.h common_ps_fxc.h lightinfo_fxc.h vertexlitgeneric_dx11_shared.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." decalmodulate_ps40.fxc-----decalmodulate_ps40 + +fxctmp9_tmp\vertexlit_and_unlit_generic_vs40.inc : vertexlit_and_unlit_generic_vs40.fxc common_cbuffers_fxc.h shader_register_map.h common_pragmas.h common_vs_fxc.h common_cbuffers_def_fxc.h common_fxc.h vertexlitgeneric_dx11_shared.h lightinfo_fxc.h common_hlsl_cpp_consts.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." vertexlit_and_unlit_generic_vs40.fxc-----vertexlit_and_unlit_generic_vs40 + +fxctmp9_tmp\vertexlit_and_unlit_generic_ps40.inc : vertexlit_and_unlit_generic_ps40.fxc common_pragmas.h shader_register_map.h common_cbuffers_fxc.h common_fxc.h lightinfo_fxc.h common_flashlight_fxc.h vertexlitgeneric_dx11_shared.h common_cbuffers_def_noskinning_fxc.h common_ps_fxc.h common_vertexlitgeneric_dx11.h common_hlsl_cpp_consts.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." vertexlit_and_unlit_generic_ps40.fxc-----vertexlit_and_unlit_generic_ps40 + +fxctmp9_tmp\depthtodestalpha_vs40.inc : depthtodestalpha_vs40.fxc common_fxc.h common_hlsl_cpp_consts.h common_vs_fxc.h common_pragmas.h lightinfo_fxc.h shader_register_map.h common_cbuffers_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." depthtodestalpha_vs40.fxc-----depthtodestalpha_vs40 + +fxctmp9_tmp\depthtodestalpha_ps40.inc : depthtodestalpha_ps40.fxc common_hlsl_cpp_consts.h common_ps_fxc.h common_fxc.h shader_register_map.h lightinfo_fxc.h common_pragmas.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." depthtodestalpha_ps40.fxc-----depthtodestalpha_ps40 + +fxctmp9_tmp\wireframe_ps40.inc : wireframe_ps40.fxc common_pragmas.h lightinfo_fxc.h shader_register_map.h common_fxc.h common_ps_fxc.h common_hlsl_cpp_consts.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." wireframe_ps40.fxc-----wireframe_ps40 + +fxctmp9_tmp\wireframe_vs40.inc : wireframe_vs40.fxc common_hlsl_cpp_consts.h common_fxc.h common_cbuffers_fxc.h shader_register_map.h lightinfo_fxc.h common_vs_fxc.h common_pragmas.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." wireframe_vs40.fxc-----wireframe_vs40 + +fxctmp9_tmp\lightmappedgeneric_ps40.inc : lightmappedgeneric_ps40.fxc common_cbuffers_fxc.h shader_register_map.h common_pragmas.h lightmappedgeneric_dx11_shared_fxc.h common_fxc.h common_flashlight_fxc.h lightinfo_fxc.h lightmappedgeneric_ps40.h common_lightmappedgeneric_fxc.h common_ps_fxc.h common_hlsl_cpp_consts.h common_cbuffers_def_noskinning_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." lightmappedgeneric_ps40.fxc-----lightmappedgeneric_ps40 + +fxctmp9_tmp\lightmappedgeneric_vs40.inc : lightmappedgeneric_vs40.fxc lightinfo_fxc.h common_cbuffers_def_noskinning_fxc.h common_hlsl_cpp_consts.h common_pragmas.h common_vs_fxc.h common_cbuffers_fxc.h shader_register_map.h common_fxc.h lightmappedgeneric_dx11_shared_fxc.h + perl ..\..\devtools\bin\fxc_prep.pl -novcs -source "..\.." lightmappedgeneric_vs40.fxc-----lightmappedgeneric_vs40 + diff --git a/materialsystem/stdshadersdx11/modulate_constants_fxc.h b/materialsystem/stdshadersdx11/modulate_constants_fxc.h new file mode 100644 index 0000000..c083b5c --- /dev/null +++ b/materialsystem/stdshadersdx11/modulate_constants_fxc.h @@ -0,0 +1,16 @@ +#ifndef MODULATE_CONSTANTS_FXC_H_ +#define MODULATE_CONSTANTS_FXC_H_ + +struct Modulate_t +{ + // vsh + float4 cBaseTextureTransform[2]; + float4 cModulationColor; + + // psh + float4 cWhiteGrayMix; + float4 g_FogParams; + float4 g_FogColor; +}; + +#endif // MODULATE_CONSTANTS_FXC_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/modulate_dx11.cpp b/materialsystem/stdshadersdx11/modulate_dx11.cpp new file mode 100644 index 0000000..2afc726 --- /dev/null +++ b/materialsystem/stdshadersdx11/modulate_dx11.cpp @@ -0,0 +1,282 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// +#if 0 +#include "BaseVSShader.h" + +#include "modulate_vs40.inc" +#include "modulate_ps40.inc" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" +//#include "cloak_blended_pass_helper.h" + +CREATE_CONSTANT_BUFFER( Modulate ) +{ + // vsh + Vector4D BaseTextureTransform[2]; + Vector4D ModulationColor; + + // psh + Vector4D WhiteGrayMix; + Vector4D FogParams; + Vector4D FogColor; +}; + +DEFINE_FALLBACK_SHADER( Modulate, Modulate_DX11 ) + +BEGIN_VS_SHADER( Modulate_DX11, + "Help for Modulate" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( WRITEZ, SHADER_PARAM_TYPE_BOOL, "0", "Forces z to be written if set" ) + SHADER_PARAM( MOD2X, SHADER_PARAM_TYPE_BOOL, "0", "forces a 2x modulate so that you can brighten and darken things" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER( Modulate ) + + SHADER_FALLBACK + { + return 0; + } + + // Cloak Pass + //void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + //{ + // info.m_nCloakFactor = CLOAKFACTOR; + //// info.m_nCloakColorTint = CLOAKCOLORTINT; + // info.m_nRefractAmount = REFRACTAMOUNT; + //} + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + //{ + // if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + // return true; + // else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + // return true; + // // else, not cloaking this frame, so check flag2 in case the base material still needs it + //} + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + //{ + // if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + // return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + //} + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + // Cloak Pass + //if ( !params[CLOAKPASSENABLED]->IsDefined() ) + //{ + // params[CLOAKPASSENABLED]->SetIntValue( 0 ); + //} + //else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + //{ + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + //} + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } + + // Cloak Pass + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) + //{ + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // InitCloakBlendedPass( this, params, info ); + //} + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + //if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + //{ + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + // { + // bDrawStandardPass = false; + // } + //} + + // Standard rendering pass + if ( bDrawStandardPass ) + { + bool bMod2X = params[MOD2X]->IsDefined() && params[MOD2X]->GetIntValue(); + bool bVertexColorOrAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) || IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + bool bWriteZ = params[WRITEZ]->GetIntValue() != 0; + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + if( bMod2X ) + { + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); + } + + if ( bWriteZ ) + { + // This overrides the disabling of depth writes performed in + // EnableAlphaBlending + pShaderShadow->EnableDepthWrites( true ); + } + + unsigned int flags = VERTEX_POSITION; + int numTexCoords = 0; + int userDataSize = 0; + + if( params[BASETEXTURE]->IsTexture() ) + { + numTexCoords = 1; + } + + if( bVertexColorOrAlpha ) + { + flags |= VERTEX_COLOR; + } + + // HACK: add 1 texcoord if these verts are too thin (to do with how we + // bind stream 2 - see CShaderShadowDX8::VertexShaderVertexFormat) + // FIXME: instead of this, don't add stream 2 elements to all vertex decls! + if ( !( flags & VERTEX_COLOR ) && ( numTexCoords == 0 ) ) + { + numTexCoords = 1; + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, NULL, userDataSize ); + + SetVertexShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_SKINNING ); + SetVertexShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 2, SHADER_CONSTANTBUFFER_PERSCENE ); + SetVertexShaderConstantBuffer( 3, CONSTANT_BUFFER( Modulate ) ); + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + SetPixelShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERSCENE ); + SetPixelShaderConstantBuffer( 2, CONSTANT_BUFFER( Modulate ) ); + + DECLARE_STATIC_VERTEX_SHADER( modulate_vs40 ); + SET_STATIC_VERTEX_SHADER( modulate_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( modulate_ps40 ); + SET_STATIC_PIXEL_SHADER( modulate_ps40 ); + + // We need to fog to *white* regardless of overbrighting... + if( bMod2X ) + { + FogToGrey(); + } + else + { + FogToOOOverbright(); + } + + pShaderShadow->EnableAlphaWrites( bWriteZ && bFullyOpaque ); + } + DYNAMIC_STATE + { + ALIGN16 CONSTANT_BUFFER_TYPE( Modulate ) consts; + + /*if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + StoreVertexShaderTextureTransform( consts.BaseTextureTransform, BASETEXTURETRANSFORM ); + }*/ + + //pShaderAPI->GetFogParamsAndColor( consts.FogParams.Base(), consts.FogColor.Base() ); + + // set constant color for modulation + SetModulationDynamicState( consts.ModulationColor ); + + // We need to fog to *white* regardless of overbrighting... + if( bMod2X ) + { + float grey[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; + pShaderAPI->SetPixelShaderConstant( 0, grey ); + } + else + { + float white[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; + pShaderAPI->SetPixelShaderConstant( 0, white ); + } + + UPDATE_CONSTANT_BUFFER( Modulate, consts ); + + DECLARE_DYNAMIC_VERTEX_SHADER( modulate_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( modulate_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( modulate_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( modulate_ps40 ); + } + Draw(); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) + //{ + // If ( snapshotting ) or ( we need to draw this frame ) + // if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + // { + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + // } + // else // We're not snapshotting and we don't need to draw this frame + // { + // // Skip this pass! + // Draw( false ); + // } + //} + } +END_SHADER +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/modulate_ps40.fxc b/materialsystem/stdshadersdx11/modulate_ps40.fxc new file mode 100644 index 0000000..0cbd935 --- /dev/null +++ b/materialsystem/stdshadersdx11/modulate_ps40.fxc @@ -0,0 +1,42 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#include "common_ps_fxc.h" +#include "modulate_constants_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_PERFRAME( register(b0) ) +CBUFFER_PERSCENE( register(b1) ) + +cbuffer Modulate_CBuffer : register( b2 ) +{ + Modulate_t c; +}; + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); + +#define g_WhiteGrayMix c.cWhiteGrayMix +#define g_EyePos_SpecExponent cEyePos + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + float2 vTexCoord0 : TEXCOORD0; + float4 vColor : COLOR0; + + float4 worldPos_projPosZ : TEXCOORD1; // Necessary for pixel fog + float3 eyeSpacePos : COLOR1; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + float4 textureColor = BaseTexture.Sample( BaseTextureSampler, i.vTexCoord0 ); + + float4 resultColor = saturate( textureColor * i.vColor ); + resultColor.rgb = lerp( g_WhiteGrayMix.rgb, resultColor.rgb, resultColor.a ); + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, c.g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, length( i.eyeSpacePos ) ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, c.g_FogColor, + TONEMAP_SCALE_NONE, float4(1, 1, 1, 1), (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/materialsystem/stdshadersdx11/modulate_vs40.fxc b/materialsystem/stdshadersdx11/modulate_vs40.fxc new file mode 100644 index 0000000..96ce2df --- /dev/null +++ b/materialsystem/stdshadersdx11/modulate_vs40.fxc @@ -0,0 +1,72 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +#include "common_cbuffers_fxc.h" +#include "modulate_constants_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +CBUFFER_SKINNING(register(b0)) +CBUFFER_PERFRAME(register(b1)) +CBUFFER_PERSCENE(register(b2)) + +cbuffer Modulate_CBuffer : register(b3) +{ + Modulate_t c; +}; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + uint4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + + float4 vColor : COLOR; + + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : SV_POSITION; + float2 vTexCoord0 : TEXCOORD0; + float4 vColor : COLOR0; + float4 worldPos_projPosZ : TEXCOORD1; // Necessary for pixel fog + float3 eyeSpacePos : COLOR1; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + float3 worldNormal; + + //------------------------------------------------------------------------------ + // Vertex blending + //------------------------------------------------------------------------------ + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, cModel, worldPos ); + + float4x4 viewProj = mul( cViewMatrix, cProjMatrix ); + o.vProjPos = mul( float4( worldPos, 1 ), viewProj ); + o.worldPos_projPosZ = float4( worldPos.xyz, o.vProjPos.z ); + o.eyeSpacePos = mul(float4(worldPos, 1), cViewMatrix).xyz; + + //------------------------------------------------------------------------------ + // Texture coord transforms + //------------------------------------------------------------------------------ + o.vTexCoord0 = mul( v.vTexCoord0, (float2x4)c.cBaseTextureTransform ); + + o.vColor = c.cModulationColor; + + return o; +} + + + diff --git a/materialsystem/stdshadersdx11/occlusion_dx11.cpp b/materialsystem/stdshadersdx11/occlusion_dx11.cpp new file mode 100644 index 0000000..fbf3dd3 --- /dev/null +++ b/materialsystem/stdshadersdx11/occlusion_dx11.cpp @@ -0,0 +1,69 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#if 0 +#include "BaseVSShader.h" + +#include "writez_vs40.inc" +#include "white_ps40.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Occlusion, Occlusion_DX11 ) + +BEGIN_VS_SHADER_FLAGS( Occlusion_DX11, "Help for Occlusion", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableColorWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + pShaderShadow->EnableDepthWrites( false ); + + SetInternalVertexShaderConstantBuffersNoSkinning(); + + DECLARE_STATIC_VERTEX_SHADER( writez_vs40 ); + SET_STATIC_VERTEX_SHADER( writez_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( white_ps40 ); + SET_STATIC_PIXEL_SHADER( white_ps40 ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + } + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( writez_vs40 ); + SET_DYNAMIC_VERTEX_SHADER( writez_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( white_ps40 ); + SET_DYNAMIC_PIXEL_SHADER( white_ps40 ); + } + Draw(); + } +END_SHADER +#endif diff --git a/materialsystem/stdshadersdx11/shader_register_map.h b/materialsystem/stdshadersdx11/shader_register_map.h new file mode 100644 index 0000000..c02f287 --- /dev/null +++ b/materialsystem/stdshadersdx11/shader_register_map.h @@ -0,0 +1,48 @@ +#ifndef SHADER_REGISTER_MAP_H_ +#define SHADER_REGISTER_MAP_H_ + +#ifdef __cplusplus + +// Constant buffer registers delegated to engine +#define INTERNAL_CBUFFER_REG_0 0 +#define INTERNAL_CBUFFER_REG_1 1 +#define INTERNAL_CBUFFER_REG_2 2 +#define INTERNAL_CBUFFER_REG_3 3 + +// Dear god I hope you don't use all of these + +// Constant buffer registers delegated to user shaders +#define USER_CBUFFER_REG_0 4 +#define USER_CBUFFER_REG_1 5 +#define USER_CBUFFER_REG_2 6 +#define USER_CBUFFER_REG_3 7 +#define USER_CBUFFER_REG_4 8 +#define USER_CBUFFER_REG_5 9 +#define USER_CBUFFER_REG_6 10 +#define USER_CBUFFER_REG_7 11 +#define USER_CBUFFER_REG_8 12 + +#else // Not C++, HLSL case + +// Constant buffer registers delegated to engine +#define INTERNAL_CBUFFER_REG_0 register( b0 ) +#define INTERNAL_CBUFFER_REG_1 register( b1 ) +#define INTERNAL_CBUFFER_REG_2 register( b2 ) +#define INTERNAL_CBUFFER_REG_3 register( b3 ) + +// Dear god I hope you don't use all of these + +// Constant buffer registers delegated to user shaders +#define USER_CBUFFER_REG_0 register( b4 ) +#define USER_CBUFFER_REG_1 register( b5 ) +#define USER_CBUFFER_REG_2 register( b6 ) +#define USER_CBUFFER_REG_3 register( b7 ) +#define USER_CBUFFER_REG_4 register( b8 ) +#define USER_CBUFFER_REG_5 register( b9 ) +#define USER_CBUFFER_REG_6 register( b10 ) +#define USER_CBUFFER_REG_7 register( b11 ) +#define USER_CBUFFER_REG_8 register( b12 ) + +#endif + +#endif // SHADER_REGISTER_MAP_H_ diff --git a/materialsystem/stdshadersdx11/sky_dx11.cpp b/materialsystem/stdshadersdx11/sky_dx11.cpp new file mode 100644 index 0000000..455f9e5 --- /dev/null +++ b/materialsystem/stdshadersdx11/sky_dx11.cpp @@ -0,0 +1,119 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "BaseVSShader.h" +#include "sky_vs40.inc" +#include "sky_ps40.inc" + +#include "ConVar.h" + +CREATE_CONSTANT_BUFFER( Sky ) +{ + // Vertex shader + Vector4D vTextureSizeInfo; + Vector4D mBaseTexCoordTransform[2]; + + // Pixel shadere + Vector4D vInputScale; +}; + +BEGIN_VS_SHADER( Sky_DX11, "Help for Sky_DX11 shader" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER( Sky ) + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } + } + SHADER_INIT_GLOBAL + { + INIT_CONSTANT_BUFFER( Sky ); + } + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + SetVertexShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERMODEL ); + SetVertexShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 2, SHADER_CONSTANTBUFFER_PERSCENE ); + SetVertexShaderConstantBuffer( 3, CONSTANT_BUFFER( Sky ) ); + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + SetPixelShaderConstantBuffer( 1, CONSTANT_BUFFER( Sky ) ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs40 ); + SET_STATIC_VERTEX_SHADER( sky_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( sky_ps40 ); + SET_STATIC_PIXEL_SHADER( sky_ps40 ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + ALIGN16 Sky_CBuffer_t constants; + memset( &constants, 0, sizeof( Sky_CBuffer_t ) ); + + // Texture coord transform + StoreVertexShaderTextureTransform( constants.mBaseTexCoordTransform, BASETEXTURETRANSFORM ); + + if (params[COLOR]->IsDefined()) + { + params[COLOR]->GetVecValue( constants.vInputScale.Base(), 3 ); + } + ITexture *txtr = params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt = txtr->GetImageFormat(); + if ( + ( fmt == IMAGE_FORMAT_RGBA16161616 ) || + ( ( fmt == IMAGE_FORMAT_RGBA16161616F ) && + ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) ) + ) + { + constants.vInputScale[0]*=16.0; + constants.vInputScale[1]*=16.0; + constants.vInputScale[2]*=16.0; + } + + UPDATE_CONSTANT_BUFFER( Sky, constants ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs40 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps40 ); + } + Draw( ); + } + +END_SHADER + diff --git a/materialsystem/stdshadersdx11/sky_hdr_compressed_ps40.fxc b/materialsystem/stdshadersdx11/sky_hdr_compressed_ps40.fxc new file mode 100644 index 0000000..bbde745 --- /dev/null +++ b/materialsystem/stdshadersdx11/sky_hdr_compressed_ps40.fxc @@ -0,0 +1,33 @@ +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +#include "common_ps_fxc.h" +#include "common_cbuffers_fxc.h" +CBUFFER_PERFRAME(register(b0)) + +Texture2D ExposureTexture0 : register( t0 ); +sampler ExposureTextureSampler0 : register( s0 ); +Texture2D ExposureTexture1 : register( t1 ); +sampler ExposureTextureSampler1 : register( s1 ); +Texture2D ExposureTexture2 : register( t2 ); +sampler ExposureTextureSampler2 : register( s2 ); + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + + float2 baseTexCoord : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + HALF3 color0 = 0.25*ExposureTexture0.Sample( ExposureTextureSampler0, i.baseTexCoord ); + HALF3 color1 = 2.0*ExposureTexture1.Sample( ExposureTextureSampler1, i.baseTexCoord ); + HALF3 color2 = 16.0*ExposureTexture2.Sample( ExposureTextureSampler2, i.baseTexCoord ); + + // This is never fogged. + return FinalOutput( float4(1,0,0,1 ), 0, PIXEL_FOG_TYPE_NONE, float4(0, 0, 0, 1), + TONEMAP_SCALE_LINEAR, cToneMappingScale, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/materialsystem/stdshadersdx11/sky_hdr_compressed_rgbs_ps40.fxc b/materialsystem/stdshadersdx11/sky_hdr_compressed_rgbs_ps40.fxc new file mode 100644 index 0000000..9b11813 --- /dev/null +++ b/materialsystem/stdshadersdx11/sky_hdr_compressed_rgbs_ps40.fxc @@ -0,0 +1,51 @@ +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +#include "common_ps_fxc.h" + +Texture2D RGBSTexture : register( t0 ); +sampler RGBSTextureSampler : register( s0 ); + +#include "common_sky_fxc.h" +#include "common_cbuffers_fxc.h" +CBUFFER_PERFRAME(register(b0)) + +cbuffer Sky_CBuffer : register(b1) +{ + Sky_t cSky; +}; + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + float3 result; + + float4 s00 = RGBSTexture.Sample(RGBSTextureSampler, i.baseTexCoord00); + float4 s10 = RGBSTexture.Sample(RGBSTextureSampler, i.baseTexCoord10); + float4 s01 = RGBSTexture.Sample(RGBSTextureSampler, i.baseTexCoord01); + float4 s11 = RGBSTexture.Sample(RGBSTextureSampler, i.baseTexCoord11); + + float2 fracCoord = frac(i.baseTexCoord_In_Pixels); + + s00.rgb*=s00.a; + s10.rgb*=s10.a; + + s00.xyz = lerp(s00, s10, fracCoord.x); + + s01.rgb*=s01.a; + s11.rgb*=s11.a; + s01.xyz = lerp(s01, s11, fracCoord.x); + + result = lerp(s00, s01, fracCoord.y); + + // This is never fogged. + return FinalOutput( float4( cSky.InputScale*result, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, float4(0, 0, 0, 1), + TONEMAP_SCALE_LINEAR, cToneMappingScale, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/materialsystem/stdshadersdx11/sky_hdr_dx11.cpp b/materialsystem/stdshadersdx11/sky_hdr_dx11.cpp new file mode 100644 index 0000000..18ddbc1 --- /dev/null +++ b/materialsystem/stdshadersdx11/sky_hdr_dx11.cpp @@ -0,0 +1,219 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "BaseVSShader.h" +#include "sky_vs40.inc" +#include "sky_ps40.inc" +#include "sky_hdr_compressed_ps40.inc" +#include "sky_hdr_compressed_rgbs_ps40.inc" + +CREATE_CONSTANT_BUFFER( Sky_HDR ) +{ + // Vertex shader + Vector4D vTextureSizeInfo; + Vector4D mBaseTexCoordTransform[2]; + + // Pixel shadere + Vector4D vInputScale; +}; + +#include "ConVar.h" + +static ConVar mat_use_compressed_hdr_textures( "mat_use_compressed_hdr_textures", "1" ); + +DEFINE_FALLBACK_SHADER( Sky, Sky_HDR_DX11 ) + +BEGIN_VS_SHADER( Sky_HDR_DX11, "Help for Sky_HDR_DX11 shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( HDRBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture when running with HDR enabled" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture (compressed) for hdr compression method A" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture0 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture1 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture2 for hdr compression method B" ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER( Sky_HDR ) + + SHADER_INIT_GLOBAL + { + INIT_CONSTANT_BUFFER( Sky_HDR ); + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "Sky_DX11"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + if (params[HDRCOMPRESSEDTEXTURE]->IsDefined() && (mat_use_compressed_hdr_textures.GetBool() ) ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE ); + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE0 ); + if (params[HDRCOMPRESSEDTEXTURE1]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE1 ); + } + if (params[HDRCOMPRESSEDTEXTURE2]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE2 ); + } + } + else + { + if (params[HDRBASETEXTURE]->IsDefined()) + { + LoadTexture( HDRBASETEXTURE ); + } + } + } + } + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + SetVertexShaderConstantBuffer( 0, + SHADER_CONSTANTBUFFER_PERMODEL ); + SetVertexShaderConstantBuffer( 1, + SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 2, + SHADER_CONSTANTBUFFER_PERSCENE ); + SetVertexShaderConstantBuffer( 3, CONSTANT_BUFFER( Sky_HDR ) ); + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs40 ); + SET_STATIC_VERTEX_SHADER( sky_vs40 ); + + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && + mat_use_compressed_hdr_textures.GetBool() ) + { + SetPixelShaderConstantBuffer( 1, CONSTANT_BUFFER( Sky_HDR ) ); + + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps40 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps40 ); + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps40 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps40 ); + } + else + { + SetPixelShaderConstantBuffer( 1, CONSTANT_BUFFER( Sky_HDR ) ); + + DECLARE_STATIC_PIXEL_SHADER( sky_ps40 ); + SET_STATIC_PIXEL_SHADER( sky_ps40 ); + } + } + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs40 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs40 ); + + ALIGN16 Sky_HDR_CBuffer_t constants; + memset( &constants, 0, sizeof( Sky_HDR_CBuffer_t ) ); + + // Texture coord transform + StoreVertexShaderTextureTransform( constants.mBaseTexCoordTransform, BASETEXTURETRANSFORM ); + + Vector4D vInputScale( 1, 1, 1, 1 ); + if ( params[COLOR]->IsDefined() ) + { + params[COLOR]->GetVecValue( vInputScale.Base(), 3 ); + } + if ( + params[HDRCOMPRESSEDTEXTURE]->IsDefined() && + mat_use_compressed_hdr_textures.GetBool() + ) + { + + // set up data needs for pixel shader interpolation + ITexture *txtr=params[HDRCOMPRESSEDTEXTURE]->GetTextureValue(); + float w = txtr->GetActualWidth(); + float h = txtr->GetActualHeight(); + float FUDGE = 0.01 / max( w, h ); // per ATI + constants.vTextureSizeInfo.Init( 0.5 / w - FUDGE, 0.5 / h - FUDGE, w, h ); + + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE, FRAME ); + vInputScale[0]*=8.0; + vInputScale[1]*=8.0; + vInputScale[2]*=8.0; + constants.vInputScale = vInputScale; + + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps40 ); + } + else + { + + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE0, FRAME ); + BindTexture( SHADER_SAMPLER1, HDRCOMPRESSEDTEXTURE1, FRAME ); + BindTexture( SHADER_SAMPLER2, HDRCOMPRESSEDTEXTURE2, FRAME ); + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps40 ); + + } + else + { + + BindTexture( SHADER_SAMPLER0, HDRBASETEXTURE, FRAME ); + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + vInputScale[0]*=16.0; + vInputScale[1]*=16.0; + vInputScale[2]*=16.0; + } + + constants.vInputScale = vInputScale; + + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps40 ); + } + } + + UPDATE_CONSTANT_BUFFER( Sky_HDR, constants ); + } + Draw( ); + } +END_SHADER diff --git a/materialsystem/stdshadersdx11/sky_ps40.fxc b/materialsystem/stdshadersdx11/sky_ps40.fxc new file mode 100644 index 0000000..c48f13a --- /dev/null +++ b/materialsystem/stdshadersdx11/sky_ps40.fxc @@ -0,0 +1,36 @@ +// HDRFIXME: Make this work with nonHDR +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#include "common_ps_fxc.h" +#include "common_cbuffers_fxc.h" +CBUFFER_PERFRAME(register(b0)) + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); + +#include "common_sky_fxc.h" + +cbuffer Sky_CBuffer : register( b1 ) +{ + Sky_t cSky; +}; + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + float2 baseTexCoord : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + float4 color = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy ); + color.rgb *= cSky.InputScale.rgb; + + // This is never fogged. + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, float4(0, 0, 0, 1), + TONEMAP_SCALE_LINEAR, cToneMappingScale, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/materialsystem/stdshadersdx11/sky_vs40.fxc b/materialsystem/stdshadersdx11/sky_vs40.fxc new file mode 100644 index 0000000..98016b1 --- /dev/null +++ b/materialsystem/stdshadersdx11/sky_vs40.fxc @@ -0,0 +1,64 @@ +#include "common_cbuffers_fxc.h" +CBUFFER_PERMODEL(register(b0)) // model matrix +CBUFFER_PERFRAME(register(b1)) // view matrix +CBUFFER_PERSCENE(register(b2)) // proj matrix + +#include "common_sky_fxc.h" + +cbuffer Sky_CBuffer_t : register(b3) +{ + Sky_t cSky; +}; + +#include "common_vs_fxc.h" + +#define TEXEL_XINCR (cSky.vTextureSizeInfo.x) +#define TEXEL_YINCR (cSky.vTextureSizeInfo.y) +#define U_TO_PIXEL_COORD_SCALE (cSky.vTextureSizeInfo.z) +#define V_TO_PIXEL_COORD_SCALE (cSky.vTextureSizeInfo.w) + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; + + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = ComputeProjPos(v.vPos.xyz, cModelMatrix, cViewMatrix, cProjMatrix); + + float4 vTexCoordInput = { v.vTexCoord0.x, v.vTexCoord0.y, 0.0f, 1.0f }; + float2 vTexCoord; + vTexCoord.x = dot( vTexCoordInput.xyzw, cSky.mBaseTexCoordTransform[0] ); + vTexCoord.y = dot( vTexCoordInput.xyzw, cSky.mBaseTexCoordTransform[1] ); + + // Compute quantities needed for pixel shader texture lerping + o.baseTexCoord00.x = vTexCoord.x - TEXEL_XINCR; + o.baseTexCoord00.y = vTexCoord.y - TEXEL_YINCR; + o.baseTexCoord10.x = vTexCoord.x + TEXEL_XINCR; + o.baseTexCoord10.y = vTexCoord.y - TEXEL_YINCR; + + o.baseTexCoord01.x = vTexCoord.x - TEXEL_XINCR; + o.baseTexCoord01.y = vTexCoord.y + TEXEL_YINCR; + o.baseTexCoord11.x = vTexCoord.x + TEXEL_XINCR; + o.baseTexCoord11.y = vTexCoord.y + TEXEL_YINCR; + + o.baseTexCoord_In_Pixels.xy = o.baseTexCoord00.xy; + o.baseTexCoord_In_Pixels.x *= U_TO_PIXEL_COORD_SCALE; + o.baseTexCoord_In_Pixels.y *= V_TO_PIXEL_COORD_SCALE; + + return o; +} diff --git a/materialsystem/stdshadersdx11/splinecard_vs40.fxc b/materialsystem/stdshadersdx11/splinecard_vs40.fxc new file mode 100644 index 0000000..7895d35 --- /dev/null +++ b/materialsystem/stdshadersdx11/splinecard_vs40.fxc @@ -0,0 +1,68 @@ +#include "common_vs_fxc.h" + +#include "common_cbuffers_fxc.h" + +CBUFFER_PERFRAME(register( b0 )) +CBUFFER_PERSCENE(register( b1 )) + +// derivative of catmull rom spline courtesy of calc +float4 DCatmullRomSpline ( float4 a, float4 b, float4 c, float4 d, float t ) +{ + return 0.5 *( c - a + t * ( 2 * a - 5 * b + 4 * c - d + t * (3 * b - a - 3 * c + d ) ) + + t * ( 2 * a - 5 * b + 4 * c - d + 2 * ( t * ( 3 * b - a - 3 * c + d ) ) ) ); +} + +float3 DCatmullRomSpline3 ( float3 a, float3 b, float3 c, float3 d, float t ) +{ + return 0.5 *( c - a + t * ( 2 * a - 5 * b + 4 * c - d + t * (3 * b - a - 3 * c + d ) ) + + t * ( 2 * a - 5 * b + 4 * c - d + 2 * ( t * ( 3 * b - a - 3 * c + d ) ) ) ); +} + + +float4 CatmullRomSpline( float4 a, float4 b, float4 c, float4 d, float t ) +{ + return b + 0.5 * t * ( c - a + t * ( 2 * a - 5 * b + 4 * c - d + t * ( -a + 3 * b -3 * c + d ) ) ); +} + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vTint : COLOR; + float4 vParms : POSITION; // T V side_id + float4 vSplinePt0 : TEXCOORD0; // x y z rad + float4 vSplinePt1 : TEXCOORD1; // x y z rad + float4 vSplinePt2 : TEXCOORD2; // x y z rad + float4 vSplinePt3 : TEXCOORD3; // x y z rad +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; + + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; + float4 vScreenPos : TEXCOORD7; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + float4x4 viewProj = mul(cViewMatrix, cProjMatrix); + + float4 posrad = + CatmullRomSpline( v.vSplinePt0, v.vSplinePt1, v.vSplinePt2, v.vSplinePt3, v.vParms.x ); + float3 v2p = ( posrad.xyz - cEyePos ); + float3 tangent=DCatmullRomSpline3( v.vSplinePt0, v.vSplinePt1, v.vSplinePt2, v.vSplinePt3, v.vParms.x ); + float3 ofs = normalize( cross(v2p, normalize( tangent) ) ); + posrad.xyz += ofs * ( posrad.w * ( v.vParms.z - .5 ) ); + o.projPos = mul( float4(posrad.xyz, 1.0f), viewProj ); + o.texCoord0 = o.texCoord1 = float2( (1-v.vParms.z), v.vParms.y); + o.argbcolor = v.vTint; + o.blendfactor0 = float4(0,0,0,0); + o.vScreenPos = float4(0,0,0,0); + return o; + +} diff --git a/materialsystem/stdshadersdx11/sprite_dx11.cpp b/materialsystem/stdshadersdx11/sprite_dx11.cpp new file mode 100644 index 0000000..488a3fa --- /dev/null +++ b/materialsystem/stdshadersdx11/sprite_dx11.cpp @@ -0,0 +1,452 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "BaseVSShader.h" +#include +#include "const.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#include "sprite_vs40.inc" +#include "sprite_ps40.inc" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + +CREATE_CONSTANT_BUFFER( Sprite ) +{ + Vector4D cHDRColorScale; + Vector4D cModulationColor; + Vector4D cFogParams; + Vector4D cFogColor; +}; + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX11 ) + +BEGIN_VS_SHADER( Sprite_DX11, + "Help for Sprite_DX11" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + SHADER_PARAM( NOSRGB, SHADER_PARAM_TYPE_BOOL, "0", "do not operate in srgb space" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER( Sprite ) + SHADER_INIT_GLOBAL + { + INIT_CONSTANT_BUFFER( Sprite ); + } + + SHADER_FALLBACK + { + return 0; + } + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + if (!params[ALPHA]->IsDefined()) + { + params[ALPHA]->SetFloatValue( 1.0f ); + } + + if (!params[HDRCOLORSCALE]->IsDefined()) + { + params[HDRCOLORSCALE]->SetFloatValue( 1.0f ); + } + + if ( !params[NOSRGB]->IsDefined() ) + { + // Disable sRGB reads and writes by default + params[NOSRGB]->SetIntValue( 1 ); + } + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + +#define SHADER_USE_VERTEX_COLOR 1 +#define SHADER_USE_CONSTANT_COLOR 2 + + void SetSpriteCommonShadowState( unsigned int shaderFlags ) + { + IShaderShadow *pShaderShadow = s_pShaderShadow; + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + + unsigned int flags = VERTEX_POSITION; + if( shaderFlags & SHADER_USE_VERTEX_COLOR ) + { + flags |= VERTEX_COLOR; + } + int numTexCoords = 1; + s_pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + SetInternalVertexShaderConstantBuffersNoSkinning(); + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + SetPixelShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERSCENE ); + SetPixelShaderConstantBuffer( 2, CONSTANT_BUFFER( Sprite ) ); + + DECLARE_STATIC_VERTEX_SHADER( sprite_vs40 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_VERTEX_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_VERTEX_SHADER( sprite_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( sprite_ps40 ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_PIXEL_SHADER( sprite_ps40 ); + } + + void SetSpriteCommonDynamicState( unsigned int shaderFlags ) + { + IShaderDynamicAPI *pShaderAPI = s_pShaderAPI; + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps40 ); + + ALIGN16 Sprite_CBuffer_t psConsts; + psConsts.cModulationColor.Init( 1, 1, 1, 1 ); + if ( IsHDREnabled() ) + { + if ( bSRGB ) + StoreConstantGammaToLinear( psConsts.cHDRColorScale.Base(), HDRCOLORSCALE ); + else + s_ppParams[HDRCOLORSCALE]->GetVecValueFast( psConsts.cHDRColorScale.Base(), 4 ); + } + else + { + psConsts.cHDRColorScale.Init( 0, 0, 0, 0 ); + } + pShaderAPI->GetFogParamsAndColor( psConsts.cFogParams.Base(), psConsts.cFogColor.Base() ); + + UPDATE_CONSTANT_BUFFER( Sprite, psConsts ); + + } + + SHADER_DRAW + { + bool bSRGB = params[NOSRGB]->GetIntValue() == 0; + + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + FogToFogColor(); + + SetSpriteCommonShadowState( 0 ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( 0 ); + } + Draw(); + break; + case kRenderTransColor: + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlpha: + // untested cut and past from kRenderTransAlphaAdd . . same as first pass of that. + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + + SHADOW_STATE + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + + case kRenderTransAdd: + { + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( flags ); + } + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps40 ); + + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + + ALIGN16 Sprite_CBuffer_t psConsts; + psConsts.cModulationColor = color; + if ( IsHDREnabled() ) + { + if ( bSRGB ) + StoreConstantGammaToLinear( psConsts.cHDRColorScale.Base(), HDRCOLORSCALE ); + else + s_ppParams[HDRCOLORSCALE]->GetVecValueFast( psConsts.cHDRColorScale.Base(), 4 ); + } + else + { + psConsts.cHDRColorScale.Init( 0, 0, 0, 0 ); + } + pShaderAPI->GetFogParamsAndColor( psConsts.cFogParams.Base(), psConsts.cFogColor.Base() ); + + UPDATE_CONSTANT_BUFFER( Sprite, psConsts ); + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps40 ); + + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + + ALIGN16 Sprite_CBuffer_t psConsts; + psConsts.cModulationColor = color; + if ( IsHDREnabled() ) + { + if ( bSRGB ) + StoreConstantGammaToLinear( psConsts.cHDRColorScale.Base(), HDRCOLORSCALE ); + else + s_ppParams[HDRCOLORSCALE]->GetVecValueFast( psConsts.cHDRColorScale.Base(), 4 ); + } + else + { + psConsts.cHDRColorScale.Init( 0, 0, 0, 0 ); + } + pShaderAPI->GetFogParamsAndColor( psConsts.cFogParams.Base(), psConsts.cFogColor.Base() ); + + UPDATE_CONSTANT_BUFFER( Sprite, psConsts ); + } + Draw(); + } + + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/materialsystem/stdshadersdx11/sprite_ps40.fxc b/materialsystem/stdshadersdx11/sprite_ps40.fxc new file mode 100644 index 0000000..17bb9b9 --- /dev/null +++ b/materialsystem/stdshadersdx11/sprite_ps40.fxc @@ -0,0 +1,63 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CONSTANTCOLOR" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "SRGB" "0..1" + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_cbuffers_fxc.h" +CBUFFER_PERFRAME(register(b0)) +CBUFFER_PERSCENE(register(b1)) + +cbuffer Sprite_PS40_t : register(b2) +{ + float4 g_HDRColorScale; + float4 cModulationColor; + float4 g_FogParams; + float4 g_FogColor; +}; + +#include "common_ps_fxc.h" + +#define g_Color cModulationColor + +#define g_EyePos_SpecExponent cEyePos + +Texture2D Tex : register( t0 ); +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + float3 eyeSpacePos : TEXCOORD3; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + float4 sample = Tex.Sample( TexSampler, i.baseTexCoord ); + +#if VERTEXCOLOR + sample *= i.color; +#endif + +#if CONSTANTCOLOR + sample *= g_Color; +#endif + +#if HDRTYPE && HDRENABLED + sample.xyz *= g_HDRColorScale.x; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, length( i.eyeSpacePos ) ); +#if SRGB + return FinalOutput( sample, fogFactor, PIXELFOGTYPE, g_FogColor, TONEMAP_SCALE_LINEAR, cToneMappingScale ); +#else + return FinalOutput( sample, fogFactor, PIXELFOGTYPE, g_FogColor, TONEMAP_SCALE_GAMMA, cToneMappingScale ); +#endif +} + diff --git a/materialsystem/stdshadersdx11/sprite_vs40.fxc b/materialsystem/stdshadersdx11/sprite_vs40.fxc new file mode 100644 index 0000000..cba32b0 --- /dev/null +++ b/materialsystem/stdshadersdx11/sprite_vs40.fxc @@ -0,0 +1,68 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SRGB" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_cbuffers_fxc.h" +CBUFFER_PERMODEL(register(b0)) // model matrix +CBUFFER_PERFRAME(register(b1)) // view matrix +CBUFFER_PERSCENE(register(b2)) // proj matrix + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vColor : COLOR0; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + float3 eyeSpacePos : TEXCOORD3; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul4x3( v.vPos, cModelMatrix ); + + matrix viewProj = mul(cViewMatrix, cProjMatrix); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), viewProj ); + o.projPos = projPos; + + o.eyeSpacePos = mul(float4(worldPos, 1), cViewMatrix).xyz; + + o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); + + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. +#if SRGB + o.color.rgba = GammaToLinear( v.vColor.rgba ); +#else + o.color.rgba = v.vColor.rgba; +#endif + } + + // Base texture coordinates + o.baseTexCoord.xy = v.vTexCoord0.xy; + + return o; +} + + diff --git a/materialsystem/stdshadersdx11/spritecard.cpp b/materialsystem/stdshadersdx11/spritecard.cpp new file mode 100644 index 0000000..8de3aaa --- /dev/null +++ b/materialsystem/stdshadersdx11/spritecard.cpp @@ -0,0 +1,352 @@ +//===== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======// +// +// Purpose: shader for drawing sprites as cards, with animation frame lerping +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +#include "spritecard_ps40.inc" +#include "spritecard_vs40.inc" +#include "splinecard_vs40.inc" + +#include "tier0/icommandline.h" //command line + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define DEFAULT_PARTICLE_FEATHERING_ENABLED 1 + +CREATE_CONSTANT_BUFFER( SpriteCard ) +{ + Vector4D ScaleParms; + Vector4D SizeParms; + Vector4D SizeParms2; + IntVector4D SpriteControls; + + Vector4D PixelParms; + Vector4D DepthFeatheringConstants; +}; + +int GetDefaultDepthFeatheringValue( void ) //Allow the command-line to go against the default soft-particle value +{ + static int iRetVal = -1; + + if( iRetVal == -1 ) + { +# if( DEFAULT_PARTICLE_FEATHERING_ENABLED == 1 ) + { + if( CommandLine()->CheckParm( "-softparticlesdefaultoff" ) ) + iRetVal = 0; + else + iRetVal = 1; + } +# else + { + if( CommandLine()->CheckParm( "-softparticlesdefaulton" ) ) + iRetVal = 1; + else + iRetVal = 0; + } +# endif + } + + return iRetVal; +} + + +BEGIN_VS_SHADER_FLAGS( Spritecard, "Help for Spritecard", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + SHADER_PARAM( ORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "0 = always face camera, 1 = rotate around z, 2= parallel to ground" ) + SHADER_PARAM( ADDBASETEXTURE2, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount to blend second texture into frame by" ) + SHADER_PARAM( OVERBRIGHTFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "overbright factor for texture. For HDR effects.") + SHADER_PARAM( DUALSEQUENCE, SHADER_PARAM_TYPE_INTEGER, "0", "blend two separate animated sequences.") + SHADER_PARAM( SEQUENCE_BLEND_MODE, SHADER_PARAM_TYPE_INTEGER, "0", "defines the blend mode between the images un dual sequence particles. 0 = avg, 1=alpha from first, rgb from 2nd, 2= first over second" ) + SHADER_PARAM( MAXLUMFRAMEBLEND1, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the first sequence, select pixels based upon max luminance" ) + SHADER_PARAM( MAXLUMFRAMEBLEND2, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the 2nd sequence, select pixels based upon max luminance" ) + SHADER_PARAM( RAMPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "if specified, then the red value of the image is used to index this ramp to produce the output color" ) + SHADER_PARAM( ZOOMANIMATESEQ2, SHADER_PARAM_TYPE_FLOAT, "1.0", "amount to gradually zoom between frames on the second sequence. 2.0 will double the size of a frame over its lifetime.") + SHADER_PARAM( EXTRACTGREENALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "grayscale data sitting in green/alpha channels") + SHADER_PARAM( ADDOVERBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "use ONE:INVSRCALPHA blending") + SHADER_PARAM( ADDSELF, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount of base texture to additively blend in" ) + SHADER_PARAM( BLENDFRAMES, SHADER_PARAM_TYPE_BOOL, "1", "whether or not to smoothly blend between animated frames" ) + SHADER_PARAM( MINSIZE, SHADER_PARAM_TYPE_FLOAT, "0.0", "minimum screen fractional size of particle") + SHADER_PARAM( STARTFADESIZE, SHADER_PARAM_TYPE_FLOAT, "10.0", "screen fractional size to start fading particle out") + SHADER_PARAM( ENDFADESIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "screen fractional size to finish fading particle out") + SHADER_PARAM( MAXSIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "maximum screen fractional size of particle") + SHADER_PARAM( USEINSTANCING, SHADER_PARAM_TYPE_BOOL, "1", "whether to use GPU vertex instancing (submit 1 vert per particle quad)") + SHADER_PARAM( SPLINETYPE, SHADER_PARAM_TYPE_INTEGER, "0", "spline type 0 = none, 1=ctamull rom") + SHADER_PARAM( MAXDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100000.0", "maximum distance to draw particles at") + SHADER_PARAM( FARFADEINTERVAL, SHADER_PARAM_TYPE_FLOAT, "400.0", "interval over which to fade out far away particles") + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER(SpriteCard) + + SHADER_INIT_GLOBAL + { + INIT_CONSTANT_BUFFER( SpriteCard ); + } + + SHADER_INIT_PARAMS() + { + INIT_FLOAT_PARM( MAXDISTANCE, 100000.0); + INIT_FLOAT_PARM( FARFADEINTERVAL, 400.0); + INIT_FLOAT_PARM( MAXSIZE, 20.0 ); + INIT_FLOAT_PARM( ENDFADESIZE, 20.0 ); + INIT_FLOAT_PARM( STARTFADESIZE, 10.0 ); + INIT_FLOAT_PARM( DEPTHBLENDSCALE, 50.0 ); + INIT_FLOAT_PARM( OVERBRIGHTFACTOR, 1.0 ); + INIT_FLOAT_PARM( ADDBASETEXTURE2, 0.0 ); + INIT_FLOAT_PARM( ADDSELF, 0.0 ); + INIT_FLOAT_PARM( ZOOMANIMATESEQ2, 0.0 ); + + if ( !params[DEPTHBLEND]->IsDefined() ) + { + params[ DEPTHBLEND ]->SetIntValue( GetDefaultDepthFeatheringValue() ); + } + if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + params[ DEPTHBLEND ]->SetIntValue( 0 ); + } + if ( !params[DUALSEQUENCE]->IsDefined() ) + { + params[DUALSEQUENCE]->SetIntValue( 0 ); + } + if ( !params[MAXLUMFRAMEBLEND1]->IsDefined() ) + { + params[MAXLUMFRAMEBLEND1]->SetIntValue( 0 ); + } + if ( !params[MAXLUMFRAMEBLEND2]->IsDefined() ) + { + params[MAXLUMFRAMEBLEND2]->SetIntValue( 0 ); + } + if ( !params[EXTRACTGREENALPHA]->IsDefined() ) + { + params[EXTRACTGREENALPHA]->SetIntValue( 0 ); + } + if ( !params[ADDOVERBLEND]->IsDefined() ) + { + params[ADDOVERBLEND]->SetIntValue( 0 ); + } + if ( !params[BLENDFRAMES]->IsDefined() ) + { + params[ BLENDFRAMES ]->SetIntValue( 1 ); + } + if ( !params[USEINSTANCING]->IsDefined() ) + { + params[ USEINSTANCING ]->SetIntValue( IsX360() ? 1 : 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_IS_SPRITECARD ); + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + if ( params[BASETEXTURE]->IsDefined() ) + { + bool bExtractGreenAlpha = false; + if ( params[EXTRACTGREENALPHA]->IsDefined() ) + bExtractGreenAlpha = params[EXTRACTGREENALPHA]->GetIntValue() != 0; + + LoadTexture( BASETEXTURE ); + } + if ( params[RAMPTEXTURE]->IsDefined() ) + { + LoadTexture( RAMPTEXTURE ); + } + } + + SHADER_DRAW + { + bool bUseRampTexture = ( params[RAMPTEXTURE]->IsDefined() ); + bool bZoomSeq2 = ( ( params[ZOOMANIMATESEQ2]->GetFloatValue()) > 1.0 ); + bool bDepthBlend = ( params[DEPTHBLEND]->GetIntValue() != 0 ); + bool bAdditive2ndTexture = params[ADDBASETEXTURE2]->GetFloatValue() != 0.0; + bool bExtractGreenAlpha = ( params[EXTRACTGREENALPHA]->GetIntValue() != 0 ); + int nSplineType = params[SPLINETYPE]->GetIntValue(); + bool bUseInstancing = false; + + SHADOW_STATE + { + bool bSecondSequence = params[DUALSEQUENCE]->GetIntValue() != 0; + bool bAddOverBlend = params[ADDOVERBLEND]->GetIntValue() != 0; + bool bBlendFrames = ( params[BLENDFRAMES]->GetIntValue() != 0 ); + if ( nSplineType ) + { + bBlendFrames = false; + bUseInstancing = false; + } + bool bAddSelf = params[ADDSELF]->GetFloatValue() != 0.0; + + // draw back-facing because of yaw spin + pShaderShadow->EnableCulling( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + if ( bAdditive2ndTexture || bAddOverBlend || bAddSelf ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + + unsigned int flags = VERTEX_POSITION | VERTEX_COLOR; + static int s_TexCoordSize[8]={4, // 0 = sheet bounding uvs, frame0 + 4, // 1 = sheet bounding uvs, frame 1 + 4, // 2 = frame blend, rot, radius, ??? + 2, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 ) + 4, // 4 = texture 2 bounding uvs + 4, // 5 = second sequence bounding uvs, frame0 + 4, // 6 = second sequence bounding uvs, frame1 + 4, // 7 = second sequence frame blend, ?,?,? + }; + static int s_TexCoordSizeSpline[]={4, // 0 = sheet bounding uvs, frame0 + 4, // 1 = sheet bounding uvs, frame 1 + 4, // 2 = frame blend, rot, radius, ??? + 4, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 ) + 4, // 4 = texture 2 bounding uvs + 4, // 5 = second sequence bounding uvs, frame0 + 4, // 6 = second sequence bounding uvs, frame1 + 4, // 7 = second sequence frame blend, ?,?,? + }; + + int numTexCoords = 4; + if ( bAdditive2ndTexture ) + { + numTexCoords = 5; + } + if ( bSecondSequence ) + { + // the whole shebang - 2 sequences, with a possible multi-image sequence first + numTexCoords = 8; + } + pShaderShadow->VertexShaderVertexFormat( flags, + numTexCoords, + nSplineType? s_TexCoordSizeSpline : s_TexCoordSize, 0 ); + + if ( nSplineType ) + { + SetVertexShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERSCENE ); + + DECLARE_STATIC_VERTEX_SHADER( splinecard_vs40 ); + SET_STATIC_VERTEX_SHADER( splinecard_vs40 ); + } + else + { + SetVertexShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERMODEL ); + SetVertexShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 2, SHADER_CONSTANTBUFFER_PERSCENE ); + SetVertexShaderConstantBuffer( 3, CONSTANT_BUFFER( SpriteCard ) ); + + DECLARE_STATIC_VERTEX_SHADER( spritecard_vs40 ); + SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_VERTEX_SHADER( spritecard_vs40 ); + } + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + SetPixelShaderConstantBuffer( 1, CONSTANT_BUFFER( SpriteCard ) ); + + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps40 ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames ); + SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( ALPHATEST, !( bAdditive2ndTexture || bAddSelf ) ); + SET_STATIC_PIXEL_SHADER( spritecard_ps40 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + if ( bUseRampTexture ) + { + BindTexture( SHADER_SAMPLER1, RAMPTEXTURE, FRAME ); + } + + if ( bDepthBlend ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + + int nOrientation = params[ORIENTATION]->GetIntValue(); + nOrientation = clamp( nOrientation, 0, 2 ); + + ALIGN16 CONSTANT_BUFFER_TYPE( SpriteCard ) consts; + + if ( bZoomSeq2 ) + { + float flZScale=1.0/(params[ZOOMANIMATESEQ2]->GetFloatValue()); + consts.ScaleParms.Init( 0.5 * ( 1.0 + flZScale ), flZScale, 0, 0 ); + } + + // set fade constants in vsconsts 8 and 9 + float flMaxDistance = params[MAXDISTANCE]->GetFloatValue(); + float flStartFade = max( 1.0, flMaxDistance - params[FARFADEINTERVAL]->GetFloatValue() ); + + float VC0[8]={ params[MINSIZE]->GetFloatValue(), params[MAXSIZE]->GetFloatValue(), + params[STARTFADESIZE]->GetFloatValue(), params[ENDFADESIZE]->GetFloatValue(), + flStartFade, 1.0/(flMaxDistance-flStartFade), + 0,0 }; + + consts.SizeParms = VC0; + consts.SizeParms2 = VC0 + 4; + consts.SpriteControls.Init( bZoomSeq2, bExtractGreenAlpha, bUseInstancing, 0 ); + + // FIXME + //pShaderAPI->SetDepthFeatheringPixelShaderConstant( 2, params[DEPTHBLENDSCALE]->GetFloatValue() ); + consts.DepthFeatheringConstants.Init(); + + float C0[4]={ params[ADDBASETEXTURE2]->GetFloatValue(), + params[OVERBRIGHTFACTOR]->GetFloatValue(), + params[ADDSELF]->GetFloatValue(), + 0.0f }; + consts.PixelParms = C0; + + UPDATE_CONSTANT_BUFFER( SpriteCard, consts ); + + if ( nSplineType ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( splinecard_vs40 ); + SET_DYNAMIC_VERTEX_SHADER( splinecard_vs40 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( spritecard_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation ); + SET_DYNAMIC_VERTEX_SHADER( spritecard_vs40 ); + } + + DECLARE_DYNAMIC_PIXEL_SHADER( spritecard_ps40 ); + SET_DYNAMIC_PIXEL_SHADER( spritecard_ps40 ); + } + Draw( ); + } +END_SHADER diff --git a/materialsystem/stdshadersdx11/spritecard_constants_fxc.h b/materialsystem/stdshadersdx11/spritecard_constants_fxc.h new file mode 100644 index 0000000..884f8f7 --- /dev/null +++ b/materialsystem/stdshadersdx11/spritecard_constants_fxc.h @@ -0,0 +1,17 @@ +#ifndef SPRITECARD_CONSTANTS_FXC_H_ +#define SPRITECARD_CONSTANTS_FXC_H_ + +struct SpriteCard_t +{ + // Vertex shader + float4 ScaleParms; + float4 SizeParms; + float4 SizeParms2; + int4 SpriteControls; + + // Pixel shader + float4 g_Parameters; + float4 g_DepthFeatheringConstants; +}; + +#endif // SPRITECARD_CONSTANTS_FXC_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/spritecard_ps40.fxc b/materialsystem/stdshadersdx11/spritecard_ps40.fxc new file mode 100644 index 0000000..9a44ea3 --- /dev/null +++ b/materialsystem/stdshadersdx11/spritecard_ps40.fxc @@ -0,0 +1,204 @@ +// STATIC: "DUALSEQUENCE" "0..1" +// STATIC: "SEQUENCE_BLEND_MODE" "0..2" +// STATIC: "ADDBASETEXTURE2" "0..1" +// STATIC: "MAXLUMFRAMEBLEND1" "0..1" +// STATIC: "MAXLUMFRAMEBLEND2" "0..1" +// STATIC: "EXTRACTGREENALPHA" "0..1" +// STATIC: "COLORRAMP" "0..1" +// STATIC: "ANIMBLEND" "0..1" +// STATIC: "ADDSELF" "0..1" +// STATIC: "ALPHATEST" "0..1" +// STATIC: "DEPTHBLEND" "0..1" + +#define COMBINE_MODE_AVERAGE 0 +#define COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND 1 +#define COMBINE_MODE_USE_FIRST_OVER_SECOND 2 + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +#include "common_cbuffers_fxc.h" +CBUFFER_PERFRAME(register(b0)) + +#include "spritecard_constants_fxc.h" + +cbuffer SpriteCard_CBuffer : register( b1 ) +{ + SpriteCard_t c; +}; + +#define fAdditiveBlendWeight c.g_Parameters.x +#define fOverbrightFactor c.g_Parameters.y +#define fAdditiveSelfBlendWeight c.g_Parameters.z + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; +#if ADDBASETEXTURE2 + float2 texCoord2 : TEXCOORD3; +#endif +#if EXTRACTGREENALPHA + float4 blendfactor1 : TEXCOORD4; +#endif + +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + + float4 vScreenPos : TEXCOORD7; +}; + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); +Texture2D ColorRampTexture : register( t1 ); +sampler ColorRampSampler : register( s1 ); +Texture2D DepthTexture : register( t2 ); +sampler DepthSampler : register( s2 ); + +float4 main( PS_INPUT i ) : SV_TARGET +{ + bool bMaxLumFrameBlend1 = MAXLUMFRAMEBLEND1 ? true : false; + bool bMaxLumFrameBlend2 = MAXLUMFRAMEBLEND2 ? true : false; + bool bExtractGreenAlpha = EXTRACTGREENALPHA ? true : false; + bool bAddBaseTexture2 = ADDBASETEXTURE2 ? true : false; + bool bDualSequence = DUALSEQUENCE ? true : false; + bool bColorRamp = COLORRAMP ? true : false; +#ifdef DEPTHBLEND + bool bDepthBlend = DEPTHBLEND ? true : false; +#endif + int nSequenceBlendMode = SEQUENCE_BLEND_MODE; + + // Sample frames from texture 0 + float4 baseTex0 = BaseTexture.Sample( BaseTextureSampler, i.texCoord0 ); + + float4 baseTex1 = BaseTexture.Sample( BaseTextureSampler, i.texCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend1 or bExtractGreenAlpha) +#if ANIMBLEND + float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); +#else + float4 blended_rgb = baseTex0; +#endif + + if ( bMaxLumFrameBlend1 ) + { + // Blend between animation frames based upon max luminance + float lum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float lum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( lum0 > lum1 ) + blended_rgb = baseTex0; + else + blended_rgb = baseTex1; + } + else if( bExtractGreenAlpha ) + { +#if EXTRACTGREENALPHA + // Weight Green/Alphas from the two frames for a scalar result + blended_rgb = dot( baseTex0, i.blendfactor0 ) + dot( baseTex1, i.blendfactor1 ); +#endif + } + +#if DUALSEQUENCE + if ( bDualSequence ) + { + baseTex0 = BaseTexture.Sample( BaseTextureSampler, i.vSeq2TexCoord0 ); + baseTex1 = BaseTexture.Sample( BaseTextureSampler, i.vSeq2TexCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend2) + float4 rgb2 = lerp( baseTex0, baseTex1, i.blendfactor0.z ); + + if ( bMaxLumFrameBlend2 ) + { + // blend between animation frames based upon max luminance + float tlum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float tlum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( tlum0 > tlum1 ) + rgb2 = baseTex0; + else + rgb2 = baseTex1; + } + + if ( nSequenceBlendMode == COMBINE_MODE_AVERAGE ) + { + blended_rgb = 0.5 * ( blended_rgb + rgb2 ); + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND ) + { + blended_rgb.rgb = rgb2.rgb; + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_OVER_SECOND ) + { + blended_rgb.rgb = lerp( blended_rgb.rgb, rgb2.rgb, rgb2.a ); + } + } // bDualSequence +#endif + + // Optional color ramp + if ( bColorRamp ) + { + blended_rgb.rgb = ColorRampTexture.Sample( ColorRampSampler, float2( blended_rgb.r, blended_rgb.g ) ); + } + + // Overbright + blended_rgb.rgb *= fOverbrightFactor; + + //Soft Particles FTW +# if (DEPTHBLEND == 1) + float fDepthBlend = DepthFeathering( DepthTexture, DepthSampler, i.vScreenPos.xy / i.vScreenPos.w, + i.vScreenPos.z, i.vScreenPos.w, c.g_DepthFeatheringConstants ); + i.argbcolor.a *= fDepthBlend; +# endif + + // Premultiply the alpha for a ONE:INVALPHA blend +#if ADDBASETEXTURE2 + if ( bAddBaseTexture2 ) + { + blended_rgb.a *= i.argbcolor.a; + + // In this case, we don't really want to pre-multiply by alpha + if ( !bColorRamp ) + { + blended_rgb.rgb *= blended_rgb.a; + } + + if ( bExtractGreenAlpha ) + { + blended_rgb.rgb += fAdditiveBlendWeight * i.argbcolor.a * blended_rgb.rgb; + } + else + { + blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * BaseTexture.Sample( BaseTextureSampler, i.texCoord2 ); + } + + blended_rgb.rgb *= i.argbcolor.rgb; + } + else +#endif + { +#if ADDSELF + blended_rgb.a *= i.argbcolor.a; + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * fAdditiveSelfBlendWeight * i.argbcolor.a * blended_rgb; + blended_rgb.rgb *= i.argbcolor.rgb; +#else + blended_rgb *= i.argbcolor; +#endif + } + +#if ALPHATEST + if ( !GreaterAlphaTest(blended_rgb.a, 0.01f) ) + { + discard; + } +#endif + + return FinalOutput( blended_rgb, 0, PIXEL_FOG_TYPE_NONE, float4(0, 0, 0, 1), TONEMAP_SCALE_LINEAR, cToneMappingScale ); +} + diff --git a/materialsystem/stdshadersdx11/spritecard_vs40.fxc b/materialsystem/stdshadersdx11/spritecard_vs40.fxc new file mode 100644 index 0000000..9dc4d01 --- /dev/null +++ b/materialsystem/stdshadersdx11/spritecard_vs40.fxc @@ -0,0 +1,307 @@ +// STATIC: "DUALSEQUENCE" "0..1" +// DYNAMIC: "ORIENTATION" "0..2" + +#include "common_cbuffers_fxc.h" + +#include "common_vs_fxc.h" + +#include "spritecard_constants_fxc.h" + +CBUFFER_PERMODEL( register( b0 ) ) +CBUFFER_PERFRAME( register( b1 ) ) +CBUFFER_PERSCENE( register( b2 ) ) + +cbuffer SpriteCard_CBuffer : register( b3 ) +{ + SpriteCard_t c; +}; + +#define OLDFRM_SCALE_START (c.ScaleParms.x) +#define OLDFRM_SCALE_END (c.ScaleParms.y) + +#define g_bZoomAnimateSeq2 (c.SpriteControls.x != 0) +#define g_bExtractGreenAlpha (c.SpriteControls.y != 0) +#define g_bUseInstancing (c.SpriteControls.z != 0) + +#define MINIMUM_SIZE_FACTOR (c.SizeParms.x) +#define MAXIMUM_SIZE_FACTOR (c.SizeParms.y) + +#define START_FADE_SIZE_FACTOR (c.SizeParms.z) +#define END_FADE_SIZE_FACTOR (c.SizeParms.w) + +// alpha fade w/ distance +#define START_FAR_FADE ( c.SizeParms2.x ) +#define FAR_FADE_FACTOR ( c.SizeParms2.y ) // alpha = 1-min(1,max(0, (dist-start_fade)*factor)) + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vTint : COLOR; + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vParms : TEXCOORD2; // frame blend, rot, radius, yaw + // FIXME: remove this vertex element for (USE_INSTANCING == 1), need to shuffle the following elements down + float2 vCornerID : TEXCOORD3; // 0,0 1,0 1,1 0,1 + float4 vTexCoord2 : TEXCOORD4; +#if DUALSEQUENCE + float4 vSeq2TexCoord0 : TEXCOORD5; + float4 vSeq2TexCoord1 : TEXCOORD6; + float4 vParms1 : TEXCOORD7; // second frame blend, ?,?,? +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; + + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; + float2 texCoord2 : TEXCOORD3; + float4 blendfactor1 : TEXCOORD4; // for extracting green/alpha +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + + float4 vScreenPos : TEXCOORD7; +}; + +#define BLENDFACTOR v.vParms.x +#define ROTATION v.vParms.y +#define RADIUS v.vParms.z +#define YAW (v.vParms.w) + +float getlerpscaled( float l_in, float s0, float s1, float ts ) +{ + l_in = 2.0*(l_in-.5); + l_in *= lerp(s0,s1,ts); + return 0.5+0.5*l_in; +} + +float getlerpscale_for_old_frame( float l_in, float ts ) +{ + return getlerpscaled( l_in, OLDFRM_SCALE_START, OLDFRM_SCALE_END, ts); +} + +float getlerpscale_for_new_frame( float l_in, float ts ) +{ + return getlerpscaled( l_in, 1.0, OLDFRM_SCALE_START, ts ); +} + +#ifdef DO_INSTANCING +void InstancedVertexRead( inout VS_INPUT v, int index ) +{ + // Duplicate each VB vertex 4 times (and generate vCornerID - the only thing that varies per-corner) + float4 vTint; + float4 vPos; + float4 vTexCoord0; + float4 vTexCoord1; + float4 vParms; + float4 vTexCoord2; + float4 vSeq_TexCoord0; // NOTE: April XDK compiler barfs on var names which have a number in the middle! (i.e. vSeq2TexCoord0) + float4 vSeq_TexCoord1; + float4 vParms1; + + int spriteIndex = index / 4; + int cornerIndex = index - 4*spriteIndex; + asm + { + vfetch vTint, spriteIndex, color0; + vfetch vPos, spriteIndex, position0; + vfetch vTexCoord0, spriteIndex, texcoord0; + vfetch vTexCoord1, spriteIndex, texcoord1; + vfetch vParms, spriteIndex, texcoord2; + vfetch vTexCoord2, spriteIndex, texcoord4; +#if DUALSEQUENCE + vfetch vSeq_TexCoord0, spriteIndex, texcoord5; + vfetch vSeq_TexCoord1, spriteIndex, texcoord6; + vfetch vParms1, spriteIndex, texcoord7; +#endif + }; + + v.vTint = vTint; + v.vPos = vPos; + v.vTexCoord0 = vTexCoord0; + v.vTexCoord1 = vTexCoord1; + v.vParms = vParms; + v.vTexCoord2 = vTexCoord2; +#if DUALSEQUENCE + v.vSeq2TexCoord0 = vSeq_TexCoord0; + v.vSeq2TexCoord1 = vSeq_TexCoord1; + v.vParms1 = vParms1; +#endif + + // Compute vCornerID - order is: (0,0) (1,0) (1,1) (0,1) + // float2 IDs[4] = { {0,0}, {1,0}, {1,1}, {0,1} }; + // v.vCornerID.xy = IDs[ cornerIndex ]; + // This compiles to 2 ops on 360 (MADDs with abs/sat register read/write modifiers): + v.vCornerID.xy = float2( 1.5f, 0.0f ) + cornerIndex*float2( -1.0f, 1.0f ); + v.vCornerID.xy = saturate( float2(1.5f, -3.0f) + float2( -1.0f, 2.0f )*abs( v.vCornerID.xy ) ); +} +#endif + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + +#ifdef DO_INSTANCING + if ( g_bUseInstancing ) + { + InstancedVertexRead( v, Index ); + } +#endif + + float4 tint = GammaToLinear( v.vTint ); + + float2 sc_yaw; + sincos( YAW, sc_yaw.y, sc_yaw.x ); + + float2 sc; + sincos( ROTATION, sc.y, sc.x ); + + float2 ix=2*v.vCornerID.xy-1; + float x1=dot(ix,sc); + float y1=sc.x*ix.y-sc.y*ix.x; + + float4 projPos; + float3 worldPos; + worldPos = mul( float4( v.vPos.xyz, 1.0f ), cModelMatrix ).xyz; + + float rad = RADIUS; + float3 v2p = ( worldPos - cEyePos.xyz ); + float l = length(v2p); + rad=max(rad, MINIMUM_SIZE_FACTOR * l); + // now, perform fade out + if ( rad > START_FADE_SIZE_FACTOR * l ) + { + if ( rad > END_FADE_SIZE_FACTOR *l ) + { + tint = 0; + rad = 0; // cull so we emit 0-sized sprite + } + else + { + tint *= 1-(rad-START_FADE_SIZE_FACTOR*l)/(END_FADE_SIZE_FACTOR*l-START_FADE_SIZE_FACTOR*l); + } + } + + + // perform far fade + float tscale = 1-min(1, max(0, (l-START_FAR_FADE)*FAR_FADE_FACTOR) ); + tint *= tscale; + + if ( tscale <= 0) + rad = 0; // cull so we emit 0-sized sprite + + rad=min(rad, MAXIMUM_SIZE_FACTOR * l); + +#if ORIENTATION == 0 + // Screen-aligned case + float3 viewPos; + float4x4 modelView = mul( cModelMatrix, cViewMatrix ); + viewPos = mul( v.vPos, modelView ).xyz; + + float3 disp=float3( -x1,y1,0); + float tmpx=disp.x*sc_yaw.x+disp.z*sc_yaw.y; + disp.z = disp.z*sc_yaw.x-disp.x*sc_yaw.y; + disp.x=tmpx; + + viewPos.xyz += disp * rad; + + projPos = mul( float4(viewPos, 1.0f), cProjMatrix ); +#endif + +#if ORIENTATION == 1 + // Z-aligned case + if (l > rad/2) + { + float3 up = float3(0,0,1); + float3 right = normalize(cross(up, v2p)); + float tmpx=right.x*sc_yaw.x+right.y*sc_yaw.y; + right.y = right.y*sc_yaw.x-right.x*sc_yaw.y; + right.x=tmpx; + + worldPos += (x1*rad)*right; + worldPos.z += (y1*rad)*up.z; + + if (l < rad*2 ) + { + tint *= smoothstep(rad/2,rad,l); + } + + } + float4x4 viewProj = mul(cViewMatrix, cProjMatrix); + projPos = mul( float4(worldPos, 1.0f), viewProj ); +#endif + +#if ORIENTATION == 2 + // aligned with z plane case - easy + float3 wpos=v.vPos+RADIUS*float3( y1,x1,0); + projPos = ComputeProjPos( wpos, cModelMatrix, cViewMatrix, cProjMatrix ); +#endif + + o.blendfactor0 = float4( v.vParms.x, 0, 0, 0 ); + o.projPos = projPos; + o.texCoord0.x = lerp( v.vTexCoord0.z, v.vTexCoord0.x, v.vCornerID.x ); + o.texCoord0.y = lerp( v.vTexCoord0.w, v.vTexCoord0.y, v.vCornerID.y ); + o.texCoord1.x = lerp( v.vTexCoord1.z, v.vTexCoord1.x, v.vCornerID.x ); + o.texCoord1.y = lerp( v.vTexCoord1.w, v.vTexCoord1.y, v.vCornerID.y ); + o.texCoord2.x = lerp( v.vTexCoord2.z, v.vTexCoord2.x, v.vCornerID.x ); + o.texCoord2.y = lerp( v.vTexCoord2.w, v.vTexCoord2.y, v.vCornerID.y ); + +#if DUALSEQUENCE + float2 lerpold = v.vCornerID.xy; + float2 lerpnew = v.vCornerID.xy; + + if ( g_bZoomAnimateSeq2 ) + { + lerpold.x = getlerpscale_for_old_frame( v.vCornerID.x, v.vParms1.x ); + lerpold.y = getlerpscale_for_old_frame( v.vCornerID.y, v.vParms1.x ); + lerpnew.x = getlerpscale_for_new_frame( v.vCornerID.x, v.vParms1.x ); + lerpnew.y = getlerpscale_for_new_frame( v.vCornerID.y, v.vParms1.x ); + } + + o.vSeq2TexCoord0.xy = lerp( v.vSeq2TexCoord0.zw, v.vSeq2TexCoord0.xy, lerpold.xy ); + o.vSeq2TexCoord1.xy = lerp( v.vSeq2TexCoord1.zw, v.vSeq2TexCoord1.xy, lerpnew.xy ); + + o.blendfactor0.z = v.vParms1.x; +#endif + + + o.blendfactor1 = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + + if ( g_bExtractGreenAlpha ) + { + // Input range Output range + if ( v.vParms.x < 0.25f ) // 0.0 .. 0.25 + { + o.blendfactor0.a = v.vParms.x * 2 + 0.5f; // 0.5 .. 1.0 + o.blendfactor0.g = 1 - o.blendfactor0.a; // 0.5 .. 0.0 + } + else if ( v.vParms.x < 0.75f ) // 0.25 .. 0.75 + { + o.blendfactor1.g = v.vParms.x * 2 - 0.5f; // 0.0 .. 1.0 + o.blendfactor0.a = 1 - o.blendfactor1.g; // 1.0 .. 0.0 + } + else // 0.75 .. 1.0 + { + o.blendfactor1.a = v.vParms.x * 2 - 1.5f; // 0.0 .. 0.5 + o.blendfactor1.g = 1 - o.blendfactor1.a; // 1.0 .. 0.5 + } + } + + // Map projected position to the refraction texture + float2 vScreenPos; + vScreenPos.x = projPos.x; + vScreenPos.y = -projPos.y; // invert Y + vScreenPos = (vScreenPos + projPos.w) * 0.5f; + o.vScreenPos = float4(vScreenPos.x, vScreenPos.y, projPos.z, projPos.w ); + + o.argbcolor = tint; + return o; +} + + diff --git a/materialsystem/stdshadersdx11/stdshader_dx11.vpc b/materialsystem/stdshadersdx11/stdshader_dx11.vpc new file mode 100644 index 0000000..8e3acb4 --- /dev/null +++ b/materialsystem/stdshadersdx11/stdshader_dx11.vpc @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// STDSHADER_DX9.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +// shader_dll_verify.cpp defines a function called _ftol3. This means that we can't +// link with the bug-fixed ftol3.obj. It also means we can't convert float-to-unsigned. +$Macro DISABLE_FTOL3_OVERRIDE "1" + +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" + +$Configuration "Debug" +{ + $General + { + $OutputDirectory "Debug_dx9" [$WINDOWS] + $IntermediateDirectory "Debug_dx9" [$WINDOWS] + + $OutputDirectory "Debug_dx9_360" [$X360] + $IntermediateDirectory "Debug_dx9_360" [$X360] + } +} + +$Configuration "Release" +{ + $General + { + $OutputDirectory "Release_dx9" [$WINDOWS] + $IntermediateDirectory "Release_dx9" [$WINDOWS] + + $OutputDirectory "Release_dx9_360" [$X360] + $IntermediateDirectory "Release_dx9_360" [$X360] + } +} + +// Common Configuration +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;fxctmp9;vshtmp9;" [$WIN32||$POSIX] + $AdditionalIncludeDirectories "$BASE;..\..\dx9sdk\include" [$WIN32] + $AdditionalIncludeDirectories "$BASE;fxctmp9_360;vshtmp9_360" [$X360] + $PreprocessorDefinitions "$BASE;STDSHADER_DX9_DLL_EXPORT;FAST_MATERIALVAR_ACCESS" + $PreprocessorDefinitions "$BASE;USE_ACTUAL_DX" [($WIN32||$X360) && !$GL] + } + + $Linker + { + $AdditionalDependencies "$BASE version.lib winmm.lib" [$WIN32] + $ModuleDefinitionFile "xbox\xbox_dx9.def" [$X360] + $SystemLibraries "iconv" [$OSXALL] + } +} + +$Project "stdshader_dx11" +{ + $Folder "Source Files" + { + $File "BaseVSShader.cpp" \ + "bik_dx11.cpp"\ +// "decalmodulate_dx11.cpp"\/ +// "lightmappedgeneric_dx11.cpp"\ +// "lightmappedgeneric_dx11_helper.cpp"\ + "modulate_dx11.cpp"\ + "occlusion_dx11.cpp"\ +// "sky_dx11.cpp"\ +// "sky_hdr_dx11.cpp"\ +// "sprite_dx11.cpp"\ +// "spritecard.cpp"\ + "test_dx11.cpp"\ + "unlitgeneric_dx11.cpp"\ +// "unlittwotexture_dx11.cpp"\ +// "vertexlitgeneric_dx11.cpp"\ +// "vertexlitgeneric_dx11_helper.cpp"\ + "wireframe_dx11.cpp"\ +// "worldvertextransition.cpp"\ + "writez_dx11.cpp" + + $File "../shader_dll_verify.cpp" + } + $Folder "Header Files" + { + $File "BaseVSShader.h" + $File "../shader_dll_verify.h" + } + + $Folder "Link Libraries" + { + $Lib mathlib + $Lib shaderlib_dx11 + } + + $File "$SRCDIR\devtools\bin\vsh_prep.pl" + $File "$SRCDIR\devtools\bin\psh_prep.pl" + $File "$SRCDIR\devtools\bin\fxc_prep.pl" + $File "$SRCDIR\devtools\bin\updateshaders.pl" + $File "$SRCDIR\devtools\bin\copyshaders.pl" + $File "$SRCDIR\devtools\bin\valve_perl_helpers.pl" + $File "$SRCDIR\devtools\bin\checkshaderchecksums.pl" + $File "_buildshaders.bat" + + $Shaders "_shaderlist_dx11.txt" +} diff --git a/materialsystem/stdshadersdx11/test_dx11.cpp b/materialsystem/stdshadersdx11/test_dx11.cpp new file mode 100644 index 0000000..b67af32 --- /dev/null +++ b/materialsystem/stdshadersdx11/test_dx11.cpp @@ -0,0 +1,39 @@ +#if 0 +#include "BaseVSShader.h" + +CREATE_CONSTANT_BUFFER( Test ) +{ + float x; +}; + +BEGIN_VS_SHADER( TestDX11, "Help for TestDX11" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER( Test ) + + SHADER_INIT + { + INIT_CONSTANT_BUFFER( Test ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + //SET_CONSTANT_BUFFER( Test ); + } + + DYNAMIC_STATE + { + CONSTANT_BUFFER_TYPE(Test) temp; + temp.x = 5.0f; + UPDATE_CONSTANT_BUFFER(Test, temp); + } + + Draw(); + } + +END_SHADER +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/uniquefilestocopy.txt b/materialsystem/stdshadersdx11/uniquefilestocopy.txt new file mode 100644 index 0000000..7ff3c7c --- /dev/null +++ b/materialsystem/stdshadersdx11/uniquefilestocopy.txt @@ -0,0 +1,6 @@ +..\..\devtools\bin\d3dx9_33.dll +..\..\dx10sdk\utilities\dx9_30\dx_proxy.dll +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\shadercompile.exe +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\shadercompile_dll.dll +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\tier0.dll +E:\Src\CoolSource\src\materialsystem\stdshadersdx11\..\..\..\game\bin\vstdlib.dll diff --git a/materialsystem/stdshadersdx11/unlitgeneric_dx11.cpp b/materialsystem/stdshadersdx11/unlitgeneric_dx11.cpp new file mode 100644 index 0000000..ddc1824 --- /dev/null +++ b/materialsystem/stdshadersdx11/unlitgeneric_dx11.cpp @@ -0,0 +1,219 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "fxctmp9/unlitgeneric_ps40.inc" +#include "fxctmp9/unlitgeneric_vs40.inc" + +//extern ConVar r_flashlight_version2; + +// HACKHACK +DEFINE_FALLBACK_SHADER(Vertexlitgeneric, UnlitGeneric) +DEFINE_FALLBACK_SHADER(Lightmappedgeneric, UnlitGeneric) +DEFINE_FALLBACK_SHADER(WorldVertexTransition, UnlitGeneric) + +BEGIN_VS_SHADER( UnlitGeneric, "Help for UnlitGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + SHADER_PARAM( VERTEXALPHATEST, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "2D map for warping specular" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + SHADER_PARAM( DISTANCEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use distance-coded alpha generated from hi-res texture by vtex.") + SHADER_PARAM( DISTANCEALPHAFROMDETAIL, SHADER_PARAM_TYPE_BOOL, "0", "Take the distance-coded alpha mask from the detail texture.") + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( SCALEEDGESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft edges based upon resolution. 1024x768 = nominal.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); + + SHADER_PARAM( GLOW, SHADER_PARAM_TYPE_BOOL, "0", "Enable glow/shadow for distance coded textures.") + SHADER_PARAM( GLOWCOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outter glow for distance coded line art." ) + SHADER_PARAM( GLOWALPHA, SHADER_PARAM_TYPE_FLOAT, "1", "Base glow alpha amount for glows/shadows with distance alpha." ) + SHADER_PARAM( GLOWSTART, SHADER_PARAM_TYPE_FLOAT, "0.7", "start value for glow/shadow") + SHADER_PARAM( GLOWEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "end value for glow/shadow") + SHADER_PARAM( GLOWX, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset x for glow mask.") + SHADER_PARAM( GLOWY, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset y for glow mask.") + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + SHADER_PARAM( SCALEOUTLINESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft part of the outline based upon resolution. 1024x768 = nominal.") + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + + SHADER_PARAM( GAMMACOLORREAD, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of color texture read." ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + SHADER_PARAM( RECEIVEFLASHLIGHT, SHADER_PARAM_TYPE_INTEGER, "0", "Forces this material to receive flashlights." ) + + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture(BASETEXTURE); + } + } + + SHADER_DRAW + { + bool bDrawStandardPass = true; + + bool bHasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool bHasVertexAlpha = IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA); + + if (bDrawStandardPass) + { + BlendType_t nBlendType = EvaluateBlendRequirements(BASETEXTURE, true); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a texture alpha on either texture + isTranslucent = isTranslucent || TextureIsTranslucent(BASETEXTURE, true); + + if (isTranslucent) + { + if (IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) + { + EnableAlphaBlending(SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE); + } + else + { + EnableAlphaBlending(SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA); + } + } + else + { + if (IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) + { + EnableAlphaBlending(SHADER_BLEND_ONE, SHADER_BLEND_ONE); + } + else + { + DisableAlphaBlending(); + } + } + + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + if (bHasVertexColor || bHasVertexAlpha) + { + flags |= VERTEX_COLOR; + } + int nTexCoordCount = 1; + int userDataSize = 0; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + { + flags |= VERTEX_COLOR; + } + int pTexCoordDim[1] = { 4 }; + pShaderShadow->VertexShaderVertexFormat(flags, nTexCoordCount, pTexCoordDim, userDataSize); + + SetVertexShaderConstantBuffer(0, SHADER_CONSTANTBUFFER_SKINNING); + SetVertexShaderConstantBuffer(1, SHADER_CONSTANTBUFFER_PERFRAME); + SetVertexShaderConstantBuffer(2, SHADER_CONSTANTBUFFER_PERSCENE); + + SetPixelShaderConstantBuffer(0, SHADER_CONSTANTBUFFER_PERFRAME); + SetPixelShaderConstantBuffer(1, SHADER_CONSTANTBUFFER_PERSCENE); + + DECLARE_STATIC_VERTEX_SHADER(unlitgeneric_vs40); + SET_STATIC_VERTEX_SHADER_COMBO(VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha); + SET_STATIC_VERTEX_SHADER_COMBO(MODEL, 1); + SET_STATIC_VERTEX_SHADER(unlitgeneric_vs40); + + DECLARE_STATIC_PIXEL_SHADER(unlitgeneric_ps40); + SET_STATIC_PIXEL_SHADER(unlitgeneric_ps40); + + DefaultFog(); + + pShaderShadow->EnableAlphaWrites(bFullyOpaque); + } + DYNAMIC_STATE + { + BindTexture(SHADER_SAMPLER0, BASETEXTURE, FRAME); + + //pShaderAPI->GetFogParamsAndColor(consts.FogParams.Base(), consts.FogColor.Base()); + + //StoreVertexShaderTextureTransform(consts.BaseTextureTransform, BASETEXTURETRANSFORM); + //StoreVertexShaderTextureTransform(consts.BaseTexture2Transform, TEXTURE2TRANSFORM); + + //SetModulationDynamicState_LinearColorSpace(consts.ModulationColor); + + //UPDATE_CONSTANT_BUFFER(UnlitTwoTexture, consts); + + //MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + //int fogIndex = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z) ? 1 : 0; + //int numBones = pShaderAPI->GetCurrentNumBones(); + + DECLARE_DYNAMIC_VERTEX_SHADER(unlitgeneric_vs40); + SET_DYNAMIC_VERTEX_SHADER(unlitgeneric_vs40); + + DECLARE_DYNAMIC_PIXEL_SHADER(unlitgeneric_ps40); + SET_DYNAMIC_PIXEL_SHADER(unlitgeneric_ps40); + } + Draw(); + } + else + { + // Skip this pass! + Draw(false); + } + } +END_SHADER diff --git a/materialsystem/stdshadersdx11/unlitgeneric_ps40.fxc b/materialsystem/stdshadersdx11/unlitgeneric_ps40.fxc new file mode 100644 index 0000000..12807b3 --- /dev/null +++ b/materialsystem/stdshadersdx11/unlitgeneric_ps40.fxc @@ -0,0 +1,37 @@ +#include "common_ps_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_PERFRAME(register(b0)) +CBUFFER_PERSCENE(register(b1)) + +/*cbuffer UnlitTwoTexture_CBuffer : register(b2) +{ + UnlitTwoTexture_t c; +};*/ + +//#define g_DiffuseModulation c.cModulationColor + +#define g_EyePos_SpecExponent cEyePos + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 vertexColor : TEXCOORD1; + float3 eyeSpacePos : TEXCOORD2; + float3 normals : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + HALF4 baseColor = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord ); + HALF4 result = baseColor.xyzw * i.vertexColor; + float alpha = baseColor.a * i.vertexColor.a; + + return float4( result.rgb, alpha ); +} + diff --git a/materialsystem/stdshadersdx11/unlitgeneric_vs40.fxc b/materialsystem/stdshadersdx11/unlitgeneric_vs40.fxc new file mode 100644 index 0000000..236dc19 --- /dev/null +++ b/materialsystem/stdshadersdx11/unlitgeneric_vs40.fxc @@ -0,0 +1,87 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "MODEL" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = false; +static const int g_FogType = 0; + +#include "unlittwotexture_constants_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_SKINNING(register(b0)) +CBUFFER_PERFRAME(register(b1)) +CBUFFER_PERSCENE(register(b2)) + +/*cbuffer UnlitTwoTexture_CBuffer : register(b3) +{ + UnlitTwoTexture_t c; +};*/ + +#define cBaseTexCoordTransform c.cBaseTextureTransform +#define cBaseTexCoordTransform2 c.cBaseTexture2Transform + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + uint4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR; + float3 vSpecular : SPECULAR; + // make these float2's and stick the [n n 0 1] in the dot math. + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : FLEXDELTA; + float3 vNormalFlex : FLEXNORMAL; +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 vertexColor : TEXCOORD1; + float3 eyeSpacePos : TEXCOORD2; + float3 normals : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = float4(v.vPos.xyz, 1.0f); + + // Perform skinning + float3 worldNormal, worldPos; + + worldPos = mul4x3( vPosition, (float4x3)cModel[0] ); + worldNormal = mul3x3( v.vNormal.xyz, ( const float3x3 )cModel[0] ); + + float4x4 viewProj = mul(cViewMatrix, cProjMatrix); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), viewProj ); + o.projPos = projPos; + + o.eyeSpacePos = mul(float4(worldPos, 1), cViewMatrix).xyz; + + // Needed for water fog alpha; + // FIXME: we shouldn't have to compute this all thie time. + o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); + + // Base texture coordinates + o.baseTexCoord = v.vTexCoord0.xy; + +#if VERTEXCOLOR + o.vertexColor = v.vColor; + #else + o.vertexColor = 1.0f.xxxx; +#endif + + o.normals = v.vNormal.xyz; + + return o; +} diff --git a/materialsystem/stdshadersdx11/unlittwotexture_constants_fxc.h b/materialsystem/stdshadersdx11/unlittwotexture_constants_fxc.h new file mode 100644 index 0000000..ee7a469 --- /dev/null +++ b/materialsystem/stdshadersdx11/unlittwotexture_constants_fxc.h @@ -0,0 +1,16 @@ +#ifndef UNLITTWOTEXTURE_CONSTANTS_FXC_H_ +#define UNLITTWOTEXTURE_CONSTANTS_FXC_H_ + +struct UnlitTwoTexture_t +{ + // vsh + float4 cBaseTextureTransform[2]; + float4 cBaseTexture2Transform[2]; + + // psh + float4 cModulationColor; + float4 g_FogParams; + float4 g_FogColor; +}; + +#endif // UNLITTWOTEXTURE_CONSTANTS_FXC_H_ \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/unlittwotexture_dx11.cpp b/materialsystem/stdshadersdx11/unlittwotexture_dx11.cpp new file mode 100644 index 0000000..31bb441 --- /dev/null +++ b/materialsystem/stdshadersdx11/unlittwotexture_dx11.cpp @@ -0,0 +1,274 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +//#include "cloak_blended_pass_helper.h" + +#include "unlittwotexture_vs40.inc" +#include "unlittwotexture_ps40.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CREATE_CONSTANT_BUFFER( UnlitTwoTexture ) +{ + // vsh + Vector4D BaseTextureTransform[2]; + Vector4D BaseTexture2Transform[2]; + + // psh + Vector4D ModulationColor; + Vector4D FogParams; + Vector4D FogColor; +}; + +DEFINE_FALLBACK_SHADER( UnlitTwoTexture, UnlitTwoTexture_DX11 ) + +//extern ConVar r_flashlight_version2; + +BEGIN_VS_SHADER( UnlitTwoTexture_DX11, "Help for UnlitTwoTexture_DX11" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "second texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $texture2" ) + SHADER_PARAM( TEXTURE2TRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$texture2 texcoord transform" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + END_SHADER_PARAMS + + DECLARE_CONSTANT_BUFFER( UnlitTwoTexture ) + + SHADER_INIT_GLOBAL + { + INIT_CONSTANT_BUFFER( UnlitTwoTexture ); + } + + SHADER_FALLBACK + { + return 0; + } + + // Cloak Pass + //void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + //{ + // info.m_nCloakFactor = CLOAKFACTOR; + // info.m_nCloakColorTint = CLOAKCOLORTINT; + // info.m_nRefractAmount = REFRACTAMOUNT; + //} + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + //{ + // if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + // return true; + // else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + // return true; + // // else, not cloaking this frame, so check flag2 in case the base material still needs it + //} + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + //{ + // if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + // return true; + // // else, not cloaking this frame, so check flag in case the base material still needs it + //} + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + // Cloak Pass + //if ( !params[CLOAKPASSENABLED]->IsDefined() ) + //{ + // params[CLOAKPASSENABLED]->SetIntValue( 0 ); + //} + //else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + //{ + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + //} + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + LoadTexture( BASETEXTURE ); + if (params[TEXTURE2]->IsDefined()) + LoadTexture( TEXTURE2 ); + + // Cloak Pass + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) + //{ + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // InitCloakBlendedPass( this, params, info ); + //} + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + //if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + //{ + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + // { + // bDrawStandardPass = false; + // } + //} + + // Skip flashlight pass for unlit stuff + //bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 ); + //if ( bDrawStandardPass && ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && + // !bNewFlashlightPath && ( pShaderAPI->InFlashlightMode() ) ) // not snapshotting && flashlight pass) + //{ + // bDrawStandardPass = false; + //} + + // Standard rendering pass + if ( bDrawStandardPass ) + { + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a texture alpha on either texture + isTranslucent = isTranslucent || TextureIsTranslucent( BASETEXTURE, true ) || + TextureIsTranslucent( TEXTURE2, true ); + + if ( isTranslucent ) + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + DisableAlphaBlending( ); + } + } + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + if (IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR )) + { + flags |= VERTEX_COLOR; + } + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + SetVertexShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_SKINNING ); + SetVertexShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERFRAME ); + SetVertexShaderConstantBuffer( 2, SHADER_CONSTANTBUFFER_PERSCENE ); + SetVertexShaderConstantBuffer( 3, CONSTANT_BUFFER( UnlitTwoTexture ) ); + + SetPixelShaderConstantBuffer( 0, SHADER_CONSTANTBUFFER_PERFRAME ); + SetPixelShaderConstantBuffer( 1, SHADER_CONSTANTBUFFER_PERSCENE ); + SetPixelShaderConstantBuffer( 2, CONSTANT_BUFFER( UnlitTwoTexture ) ); + + DECLARE_STATIC_VERTEX_SHADER( unlittwotexture_vs40 ); + SET_STATIC_VERTEX_SHADER( unlittwotexture_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( unlittwotexture_ps40 ); + SET_STATIC_PIXEL_SHADER( unlittwotexture_ps40 ); + + DefaultFog(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, TEXTURE2, FRAME2 ); + + ALIGN16 CONSTANT_BUFFER_TYPE( UnlitTwoTexture ) consts; + + pShaderAPI->GetFogParamsAndColor( consts.FogParams.Base(), consts.FogColor.Base() ); + + StoreVertexShaderTextureTransform( consts.BaseTextureTransform, BASETEXTURETRANSFORM ); + StoreVertexShaderTextureTransform( consts.BaseTexture2Transform, TEXTURE2TRANSFORM ); + + SetModulationDynamicState_LinearColorSpace( consts.ModulationColor ); + + UPDATE_CONSTANT_BUFFER( UnlitTwoTexture, consts ); + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + DECLARE_DYNAMIC_VERTEX_SHADER( unlittwotexture_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( unlittwotexture_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( unlittwotexture_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( unlittwotexture_ps40 ); + } + Draw(); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + //if ( params[CLOAKPASSENABLED]->GetIntValue() ) + //{ + // If ( snapshotting ) or ( we need to draw this frame ) + // if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + // { + // CloakBlendedPassVars_t info; + // SetupVarsCloakBlendedPass( info ); + // DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + // } + // else // We're not snapshotting and we don't need to draw this frame + // { + // // Skip this pass! + // Draw( false ); + // } + //} + } +END_SHADER diff --git a/materialsystem/stdshadersdx11/unlittwotexture_ps40.fxc b/materialsystem/stdshadersdx11/unlittwotexture_ps40.fxc new file mode 100644 index 0000000..f6142dd --- /dev/null +++ b/materialsystem/stdshadersdx11/unlittwotexture_ps40.fxc @@ -0,0 +1,47 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#include "common_ps_fxc.h" +#include "unlittwotexture_constants_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_PERFRAME(register(b0)) +CBUFFER_PERSCENE(register(b1)) + +cbuffer UnlitTwoTexture_CBuffer : register(b2) +{ + UnlitTwoTexture_t c; +}; + +#define g_DiffuseModulation c.cModulationColor + +#define g_EyePos_SpecExponent cEyePos + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); +Texture2D BaseTexture2 : register( t1 ); +sampler BaseTextureSampler2 : register( s1 ); + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + HALF2 baseTexCoord2 : TEXCOORD1; // Base texture coordinate + float3 eyeSpacePos : TEXCOORD2; + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + + + HALF4 baseColor = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy ); + HALF4 baseColor2 = BaseTexture2.Sample( BaseTextureSampler2, i.baseTexCoord2.xy ); + HALF4 result = baseColor * baseColor2 * g_DiffuseModulation; + float alpha = 1.0f; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, c.g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, length( i.eyeSpacePos ) ); + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, c.g_FogColor, + TONEMAP_SCALE_LINEAR, cToneMappingScale, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} + diff --git a/materialsystem/stdshadersdx11/unlittwotexture_vs40.fxc b/materialsystem/stdshadersdx11/unlittwotexture_vs40.fxc new file mode 100644 index 0000000..40e64e1 --- /dev/null +++ b/materialsystem/stdshadersdx11/unlittwotexture_vs40.fxc @@ -0,0 +1,79 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +#include "unlittwotexture_constants_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_SKINNING(register(b0)) +CBUFFER_PERFRAME(register(b1)) +CBUFFER_PERSCENE(register(b2)) + +cbuffer UnlitTwoTexture_CBuffer : register(b3) +{ + UnlitTwoTexture_t c; +}; + +#define cBaseTexCoordTransform c.cBaseTextureTransform +#define cBaseTexCoordTransform2 c.cBaseTexture2Transform + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + uint4 vBoneIndices : BLENDINDICES; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + HALF2 baseTexCoord2 : TEXCOORD1; // Base texture coordinate + float3 eyeSpacePos : TEXCOORD2; + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + + // Perform skinning + float3 worldNormal, worldPos; + SkinPosition( + g_bSkinning, + vPosition, + v.vBoneWeights, v.vBoneIndices, + cModel, + worldPos ); + + float4x4 viewProj = mul(cViewMatrix, cProjMatrix); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), viewProj ); + o.projPos = projPos; + + o.eyeSpacePos = mul(float4(worldPos, 1), cViewMatrix).xyz; + + // Needed for water fog alpha; + // FIXME: we shouldn't have to compute this all thie time. + o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); + + // Base texture coordinates + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + + // Base texture coordinates + o.baseTexCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] ); + o.baseTexCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] ); + + return o; +} diff --git a/materialsystem/stdshadersdx11/vcslist.txt b/materialsystem/stdshadersdx11/vcslist.txt new file mode 100644 index 0000000..e69de29 diff --git a/materialsystem/stdshadersdx11/vertexlit_and_unlit_generic_ps40.fxc b/materialsystem/stdshadersdx11/vertexlit_and_unlit_generic_ps40.fxc new file mode 100644 index 0000000..7d0a749 --- /dev/null +++ b/materialsystem/stdshadersdx11/vertexlit_and_unlit_generic_ps40.fxc @@ -0,0 +1,696 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +//=============================================================================// +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMMASK" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// DYNAMIC: "FLASHLIGHT" "0..1" +// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "DISTANCEALPHA" "0..1" +// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" +// STATIC: "SOFT_MASK" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "OUTER_GLOW" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// STATIC: "DEPTHBLEND" "0..1" +// STATIC: "ALPHATEST" "0..1" + +// Stuff from the "skin" shader + +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" + +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "PHONG" "0..1" +// DYNAMIC: "WRINKLEMAP" "0..1" +// DYNAMIC: "PHONGWARPTEXTURE" "0..1" +// DYNAMIC: "RIMLIGHT" "0..1" + +// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && ( $SELFILLUM == 0 ) +// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $SEAMLESS_BASE +// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $DISTANCEALPHA +// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $LIGHTING_PREVIEW +// _SKIP: $SELFILLUM_TWOTEXTURE_BLEND && $FLASHLIGHT + +// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK +// SKIP: $NORMALMAPALPHAENVMAPMASK && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM_ENVMAPMASK_ALPHA + +// SKIP: ($CASCADED_SHADOW) && ($FLASHLIGHT) +// SKIP: ($CASCADED_SHADOW) && ($SEAMLESS_BASE) +// SKIP: ($CASCADED_SHADOW) && ($SEAMLESS_DETAIL) +// SKIP: ($CASCADED_SHADOW) && (!$DIFFUSELIGHTING) +// SKIP: ($CASCADED_SHADOW) && (!$DIFFUSELIGHTING) +// SKIP: ($CASCADED_SHADOW) && ($VERTEXCOLOR) +// SKIP: (!$CASCADED_SHADOW) && ($TWO_SIDED_LIGHTING) + +// detail blend mode 6 = ps20b only +// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] + +// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) +// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) +// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) +// _SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) +// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) +// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS ) [ps30] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS ) [ps40] + +// We don't care about uberlight unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $UBERLIGHT == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps40] + +// DISTANCEALPHA-related skips +// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA ) +// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) +// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) + +// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER +// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) + +// _SKIP: $FLASHLIGHT && $CUBEMAP + +// _SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +// Debugging luxels only makes sense if we have lightmaps on this geometry. +// _SKIP: ($STATIC_LIGHT_LIGHTMAP == 0) && ($DEBUG_LUXELS == 1) + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMMASK == 1 ) +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $SELFILLUMMASK == 1 ) +// _SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] +// _SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) +// Meaningless combinations +// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP + +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Don't do diffuse warp on flashlight +// _SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] + +#include "common_cbuffers_def_noskinning_fxc.h" + +#include "shader_register_map.h" +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx11.h" +#include "vertexlitgeneric_dx11_shared.h" + +cbuffer VertexLitAndUnlitGeneric_t : register(b3) +{ + VertexLitAndUnlitGeneric_t c; +}; + +#define g_DiffuseModulation c.cModulationColor +#define g_EyePos cEyePos + +#define g_SelfIllumTint c.g_SelfIllumTint_and_BlendFactor.xyz +#define g_DetailBlendFactor c.g_SelfIllumTint_and_BlendFactor.w +#define g_EnvmapSaturation c.g_EnvmapSaturation_SelfIllumMask.xyz +#define g_SelfIllumMaskControl c.g_EnvmapSaturation_SelfIllumMask.w + +#define g_FresnelRanges c.g_FresnelSpecParams.xyz +#define g_SpecularBoost c.g_FresnelSpecParams.w +#define g_SpecularTint c.g_SpecularRimParams.xyz +#define g_RimExponent c.g_SpecularRimParams.w +#define g_fRimBoost c.g_RimPhongParams.x +#define g_RimMaskControl c.g_RimPhongParams.y +#define g_fBaseMapAlphaPhongMask c.g_RimPhongParams.z +#define g_fInvertPhongMask c.g_RimPhongParams.w + +#define g_FlashlightAttenuationFactors cFlashlightAttenuationFactors +#define g_FlashlightPos cFlashlightPos +#define g_FlashlightWorldToTexture cFlashlightWorldToTexture + +#define g_SelfIllumTwoTextureBlend c.g_EnvmapSaturation_SelfIllumMask.w + +#define g_fPixelFogType c.g_ShaderControls.x +#define g_fWriteDepthToAlpha c.g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha c.g_ShaderControls.z + +Texture2D BaseTexture : register( t0 ); +sampler BaseTextureSampler : register( s0 ); + +#if PHONG +Texture2D SpecularWarpTexture : register( t3 ); +sampler SpecularWarpSampler : register( s3 ); + +Texture2D SpecExponentTexture : register( t4 ); +sampler SpecExponentSampler : register( s4 ); +#endif + +#if BUMPMAP +Texture2D BumpmapTexture : register( t1 ); +sampler BumpmapSampler : register( s1 ); +#endif + +#if CUBEMAP +TextureCube EnvmapTexture : register( t2 ); +sampler EnvmapSampler : register( s2 ); +#endif + +#if ENVMAPMASK +Texture2D EnvmapMaskTexture : register( t5 ); +sampler EnvmapMaskSampler : register( s5 ); +#endif + +#if SELFILLUMMASK +Texture2D SelfIllumMaskTexture : register( t6 ); +sampler SelfIllumMaskSampler : register( s6 ); // selfillummask +#endif + +#if FLASHLIGHT +Texture2D FlashlightTexture : register( t7 ); +sampler FlashlightSampler : register( s7 ); +#endif + +#if FLASHLIGHT && FLASHLIGHTSHADOWS +Texture2D ShadowDepthTexture : register( t8 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +#endif + +#if LIGHTWARPTEXTURE +Texture2D DiffuseWarpTexture : register( t9 ); +sampler DiffuseWarpSampler : register( s9 ); +#else +#define DiffuseWarpTexture BaseTexture +#define DiffuseWarpSampler BaseTextureSampler +#endif + +#if DEPTHBLEND +Texture2D DepthTexture : register( t10 ); +sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending +#endif + +#if DETAILTEXTURE +Texture2D DetailTexture : register( t11 ); +sampler DetailSampler : register( s11 ); +#endif + +#if WRINKLEMAP +Texture2D WrinkleTexture : register( t12 ); +sampler WrinkleSampler : register( t12 ); + +Texture2D StretchTexture : register( t13 ); +sampler StretchSampler : register( s13 ); + +Texture2D NormalWrinkleTexture : register( t14 ); +sampler NormalWrinkleSampler : register( s14 ); + +Texture2D NormalStretchTexture : register( t15 ); +sampler NormalStretchTexture : register( s15 ); +#endif + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; +#if SEAMLESS_BASE + float3 baseTexCoord : TEXCOORD0; // Base texture coordinate +#else + float2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + float3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate +#else + float2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection + + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + float4 worldPos_projPosZ : TEXCOORD5; +#if BUMPMAP + float4 vWorldTangent : TEXCOORD6; +#endif +#if WRINKLEMAP + float4 wrinkleHeight : TEXCOORD7; +#endif +#if SEAMLESS_BASE || SEAMLESS_DETAIL + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif + float3 eyeSpacePos : COLOR1; +}; + +#define GLOW_UV_OFFSET c.g_GlowParameters.xy +#define OUTER_GLOW_MIN_DVALUE c.g_GlowParameters.z +#define OUTER_GLOW_MAX_DVALUE c.g_GlowParameters.w +#define OUTER_GLOW_COLOR c.g_GlowColor + +#define g_fPixelFogType c.g_ShaderControls.x +#define g_fWriteDepthToAlpha c.g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha c.g_ShaderControls.z +#define g_fVertexAlpha c.g_ShaderControls.w + +#define SOFT_MASK_MAX c.g_DistanceAlphaParams.x +#define SOFT_MASK_MIN c.g_DistanceAlphaParams.y + +#define OUTLINE_COLOR c.g_OutlineColor + +// these are ordered this way for optimal ps20 swizzling +#define OUTLINE_MIN_VALUE0 c.g_OutlineParams.x +#define OUTLINE_MAX_VALUE1 c.g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 c.g_OutlineParams.z +#define OUTLINE_MIN_VALUE1 c.g_OutlineParams.w + +// Calculate unified fog +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.y, fogParams.z ); + float fHeightFog = CalcWaterFogAlpha( fogParams.w, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.x ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, c.g_FogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + +float4 main( PS_INPUT i ) : SV_TARGET +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHasNormal = bCubemap || bDiffuseLighting; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bPhong = PHONG ? true : false; + bool bRimLight = RIMLIGHT ? true : false; + bool bDoSpecularWarp = PHONGWARPTEXTURE ? true : false; + const int nNumLights = cLightCount.x; + + #if FLASHLIGHT + return float4(1, 0,0, 1); +#endif + + float3 vEyeDir = normalize( i.worldVertToEyeVector.xyz ); + +#if BUMPMAP + float3 vWorldBinormal = cross( i.worldSpaceNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; +#endif + + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if SEAMLESS_BASE + baseColor = + i.SeamlessWeights.x * BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.yz )+ + i.SeamlessWeights.y * BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.zx )+ + i.SeamlessWeights.z * BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy ); +#else + baseColor = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy ); + +#endif // !SEAMLESS_BASE + + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) + float distAlphaMask = baseColor.a; +#endif + + +#if DETAILTEXTURE +#if SEAMLESS_DETAIL + float4 detailColor = + i.SeamlessWeights.x * DetailTexture.Sample( DetailSampler, i.detailTexCoord.yz )+ + i.SeamlessWeights.y * DetailTexture.Sample( DetailSampler, i.detailTexCoord.zx )+ + i.SeamlessWeights.z * DetailTexture.Sample( DetailSampler, i.detailTexCoord.xy ); +#else + float4 detailColor = DetailTexture.Sample( DetailSampler, i.detailTexCoord.xy ); +#endif + detailColor.rgb *= c.g_DetailTint; + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) + float distAlphaMask = detailColor.a; + detailColor.a = 1.0; // make tcombine treat as 1.0 +#endif + baseColor = + TextureCombine( baseColor, detailColor, c.g_DetailBlendMode.x, g_DetailBlendFactor ); +#endif + +#if DISTANCEALPHA + if ( OUTLINE ) + { + float4 oFactors = smoothstep(c.g_OutlineParams.xyzw, c.g_OutlineParams.wzyx, distAlphaMask ); + baseColor = lerp( baseColor, c.g_OutlineColor, oFactors.x * oFactors.y ); + } + + float mskUsed; + if ( SOFT_MASK ) + { + mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); + baseColor.a *= mskUsed; + } + else + { + mskUsed = distAlphaMask >= 0.5; + if (DETAILTEXTURE ) + baseColor.a *= mskUsed; + else + baseColor.a = mskUsed; + } + + + if ( OUTER_GLOW ) + { +#if DISTANCEALPHAFROMDETAIL + float4 glowTexel = DetailTexture.Sample( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); +#else + float4 glowTexel = BaseTexture.Sample( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); +#endif + float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); + baseColor = lerp( glowc, baseColor, mskUsed ); + } + +#endif // DISTANCEALPHA + + float3 specularFactor = 1.0f; + float fSpecMask = 1.0f; +#if BUMPMAP + float4 normalTexel = BumpmapTexture.Sample( BumpmapSampler, i.baseTexCoord.xy ); + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; +#if PHONG + tangentSpaceNormal = lerp(tangentSpaceNormal, float3(0, 0, 1), g_fBaseMapAlphaPhongMask); + fSpecMask = lerp(normalTexel.a, baseColor.a, g_fBaseMapAlphaPhongMask); +#endif + if ( bNormalMapAlphaEnvmapMask ) + specularFactor = normalTexel.a; +#endif + float4 envmapMaskTexel = 1; + #if ENVMAPMASK + { + envmapMaskTexel = EnvmapMaskTexture.Sample( EnvmapMaskSampler, i.baseTexCoord.xy ); + specularFactor *= envmapMaskTexel.xyz; + } + #endif + + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - baseColor.a; // this blows! + } + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting || bVertexColor ) + { + diffuseLighting = i.color.rgb; + } + else if ( bDiffuseLighting ) + { + diffuseLighting = float3(0.0f, 0.0f, 0.0f); + } + + float3 worldSpaceNormal = i.worldSpaceNormal.xyz; + if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) + { +#if BUMPMAP + worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.worldSpaceNormal, i.vWorldTangent, vWorldBinormal ); +#endif + worldSpaceNormal = normalize( worldSpaceNormal ); + } + +#if PHONG + float fFresnelRanges = Fresnel(worldSpaceNormal, normalize(i.worldVertToEyeVector.xyz), g_FresnelRanges); +#endif + +#if DIFFUSELIGHTING + //float4 vLightAtten = i.lightAtten; + float4 vLightAtten = PixelShaderDoLightAtten( i.worldPos_projPosZ.xyz, nNumLights, cLightInfo ); + + diffuseLighting += PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, + cAmbientCube, BaseTexture, BaseTextureSampler, nNumLights, cLightInfo, bHalfLambert, + false, 1.0f, bDoDiffuseWarp, DiffuseWarpTexture, DiffuseWarpSampler ); +#endif + + float3 albedo = baseColor; + + //return float4(g_DiffuseModulation.rgb, 1.0f); + + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, c.g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); + +#if DIFFUSELIGHTING && PHONG + float3 rimLighting = float3(0.0f, 0.0f, 0.0f); + float fRimMask = 0.0f; + float fSpecExp = c.g_SpecExponent.x; + float4 vSpecExpMap = SpecExponentTexture.Sample(SpecExponentSampler, i.baseTexCoord.xy); + float fSpecExpMap = vSpecExpMap.r; + + fRimMask = lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl ); + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent + if ( fSpecExp == 0 ) + fSpecExp = 1.0f - fSpecExpMap + 150.0f * fSpecExpMap; + float3 vSpecularTint; + // If constant tint is negative, tint with albedo, based upon scalar tint map + if ( g_SpecularTint.r < 0 ) + vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), baseColor.rgb, vSpecExpMap.g ); + else + vSpecularTint = g_SpecularTint.rgb; + + if ( bDoSpecularWarp ) + fFresnelRanges = Fresnel( worldSpaceNormal, vEyeDir, g_FresnelRanges ); + + PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, + vEyeDir, vLightAtten, nNumLights, cLightInfo, false, 1.0f, + bDoSpecularWarp, SpecularWarpTexture, SpecularWarpSampler, fFresnelRanges, + bRimLight, g_RimExponent, + + // Output + specularLighting, rimLighting ); + + #if FLASHLIGHT + float4 flashlightSpacePosition = mul(float4(i.worldPos_projPosZ.xyz, 1.0f), g_FlashlightWorldToTexture); + float3 flashlight = 0; + float3 flashlightspec = 0; + DoSpecularFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, worldSpaceNormal, + g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, + FlashlightTexture, FlashlightSampler, ShadowDepthTexture, ShadowDepthSampler, BaseTexture, BaseTextureSampler, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, i.projPos.xy / i.projPos.z, + fSpecExp, vEyeDir, bDoSpecularWarp, SpecularWarpTexture, SpecularWarpSampler, fFresnelRanges, + c.g_EnvmapContrast_ShadowTweaks, + + // Output + flashlight, flashlightspec ); + return float4(flashlight + flashlightspec, 1.0f); + #endif + + // Modulate with spec mask, boost and tint + specularLighting *= fSpecMask * g_SpecularBoost * vSpecularTint; + + // If we didn't already apply Fresnel to specular warp, modulate the specular + if ( !bDoSpecularWarp ) + specularLighting *= fFresnelRanges; + + if (bRimLight) + { + float fRimFresnel = Fresnel4( worldSpaceNormal, vEyeDir ); + + // Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges) + rimLighting *= vSpecularTint * fRimMask * fRimFresnel; + + // Fold rim lighting into specular term by using the max so that we don't really add light twice... + specularLighting = max( specularLighting, rimLighting ); + + // Add in view-ray lookup from ambient cube + specularLighting += fRimFresnel * fRimMask * vSpecularTint * g_fRimBoost * PixelShaderAmbientLight( vEyeDir, cAmbientCube) * saturate(dot(worldSpaceNormal, float3(0, 0 , 1)) ); + } + +#endif + + // With phong, flashlight diffuse is calculated with specular + #if FLASHLIGHT && !PHONG + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; + // On ps_2_b, we can do shadow mapping + #if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) || defined(SHADER_MODEL_PS_4_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; + #endif + + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); + + // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 + bool bUseWorldNormal = true; + #if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) + bUseWorldNormal = false; + #endif + + float2 vProjPos = i.projPos.xy / i.projPos.w; // Screen-space position for shadow map noise + + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightTexture, FlashlightSampler, ShadowDepthTexture, ShadowDepthSampler, + /*RandRotSampler,*/ nShadowSampleLevel, bDoShadows, false, vProjPos, false, c.g_EnvmapContrast_ShadowTweaks ); + + return float4(flashlightColor, 1.0f); + + diffuseLighting += flashlightColor; + } + #endif + + if( bVertexColor && bDiffuseLighting ) + { + albedo *= i.color.rgb; + } + + alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); + + float3 diffuseComponent = albedo * diffuseLighting; + +#if DETAILTEXTURE + diffuseComponent = + TextureCombinePostLighting( diffuseComponent, detailColor, c.g_DetailBlendMode.x, g_DetailBlendFactor ); +#endif + +#if SELFILLUM_ENVMAPMASK_ALPHA + // range of alpha: + // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) + // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + half Adj_Alpha=8*envmapMaskTexel.a; + diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; +#else + if ( bSelfIllum ) + { + #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + float3 vVertexNormal = normalize( i.worldSpaceNormal.xyz ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVector.xyz ) ) ), c.g_SelfIllumScaleBiasExpBrightness.z ) * c.g_SelfIllumScaleBiasExpBrightness.x ) + c.g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * c.g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #else + float3 selfIllumComponent = g_SelfIllumTint * albedo; + float selfIllumMask; + #if SELFILLUMMASK + selfIllumMask = SelfIllumMaskTexture.Sample( SelfIllumMaskSampler, i.baseTexCoord.xy ).r; + #else + selfIllumMask = baseColor.a; + #endif + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, selfIllumMask ); + #endif + } +#endif + +#if CUBEMAP + { + HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); + float3 cubeSpecular = float3( 0.0f, 0.0f, 0.0f ); + cubeSpecular += ENV_MAP_SCALE * EnvmapTexture.Sample( EnvmapSampler, reflectVect ); + cubeSpecular *= specularFactor; + cubeSpecular *= c.g_EnvmapTint_TintReplaceFactor.rgb; + HALF3 specularLightingSquared = cubeSpecular * cubeSpecular; + cubeSpecular = lerp( cubeSpecular, specularLightingSquared, c.g_EnvmapContrast_ShadowTweaks ); + HALF3 greyScale = dot( cubeSpecular, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting += lerp( greyScale, cubeSpecular, g_EnvmapSaturation ); + } +#endif + + float3 result = diffuseComponent + specularLighting; + +#if ALPHATEST + if ( !GreaterEqualAlphaTest( alpha, c.g_AlphaTestRef ) ) + discard; +#endif + + //return float4(result, alpha); + +# if (DEPTHBLEND == 1) + { + float2 vScreenPos; + vScreenPos.x = i.projPos.x; + vScreenPos.y = -i.projPos.y; + vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; + alpha *= DepthFeathering( DepthTexture, DepthSampler, vScreenPos / i.projPos.w, + i.projPos.w - i.projPos.z, i.projPos.w, c.g_DepthFeatheringConstants ); + } +# endif + + + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, c.g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, length( i.eyeSpacePos ) ); + //alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog + + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, + TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); + +} + diff --git a/materialsystem/stdshadersdx11/vertexlit_and_unlit_generic_vs40.fxc b/materialsystem/stdshadersdx11/vertexlit_and_unlit_generic_vs40.fxc new file mode 100644 index 0000000..dc4bced --- /dev/null +++ b/materialsystem/stdshadersdx11/vertexlit_and_unlit_generic_vs40.fxc @@ -0,0 +1,287 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// DYNAMIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "SEPARATE_DETAIL_UVS" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "WRINKLEMAP" "0..1" +// STATIC: "DECAL" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" +// DYNAMIC: "MORPHING" "0..1" + +// SKIP: ($CASCADED_SHADOW) && ($FLASHLIGHT) +// SKIP: ($CASCADED_SHADOW) && ($SEAMLESS_BASE) +// SKIP: ($CASCADED_SHADOW) && ($SEAMLESS_DETAIL) +// SKIP: $CASCADED_SHADOW && $VERTEXCOLOR + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// _SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] +// SKIP: ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) +// SKIP: ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) + +// SKIP: ($TREESWAY) && ($MORPHING) +// SKIP: ( $TREESWAY ) && ( $SEAMLESS_DETAIL || $SEAMLESS_BASE ) + +#include "common_cbuffers_def_fxc.h" +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; +static const bool g_bCubemap = CUBEMAP ? true : false; +static const bool g_bFlashlight = FLASHLIGHT ? true : false; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +static const bool g_bBumpmap = BUMPMAP ? true : false; +#if (MORPHING && DECAL) +static const bool g_bDecalOffset = true; +#else +static const bool g_bDecalOffset = false; +#endif + +#include "vertexlitgeneric_dx11_shared.h" + +//CBUFFER_FLEX( USER_CBUFFER_REG_0 ) + +cbuffer VertexLitAndUnlitGeneric_CBuffer : USER_CBUFFER_REG_0 +{ + VertexLitAndUnlitGeneric_t c; +}; + +#define SEAMLESS_SCALE c.cSeamlessScale.x + +#if MORPHING +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +Texture2D morphTexture : register( t0 ); +SamplerState morphSampler : register( s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + uint4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR; + float3 vSpecular : SPECULAR; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; +#if STATIC_LIGHT + float4 vStaticLight : STATICLIGHTING; +#endif + +#if BUMPMAP + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : USERDATA; +#endif + + // Position and normal/tangent deltas + float3 vPosFlex : FLEXDELTA; + float3 vNormalFlex : FLEXNORMAL; +#if MORPHING + float vVertexID : MORPHVERTEXID; +#endif +}; + + +struct VS_OUTPUT +{ + float4 projPos : SV_POSITION; // Projection-space position + +#if SEAMLESS_BASE + float3 SeamlessTexCoord : TEXCOORD0; // Base texture x/y/z (indexed by swizzle) +#else + float2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + float3 SeamlessDetailTexCoord : TEXCOORD1; // Detail texture coordinate +#else + float2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for cubemaps + + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + float4 worldPos_ProjPosZ : TEXCOORD5; +#if BUMPMAP + float4 vWorldTangent : TEXCOORD6; +#endif +#if WRINKLEMAP + float4 wrinkleHeight : TEXCOORD7; +#endif +#if SEAMLESS_DETAIL || SEAMLESS_BASE + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif + float3 eyeSpacePos : COLOR1; + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); + + float4 vPosition = v.vPos; + float3 vNormal = 0; +#if BUMPMAP + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); +#else + if ( bDoLighting || FLASHLIGHT || SEAMLESS_BASE || SEAMLESS_DETAIL || LIGHTING_PREVIEW || g_bDecalOffset || CUBEMAP ) + { + // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) + DecompressVertex_Normal( v.vNormal, vNormal ); + } +#endif + +#if SEAMLESS_BASE || SEAMLESS_DETAIL + // compute blend weights in rgb + float3 NNormal=normalize( vNormal ); + o.SeamlessWeights.xyz = NNormal * NNormal; // sums to 1. +#endif + +#if !MORPHING + #if BUMPMAP + ApplyMorph( v.vPosFlex, v.vNormalFlex, cFlexScale, vPosition.xyz, vNormal, vTangent.xyz ); + #elif WRINKLEMAP + ApplyMorph( v.vPosFlex, v.vNormalFlex, cFlexScale, vPosition.xyz, vNormal, vTangent.xyz, o.wrinkleHeight.x ); + #else + ApplyMorph( v.vPosFlex, v.vNormalFlex, cFlexScale, vPosition.xyz, vNormal ); + #endif +#else + #if BUMPMAP + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz ); + #elif WRINKLEMAP + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz, o.wrinkleHeight.x ); + #else + ApplyMorph( morphTexture, morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); + #endif +#endif + +#if !BUMPMAP + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + cModel, + worldPos, worldNormal ); +#else + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, cModel, worldPos, + worldNormal, worldTangentS, worldTangentT ); +#endif + + o.eyeSpacePos = mul(float4(worldPos, 1), cViewMatrix).xyz; + + if ( !g_bVertexColor || g_bBumpmap ) + { + worldNormal = normalize( worldNormal ); + } + +#if BUMPMAP + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + o.vWorldTangent = float4( worldTangentS.xyz, vTangent.w ); // Propagate binormal sign in world tangent.w +#endif + +#if MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.worldSpaceNormal = worldNormal; + + float4x4 viewProj = mul(cViewMatrix, cProjMatrix); + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), viewProj ); + o.projPos = vProjPos; + + o.worldPos_ProjPosZ.xyz = worldPos.xyz; + o.worldPos_ProjPosZ.w = vProjPos.z; + + // Needed for cubemaps + o.worldVertToEyeVector.xyz = VSHADER_VECT_SCALE * (cEyePos.xyz - worldPos.xyz); + + if ( g_bVertexColor ) + { + //o.lightAtten = float4(0,0,0,0); + // Assume that this is unlitgeneric if you are using vertex color. + o.color.rgb = GammaToLinear( v.vColor.rgb ); + o.color.a = v.vColor.a; + } + else + { + +#if STATIC_LIGHT + float3 col = v.vStaticLight * cOverbright; + o.color = float4( GammaToLinear( col ), v.vColor.a ); +#endif + + // This moved to the pixel shader. + // Scalar light attenuation + //o.lightAtten.x = GetAttenForLight( worldPos, 0 ); + //o.lightAtten.y = GetAttenForLight( worldPos, 1 ); + //o.lightAtten.z = GetAttenForLight( worldPos, 2 ); + //o.lightAtten.w = GetAttenForLight( worldPos, 3 ); + } + + +#if SEAMLESS_BASE + o.SeamlessTexCoord.xyz = SEAMLESS_SCALE * v.vPos.xyz; +#else + // Base texture coordinates + o.baseTexCoord.x = dot( v.vTexCoord0, c.cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, c.cBaseTexCoordTransform[1] ); +#endif + +#if SEAMLESS_DETAIL + // FIXME: detail texcoord as a 2d xform doesn't make much sense here, so I just do enough so + // that scale works. More smartness could allow 3d xform. + o.SeamlessDetailTexCoord.xyz = (SEAMLESS_SCALE*c.cDetailTexCoordTransform[0].x) * v.vPos.xyz; +#else + // Detail texture coordinates + // FIXME: This shouldn't have to be computed all the time. + o.detailTexCoord.x = dot( v.vTexCoord0, c.cDetailTexCoordTransform[0] ); + o.detailTexCoord.y = dot( v.vTexCoord0, c.cDetailTexCoordTransform[1] ); +#endif + +#if SEPARATE_DETAIL_UVS + o.detailTexCoord.xy = v.vTexCoord1.xy; +#endif + +#if LIGHTING_PREVIEW + float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); + o.color.xyz=float3(dot,dot,dot); +#endif + + return o; +} + + diff --git a/materialsystem/stdshadersdx11/vertexlitgeneric_dx11.cpp b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11.cpp new file mode 100644 index 0000000..9324e28 --- /dev/null +++ b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11.cpp @@ -0,0 +1,511 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=====================================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx11_helper.h" +//#include "emissive_scroll_blended_pass_helper.h" +//#include "cloak_blended_pass_helper.h" +//#include "flesh_interior_blended_pass_helper.h" + +BEGIN_VS_SHADER( VertexLitGeneric, "Help for VertexLitGeneric" ) +BEGIN_SHADER_PARAMS +SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) +SHADER_PARAM( COMPRESS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "compression wrinklemap" ) +SHADER_PARAM( STRETCH, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "expansion wrinklemap" ) +SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) +SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) +SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) +SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) +SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) +SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) +SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) +SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) +SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) +SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) +SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) +SHADER_PARAM( BUMPCOMPRESS, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "compression bump map" ) +SHADER_PARAM( BUMPSTRETCH, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "expansion bump map" ) +SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) +SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) +SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) +SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) +SHADER_PARAM( SELFILLUM_ENVMAPMASK_ALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "defines that self illum value comes from env map mask alpha" ) +SHADER_PARAM( SELFILLUMFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "Self illum fresnel" ) +SHADER_PARAM( SELFILLUMFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC4, "0", "Self illum fresnel min, max, exp" ) +SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) +SHADER_PARAM( FLASHLIGHTNOLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Flashlight pass sets N.L=1.0" ) +//SHADER_PARAM( LIGHTMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "lightmap texture--will be bound by the engine") + +// Debugging term for visualizing ambient data on its own +SHADER_PARAM( AMBIENTONLY, SHADER_PARAM_TYPE_INTEGER, "0", "Control drawing of non-ambient light ()" ) + +SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) +SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) +SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) +SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) +SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "warp the specular term" ) +SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) +SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) +SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) +SHADER_PARAM( PHONGEXPONENTFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "When using a phong exponent texture, this will be multiplied by the 0..1 that comes out of the texture." ) +SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) +SHADER_PARAM( BASEMAPALPHAPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "indicates that there is no normal map and that the phong mask is in base alpha" ) +SHADER_PARAM( INVERTPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "invert the phong mask (0=full phong, 1=no phong)" ) +SHADER_PARAM( ENVMAPFRESNEL, SHADER_PARAM_TYPE_FLOAT, "0", "Degree to which Fresnel should be applied to env map" ) +SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) +SHADER_PARAM( SELFILLUMMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + +// detail (multi-) texturing +SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) +SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) +SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) +SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + +// Rim lighting terms +SHADER_PARAM( RIMLIGHT, SHADER_PARAM_TYPE_BOOL, "0", "enables rim lighting" ) +SHADER_PARAM( RIMLIGHTEXPONENT, SHADER_PARAM_TYPE_FLOAT, "4.0", "Exponent for rim lights" ) +SHADER_PARAM( RIMLIGHTBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Boost for rim lights" ) +SHADER_PARAM( RIMMASK, SHADER_PARAM_TYPE_BOOL, "0", "Indicates whether or not to use alpha channel of exponent texture to mask the rim term" ) + +// Seamless mapping scale +SHADER_PARAM( SEAMLESS_BASE, SHADER_PARAM_TYPE_BOOL, "0", "whether to apply seamless mapping to the base texture. requires a smooth model." ) +SHADER_PARAM( SEAMLESS_DETAIL, SHADER_PARAM_TYPE_BOOL, "0", "where to apply seamless mapping to the detail texture." ) +SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "the scale for the seamless mapping. # of repetions of texture per inch." ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries. Only supported without bumpmaps" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + + SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation" ) + SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) + + SHADER_PARAM( SELFILLUMTWOTEXTUREBLEND, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( SELFILLUMTWOTEXTUREBLEND_AMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( SELFILLUMTWOTEXTUREBLEND_TEXTURE, SHADER_PARAM_TYPE_TEXTURE, "0", "" ) + SHADER_PARAM( TWOSIDEDLIGHTING, SHADER_PARAM_TYPE_BOOL, "0", "" ) + + // vertexlitgeneric tree sway animation control + SHADER_PARAM( TREESWAY, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( TREESWAYHEIGHT, SHADER_PARAM_TYPE_FLOAT, "1000", "" ) + SHADER_PARAM( TREESWAYSTARTHEIGHT, SHADER_PARAM_TYPE_FLOAT, "0.2", "" ) + SHADER_PARAM( TREESWAYRADIUS, SHADER_PARAM_TYPE_FLOAT, "300", "" ) + SHADER_PARAM( TREESWAYSTARTRADIUS, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSPEED, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + SHADER_PARAM( TREESWAYSPEEDHIGHWINDMULTIPLIER, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( TREESWAYSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "10", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESPEED, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFREQUENCY, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.5", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPSTART, SHADER_PARAM_TYPE_FLOAT, "3", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPEND, SHADER_PARAM_TYPE_FLOAT, "6", "" ) + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX11_Vars_t &info ) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nWrinkle = COMPRESS; + info.m_nStretch = STRETCH; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nNormalWrinkle = BUMPCOMPRESS; + info.m_nNormalStretch = BUMPSTRETCH; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nFlashlightNoLambert = FLASHLIGHTNOLAMBERT; + //info.m_nLightmap = LIGHTMAP; + + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nSelfIllumEnvMapMask_Alpha = SELFILLUM_ENVMAPMASK_ALPHA; + info.m_nSelfIllumFresnel = SELFILLUMFRESNEL; + info.m_nSelfIllumFresnelMinMaxExp = SELFILLUMFRESNELMINMAXEXP; + + info.m_nAmbientOnly = AMBIENTONLY; + info.m_nPhongExponent = PHONGEXPONENT; + info.m_nPhongExponentTexture = PHONGEXPONENTTEXTURE; + info.m_nPhongTint = PHONGTINT; + info.m_nPhongAlbedoTint = PHONGALBEDOTINT; + info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; + info.m_nPhongWarpTexture = PHONGWARPTEXTURE; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongExponentFactor = PHONGEXPONENTFACTOR; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhong = PHONG; + info.m_nBaseMapAlphaPhongMask = BASEMAPALPHAPHONGMASK; + info.m_nEnvmapFresnel = ENVMAPFRESNEL; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + // Rim lighting parameters + info.m_nRimLight = RIMLIGHT; + info.m_nRimLightPower = RIMLIGHTEXPONENT; + info.m_nRimLightBoost = RIMLIGHTBOOST; + info.m_nRimMask = RIMMASK; + + // seamless + info.m_nSeamlessScale = SEAMLESS_SCALE; + info.m_nSeamlessDetail = SEAMLESS_DETAIL; + info.m_nSeamlessBase = SEAMLESS_BASE; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nDetailTint = DETAILTINT; + info.m_nInvertPhongMask = INVERTPHONGMASK; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + + info.m_nSelfIllumMask = SELFILLUMMASK; +// info.m_nSelfIllumMaskFrame = SELFILLUMMASKFRAME; + info.m_nBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA; + info.m_nTintReplacesBaseColor = BLENDTINTCOLOROVERBASE; + +/* info.m_nSelfIllumTwoTexture = SELFILLUMTWOTEXTUREBLEND; + info.m_nSelfIllumTwoTexture_Amount = SELFILLUMTWOTEXTUREBLEND_AMOUNT; + info.m_nSelfIllumTwoTexture_Texture = SELFILLUMTWOTEXTUREBLEND_TEXTURE;*/ + info.m_nTwoSidedLighting = TWOSIDEDLIGHTING; + +/* info.m_nTreeSway = TREESWAY; + info.m_nTreeSwayHeight = TREESWAYHEIGHT; + info.m_nTreeSwayStartHeight = TREESWAYSTARTHEIGHT; + info.m_nTreeSwayRadius = TREESWAYRADIUS; + info.m_nTreeSwayStartRadius = TREESWAYSTARTRADIUS; + info.m_nTreeSwaySpeed = TREESWAYSPEED; + info.m_nTreeSwaySpeedHighWindMultiplier = TREESWAYSPEEDHIGHWINDMULTIPLIER; + info.m_nTreeSwayStrength = TREESWAYSTRENGTH; + info.m_nTreeSwayScrumbleSpeed = TREESWAYSCRUMBLESPEED; + info.m_nTreeSwayScrumbleStrength = TREESWAYSCRUMBLESTRENGTH; + info.m_nTreeSwayScrumbleFrequency = TREESWAYSCRUMBLEFREQUENCY; + info.m_nTreeSwayFalloffExp = TREESWAYFALLOFFEXP; + info.m_nTreeSwayScrumbleFalloffExp = TREESWAYSCRUMBLEFALLOFFEXP; + info.m_nTreeSwaySpeedLerpStart = TREESWAYSPEEDLERPSTART; + info.m_nTreeSwaySpeedLerpEnd = TREESWAYSPEEDLERPEND;*/ +} +#if 0 +// Cloak Pass +void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) +{ + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; +} +#endif + +bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const +{ + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); +} + +bool IsTranslucent( IMaterialVar **params ) const +{ + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); +} + +#if 0 +// Emissive Scroll Pass +void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) +{ + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + info.m_nTime = TIME; +} + +// Flesh Interior Pass +void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) +{ + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + + info.m_nTime = TIME; +} +#endif + +SHADER_INIT_PARAMS() +{ + VertexLitGeneric_DX11_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX11( this, params, pMaterialName, true, vars ); + +#if 0 + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } +#endif +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 70 ) + return "VertexLitGeneric_DX6"; + + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "VertexLitGeneric_DX7"; + + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "VertexLitGeneric_DX8"; + + return 0; +} + +SHADER_INIT +{ + VertexLitGeneric_DX11_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX11( this, params, true, vars ); + +#if 0 + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } +#endif +} + +SHADER_INIT_GLOBAL +{ + g_hVertexLitGeneric_CBuffer = pShaderDevice->CreateConstantBuffer( sizeof( VertexLitGeneric_CBuffer_t ) ); +} + +SHADER_DRAW +{ + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; +#if 0 + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } +#endif + + // Standard rendering pass + if ( bDrawStandardPass ) + { + VertexLitGeneric_DX11_Vars_t vars; + SetupVars( vars ); + DrawVertexLitGeneric_DX11( this, params, pShaderAPI, pShaderShadow, true, vars, vertexCompression, pContextDataPtr ); + } + else + { + // Skip this pass! + Draw( false ); + } + +#if 0 + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } +#endif +} +END_SHADER diff --git a/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_helper.cpp b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_helper.cpp new file mode 100644 index 0000000..0f946b3 --- /dev/null +++ b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_helper.cpp @@ -0,0 +1,1204 @@ +#if 1 +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx11_helper.h" +#include "tier0/vprof.h" +//#include "skin_dx11_helper.h" + +#include "vertexlit_and_unlit_generic_vs40.inc" +#include "vertexlit_and_unlit_generic_ps40.inc" +//#include "vertexlit_and_unlit_generic_bump_vs40.inc" +//#include "vertexlit_and_unlit_generic_bump_ps40.inc" + +#include "../stdshaders/commandbuilder.h" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); +static ConVar mat_luxels( "mat_luxels", "0", FCVAR_CHEAT ); +static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); + +ConstantBufferHandle_t g_hVertexLitGeneric_CBuffer; + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsVertexLitGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX11_Vars_t &info ) +{ + InitIntParam( info.m_nPhong, params, 0 ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + InitIntParam( info.m_nVertexAlphaTest, params, 0 ); + + InitIntParam( info.m_nFlashlightNoLambert, params, 0 ); + + if ( info.m_nDetailTint != -1 && !params[info.m_nDetailTint]->IsDefined() ) + { + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if ( info.m_nEnvmapTint != -1 && !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + InitIntParam( info.m_nEnvmapFrame, params, 0 ); + InitIntParam( info.m_nBumpFrame, params, 0 ); + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nReceiveFlashlight, params, 0 ); + + InitFloatParam( info.m_nDetailScale, params, 4.0f ); + + if ( ( info.m_nSelfIllumTint != -1 ) && ( !params[info.m_nSelfIllumTint]->IsDefined() ) ) + { + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + if ( info.m_nFlashlightTexture != -1 ) + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if ( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if ( bVertexLitGeneric ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + InitIntParam( info.m_nEnvmapMaskFrame, params, 0 ); + InitFloatParam( info.m_nEnvmapContrast, params, 0.0 ); + InitFloatParam( info.m_nEnvmapSaturation, params, 1.0f ); + InitFloatParam( info.m_nSeamlessScale, params, 0.0 ); + + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nGlowAlpha, params, 1.0 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); + + // No texture means no self-illum or env mask in base alpha + if ( info.m_nBaseTexture != -1 && !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if ( IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Lots of reasons to want tangent space, since we bind a flat normal map in many cases where we don't have a bump map + bool bBump = ( info.m_nBumpmap != -1 ) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined(); + bool bEnvMap = ( info.m_nEnvmap != -1 ) && params[info.m_nEnvmap]->IsDefined(); + bool bDiffuseWarp = ( info.m_nDiffuseWarpTexture != - 1 ) && params[info.m_nDiffuseWarpTexture]->IsDefined(); + bool bPhong = ( info.m_nPhong != - 1 ) && params[info.m_nPhong]->IsDefined(); + if ( bBump || bEnvMap || bDiffuseWarp || bPhong ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else // no tangent space needed + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + if ( hasNormalMapAlphaEnvmapMask ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) && info.m_nBumpmap != -1 && + params[info.m_nBumpmap]->IsDefined() && !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and $basealphaenvmapmask. Must use $normalmapalphaenvmapmask to get specular.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + if ( !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and an envmapmask. Must use $normalmapalphaenvmapmask.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + // If mat_specular 0, then get rid of envmap + if ( !g_pConfig->UseSpecular() && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + InitFloatParam( info.m_nHDRColorScale, params, 1.0f ); + + InitIntParam( info.m_nLinearWrite, params, 0 ); + InitIntParam( info.m_nGammaColorRead, params, 0 ); + + InitIntParam( info.m_nDepthBlend, params, 0 ); + InitFloatParam( info.m_nDepthBlendScale, params, 50.0f ); + + if ( info.m_nSelfIllumMask != -1 && params[info.m_nSelfIllumMask]->IsDefined() + && info.m_nSelfIllumFresnel != -1 ) + { + params[info.m_nSelfIllumFresnel]->SetIntValue( 0 ); + } + + if ( ( info.m_nSelfIllumFresnelMinMaxExp != -1 ) && ( !params[info.m_nSelfIllumFresnelMinMaxExp]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 1.0f ); + } + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( !params[info.m_nBaseMapAlphaPhongMask]->IsDefined() ) ) + { + params[info.m_nBaseMapAlphaPhongMask]->SetIntValue( 0 ); + } + + if ( ( info.m_nEnvmapFresnel != -1 ) && ( !params[info.m_nEnvmapFresnel]->IsDefined() ) ) + { + params[info.m_nEnvmapFresnel]->SetFloatValue( 0 ); + } +} + + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- + +void InitVertexLitGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, bool bVertexLitGeneric, VertexLitGeneric_DX11_Vars_t &info ) +{ + if ( info.m_nFlashlightTexture != -1 ) + { + pShader->LoadTexture( info.m_nFlashlightTexture ); + } + + bool bIsBaseTextureTranslucent = false; + if ( info.m_nBaseTexture != -1 && params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture/*, ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ? 0 : TEXTUREFLAGS_SRGB*/ ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + + if ( ( info.m_nWrinkle != -1 ) && ( info.m_nStretch != -1 ) && + params[info.m_nWrinkle]->IsDefined() && params[info.m_nStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nWrinkle ); + pShader->LoadTexture( info.m_nStretch ); + } + } + + const bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumMask != -1 ) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent /*&& !bHasSelfIllumBlend*/ ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( ( info.m_nPhongExponentTexture != -1 ) && params[info.m_nPhongExponentTexture]->IsDefined() && + ( info.m_nPhong != -1 ) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongExponentTexture ); + } + + if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsDefined() && + ( info.m_nPhong != -1 ) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( ( info.m_nPhongWarpTexture != -1 ) && params[info.m_nPhongWarpTexture]->IsDefined() && + ( info.m_nPhong != -1 ) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongWarpTexture ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) //Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( ( info.m_nBumpmap != -1 ) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + + if ( ( info.m_nNormalWrinkle != -1 ) && ( info.m_nNormalStretch != -1 ) && + params[info.m_nNormalWrinkle]->IsDefined() && params[info.m_nNormalStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nNormalWrinkle ); + pShader->LoadTexture( info.m_nNormalStretch ); + } + } + else if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) || IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + { + if ( !IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ) + { + pShader->LoadCubeMap( info.m_nEnvmap/*, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0*/ ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap/*, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0*/ ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + } + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + + if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CVertexLitGeneric_DX11_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + + VertexLitGeneric_CBuffer_t m_Constants; + + bool m_bSeamlessDetail; + bool m_bSeamlessBase; + bool m_bBaseTextureTransform; + bool m_bHasPhong; + bool m_bHasWrinkle; + bool m_bHasPhongWarp; + bool m_bHasRimLight; + bool m_bAlphaTest; + bool m_bFullyOpaque; + + CVertexLitGeneric_DX11_Context() : + CBasePerMaterialContextData() + { + memset( &m_Constants, 0, sizeof( VertexLitGeneric_CBuffer_t ) ); + } + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +static void DrawVertexLitGeneric_DX11_Internal( CBaseVSShader *pShader, IMaterialVar **params, + IShaderDynamicAPI *pShaderAPI, + IShaderShadow *pShaderShadow, + bool bVertexLitGeneric, bool bHasFlashlight, + VertexLitGeneric_DX11_Vars_t &info, + VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + VPROF_BUDGET( "DrawVertexLitGeneric_DX11", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); + + CVertexLitGeneric_DX11_Context *pContextData = reinterpret_cast ( *pContextDataPtr ); + if ( !pContextData ) // make sure allocated + { + pContextData = new CVertexLitGeneric_DX11_Context; + *pContextDataPtr = pContextData; + } + + bool bHasBump = IsTextureSet( info.m_nBumpmap, params ); + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); + + bool hasDiffuseLighting = bVertexLitGeneric; + + if ( IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ) + { + bHasFlashlight = false; + } + + bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params ); + + bool bHasDiffuseWarp = hasDiffuseLighting && ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + + bool bFlashlightNoLambert = false; + if ( ( info.m_nFlashlightNoLambert != -1 ) && params[info.m_nFlashlightNoLambert]->GetIntValue() ) + { + bFlashlightNoLambert = true; + } + + bool bAmbientOnly = IsBoolSet( info.m_nAmbientOnly, params ); + + float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params ); + int nDetailBlendMode = bHasDetailTexture ? GetIntParam( info.m_nDetailTextureCombineMode, params ) : 0; + int nDetailTranslucencyTexture = -1; + + if ( bHasDetailTexture ) + { + if ( ( nDetailBlendMode == 6 ) && ( !( g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) ) + { + nDetailBlendMode = 5; // skip fancy threshold blending if ps2.0 + } + if ( ( nDetailBlendMode == 3 ) || ( nDetailBlendMode == 8 ) || ( nDetailBlendMode == 9 ) ) + nDetailTranslucencyTexture = info.m_nDetail; + } + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ); + + BlendType_t nBlendType; + + if ( bHasBaseTexture ) + { + // if base alpha is used for tinting, ignore the base texture for computing translucency + //nBlendType = pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true, nDetailTranslucencyTexture ); + nBlendType = pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true, nDetailTranslucencyTexture ); + } + else + { + nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false ); + } + + bool bHasEnvmap = info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsTexture(); + + bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + + const bool bHasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + const bool bHasSelfIllumMask = bHasSelfIllum && IsTextureSet( info.m_nSelfIllumMask, params ); + + const bool bSeamlessBase = IsBoolSet( info.m_nSeamlessBase, params ); + const bool bSeamlessDetail = IsBoolSet( info.m_nSeamlessDetail, params ); + pContextData->m_bSeamlessDetail = bSeamlessDetail; + pContextData->m_bSeamlessBase = bSeamlessBase; + pContextData->m_bBaseTextureTransform = info.m_nBaseTextureTransform != -1; + + if ( pShader->IsSnapshotting() || ( !pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) + { + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + pContextData->m_bAlphaTest = bIsAlphaTested; + bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested; //dest alpha is free for special use + pContextData->m_bFullyOpaque = bFullyOpaque; + bool bDistanceAlpha = IsBoolSet( info.m_nDistanceAlpha, params ); + bool bHasEnvmapMask = info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); + bool bHasSelfIllumFresnel = ( !IsTextureSet( info.m_nDetail, params ) ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + bool hasSelfIllumInEnvMapMask = + ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) && + ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ); + + bool bHasBaseTextureWrinkle = bHasBaseTexture && + ( info.m_nWrinkle != -1 ) && params[info.m_nWrinkle]->IsTexture() && + ( info.m_nStretch != -1 ) && params[info.m_nStretch]->IsTexture(); + + bool bHasBumpWrinkle = bHasBump && + ( info.m_nNormalWrinkle != -1 ) && params[info.m_nNormalWrinkle]->IsTexture() && + ( info.m_nNormalStretch != -1 ) && params[info.m_nNormalStretch]->IsTexture(); + + pContextData->m_bHasWrinkle = bHasBaseTextureWrinkle || bHasBaseTextureWrinkle; + + // Tie these to specular + bool bHasPhong = ( info.m_nPhong != -1 ) && ( params[info.m_nPhong]->GetIntValue() != 0 ); + pContextData->m_bHasPhong = bHasPhong; + bool bHasSpecularExponentTexture = ( info.m_nPhongExponentTexture != -1 ) && params[info.m_nPhongExponentTexture]->IsTexture(); + bool bHasPhongTintMap = bHasSpecularExponentTexture && ( info.m_nPhongAlbedoTint != -1 ) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 ); + bool bHasDiffuseWarp = ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + bool bHasPhongWarp = ( info.m_nPhongWarpTexture != -1 ) && params[info.m_nPhongWarpTexture]->IsTexture(); + pContextData->m_bHasPhongWarp = bHasPhongWarp; + //bool bHasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + // Rimlight must be set to non-zero to trigger rim light combo (also requires Phong) + bool bHasRimLight = r_rimlight.GetBool() && bHasPhong && ( info.m_nRimLight != -1 ) && ( params[info.m_nRimLight]->GetIntValue() != 0 ); + pContextData->m_bHasRimLight = bHasRimLight; + bool bHasRimMaskMap = bHasSpecularExponentTexture && bHasRimLight && ( info.m_nRimMask != -1 ) && ( params[info.m_nRimMask]->GetIntValue() != 0 ); + + if ( pShader->IsSnapshotting() ) + { + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + + if ( info.m_nVertexAlphaTest != -1 && params[info.m_nVertexAlphaTest]->GetIntValue() > 0 ) + { + bHasVertexAlpha = true; + } + + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + if ( bHasSelfIllumFresnel ) + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + hasNormalMapAlphaEnvmapMask = false; + } + + bool bHasNormal = bVertexLitGeneric || bHasEnvmap || bHasFlashlight || bSeamlessBase || bSeamlessDetail; + if ( IsPC() ) + { + // On PC, LIGHTING_PREVIEW requires normals (they won't use much memory - unlitgeneric isn't used on many models) + bHasNormal = true; + } + + bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ); + + if ( bHasFlashlight && bVertexLitGeneric ) + { + if ( params[info.m_nBaseTexture]->IsTexture() ) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + else + { + pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false ); + } + + if ( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + bIsAlphaTested = false; + pContextData->m_bAlphaTest = false; + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + + unsigned int flags = VERTEX_POSITION; + if ( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } + + int userDataSize = 0; + + if ( bHasFlashlight ) + { + userDataSize = 4; // tangent S + } + + if ( bHasBump || bHasDiffuseWarp ) + { + userDataSize = 4; // tangent S + } + + if ( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } + + // texcoord0 : base texcoord + int pTexCoordDim[3] = { 2, 2, 3 }; + int nTexCoordCount = 1; + + if ( IsBoolSet( info.m_nSeparateDetailUVs, params ) ) + { + ++nTexCoordCount; + } + else + { + pTexCoordDim[1] = 0; + } + + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + { + bool bDistanceAlphaFromDetail = false; + bool bSoftMask = false; + bool bGlow = false; + bool bOutline = false; + + static ConVarRef mat_reduceparticles( "mat_reduceparticles" ); + bool bDoDepthBlend = IsBoolSet( info.m_nDepthBlend, params ) && !mat_reduceparticles.GetBool(); + + if ( bDistanceAlpha ) + { + bDistanceAlphaFromDetail = IsBoolSet( info.m_nDistanceAlphaFromDetail, params ); + bSoftMask = IsBoolSet( info.m_nSoftEdges, params ); + bGlow = IsBoolSet( info.m_nGlow, params ); + bOutline = IsBoolSet( info.m_nOutline, params ); + } + + const bool bTwoSidedLighting = info.m_nTwoSidedLighting >= 0 && params[info.m_nTwoSidedLighting]->GetIntValue() > 0; + + pShader->SetInternalVertexShaderConstantBuffers(); + pShader->SetVertexShaderConstantBuffer( USER_CBUFFER_REG_0, g_hVertexLitGeneric_CBuffer ); + + pShader->SetInternalPixelShaderConstantBuffers(); + pShader->SetPixelShaderConstantBuffer( 3, g_hVertexLitGeneric_CBuffer ); + + // The vertex shader uses the vertex id stream + if ( g_pHardwareConfig->HasFastVertexTextures() ) + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bHasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); + //SET_STATIC_VERTEX_SHADER_COMBO( TWO_SIDED_LIGHTING, bTwoSidedLighting ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps40 ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMMASK, bHasSelfIllumMask ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bHasBump ); + SET_STATIC_PIXEL_SHADER_COMBO( ALPHATEST, bIsAlphaTested ); + //SET_STATIC_PIXEL_SHADER_COMBO( TWO_SIDED_LIGHTING, bTwoSidedLighting ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps40 ); + } + + pShader->DefaultFog(); + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and the loadout and character select screens. + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + + if ( pShaderAPI && ( ( !pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) ) + { + pContextData->m_SemiStaticCmdsOut.Reset(); + if ( bHasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + if ( bHasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, info.m_nDetail, info.m_nDetailFrame ); + } + if ( bHasSelfIllum ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_BLACK ); // Bind dummy + } + + if ( ( info.m_nDepthBlend != -1 ) && ( params[info.m_nDepthBlend]->GetIntValue() ) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER10, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + if ( bSeamlessDetail || bSeamlessBase ) + { + pContextData->m_Constants.cSeamlessScale.Init( params[info.m_nSeamlessScale]->GetFloatValue(), + 0.0f, 0.0f, 0.0f ); + } + + if ( pContextData->m_bBaseTextureTransform ) + { + pShader->StoreVertexShaderTextureTransform( pContextData->m_Constants.cBaseTextureTransform, + info.m_nBaseTextureTransform ); + } + + + if ( bHasDetailTexture ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + { + pShader->StoreVertexShaderTextureScaledTransform( pContextData->m_Constants.cDetailTextureTransform, + info.m_nDetailTextureTransform, info.m_nDetailScale ); + } + else + { + pShader->StoreVertexShaderTextureScaledTransform( pContextData->m_Constants.cDetailTextureTransform, + info.m_nBaseTextureTransform, info.m_nDetailScale ); + } + + if ( info.m_nDetailTint != -1 ) + pShader->StoreConstantGammaToLinear( pContextData->m_Constants.cDetailTint.Base(), info.m_nDetailTint ); + else + { + pContextData->m_Constants.cDetailTint.Init( 1, 1, 1, 1 ); + } + } + if ( bDistanceAlpha ) + { + float flSoftStart = GetFloatParam( info.m_nEdgeSoftnessStart, params ); + float flSoftEnd = GetFloatParam( info.m_nEdgeSoftnessEnd, params ); + // set all line art shader parms + bool bScaleEdges = IsBoolSet( info.m_nScaleEdgeSoftnessBasedOnScreenRes, params ); + bool bScaleOutline = IsBoolSet( info.m_nScaleOutlineSoftnessBasedOnScreenRes, params ); + + float flResScale = 1.0; + + float flOutlineStart0 = GetFloatParam( info.m_nOutlineStart0, params ); + float flOutlineStart1 = GetFloatParam( info.m_nOutlineStart1, params ); + float flOutlineEnd0 = GetFloatParam( info.m_nOutlineEnd0, params ); + float flOutlineEnd1 = GetFloatParam( info.m_nOutlineEnd1, params ); + + if ( bScaleEdges || bScaleOutline ) + { + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + flResScale = max( 0.5, max( 1024.0 / nWidth, 768 / nHeight ) ); + + if ( bScaleEdges ) + { + float flMid = 0.5 * ( flSoftStart + flSoftEnd ); + flSoftStart = clamp( flMid + flResScale * ( flSoftStart - flMid ), 0.05, 0.99 ); + flSoftEnd = clamp( flMid + flResScale * ( flSoftEnd - flMid ), 0.05, 0.99 ); + } + + + if ( bScaleOutline ) + { + // shrink the soft part of the outline, enlarging hard part + float flMidS = 0.5 * ( flOutlineStart1 + flOutlineStart0 ); + flOutlineStart1 = clamp( flMidS + flResScale * ( flOutlineStart1 - flMidS ), 0.05, 0.99 ); + float flMidE = 0.5 * ( flOutlineEnd1 + flOutlineEnd0 ); + flOutlineEnd1 = clamp( flMidE + flResScale * ( flOutlineEnd1 - flMidE ), 0.05, 0.99 ); + } + + } + + pContextData->m_Constants.cGlowParams.Init( + GetFloatParam( info.m_nGlowX, params ), + GetFloatParam( info.m_nGlowY, params ), + GetFloatParam( info.m_nGlowStart, params ), + GetFloatParam( info.m_nGlowEnd, params ) + ); + + pContextData->m_Constants.cGlowColor.Init( + 0, 0, 0, + GetFloatParam( info.m_nGlowAlpha, params ) + ); + + pContextData->m_Constants.cMaskRangeParams.Init( + flSoftStart, + flSoftEnd, + 0, 0 + ); + + pContextData->m_Constants.cOutlineColor.Init( + 0, 0, 0, + GetFloatParam( info.m_nOutlineAlpha, params ) + ); + + pContextData->m_Constants.cOutlineParams.Init( + flOutlineStart0, + flOutlineEnd1, + flOutlineEnd0, + flOutlineStart1 + ); + + if ( info.m_nGlowColor != -1 ) + { + params[info.m_nGlowColor]->GetVecValue( + pContextData->m_Constants.cGlowColor.Base(), 3 ); + } + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( + pContextData->m_Constants.cOutlineColor.Base(), 3 ); + } + + } + + pContextData->m_Constants.cDetailBlendMode.x = nDetailBlendMode; + + if ( pContextData->m_bAlphaTest ) + { + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pContextData->m_Constants.cAlphaTestRef = params[info.m_nAlphaTestReference]->GetFloatValue(); + } + } + + if ( bHasBaseTextureWrinkle ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nWrinkle, info.m_nBaseTextureFrame ); + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER13, info.m_nStretch, info.m_nBaseTextureFrame ); + } + else if ( bHasBumpWrinkle ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER13, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + + if ( !g_pConfig->m_bFastNoBump ) + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER1, info.m_nBumpmap, info.m_nBumpFrame ); + } + //else if ( bHasDiffuseWarp ) + //{ + // pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_NORMALMAP_FLAT ); + //} + + if ( bHasBumpWrinkle ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER14, info.m_nNormalWrinkle, info.m_nBumpFrame ); + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, info.m_nNormalStretch, info.m_nBumpFrame ); + } + else if ( bHasBaseTextureWrinkle ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER14, info.m_nBumpmap, info.m_nBumpFrame ); + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_NORMALMAP_FLAT ); + } + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER14, TEXTURE_NORMALMAP_FLAT ); + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER15, TEXTURE_NORMALMAP_FLAT ); + } + } + + // Setting w to 1 means use separate selfillummask + pContextData->m_Constants.cEnvMapSaturation_SelfIllumMask.Init( + 1.0f, 1.0f, 1.0f, 0.0f ); + if ( info.m_nEnvmapSaturation != -1 ) + params[info.m_nEnvmapSaturation]->GetVecValue( + pContextData->m_Constants.cEnvMapSaturation_SelfIllumMask.Base(), 3 ); + + pContextData->m_Constants.cEnvMapSaturation_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + if ( bHasEnvmap ) + { + pShader->StoreEnvmapTintGammaToLinear( pContextData->m_Constants.cEnvMapTint, info.m_nEnvmapTint ); + } + bool bHasEnvmapMask = ( !bHasFlashlight ) && info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); + + if ( bHasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + bool bHasSelfIllumFresnel = ( !bHasDetailTexture ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + if ( bHasSelfIllumFresnel ) + { + pContextData->m_Constants.cConstScaleBiasExp.Init( 1.0f, 0.0f, 1.0f, 0.0f ); + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + pContextData->m_Constants.cConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + pContextData->m_Constants.cConstScaleBiasExp[0] = 1.0f - pContextData->m_Constants.cConstScaleBiasExp[1]; // Scale + pContextData->m_Constants.cConstScaleBiasExp[2] = flExp; // Exp + pContextData->m_Constants.cConstScaleBiasExp[3] = flMax; // Brightness + } + + if ( bHasDiffuseWarp && !bHasSelfIllumFresnel ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nDiffuseWarpTexture, -1 ); + } + } + + if ( ( info.m_nEnvmapContrast != -1 ) ) + pContextData->m_Constants.cEnvMapContrast = params[info.m_nEnvmapContrast]->GetVecValue(); + + // mat_fullbright 2 handling + bool bLightingOnly = bVertexLitGeneric && mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if ( bLightingOnly ) + { + if ( bHasBaseTexture ) + { + if ( ( bHasSelfIllum && !hasSelfIllumInEnvMapMask ) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + } + + //if ( bHasBump || bHasDiffuseWarp ) + //{ + // pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + //} + + if ( info.m_nSelfIllumTint != -1 ) + { + float pSelfIllumTint[4] = { 0.0f, 0.0f, 0.0f, fBlendFactor }; + params[info.m_nSelfIllumTint]->GetVecValue( pSelfIllumTint, 3 ); + pContextData->m_Constants.cSelfIllumTint = pSelfIllumTint; + } + + if ( bHasPhongWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nPhongWarpTexture, -1 ); + } + + if ( bHasSpecularExponentTexture && bHasPhong ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nPhongExponentTexture, -1 ); + } + else if ( bHasPhong ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_WHITE ); + } + + // Build phong constants + if ( bHasPhong ) + { + float vFresnelRanges_SpecBoost[4] = { 0, 0.5, 1, 1 }; + if ( ( info.m_nPhongFresnelRanges != -1 ) && params[info.m_nPhongFresnelRanges]->IsDefined() ) + params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional Fresnel range parameters + if ( ( info.m_nPhongBoost != -1 ) && params[info.m_nPhongBoost]->IsDefined() ) // Grab optional Phong boost param + vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue(); + else + vFresnelRanges_SpecBoost[3] = 1.0f; + + float vSpecularTint[4] = { 1, 1, 1, 4 }; + // Get the tint parameter + if ( ( info.m_nPhongTint != -1 ) && params[info.m_nPhongTint]->IsDefined() ) + { + params[info.m_nPhongTint]->GetVecValue( vSpecularTint, 3 ); + } + + // If it's all zeros, there was no constant tint in the vmt + if ( ( vSpecularTint[0] == 0.0f ) && ( vSpecularTint[1] == 0.0f ) && ( vSpecularTint[2] == 0.0f ) ) + { + if ( bHasPhongTintMap ) // If we have a map to use, tell the shader + { + vSpecularTint[0] = -1; + } + else // Otherwise, just tint with white + { + vSpecularTint[0] = 1.0f; + vSpecularTint[1] = 1.0f; + vSpecularTint[2] = 1.0f; + } + } + + // Get the rim light power (goes in w of Phong tint) + if ( bHasRimLight && ( info.m_nRimLightPower != -1 ) && params[info.m_nRimLightPower]->IsDefined() ) + { + vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue(); + vSpecularTint[3] = max( vSpecularTint[3], 1.0f ); // Make sure this is at least 1 + } + + float vRimPhongParams[4] = { 1, 1, 1, 1 }; + // Get the rim boost + if ( bHasRimLight && ( info.m_nRimLightBoost != -1 ) && params[info.m_nRimLightBoost]->IsDefined() ) + { + vRimPhongParams[0] = params[info.m_nRimLightBoost]->GetFloatValue(); + } + + // Rim mask control + vRimPhongParams[1] = bHasRimMaskMap ? params[info.m_nRimMask]->GetFloatValue() : 0.0f; + + bool bHasBaseAlphaPhongMask = ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + vRimPhongParams[2] = bHasBaseAlphaPhongMask ? 1 : 0; + + bool bInvertPhongMask = ( info.m_nInvertPhongMask != -1 ) && ( params[info.m_nInvertPhongMask]->GetIntValue() != 0 ); + float fInvertPhongMask = bInvertPhongMask ? 1 : 0; + vRimPhongParams[3] = fInvertPhongMask; + + float vSpecExponent[4] = { 1, 0, 0, 0 }; + if ( ( info.m_nPhongExponent != -1 ) && params[info.m_nPhongExponent]->IsDefined() ) + vSpecExponent[0] = params[info.m_nPhongExponent]->GetFloatValue(); // This overrides the channel in the map + else + vSpecExponent[0] = 0; + + // Store the constants + pContextData->m_Constants.cFresnelSpecParams = Vector4D( vFresnelRanges_SpecBoost ); + pContextData->m_Constants.cSpecularRimParams = Vector4D( vSpecularTint ); + pContextData->m_Constants.cPhongRimParams = Vector4D( vRimPhongParams ); + pContextData->m_Constants.cSpecExponent = Vector4D( vSpecExponent ); + } + + + + pContextData->m_SemiStaticCmdsOut.End(); + } + } + if ( pShaderAPI ) + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + pShaderAPI->GetFogParamsAndColor( pContextData->m_Constants.g_FogParams.Base(), + pContextData->m_Constants.g_FogColor.Base() ); + + if ( bHasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + bool bFlashlightShadows = false; + // DX11FIXME: Flashlight +#if 1 + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + const FlashlightState_t &state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows;// && ( pFlashlightDepthTexture != NULL ); + + if ( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER8, pFlashlightDepthTexture, 0 ); + //DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_SHADOW_NOISE_2D ); + } + + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + } +#endif + + // Set up light combo state + LightState_t lightState = { 0, false, false/*, false*/ }; + if ( bVertexLitGeneric ) + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if ( pContextData->m_bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + AssertMsg( !( bWriteDepthToAlpha && bWriteWaterFogToAlpha ), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + { + if ( bAmbientOnly ) // Override selected light combo to be ambient only + { + lightState.m_bAmbientLight = true; + lightState.m_bStaticLight = false; + lightState.m_nNumLights = 0; + } + + const bool bHasFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + if ( bHasFastVertexTextures ) + pShader->SetHWMorphVertexShaderState( pContextData->m_Constants.cMorphDimensions, + pContextData->m_Constants.cMorphSubrect, + SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs40 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) != 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, /*bHasFastVertexTextures && pShaderAPI->IsHWMorphingEnabled()*/false ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps40 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bHasFlashlight ); + //SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW, iCascadedShadowCombo ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PHONG, pContextData->m_bHasPhong ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( RIMLIGHT, pContextData->m_bHasRimLight ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRINKLEMAP, pContextData->m_bHasWrinkle ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, pContextData->m_bHasPhongWarp ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, bHasFlashlight ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps40 ); + + if ( bHasFastVertexTextures ) + { + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } + } + + if ( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() ) + { + pShader->SetModulationDynamicState_LinearColorSpace_LinearScale( pContextData->m_Constants.cModulationColor, + params[info.m_nHDRColorScale]->GetFloatValue() ); + } + else + { + pShader->SetModulationDynamicState_LinearColorSpace( pContextData->m_Constants.cModulationColor ); + } + + //float eyePos[4]; + //pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + //DynamicCmdsOut.SetPixelShaderConstant( 20, eyePos ); + + // Non-bump case does its own depth feathering work + if ( !bHasBump && !bHasDiffuseWarp ) + { + pContextData->m_Constants.cDepthFeathering[0] = GetFloatParam( info.m_nDepthBlendScale, params, 50.0f ); + } + + int fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; + int fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1 : 0; + int fWriteWaterFogToDestAlpha = ( pShaderAPI->GetPixelFogCombo() == 1 && bWriteWaterFogToAlpha ) ? 1 : 0; + int fVertexAlpha = bHasVertexAlpha ? 1 : 0; + pContextData->m_Constants.cShaderControls.Init( fPixelFogType, fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha ); + + // flashlightfixme: put this in common code. + if ( bHasFlashlight ) + { + pShader->BindTexture( SHADER_SAMPLER7, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + } + + DynamicCmdsOut.End(); + + pShader->UpdateConstantBuffer( g_hVertexLitGeneric_CBuffer, &pContextData->m_Constants ); + + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); +} + + +void DrawVertexLitGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow *pShaderShadow, bool bVertexLitGeneric, VertexLitGeneric_DX11_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr, bool bForceFlashlight ) +{ + bool bReceiveFlashlight = bVertexLitGeneric; + bool bNewFlashlight = IsX360(); + if ( bNewFlashlight ) + { + bReceiveFlashlight = bReceiveFlashlight || ( GetIntParam( info.m_nReceiveFlashlight, params ) != 0 ); + } + bool bHasFlashlight = bReceiveFlashlight && pShader->UsingFlashlight( params ) || bForceFlashlight; + + DrawVertexLitGeneric_DX11_Internal( pShader, params, pShaderAPI, + pShaderShadow, bVertexLitGeneric, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} + +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_helper.h b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_helper.h new file mode 100644 index 0000000..0ed47e4 --- /dev/null +++ b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_helper.h @@ -0,0 +1,194 @@ +//========= Copyright © 1996-2005, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VERTEXLITGENERIC_DX11_HELPER_H +#define VERTEXLITGENERIC_DX11_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Structure that defines that constants used by the shader +//----------------------------------------------------------------------------- +ALIGN16 struct VertexLitGeneric_CBuffer_t +{ + // Vertex shader + Vector4D cBaseTextureTransform[2]; + Vector4D cDetailTextureTransform[2]; + Vector4D cMorphDimensions; + Vector4D cMorphSubrect; + Vector4D cSeamlessScale; + Vector4D cModulationColor; + + // Pixel shader + Vector4D cDetailTint; + Vector4D cGlowParams; + Vector4D cGlowColor; + Vector4D cMaskRangeParams; + Vector4D cOutlineColor; + Vector4D cOutlineParams; + Vector4D cEnvMapSaturation_SelfIllumMask; + Vector4D cEnvMapTint; + Vector4D cConstScaleBiasExp; + Vector4D cEnvMapContrast; + Vector4D cSelfIllumTint; + Vector4D cDepthFeathering; + IntVector4D cShaderControls; + + // Pixel shader (phong) + Vector4D cFresnelSpecParams; + Vector4D cSpecularRimParams; + Vector4D cPhongRimParams; + Vector4D cSpecExponent; + + IntVector4D cDetailBlendMode; + + Vector4D g_FogParams; + Vector4D g_FogColor; + + float cAlphaTestRef; +}; + +extern ConstantBufferHandle_t g_hVertexLitGeneric_CBuffer; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VertexLitGeneric_DX11_Vars_t +{ + VertexLitGeneric_DX11_Vars_t() + { + memset( this, 0xFF, sizeof( *this ) ); + } + + int m_nBaseTexture; + int m_nWrinkle; + int m_nStretch; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nNormalWrinkle; + int m_nNormalStretch; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nAlphaTestReference; + int m_nVertexAlphaTest; + int m_nFlashlightNoLambert; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + + int m_nSelfIllumTint; + int m_nSelfIllumFresnel; + int m_nSelfIllumFresnelMinMaxExp; + + int m_nPhongExponent; + int m_nPhongTint; + int m_nPhongAlbedoTint; + int m_nPhongExponentTexture; + int m_nDiffuseWarpTexture; + int m_nPhongWarpTexture; + int m_nPhongBoost; + int m_nPhongExponentFactor; + int m_nPhongFresnelRanges; + int m_nSelfIllumEnvMapMask_Alpha; + int m_nAmbientOnly; + int m_nHDRColorScale; + int m_nPhong; + int m_nBaseMapAlphaPhongMask; + int m_nEnvmapFresnel; + + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + + // Rim lighting parameters + int m_nRimLight; + int m_nRimLightPower; + int m_nRimLightBoost; + int m_nRimMask; + + int m_nSeamlessScale; + int m_nSeamlessBase; + int m_nSeamlessDetail; + + // distance coded line art parameters + int m_nDistanceAlpha; + int m_nDistanceAlphaFromDetail; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + int m_nScaleEdgeSoftnessBasedOnScreenRes; + + int m_nGlow; + int m_nGlowColor; + int m_nGlowAlpha; + int m_nGlowStart; + int m_nGlowEnd; + int m_nGlowX; + int m_nGlowY; + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + int m_nScaleOutlineSoftnessBasedOnScreenRes; + + int m_nSeparateDetailUVs; + int m_nDetailTextureTransform; + + int m_nLinearWrite; + int m_nGammaColorRead; + + int m_nDetailTint; + int m_nInvertPhongMask; + + int m_nDepthBlend; + int m_nDepthBlendScale; + + int m_nSelfIllumMask; + int m_nReceiveFlashlight; + +// new -------------------------------- + + int m_nBlendTintByBaseAlpha; + + int m_nTintReplacesBaseColor; + + int m_nTwoSidedLighting; +}; + +void InitParamsVertexLitGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX11_Vars_t &info ); +void InitVertexLitGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, bool bVertexLitGeneric, VertexLitGeneric_DX11_Vars_t &info ); +void DrawVertexLitGeneric_DX11( CBaseVSShader *pShader, IMaterialVar **params, IShaderDynamicAPI *pShaderAPI, IShaderShadow *pShaderShadow, + bool bVertexLitGeneric, VertexLitGeneric_DX11_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr, bool bForceFlashlight = false +); + + +#endif // VERTEXLITGENERIC_DX11_HELPER_H diff --git a/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_shared.h b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_shared.h new file mode 100644 index 0000000..a6c2f87 --- /dev/null +++ b/materialsystem/stdshadersdx11/vertexlitgeneric_dx11_shared.h @@ -0,0 +1,44 @@ +#ifndef VERTEXLITGENERIC_DX11_SHARED_H_ +#define VERTEXLITGENERIC_DX11_SHARED_H_ + +struct VertexLitAndUnlitGeneric_t +{ + // Vertex shader + float4 cBaseTexCoordTransform[2]; + float4 cDetailTexCoordTransform[2]; + float4 cSeamlessScale; + float4 cMorphSubrect; + float4 cMorphTargetTextureDim; + float4 cModulationColor; + + // Pixel shader + float4 g_DetailTint; + float4 g_GlowParameters; + float4 g_GlowColor; + float4 g_DistanceAlphaParams; + float4 g_OutlineColor; + float4 g_OutlineParams; + float4 g_EnvmapSaturation_SelfIllumMask; + float4 g_EnvmapTint_TintReplaceFactor; + float4 g_SelfIllumScaleBiasExpBrightness; + float4 g_EnvmapContrast_ShadowTweaks; + float4 g_SelfIllumTint_and_BlendFactor; + float4 g_DepthFeatheringConstants; + int4 g_ShaderControls; + + // Pixel shader (phong) + float4 g_FresnelSpecParams; + float4 g_SpecularRimParams; + // RimBoost_RimMaskControl_BaseMapAlphaPhongMask_InvertPhongMask + float4 g_RimPhongParams; + float4 g_SpecExponent; + + int4 g_DetailBlendMode; + + float4 g_FogParams; + float4 g_FogColor; + + float g_AlphaTestRef; +}; + +#endif //#ifndef VERTEXLITGENERIC_DX11_SHARED_H_ diff --git a/materialsystem/stdshadersdx11/white_ps40.fxc b/materialsystem/stdshadersdx11/white_ps40.fxc new file mode 100644 index 0000000..ac2dfcf --- /dev/null +++ b/materialsystem/stdshadersdx11/white_ps40.fxc @@ -0,0 +1,11 @@ +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 projPos : SV_POSITION; +}; + +float4 main( PS_INPUT i ) : SV_TARGET +{ + return FinalOutput( float4( 1.0f, 1.0f, 1.0f, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, float4(0, 0, 0, 1), TONEMAP_SCALE_NONE ); +} diff --git a/materialsystem/stdshadersdx11/wireframe_dx11.cpp b/materialsystem/stdshadersdx11/wireframe_dx11.cpp new file mode 100644 index 0000000..6ea2217 --- /dev/null +++ b/materialsystem/stdshadersdx11/wireframe_dx11.cpp @@ -0,0 +1,70 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#if 1 +#include "shaderlib_dx11/cshader.h" + +#include "wireframe_vs40.inc" +#include "wireframe_ps40.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef _WIN32 +DEFINE_FALLBACK_SHADER(Wireframe, Wireframe_DX11) +BEGIN_SHADER( Wireframe_DX11, + "Help for Wireframe_DX11" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + LoadTexture( BASETEXTURE ); + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_LINE ); + pShaderShadow->EnableCulling( false ); + + VertexFormat_t format = VERTEX_POSITION | VERTEX_COLOR; + int dimensions[] = { 2 }; + pShaderShadow->VertexShaderVertexFormat( format, 1, dimensions, 0 ); + + SetInternalVertexShaderConstantBuffersNoSkinning(); + + DECLARE_STATIC_VERTEX_SHADER( wireframe_vs40 ); + SET_STATIC_VERTEX_SHADER( wireframe_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( wireframe_ps40 ); + SET_STATIC_PIXEL_SHADER( wireframe_ps40 ); + } + DYNAMIC_STATE + { + + DECLARE_DYNAMIC_VERTEX_SHADER( wireframe_vs40 ); + SET_DYNAMIC_VERTEX_SHADER( wireframe_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( wireframe_ps40 ); + SET_DYNAMIC_PIXEL_SHADER( wireframe_ps40 ); + } + Draw(); + } +END_SHADER +#endif + +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/wireframe_ps40.fxc b/materialsystem/stdshadersdx11/wireframe_ps40.fxc new file mode 100644 index 0000000..5938727 --- /dev/null +++ b/materialsystem/stdshadersdx11/wireframe_ps40.fxc @@ -0,0 +1,12 @@ +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 vPos : SV_POSITION; + float4 vColor : COLOR; +}; + +float4 main(PS_INPUT i) : SV_TARGET +{ + return i.vColor; +} \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/wireframe_vs40.fxc b/materialsystem/stdshadersdx11/wireframe_vs40.fxc new file mode 100644 index 0000000..daf4416 --- /dev/null +++ b/materialsystem/stdshadersdx11/wireframe_vs40.fxc @@ -0,0 +1,27 @@ +#include "common_cbuffers_fxc.h" +CBUFFER_PERMODEL(register(b0)) // model matrix +CBUFFER_PERFRAME(register(b1)) // view matrix +CBUFFER_PERSCENE(register(b2)) // proj matrix + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vColor : COLOR; +}; + +struct VS_OUTPUT +{ + float4 vPos : SV_POSITION; + float4 vColor : COLOR; +}; + +VS_OUTPUT main( VS_INPUT i ) +{ + VS_OUTPUT o = (VS_OUTPUT)0; + o.vPos = ComputeProjPos(i.vPos.xyz, cModelMatrix, cViewMatrix, cProjMatrix); + o.vColor = i.vColor; + + return o; +} \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/worldvertextransition.cpp b/materialsystem/stdshadersdx11/worldvertextransition.cpp new file mode 100644 index 0000000..4199e2c --- /dev/null +++ b/materialsystem/stdshadersdx11/worldvertextransition.cpp @@ -0,0 +1,150 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#if 1 + +#include "BaseVSShader.h" +#include "convar.h" + +#include "lightmappedgeneric_dx11_helper.h" + +static LightmappedGeneric_DX11_Vars_t s_info; + + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX11 ) + +BEGIN_VS_SHADER( WorldVertexTransition_DX11, "Help for WorldVertexTransition" ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) +SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) +SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) +SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) +SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + +// detail (multi-) texturing +SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) +SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) +SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + +SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) +SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) +SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) +SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) +SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) +SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) +SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) +SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) +SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) +SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) +SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) +SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) +SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) +SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) +SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) +SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) +SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) +SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) +SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) +SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) +SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) +SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + + END_SHADER_PARAMS + +void SetupVars( LightmappedGeneric_DX11_Vars_t &info ) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = -1; + + info.m_nPhong = PHONG; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhongExponent = PHONGEXPONENT; +} + +SHADER_FALLBACK +{ + return 0; +} + +SHADER_INIT_PARAMS() +{ + SetupVars( s_info ); + InitParamsLightmappedGeneric_DX11( this, params, pMaterialName, s_info ); +} + +SHADER_INIT +{ + SetupVars( s_info ); + InitLightmappedGeneric_DX11( this, params, s_info ); +} + +SHADER_DRAW +{ + + DrawLightmappedGeneric_DX11( this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr ); +} + END_SHADER + +#endif \ No newline at end of file diff --git a/materialsystem/stdshadersdx11/writez_dx11.cpp b/materialsystem/stdshadersdx11/writez_dx11.cpp new file mode 100644 index 0000000..a9a1e99 --- /dev/null +++ b/materialsystem/stdshadersdx11/writez_dx11.cpp @@ -0,0 +1,70 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#if 0 +#include "BaseVSShader.h" + + +#include "writez_vs40.inc" +#include "white_ps40.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WriteZ, WriteZ_DX11 ) + +BEGIN_VS_SHADER_FLAGS( WriteZ_DX11, "Help for WriteZ", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableColorWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + SetInternalVertexShaderConstantBuffersNoSkinning(); + + DECLARE_STATIC_VERTEX_SHADER( writez_vs40 ); + SET_STATIC_VERTEX_SHADER( writez_vs40 ); + + DECLARE_STATIC_PIXEL_SHADER( white_ps40 ); + SET_STATIC_PIXEL_SHADER( white_ps40 ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + } + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( writez_vs40 ); + SET_DYNAMIC_VERTEX_SHADER( writez_vs40 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( white_ps40 ); + SET_DYNAMIC_PIXEL_SHADER( white_ps40 ); + + } + Draw(); + } +END_SHADER +#endif diff --git a/materialsystem/stdshadersdx11/writez_vs40.fxc b/materialsystem/stdshadersdx11/writez_vs40.fxc new file mode 100644 index 0000000..7e9856d --- /dev/null +++ b/materialsystem/stdshadersdx11/writez_vs40.fxc @@ -0,0 +1,26 @@ +#include "common_vs_fxc.h" +#include "common_cbuffers_fxc.h" + +CBUFFER_PERMODEL(register(b0)) +CBUFFER_PERFRAME(register(b1)) +CBUFFER_PERSCENE(register(b2)) + +struct VS_INPUT +{ + float4 vPos : POSITION; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : SV_POSITION; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.vProjPos = ComputeProjPos( v.vPos.xyz, cModelMatrix, cViewMatrix, cProjMatrix ); + + return o; +} \ No newline at end of file diff --git a/public/materialsystem/IShader.h b/public/materialsystem/IShader.h index 7815e8a..5d6f10b 100644 --- a/public/materialsystem/IShader.h +++ b/public/materialsystem/IShader.h @@ -102,4 +102,10 @@ public: // virtual const ShaderParamInfo_t& GetParamInfo( int paramIndex ) const = 0; }; +abstract_class IShaderDX11 : public IShader +{ +public: + virtual void InitShader(IShaderDevice* pShaderDevice) = 0; +}; + #endif // ISHADER_H diff --git a/public/materialsystem/imesh.h b/public/materialsystem/imesh.h index 3da443b..288ad3f 100644 --- a/public/materialsystem/imesh.h +++ b/public/materialsystem/imesh.h @@ -55,8 +55,14 @@ enum // Internal maximums for sizes. Don't use directly, use IMaterialSystem::GetMaxToRender() enum { - INDEX_BUFFER_SIZE = 32768, - DYNAMIC_VERTEX_BUFFER_MEMORY = ( 1024 + 512 ) * 1024, + // DX11FIXME +#ifdef DX11 + INDEX_BUFFER_SIZE = 32768 * 2, + DYNAMIC_VERTEX_BUFFER_MEMORY = ( 1024 + 512 ) * 1024 * 2, +#else + INDEX_BUFFER_SIZE = 32768, + DYNAMIC_VERTEX_BUFFER_MEMORY = (1024 + 512) * 1024, +#endif DYNAMIC_VERTEX_BUFFER_MEMORY_SMALL = 384 * 1024, // Only allocate this much during map transitions }; diff --git a/public/materialsystem/ishadersystem_declarations.h b/public/materialsystem/ishadersystem_declarations.h index 3c54edc..a588a5c 100644 --- a/public/materialsystem/ishadersystem_declarations.h +++ b/public/materialsystem/ishadersystem_declarations.h @@ -116,7 +116,6 @@ enum PrecompiledShaderType_t PRECOMPILED_SHADER_TYPE_COUNT, }; - //----------------------------------------------------------------------------- // Flags field of PrecompiledShader_t //----------------------------------------------------------------------------- @@ -125,6 +124,7 @@ enum // runtime flags SHADER_IS_ASM = 0x1, SHADER_FAILED_LOAD = 0x2, + SHADER_DYNAMIC_COMPILE_IS_HLSL = 0x4, }; diff --git a/public/shaderapi/IShaderDevice.h b/public/shaderapi/IShaderDevice.h index 832e6ac..fc9d58e 100644 --- a/public/shaderapi/IShaderDevice.h +++ b/public/shaderapi/IShaderDevice.h @@ -116,10 +116,12 @@ inline bool IsDynamicBufferType( ShaderBufferType_t type ) DECLARE_POINTER_HANDLE( VertexShaderHandle_t ); DECLARE_POINTER_HANDLE( GeometryShaderHandle_t ); DECLARE_POINTER_HANDLE( PixelShaderHandle_t ); +DECLARE_POINTER_HANDLE( ConstantBufferHandle_t ); #define VERTEX_SHADER_HANDLE_INVALID ( (VertexShaderHandle_t)0 ) #define GEOMETRY_SHADER_HANDLE_INVALID ( (GeometryShaderHandle_t)0 ) #define PIXEL_SHADER_HANDLE_INVALID ( (PixelShaderHandle_t)0 ) +#define CONSTANT_BUFFER_HANDLE_INVALID ( (ConstantBufferHandle_t)0 ) //----------------------------------------------------------------------------- @@ -275,6 +277,15 @@ public: }; +abstract_class IShaderDeviceDX11 : public IShaderDevice +{ +public: + virtual ConstantBufferHandle_t CreateConstantBuffer(size_t nBufSize) = 0; + virtual void UpdateConstantBuffer(ConstantBufferHandle_t hBuffer, void* pData) = 0; + virtual void UploadConstantBuffers(ConstantBufferHandle_t* pBuffers, int nBuffers) = 0; + virtual void DestroyConstantBuffer(ConstantBufferHandle_t hBuffer) = 0; + virtual ConstantBufferHandle_t GetInternalConstantBuffer(int type) = 0; +}; //----------------------------------------------------------------------------- // Helper wrapper for IShaderBuffer for reading precompiled shader files diff --git a/public/shaderapi/ishaderapi.h b/public/shaderapi/ishaderapi.h index 1a90cae..6381066 100644 --- a/public/shaderapi/ishaderapi.h +++ b/public/shaderapi/ishaderapi.h @@ -620,5 +620,12 @@ public: virtual void UnlockRect( ShaderAPITextureHandle_t texHandle, int mipmap ) = 0; }; +abstract_class IShaderAPIDX11 : public IShaderAPI +{ +public: + virtual void UpdateConstantBuffer(ConstantBufferHandle_t cbuffer, void* pNewData) = 0; + virtual ConstantBufferHandle_t GetInternalConstantBuffer(int type) = 0; +}; + #endif // ISHADERAPI_H diff --git a/public/shaderapi/ishaderconstantbuffer.h b/public/shaderapi/ishaderconstantbuffer.h new file mode 100644 index 0000000..01233e9 --- /dev/null +++ b/public/shaderapi/ishaderconstantbuffer.h @@ -0,0 +1,20 @@ +#pragma once + +#include "IShaderDevice.h" + +class IShaderConstantBuffer +{ +public: + virtual void Create( size_t nBufferSize, bool bDynamic = true ) = 0; + virtual void Update( void *pNewData ) = 0; + virtual void Destroy() = 0; + + virtual ConstantBufferHandle_t GetBuffer() const = 0; + + // Do we need to update the data to the graphics card? + virtual bool NeedsUpdate() const = 0; + + virtual void UploadToGPU() = 0; + + //virtual void Bind() = 0; +}; \ No newline at end of file diff --git a/public/shaderapi/ishadershadow.h b/public/shaderapi/ishadershadow.h index 170988f..92c4abc 100644 --- a/public/shaderapi/ishadershadow.h +++ b/public/shaderapi/ishadershadow.h @@ -14,6 +14,7 @@ #endif #include "shaderapi/shareddefs.h" +#include "shaderapi/IShaderDevice.h" #include @@ -232,6 +233,15 @@ enum PolygonOffsetMode_t SHADER_POLYOFFSET_RESERVED = 0x3 // Reserved for future use }; +enum ShaderInternalConstantBuffer_t +{ + SHADER_CONSTANTBUFFER_PERFRAME, + SHADER_CONSTANTBUFFER_PERMODEL, + SHADER_CONSTANTBUFFER_PERSCENE, + SHADER_CONSTANTBUFFER_SKINNING, + SHADER_CONSTANTBUFFER_FLEX, +}; + //----------------------------------------------------------------------------- // The Shader interface versions @@ -363,6 +373,16 @@ public: }; // end class IShaderShadow +abstract_class IShaderShadowDX11 : public IShaderShadow +{ +public: + virtual void SetVertexShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer) = 0; + virtual void SetGeometryShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer) = 0; + virtual void SetPixelShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer) = 0; + virtual void SetVertexShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer) = 0; + virtual void SetGeometryShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer) = 0; + virtual void SetPixelShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer) = 0; +}; #endif // ISHADERSHADOW_H diff --git a/public/shaderapi/shareddefs.h b/public/shaderapi/shareddefs.h index 663fbfa..7b0a191 100644 --- a/public/shaderapi/shareddefs.h +++ b/public/shaderapi/shareddefs.h @@ -95,6 +95,7 @@ enum VertexTextureSampler_t SHADER_VERTEXTEXTURE_SAMPLER3, }; +typedef int ShaderIndex_t; #if defined( _X360 ) #define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in materialsystem/stdshaders/common_fxc.h diff --git a/public/shaderlib_dx11/BaseShader.h b/public/shaderlib_dx11/BaseShader.h new file mode 100644 index 0000000..390f2ba --- /dev/null +++ b/public/shaderlib_dx11/BaseShader.h @@ -0,0 +1,353 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all shaders inherit from. +//===========================================================================// + +#ifndef BASESHADER_H +#define BASESHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "materialsystem/IShader.h" +#include "materialsystem/imaterialvar.h" +#include "materialsystem/ishaderapi.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "shaderapi/ishaderapi.h" +#include "shaderlib/BaseShader.h" +#include "convar.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class IMaterialVar; + +//----------------------------------------------------------------------------- +// Standard material vars +//----------------------------------------------------------------------------- +// Note: if you add to these, add to s_StandardParams in CBaseShader.cpp +enum ShaderMaterialVars_t +{ + FLAGS = 0, + FLAGS_DEFINED, // mask indicating if the flag was specified + FLAGS2, + FLAGS_DEFINED2, + COLOR, + ALPHA, + BASETEXTURE, + FRAME, + BASETEXTURETRANSFORM, + FLASHLIGHTTEXTURE, + FLASHLIGHTTEXTUREFRAME, + COLOR2, + SRGBTINT, + + NUM_SHADER_MATERIAL_VARS +}; + + +// Alpha belnd mode enums. Moved from basevsshader +enum BlendType_t +{ + // no alpha blending + BT_NONE = 0, + + + + // src * srcAlpha + dst * (1-srcAlpha) + // two passes for HDR: + // pass 1: + // color: src * srcAlpha + dst * (1-srcAlpha) + // alpha: srcAlpha * zero + dstAlpha * (1-srcAlpha) + // pass 2: + // color: none + // alpha: srcAlpha * one + dstAlpha * one + // + BT_BLEND, + + + + // src * one + dst * one + // one pass for HDR + BT_ADD, + + + + // Why do we ever use this instead of using premultiplied alpha? + // src * srcAlpha + dst * one + // two passes for HDR + // pass 1: + // color: src * srcAlpha + dst * one + // alpha: srcAlpha * one + dstAlpha * one + // pass 2: + // color: none + // alpha: srcAlpha * one + dstAlpha * one + BT_BLENDADD +}; + + +//----------------------------------------------------------------------------- +// Base class for shaders, contains helper methods. +//----------------------------------------------------------------------------- +class CBaseShader : public IShaderDX11 +{ +public: + // constructor + CBaseShader(); + + // Methods inherited from IShader + virtual char const* GetFallbackShader( IMaterialVar** params ) const { return 0; } + virtual int GetNumParams( ) const; + virtual char const* GetParamName( int paramIndex ) const; + virtual char const* GetParamHelp( int paramIndex ) const; + virtual ShaderParamType_t GetParamType( int paramIndex ) const; + virtual char const* GetParamDefault( int paramIndex ) const; + virtual int GetParamFlags( int nParamIndex ) const; + + virtual void InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ); + virtual void InitShader(IShaderDevice* pShaderDevice); + virtual void InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName ); + virtual void DrawElements( IMaterialVar **params, int nModulationFlags, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, + VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContext ); + + virtual const SoftwareVertexShader_t GetSoftwareVertexShader() const { return m_SoftwareVertexShader; } + + virtual int ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI ); + virtual bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame = true ) const; + virtual bool NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame = true ) const; + virtual bool IsTranslucent( IMaterialVar **params ) const; + +public: + // These functions must be implemented by the shader + virtual void OnInitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ) {} + virtual void OnInitShader(IShaderDevice* pShaderDevice) {} + virtual void OnInitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName ) = 0; + virtual void OnDrawElements( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) = 0; + + // Sets the default shadow state + void SetInitialShadowState( ); + + // Draws a snapshot + void Draw( bool bMakeActualDrawCall = true ); + + // Are we currently taking a snapshot? + bool IsSnapshotting() const; + + // Gets at the current materialvar flags + int CurrentMaterialVarFlags() const; + + // Finds a particular parameter (works because the lowest parameters match the shader) + int FindParamIndex( const char *pName ) const; + + // Are we using graphics? + bool IsUsingGraphics(); + + // Are we using editor materials? + bool CanUseEditorMaterials(); + + // Gets the builder... + CMeshBuilder* MeshBuilder(); + + // Loads a texture + void LoadTexture( int nTextureVar, int nAdditionalCreationFlags = 0 ); + + // Loads a bumpmap + void LoadBumpMap( int nTextureVar ); + + // Loads a cubemap + void LoadCubeMap( int nTextureVar, int nAdditionalCreationFlags = 0 ); + + // get the shaderapi handle for a texture. BE CAREFUL WITH THIS. + ShaderAPITextureHandle_t GetShaderAPITextureBindHandle( int nTextureVar, int nFrameVar, int nTextureChannel = 0 ); + + + // Binds a texture + void BindTexture( Sampler_t sampler1, Sampler_t sampler2, int nTextureVar, int nFrameVar = -1 ); + void BindTexture( Sampler_t sampler1, int nTextureVar, int nFrameVar = -1 ); + void BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrame = 0 ); + void BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrame = 0 ); + + void GetTextureDimensions( float* pOutWidth, float* pOutHeight, int nTextureVar ); + + // Is the texture translucent? + bool TextureIsTranslucent( int textureVar, bool isBaseTexture ); + + // Returns the translucency... + float GetAlpha( IMaterialVar** params = NULL ); + + // Is the color var white? + bool IsWhite( int colorVar ); + + // Helper methods for fog + void FogToOOOverbright( void ); + void FogToWhite( void ); + void FogToBlack( void ); + void FogToGrey( void ); + void FogToFogColor( void ); + void DisableFog( void ); + void DefaultFog( void ); + + // Helpers for alpha blending + void EnableAlphaBlending( ShaderBlendFactor_t src, ShaderBlendFactor_t dst ); + void DisableAlphaBlending(); + + void SetBlendingShadowState( BlendType_t nMode ); + + void SetNormalBlendingShadowState( int textureVar = -1, bool isBaseTexture = true ); + void SetAdditiveBlendingShadowState( int textureVar = -1, bool isBaseTexture = true ); + void SetDefaultBlendingShadowState( int textureVar = -1, bool isBaseTexture = true ); + void SingleTextureLightmapBlendMode( ); + + virtual void SetInternalVertexShaderConstantBuffers(); + virtual void SetInternalVertexShaderConstantBuffersNoSkinning(); + virtual void SetInternalPixelShaderConstantBuffers(); + virtual void SetPixelShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer); + virtual void SetVertexShaderConstantBuffer(int slot, ConstantBufferHandle_t cbuffer); + virtual void SetPixelShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer); + virtual void SetVertexShaderConstantBuffer(int slot, ShaderInternalConstantBuffer_t cbuffer); + virtual void UpdateConstantBuffer(ConstantBufferHandle_t cbuffer, void* pNewData); + + // Helpers for color modulation + void SetColorState( int colorVar, bool setAlpha = false ); + bool IsAlphaModulating(); + bool IsColorModulating(); + void ComputeModulationColor( float* color ); + void SetModulationShadowState( int tintVar = -1 ); + void SetModulationDynamicState( int tintVar = -1 ); + + // Helpers for HDR + bool IsHDREnabled( void ); + + // Loads the identity matrix into the texture + void LoadIdentity( MaterialMatrixMode_t matrixMode ); + + // Loads the camera to world transform + void LoadCameraToWorldTransform( MaterialMatrixMode_t matrixMode ); + void LoadCameraSpaceSphereMapTransform( MaterialMatrixMode_t matrixMode ); + + // Sets a texture translation transform in fixed function + void SetFixedFunctionTextureTranslation( MaterialMatrixMode_t mode, int translationVar ); + void SetFixedFunctionTextureScale( MaterialMatrixMode_t mode, int scaleVar ); + void SetFixedFunctionTextureScaledTransform( MaterialMatrixMode_t textureTransform, int transformVar, int scaleVar ); + void SetFixedFunctionTextureTransform( MaterialMatrixMode_t textureTransform, int transformVar ); + + void CleanupDynamicStateFixedFunction( ); + + // Fixed function Base * detail pass + void FixedFunctionBaseTimesDetailPass( int baseTextureVar, int frameVar, + int baseTextureTransformVar, int detailVar, int detailScaleVar ); + + // Fixed function Self illumination pass + void FixedFunctionSelfIlluminationPass( Sampler_t sampler, + int baseTextureVar, int frameVar, int baseTextureTransformVar, int selfIllumTintVar ); + + // Masked environment map + void FixedFunctionMaskedEnvmapPass( int envMapVar, int envMapMaskVar, + int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, + int frameVar, int maskOffsetVar, int maskScaleVar, int tintVar = -1 ); + + // Additive masked environment map + void FixedFunctionAdditiveMaskedEnvmapPass( int envMapVar, int envMapMaskVar, + int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, + int frameVar, int maskOffsetVar, int maskScaleVar, int tintVar = -1 ); + + // Modulate by detail texture pass + void FixedFunctionMultiplyByDetailPass( int baseTextureVar, int frameVar, + int textureOffsetVar, int detailVar, int detailScaleVar ); + + // Multiply by lightmap pass + void FixedFunctionMultiplyByLightmapPass( int baseTextureVar, int frameVar, + int baseTextureTransformVar, float alphaOverride = -1 ); + + // Helper methods for environment mapping + int SetShadowEnvMappingState( int envMapMaskVar, int tintVar = -1 ); + void SetDynamicEnvMappingState( int envMapVar, int envMapMaskVar, + int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, + int frameVar, int maskOffsetVar, int maskScaleVar, int tintVar = -1 ); + + bool UsingFlashlight( IMaterialVar **params ) const; + bool UsingEditor( IMaterialVar **params ) const; + + void DrawFlashlight_dx70( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + int flashlightTextureVar, int flashlightTextureFrameVar, + bool suppress_lighting = false ); + + void SetFlashlightFixedFunctionTextureTransform( MaterialMatrixMode_t matrix ); + + void GetColorParameter( IMaterialVar** params, float *pColorOut ) const; // return tint color (color*color2) + void ApplyColor2Factor( float *pColorOut ) const; // (*pColorOut) *= COLOR2 + + static IMaterialVar **s_ppParams; + +protected: + SoftwareVertexShader_t m_SoftwareVertexShader; + + static const char *s_pTextureGroupName; // Current material's texture group name. + static IShaderShadowDX11 *s_pShaderShadow; + static IShaderAPIDX11 *s_pShaderAPI; + static IShaderInit *s_pShaderInit; + +private: + static int s_nModulationFlags; + static CMeshBuilder *s_pMeshBuilder; +}; + + +//----------------------------------------------------------------------------- +// Gets at the current materialvar flags +//----------------------------------------------------------------------------- +inline int CBaseShader::CurrentMaterialVarFlags() const +{ + return s_ppParams[FLAGS]->GetIntValue(); +} + +//----------------------------------------------------------------------------- +// Are we currently taking a snapshot? +//----------------------------------------------------------------------------- +inline bool CBaseShader::IsSnapshotting() const +{ + return (s_pShaderShadow != NULL); +} + +//----------------------------------------------------------------------------- +// Is the color var white? +//----------------------------------------------------------------------------- +inline bool CBaseShader::IsWhite( int colorVar ) +{ + if (colorVar < 0) + return true; + + if (!s_ppParams[colorVar]->IsDefined()) + return true; + + float color[3]; + s_ppParams[colorVar]->GetVecValue( color, 3 ); + return (color[0] >= 1.0f) && (color[1] >= 1.0f) && (color[2] >= 1.0f); +} + + +class CBasePerMaterialContextData // shaders can keep per material data in classes descended from this +{ + public: + uint32 m_nVarChangeID; + bool m_bMaterialVarsChanged; // set by mat system when material vars change. shader should rehtink and then clear the var + + FORCEINLINE CBasePerMaterialContextData( void ) + { + m_bMaterialVarsChanged = true; + m_nVarChangeID = 0xffffffff; + } + + // virtual destructor so that derived classes can have their own data to be cleaned up on + // delete of material + virtual ~CBasePerMaterialContextData( void ) + { + } +}; + +#endif // BASESHADER_H diff --git a/public/shaderlib_dx11/ShaderDLL.h b/public/shaderlib_dx11/ShaderDLL.h new file mode 100644 index 0000000..69520d9 --- /dev/null +++ b/public/shaderlib_dx11/ShaderDLL.h @@ -0,0 +1,49 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef SHADERDLL_H +#define SHADERDLL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IShader; +class ICvar; + +//----------------------------------------------------------------------------- +// The standard implementation of CShaderDLL +//----------------------------------------------------------------------------- +class IShaderDLL +{ +public: + // Adds a shader to the list of shaders + virtual void InsertShader( IShader *pShader ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Singleton interface +//----------------------------------------------------------------------------- +IShaderDLL *GetShaderDLL(); + +//----------------------------------------------------------------------------- +// Singleton interface for CVars +//----------------------------------------------------------------------------- +ICvar *GetCVar(); + + + + + +#endif // SHADERDLL_H diff --git a/public/shaderlib_dx11/cshader.h b/public/shaderlib_dx11/cshader.h new file mode 100644 index 0000000..5f05e38 --- /dev/null +++ b/public/shaderlib_dx11/cshader.h @@ -0,0 +1,499 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef CSHADER_H +#define CSHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +// uncomment this if you want to build for nv3x +//#define NV3X 1 + +// This is what all shaders include. +// CBaseShader will become CShader in this file. +#include "materialsystem/ishaderapi.h" +#include "utlvector.h" +#include "materialsystem/imaterialvar.h" +#include "materialsystem/imaterial.h" +#include "BaseShader.h" + +#include "materialsystem/itexture.h" + +// Included for convenience because they are used in a bunch of shaders +#include "materialsystem/imesh.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "materialsystem/materialsystem_config.h" +#include "shaderlib/ShaderDLL.h" + +// make "local variable is initialized but not referenced" warnings errors for combo checking macros +#pragma warning ( error : 4189 ) + +//----------------------------------------------------------------------------- +// Global interfaces +//----------------------------------------------------------------------------- +extern IMaterialSystemHardwareConfig *g_pHardwareConfig; +extern const MaterialSystem_Config_t *g_pConfig; +extern bool g_shaderConfigDumpEnable; + +// Helper method +bool IsUsingGraphics(); + +#define SOFTWARE_VERTEX_SHADER(name) \ + static void SoftwareVertexShader_ ## name( CMeshBuilder &meshBuilder, IMaterialVar **params, IShaderDynamicAPI* pShaderAPI ) + +#define FORWARD_DECLARE_SOFTWARE_VERTEX_SHADER(name)\ + static void SoftwareVertexShader_ ## name( CMeshBuilder &meshBuilder, IMaterialVar **params, IShaderDynamicAPI* pShaderAPI ); + +#define USE_SOFTWARE_VERTEX_SHADER(name) \ + m_SoftwareVertexShader = SoftwareVertexShader_ ## name + +#define SHADER_INIT_PARAMS() \ + virtual void OnInitShaderParams( IMaterialVar **params, const char *pMaterialName ) + +#define SHADER_FALLBACK \ + virtual char const* GetFallbackShader( IMaterialVar** params ) const + +#define CONSTANT_BUFFER_TYPE(name) name##_CBuffer_t +#define CREATE_CONSTANT_BUFFER(name) ALIGN16 struct name##_CBuffer_t +#define DECLARE_CONSTANT_BUFFER(name) ConstantBufferHandle_t m_CB##name; +#define CONSTANT_BUFFER(name) m_CB##name +#define INIT_CONSTANT_BUFFER(name) m_CB##name = pShaderDevice->CreateConstantBuffer(sizeof( name##_CBuffer_t )) +#define UPDATE_CONSTANT_BUFFER(name, newData) UpdateConstantBuffer( m_CB##name, &newData ) + +// Typesafe flag setting +inline void CShader_SetFlags( IMaterialVar **params, MaterialVarFlags_t _flag ) +{ + params[FLAGS]->SetIntValue( params[FLAGS]->GetIntValue() | (_flag) ); +} + +inline bool CShader_IsFlagSet( IMaterialVar **params, MaterialVarFlags_t _flag ) +{ + return ((params[FLAGS]->GetIntValue() & (_flag) ) != 0); +} + +#define SET_FLAGS( _flag ) CShader_SetFlags( params, _flag ) +#define CLEAR_FLAGS( _flag ) params[FLAGS]->SetIntValue( params[FLAGS]->GetIntValue() & ~(_flag) ) +#define IS_FLAG_SET( _flag ) CShader_IsFlagSet( params, _flag ) +#define IS_FLAG_DEFINED( _flag ) ((params[FLAGS_DEFINED]->GetIntValue() & (_flag) ) != 0) + +#define IS_PARAM_DEFINED( _param ) ( ( ( _param >= 0 ) && ( params[_param]->IsDefined() ) ) ) + +#define SET_PARAM_STRING_IF_NOT_DEFINED( nParamIndex, kDefaultValue ) \ + if ( ( nParamIndex != -1 ) && ( !params[nParamIndex]->IsDefined() ) ) \ + { \ + params[nParamIndex]->SetStringValue( kDefaultValue ); \ + } + +#define SET_PARAM_INT_IF_NOT_DEFINED( nParamIndex, kDefaultValue ) \ + if ( ( nParamIndex != -1 ) && ( !params[nParamIndex]->IsDefined() ) ) \ + { \ + params[nParamIndex]->SetIntValue( kDefaultValue ); \ + } + +#define SET_PARAM_FLOAT_IF_NOT_DEFINED( nParamIndex, kDefaultValue ) \ + if ( ( nParamIndex != -1 ) && ( !params[nParamIndex]->IsDefined() ) ) \ + { \ + params[nParamIndex]->SetFloatValue( kDefaultValue ); \ + } + +#define SET_PARAM_VEC_IF_NOT_DEFINED( nParamIndex, kDefaultValue, nSize ) \ + if ( ( nParamIndex != -1 ) && ( !params[nParamIndex]->IsDefined() ) ) \ + { \ + params[nParamIndex]->SetVecValue( kDefaultValue, nSize ); \ + } + +// Typesafe flag setting +inline void CShader_SetFlags2( IMaterialVar **params, MaterialVarFlags2_t _flag ) +{ + params[FLAGS2]->SetIntValue( params[FLAGS2]->GetIntValue() | (_flag) ); +} + +inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag ) +{ + return ((params[FLAGS2]->GetIntValue() & (_flag) ) != 0); +} + +#define SET_FLAGS2( _flag ) CShader_SetFlags2( params, _flag ) +#define CLEAR_FLAGS2( _flag ) params[FLAGS2]->SetIntValue( params[FLAGS2]->GetIntValue() & ~(_flag) ) +#define IS_FLAG2_SET( _flag ) CShader_IsFlag2Set( params, _flag ) +#define IS_FLAG2_DEFINED( _flag ) ((params[FLAGS_DEFINED2]->GetIntValue() & (_flag) ) != 0) + +#define __BEGIN_SHADER_INTERNAL(_baseclass, name, help, flags) \ + namespace name \ + {\ + typedef _baseclass CBaseClass;\ + static const char *s_HelpString = help; \ + static const char *s_Name = #name; \ + static int s_nFlags = flags; \ + class CShaderParam;\ + static CUtlVector s_ShaderParams;\ + static CShaderParam *s_pShaderParamOverrides[NUM_SHADER_MATERIAL_VARS];\ + class CShaderParam\ + {\ + public:\ + CShaderParam( ShaderMaterialVars_t var, ShaderParamType_t type, const char *pDefaultParam, const char *pHelp, int nFlags )\ + {\ + m_Info.m_pName = "override";\ + m_Info.m_Type = type;\ + m_Info.m_pDefaultValue = pDefaultParam;\ + m_Info.m_pHelp = pHelp;\ + m_Info.m_nFlags = nFlags;\ + AssertMsg( !s_pShaderParamOverrides[var], ( "Shader parameter override duplicately defined!" ) );\ + s_pShaderParamOverrides[var] = this;\ + m_Index = var;\ + }\ + CShaderParam( const char *pName, ShaderParamType_t type, const char *pDefaultParam, const char *pHelp, int nFlags )\ + {\ + m_Info.m_pName = pName;\ + m_Info.m_Type = type;\ + m_Info.m_pDefaultValue = pDefaultParam;\ + m_Info.m_pHelp = pHelp;\ + m_Info.m_nFlags = nFlags;\ + m_Index = NUM_SHADER_MATERIAL_VARS + s_ShaderParams.Count();\ + s_ShaderParams.AddToTail( this );\ + }\ + operator int() \ + {\ + return m_Index;\ + }\ + const char *GetName()\ + {\ + return m_Info.m_pName;\ + }\ + ShaderParamType_t GetType()\ + {\ + return m_Info.m_Type;\ + }\ + const char *GetDefault()\ + {\ + return m_Info.m_pDefaultValue;\ + }\ + int GetFlags() const\ + {\ + return m_Info.m_nFlags;\ + }\ + const char *GetHelp()\ + {\ + return m_Info.m_pHelp;\ + }\ + private:\ + ShaderParamInfo_t m_Info; \ + int m_Index;\ + };\ + +#define BEGIN_SHADER(name,help) __BEGIN_SHADER_INTERNAL( CBaseShader, name, help, 0 ) +#define BEGIN_SHADER_FLAGS(name,help,flags) __BEGIN_SHADER_INTERNAL( CBaseShader, name, help, flags ) + +#define BEGIN_SHADER_PARAMS + +#define SHADER_PARAM( param, paramtype, paramdefault, paramhelp ) \ + static CShaderParam param( "$" #param, paramtype, paramdefault, paramhelp, 0 ); + +#define SHADER_PARAM_FLAGS( param, paramtype, paramdefault, paramhelp, flags ) \ + static CShaderParam param( "$" #param, paramtype, paramdefault, paramhelp, flags ); + +#define SHADER_PARAM_OVERRIDE( param, paramtype, paramdefault, paramhelp, flags ) \ + static CShaderParam param( (ShaderMaterialVars_t) ::param, paramtype, paramdefault, paramhelp, flags ); + + // regarding the macro above: the "::" was added to the first argument in order to disambiguate it for GCC. + // for example, in cloak.cpp, this usage appears: + // SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + // which in turn tries to ask the compiler to instantiate an object like so: + // static CShaderParam COLOR( (ShaderMaterialVars_t)COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + // and GCC thinks that the reference to COLOR in the arg list is actually a reference to the object we're in the middle of making. + // and you get --> error: invalid cast from type ‘Cloak_DX90::CShaderParam’ to type ‘ShaderMaterialVars_t’ + // Resolved: add the "::" so compiler knows that reference is to the enum, not to the name of the object being made. + + +#define END_SHADER_PARAMS \ + class CShader : public CBaseClass\ + {\ + public: + +#define END_SHADER }; \ + static CShader s_ShaderInstance;\ +} // namespace + + +#define SHADER_INIT \ + char const* GetName() const \ + { \ + return s_Name; \ + } \ + int GetFlags() const \ + { \ + return s_nFlags; \ + } \ + int GetNumParams() const \ + {\ + return CBaseClass::GetNumParams() + s_ShaderParams.Count();\ + }\ + char const* GetParamName( int param ) const \ + {\ + int nBaseClassParamCount = CBaseClass::GetNumParams(); \ + if (param < nBaseClassParamCount) \ + return CBaseClass::GetParamName(param); \ + else \ + return s_ShaderParams[param - nBaseClassParamCount]->GetName(); \ + }\ + char const* GetParamHelp( int param ) const \ + {\ + int nBaseClassParamCount = CBaseClass::GetNumParams(); \ + if (param < nBaseClassParamCount) \ + { \ + if ( !s_pShaderParamOverrides[param] ) \ + return CBaseClass::GetParamHelp( param ); \ + else \ + return s_pShaderParamOverrides[param]->GetHelp(); \ + } \ + else \ + return s_ShaderParams[param - nBaseClassParamCount]->GetHelp(); \ + }\ + ShaderParamType_t GetParamType( int param ) const \ + {\ + int nBaseClassParamCount = CBaseClass::GetNumParams(); \ + if (param < nBaseClassParamCount) \ + return CBaseClass::GetParamType( param ); \ + else \ + return s_ShaderParams[param - nBaseClassParamCount]->GetType(); \ + }\ + char const* GetParamDefault( int param ) const \ + {\ + int nBaseClassParamCount = CBaseClass::GetNumParams(); \ + if (param < nBaseClassParamCount) \ + { \ + if ( !s_pShaderParamOverrides[param] ) \ + return CBaseClass::GetParamDefault( param ); \ + else \ + return s_pShaderParamOverrides[param]->GetDefault(); \ + } \ + else \ + return s_ShaderParams[param - nBaseClassParamCount]->GetDefault(); \ + }\ + int GetParamFlags( int param ) const \ + {\ + int nBaseClassParamCount = CBaseClass::GetNumParams(); \ + if (param < nBaseClassParamCount) \ + { \ + if ( !s_pShaderParamOverrides[param] ) \ + return CBaseClass::GetParamFlags( param ); \ + else \ + return s_pShaderParamOverrides[param]->GetFlags(); \ + } \ + else \ + return s_ShaderParams[param - nBaseClassParamCount]->GetFlags(); \ + }\ + void OnInitShaderInstance( IMaterialVar **params, IShaderInit *pShaderInit, const char *pMaterialName ) + +#define SHADER_DRAW \ + void OnDrawElements( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) + +#define SHADOW_STATE if (pShaderShadow) +#define DYNAMIC_STATE if (pShaderAPI) + +#define ShaderWarning if (pShaderShadow) Warning + +//----------------------------------------------------------------------------- +// Used to easily define a shader which *always* falls back +//----------------------------------------------------------------------------- +#define DEFINE_FALLBACK_SHADER( _shadername, _fallbackshadername ) \ + BEGIN_SHADER( _shadername, "" ) \ + BEGIN_SHADER_PARAMS \ + END_SHADER_PARAMS \ + SHADER_FALLBACK { return #_fallbackshadername; } \ + SHADER_INIT {} \ + SHADER_DRAW {} \ + END_SHADER + + +//----------------------------------------------------------------------------- +// Used to easily define a shader which inherits from another shader +//----------------------------------------------------------------------------- + +// FIXME: There's a compiler bug preventing this from working. +// Maybe it'll work under VC7! + +/* +//#define BEGIN_INHERITED_SHADER( name, _baseclass, help ) \ +// namespace _baseclass \ +// {\ +// __BEGIN_SHADER_INTERNAL( _baseclass::CShader, name, help ) +*/ + +//#define END_INHERITED_SHADER END_SHADER } + +//#define CHAIN_SHADER_INIT_PARAMS() CBaseClass::OnInitShaderParams( params, pMaterialName ) +//#define CHAIN_SHADER_FALLBACK() CBaseClass::GetFallbackShader( params ) +//#define CHAIN_SHADER_INIT() CBaseClass::OnInitShaderInstance( params, pShaderInit, pMaterialName ) +//#define CHAIN_SHADER_DRAW() CBaseClass::OnDrawElements( params, pShaderShadow, pShaderAPI ) + +// A dumbed-down version which does what I need now which works +// This version doesn't allow you to do chain *anything* down to the base class +#define BEGIN_INHERITED_SHADER_FLAGS( _name, _base, _help, _flags ) \ + namespace _base\ + {\ + namespace _name\ + {\ + static const char *s_Name = #_name; \ + static const char *s_HelpString = _help;\ + static int s_nFlags = _flags;\ + class CShader : public _base::CShader\ + {\ + public:\ + char const* GetName() const \ + { \ + return s_Name; \ + } \ + int GetFlags() const \ + { \ + return s_nFlags; \ + } + +#define BEGIN_INHERITED_SHADER( _name, _base, _help ) BEGIN_INHERITED_SHADER_FLAGS( _name, _base, _help, 0 ) +#define END_INHERITED_SHADER END_SHADER } + +// psh ## shader is used here to generate a warning if you don't ever call SET_DYNAMIC_PIXEL_SHADER +#define DECLARE_DYNAMIC_PIXEL_SHADER( shader ) \ + int declaredynpixshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( declaredynpixshader_ ## shader ## _missingcurlybraces ); \ + shader ## _Dynamic_Index _pshIndex; \ + int psh ## shader = 0 + +// vsh ## shader is used here to generate a warning if you don't ever call SET_DYNAMIC_VERTEX_SHADER +#define DECLARE_DYNAMIC_VERTEX_SHADER( shader ) \ + int declaredynvertshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( declaredynvertshader_ ## shader ## _missingcurlybraces ); \ + shader ## _Dynamic_Index _vshIndex; \ + int vsh ## shader = 0 + + +// psh ## shader is used here to generate a warning if you don't ever call SET_STATIC_PIXEL_SHADER +#define DECLARE_STATIC_PIXEL_SHADER( shader ) \ + int declarestaticpixshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( declarestaticpixshader_ ## shader ## _missingcurlybraces ); \ + shader ## _Static_Index _pshIndex; \ + int psh ## shader = 0 + +// vsh ## shader is used here to generate a warning if you don't ever call SET_STATIC_VERTEX_SHADER +#define DECLARE_STATIC_VERTEX_SHADER( shader ) \ + int declarestaticvertshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( declarestaticvertshader_ ## shader ## _missingcurlybraces ); \ + shader ## _Static_Index _vshIndex; \ + int vsh ## shader = 0 + + +// psh_forgot_to_set_dynamic_ ## var is used to make sure that you set all +// all combos. If you don't, you will get an undefined variable used error +// in the SET_DYNAMIC_PIXEL_SHADER block. +#define SET_DYNAMIC_PIXEL_SHADER_COMBO( var, val ) \ + int dynpixshadercombo_ ## var ## _missingcurlybraces = 0; \ + NOTE_UNUSED( dynpixshadercombo_ ## var ## _missingcurlybraces ); \ + _pshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n PS dyn var %s = %d (%s)", #var, (int) val, #val );}; \ + int psh_forgot_to_set_dynamic_ ## var = 0 + +// vsh_forgot_to_set_dynamic_ ## var is used to make sure that you set all +// all combos. If you don't, you will get an undefined variable used error +// in the SET_DYNAMIC_VERTEX_SHADER block. +#define SET_DYNAMIC_VERTEX_SHADER_COMBO( var, val ) \ + int dynvertshadercombo_ ## var ## _missingcurlybraces = 0; \ + NOTE_UNUSED( dynvertshadercombo_ ## var ## _missingcurlybraces ); \ + _vshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n VS dyn var %s = %d (%s)", #var, (int) val, #val );}; \ + int vsh_forgot_to_set_dynamic_ ## var = 0 + + +// psh_forgot_to_set_static_ ## var is used to make sure that you set all +// all combos. If you don't, you will get an undefined variable used error +// in the SET_STATIC_PIXEL_SHADER block. +#define SET_STATIC_PIXEL_SHADER_COMBO( var, val ) \ + int staticpixshadercombo_ ## var ## _missingcurlybraces = 0; \ + NOTE_UNUSED( staticpixshadercombo_ ## var ## _missingcurlybraces ); \ + _pshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n PS stat var %s = %d (%s)", #var, (int) val, #val );}; \ + int psh_forgot_to_set_static_ ## var = 0 + +// vsh_forgot_to_set_static_ ## var is used to make sure that you set all +// all combos. If you don't, you will get an undefined variable used error +// in the SET_STATIC_VERTEX_SHADER block. +#define SET_STATIC_VERTEX_SHADER_COMBO( var, val ) \ + int staticvertshadercombo_ ## var ## _missingcurlybraces = 0; \ + NOTE_UNUSED( staticvertshadercombo_ ## var ## _missingcurlybraces ); \ + _vshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n VS stat var %s = %d (%s)", #var, (int) val, #val );}; \ + int vsh_forgot_to_set_static_ ## var = 0 + + +// psh_testAllCombos adds up all of the psh_forgot_to_set_dynamic_ ## var's from +// SET_DYNAMIC_PIXEL_SHADER_COMBO so that an error is generated if they aren't set. +// psh_testAllCombos is set to itself to avoid an unused variable warning. +// psh ## shader being set to itself ensures that DECLARE_DYNAMIC_PIXEL_SHADER +// was called for this particular shader. +#define SET_DYNAMIC_PIXEL_SHADER( shader ) \ + int dynamicpixshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( dynamicpixshader_ ## shader ## _missingcurlybraces ); \ + int psh_testAllCombos = shaderDynamicTest_ ## shader; \ + NOTE_UNUSED( psh_testAllCombos ); \ + NOTE_UNUSED( psh ## shader ); \ + pShaderAPI->SetPixelShaderIndex( _pshIndex.GetIndex() ) + +#define SET_DYNAMIC_PIXEL_SHADER_CMD( cmdstream, shader ) \ + int dynamicpixshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( dynamicpixshader_ ## shader ## _missingcurlybraces ); \ + int psh_testAllCombos = shaderDynamicTest_ ## shader; \ + NOTE_UNUSED( psh_testAllCombos ); \ + NOTE_UNUSED( psh ## shader ); \ + cmdstream.SetPixelShaderIndex( _pshIndex.GetIndex() ) + + +// vsh_testAllCombos adds up all of the vsh_forgot_to_set_dynamic_ ## var's from +// SET_DYNAMIC_VERTEX_SHADER_COMBO so that an error is generated if they aren't set. +// vsh_testAllCombos is set to itself to avoid an unused variable warning. +// vsh ## shader being set to itself ensures that DECLARE_DYNAMIC_VERTEX_SHADER +// was called for this particular shader. +#define SET_DYNAMIC_VERTEX_SHADER( shader ) \ + int dynamicvertshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( dynamicvertshader_ ## shader ## _missingcurlybraces ); \ + int vsh_testAllCombos = shaderDynamicTest_ ## shader; \ + NOTE_UNUSED( vsh_testAllCombos ); \ + NOTE_UNUSED( vsh ## shader ); \ + pShaderAPI->SetVertexShaderIndex( _vshIndex.GetIndex() ) + +#define SET_DYNAMIC_VERTEX_SHADER_CMD( cmdstream, shader ) \ + int dynamicvertshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( dynamicvertshader_ ## shader ## _missingcurlybraces ); \ + int vsh_testAllCombos = shaderDynamicTest_ ## shader; \ + NOTE_UNUSED( vsh_testAllCombos ); \ + NOTE_UNUSED( vsh ## shader ); \ + cmdstream.SetVertexShaderIndex( _vshIndex.GetIndex() ) + + +// psh_testAllCombos adds up all of the psh_forgot_to_set_static_ ## var's from +// SET_STATIC_PIXEL_SHADER_COMBO so that an error is generated if they aren't set. +// psh_testAllCombos is set to itself to avoid an unused variable warning. +// psh ## shader being set to itself ensures that DECLARE_STATIC_PIXEL_SHADER +// was called for this particular shader. +#define SET_STATIC_PIXEL_SHADER( shader ) \ + int staticpixshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( staticpixshader_ ## shader ## _missingcurlybraces ); \ + int psh_testAllCombos = shaderStaticTest_ ## shader; \ + NOTE_UNUSED( psh_testAllCombos ); \ + NOTE_UNUSED( psh ## shader ); \ + pShaderShadow->SetPixelShader( #shader, _pshIndex.GetIndex() ) + +// vsh_testAllCombos adds up all of the vsh_forgot_to_set_static_ ## var's from +// SET_STATIC_VERTEX_SHADER_COMBO so that an error is generated if they aren't set. +// vsh_testAllCombos is set to itself to avoid an unused variable warning. +// vsh ## shader being set to itself ensures that DECLARE_STATIC_VERTEX_SHADER +// was called for this particular shader. +#define SET_STATIC_VERTEX_SHADER( shader ) \ + int staticvertshader_ ## shader ## _missingcurlybraces = 0; \ + NOTE_UNUSED( staticvertshader_ ## shader ## _missingcurlybraces ); \ + int vsh_testAllCombos = shaderStaticTest_ ## shader; \ + NOTE_UNUSED( vsh_testAllCombos ); \ + NOTE_UNUSED( vsh ## shader ); \ + pShaderShadow->SetVertexShader( #shader, _vshIndex.GetIndex() ) + +#endif // CSHADER_H diff --git a/public/tier0/memoverride.cpp b/public/tier0/memoverride.cpp index bec06c0..cf72978 100644 --- a/public/tier0/memoverride.cpp +++ b/public/tier0/memoverride.cpp @@ -40,6 +40,13 @@ #define __cdecl #endif +#undef _malloc_dbg +#undef _calloc_dbg +#undef _free_dbg +#undef _CrtSetCheckCount +#undef _CrtGetCheckCount +#undef _CrtSetDebugFillThreshold + #if defined( _WIN32 ) && !defined( _X360 ) const char *MakeModuleFileName() { @@ -68,24 +75,23 @@ const char *MakeModuleFileName() return NULL; } -static void *AllocUnattributed( size_t nSize ) +const char* g_pszModule = NULL; +inline void* AllocUnattributed(size_t nSize) { - static const char *pszOwner = MakeModuleFileName(); - - if ( !pszOwner ) - return g_pMemAlloc->Alloc(nSize); - else - return g_pMemAlloc->Alloc(nSize, pszOwner, 0); +#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG) + return MemAlloc_Alloc(nSize); +#else + return MemAlloc_Alloc(nSize, ::g_pszModule, 0); +#endif } -static void *ReallocUnattributed( void *pMem, size_t nSize ) +inline void* ReallocUnattributed(void* pMem, size_t nSize) { - static const char *pszOwner = MakeModuleFileName(); - - if ( !pszOwner ) - return g_pMemAlloc->Realloc(pMem, nSize); - else - return g_pMemAlloc->Realloc(pMem, nSize, pszOwner, 0); +#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG) + return g_pMemAlloc->Realloc(pMem, nSize); +#else + return g_pMemAlloc->Realloc(pMem, nSize, ::g_pszModule, 0); +#endif } #else @@ -108,6 +114,9 @@ inline void *ReallocUnattributed( void *pMem, size_t nSize ) // this magic only works under win32 // under linux this malloc() overrides the libc malloc() and so we // end up in a recursion (as g_pMemAlloc->Alloc() calls malloc) +#if _MSC_VER >= 1900 && !defined( _CRTNOALIAS ) +#define _CRTNOALIAS +#endif #if _MSC_VER >= 1400 #define ALLOC_CALL _CRTNOALIAS _CRTRESTRICT #define FREE_CALL _CRTNOALIAS @@ -155,16 +164,36 @@ void* __cdecl _malloc_base( size_t nSize ) { return AllocUnattributed( nSize ); } -#else -void *_malloc_base( size_t nSize ) +#elif _MSC_VER >= 1900 +__declspec(restrict) void *_malloc_base( size_t nSize ) { return AllocUnattributed( nSize ); } -#endif - -void *_calloc_base( size_t nSize ) +__declspec(restrict) void* _calloc_base(size_t count, size_t nSize) { - void *pMem = AllocUnattributed( nSize ); + void* pMem = AllocUnattributed(count * nSize); + memset(pMem, 0, count * nSize); + return pMem; +} + +__declspec(restrict) void* _realloc_base(void* pMem, size_t nSize) +{ + return ReallocUnattributed(pMem, nSize); +} + +__declspec(restrict) void *_recalloc_base( void *pMem, size_t count, size_t nSize ) +{ + return _recalloc( pMem, count, nSize ); +} +#else +void* _malloc_base(size_t nSize) +{ + return AllocUnattributed(nSize); +} + +void* _calloc_base(size_t nSize) +{ + void* pMem = AllocUnattributed(nSize); memset(pMem, 0, nSize); return pMem; } @@ -181,14 +210,16 @@ void *_recalloc_base( void *pMem, size_t nSize ) return pMemOut; } -void _free_base( void *pMem ) +#endif + +void _free_base(void* pMem) { g_pMemAlloc->Free(pMem); } -void *__cdecl _expand_base( void *pMem, size_t nNewSize, int nBlockUse ) +void* __cdecl _expand_base(void* pMem, size_t nNewSize, int nBlockUse) { - Assert( 0 ); + Assert(0); return NULL; } @@ -200,7 +231,11 @@ void * __cdecl _malloc_crt(size_t size) void * __cdecl _calloc_crt(size_t count, size_t size) { - return _calloc_base( count * size ); +#if _MSC_VER >= 1900 + return _calloc_base(count, size); +#else + return _calloc_base(count * size); +#endif } void * __cdecl _realloc_crt(void *ptr, size_t size) @@ -210,7 +245,11 @@ void * __cdecl _realloc_crt(void *ptr, size_t size) void * __cdecl _recalloc_crt(void *ptr, size_t count, size_t size) { - return _recalloc_base( ptr, size * count ); +#if _MSC_VER >= 1900 + return _recalloc_base(ptr, count, size); +#else + return _recalloc_base(ptr, size * count); +#endif } ALLOC_CALL void * __cdecl _recalloc ( void * memblock, size_t count, size_t size ) @@ -485,6 +524,7 @@ void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse, return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine ); } +#ifdef DEBUG void *__cdecl _realloc_dbg( void *pMem, size_t nNewSize, int nBlockUse, const char *pFileName, int nLine ) { @@ -498,22 +538,24 @@ void *__cdecl _expand_dbg( void *pMem, size_t nNewSize, int nBlockUse, Assert( 0 ); return NULL; } - +#endif void __cdecl _free_dbg( void *pMem, int nBlockUse ) { AttribIfCrt(); g_pMemAlloc->Free(pMem); } -size_t __cdecl _msize_dbg( void *pMem, int nBlockUse ) +#ifdef DEBUG +size_t __cdecl _msize_dbg(void* pMem, int nBlockUse) { #ifdef _WIN32 return _msize(pMem); #elif POSIX - Assert( "_msize_dbg unsupported" ); + Assert("_msize_dbg unsupported"); return 0; #endif } +#endif #ifdef _WIN32 @@ -613,26 +655,40 @@ ALLOC_CALL void * __cdecl _aligned_offset_recalloc( void * memblock, size_t coun extern "C" { - -int _CrtDumpMemoryLeaks(void) -{ - return 0; -} +#ifdef DEBUG + int _CrtDumpMemoryLeaks(void) + { + return 0; + } -_CRT_DUMP_CLIENT _CrtSetDumpClient( _CRT_DUMP_CLIENT dumpClient ) -{ - return NULL; -} + _CRT_DUMP_CLIENT _CrtSetDumpClient(_CRT_DUMP_CLIENT dumpClient) + { + return NULL; + } -int _CrtSetDbgFlag( int nNewFlag ) -{ - return g_pMemAlloc->CrtSetDbgFlag( nNewFlag ); -} + int _CrtSetDbgFlag(int nNewFlag) + { + return g_pMemAlloc->CrtSetDbgFlag(nNewFlag); + } +#endif // 64-bit port. #define AFNAME(var) __p_ ## var #define AFRET(var) &var +#if _MSC_VER >= 1900 + int* __cdecl __p__crtDbgFlag(void) + { + static int dummy = _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF; + return &dummy; + } + + long* __cdecl __p__crtBreakAlloc(void) + { + static long dummy = 0; + return &dummy; + } +#else int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF; int* AFNAME(_crtDbgFlag)(void) { @@ -644,12 +700,14 @@ long* AFNAME(_crtBreakAlloc) (void) { return AFRET(_crtBreakAlloc); } +#endif void __cdecl _CrtSetDbgBlockType( void *pMem, int nBlockUse ) { DebuggerBreak(); } +#ifdef DEBUG _CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( _CRT_ALLOC_HOOK pfnNewHook ) { DebuggerBreak(); @@ -660,7 +718,7 @@ long __cdecl _CrtSetBreakAlloc( long lNewBreakAlloc ) { return g_pMemAlloc->CrtSetBreakAlloc( lNewBreakAlloc ); } - + int __cdecl _CrtIsValidHeapPointer( const void *pMem ) { return g_pMemAlloc->CrtIsValidHeapPointer( pMem ); @@ -710,13 +768,14 @@ void __cdecl _CrtDoForAllClientObjects( void (*pfn)(void *, void *), void * pCon { DebuggerBreak(); } - +#endif //----------------------------------------------------------------------------- // Methods in dbgrpt.cpp //----------------------------------------------------------------------------- long _crtAssertBusy = -1; +#ifdef DEBUG int __cdecl _CrtSetReportMode( int nReportType, int nReportMode ) { return g_pMemAlloc->CrtSetReportMode( nReportType, nReportMode ); @@ -750,7 +809,7 @@ int __cdecl _CrtDbgReport( int nRptType, const char * szFile, return g_pMemAlloc->CrtDbgReport( nRptType, szFile, nLine, szModule, output ); } - +#endif #if _MSC_VER >= 1400 // Configure VS so that it will record crash dumps on pure-call violations @@ -927,6 +986,7 @@ extern "C" int __cdecl _CrtGetCheckCount( void ) return __crtDebugCheckCount; } +#ifdef DEBUG // aligned offset debug extern "C" void * __cdecl _aligned_offset_recalloc_dbg( void * memblock, size_t count, size_t size, size_t align, size_t offset, const char * f_name, int line_n ) { @@ -950,13 +1010,16 @@ _CRT_REPORT_HOOK __cdecl _CrtGetReportHook( void ) { return NULL; } +#endif #endif + +#ifdef DEBUG int __cdecl _CrtReportBlockType(const void * pUserData) { return 0; } - +#endif } // end extern "C" #endif // _WIN32 @@ -1018,25 +1081,25 @@ void __cdecl _free_dbg_nolock( void * pUserData, int nBlockUse) _free_dbg(pUserData, 0); } +#ifdef DEBUG _CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook ( void) { assert(0); return NULL; } +_CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient(void) +{ + assert(0); + return NULL; +} +#endif static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize) { int bOkay = TRUE; return bOkay; } - -_CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient ( void) -{ - assert(0); - return NULL; -} - #if _MSC_VER >= 1400 static void __cdecl _printMemBlockData( _locale_t plocinfo, _CrtMemBlockHeader * pHead) { @@ -1046,6 +1109,8 @@ static void __cdecl _CrtMemDumpAllObjectsSince_stat( const _CrtMemState * state, { } #endif + +#if defined( DEBUG ) && _MSC_VER >= 1900 void * __cdecl _aligned_malloc_dbg( size_t size, size_t align, const char * f_name, int line_n) { return _aligned_malloc(size, align); @@ -1073,12 +1138,15 @@ void __cdecl _aligned_free_dbg( void * memblock) { _aligned_free(memblock); } +#endif // DEBUG +#if _MSC_VER < 1900 size_t __cdecl _CrtSetDebugFillThreshold( size_t _NewDebugFillThreshold) { assert(0); return 0; } +#endif //=========================================== // NEW!!! 64-bit @@ -1341,6 +1409,12 @@ _CRTIMP extern unsigned long __cdecl __threadid(void); _CRTIMP extern uintptr_t __cdecl __threadhandle(void); #define _threadhandle (__threadhandle()) +#if _MSC_VER >= 1900 +typedef __crt_multibyte_data* pthreadmbcinfo; +typedef __crt_locale_data* pthreadlocinfo; +typedef __crt_locale_pointers _locale_tstruct; +#endif + /* Structure for each thread's data */ struct _tiddata { diff --git a/studiorender/r_studiodraw.cpp b/studiorender/r_studiodraw.cpp index 5f3565e..8740d88 100644 --- a/studiorender/r_studiodraw.cpp +++ b/studiorender/r_studiodraw.cpp @@ -2271,7 +2271,7 @@ int CStudioRender::R_StudioDrawStaticMesh( IMatRenderContext *pRenderContext, ms int numTrianglesRendered = 0; - bool bDoSoftwareLighting = !pColorMeshes && + bool bDoSoftwareLighting = /*!pColorMeshes && */ ((m_pRC->m_Config.bSoftwareSkin != 0) || m_pRC->m_Config.bDrawNormals || m_pRC->m_Config.bDrawTangentFrame || (pMaterial ? pMaterial->NeedsSoftwareSkinning() : false) || (m_pRC->m_Config.bSoftwareLighting != 0) || diff --git a/vpc_scripts/groups.vgc b/vpc_scripts/groups.vgc index 7bb1ac8..ca078fa 100644 --- a/vpc_scripts/groups.vgc +++ b/vpc_scripts/groups.vgc @@ -37,7 +37,9 @@ $Group "game" $Group "shaders" { "game_shader_dx9" - "shaderapidx9" + "shaderapidx11" + "stdshader_dx11" + "shaderlib_dx11" } $Group "everything" diff --git a/vpc_scripts/projects.vgc b/vpc_scripts/projects.vgc index 70040af..c37b3bc 100644 --- a/vpc_scripts/projects.vgc +++ b/vpc_scripts/projects.vgc @@ -90,6 +90,21 @@ $Project "shaderapidx9" "materialsystem\shaderapidx9\shaderapidx9.vpc" } +$Project "shaderapidx11" +{ + "materialsystem\shaderapidx11\shaderapidx11.vpc" +} + +$Project "stdshader_dx11" +{ + "materialsystem\stdshadersdx11\stdshader_dx11.vpc" +} + +$Project "shaderlib_dx11" +{ + "materialsystem\shaderlib_dx11\shaderlib.vpc" +} + $Project "tgadiff" { "utils\tgadiff\tgadiff.vpc" [$WIN32]