diff options
| author | Konstantin <const@const.me> | 2023-01-16 14:52:43 +0100 |
|---|---|---|
| committer | Konstantin <const@const.me> | 2023-01-16 14:52:43 +0100 |
| commit | 8c4603c73675958efc960fbd4bb599a2909d106a (patch) | |
| tree | 714dc6fc9a1672d5fd7f89676b97e10959662abc /Whisper/D3D/shaders.cpp | |
| parent | 990a8d0dbaefc996244097397259e92758b15cce (diff) | |
Source codes
Diffstat (limited to 'Whisper/D3D/shaders.cpp')
| -rw-r--r-- | Whisper/D3D/shaders.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/Whisper/D3D/shaders.cpp b/Whisper/D3D/shaders.cpp new file mode 100644 index 0000000..f7d9ce4 --- /dev/null +++ b/Whisper/D3D/shaders.cpp @@ -0,0 +1,104 @@ +#include "stdafx.h" +#include "shaders.h" +#include "startup.h" +#include "device.h" +#include <compressapi.h> +#pragma comment( lib, "Cabinet.lib" ) + +namespace +{ +#ifdef _DEBUG +#include "shaderData-Debug.inl" +#else +#include "shaderData-Release.inl" +#endif + + constexpr DWORD compressionAlgorithm = COMPRESS_ALGORITHM_MSZIP; + + class Decompressor + { + DECOMPRESSOR_HANDLE handle = nullptr; + + public: + + HRESULT create() + { + if( CreateDecompressor( compressionAlgorithm, nullptr, &handle ) ) + return S_OK; + return HRESULT_FROM_WIN32( GetLastError() ); + } + + HRESULT decompress( const uint8_t* src, size_t compressedLength, void* dest, size_t origLength ) const + { + if( Decompress( handle, src, compressedLength, dest, origLength, nullptr ) ) + return S_OK; + return HRESULT_FROM_WIN32( GetLastError() ); + } + + ~Decompressor() + { + if( nullptr != handle ) + { + CloseDecompressor( handle ); + handle = nullptr; + } + } + }; + + static std::vector<CComPtr<ID3D11ComputeShader>> s_shaders; +} + +HRESULT DirectCompute::createComputeShaders() +{ + constexpr size_t countBinaries = s_shaderOffsets.size() - 1; + const size_t cbDecompressedLength = s_shaderOffsets[ countBinaries ]; + constexpr size_t countShaders = s_shaderBlobs32.size(); + + std::vector<uint8_t> dxbc; + try + { + s_shaders.resize( countShaders ); + dxbc.resize( cbDecompressedLength ); + } + catch( const std::bad_alloc& ) + { + return E_OUTOFMEMORY; + } + + Decompressor decomp; + CHECK( decomp.create() ); + + decomp.decompress( s_compressedShaders.data(), s_compressedShaders.size(), dxbc.data(), cbDecompressedLength ); + ID3D11Device* const dev = device(); + + const auto& blobs = gpuInfo.wave64() ? s_shaderBlobs64 : s_shaderBlobs32; + + for( size_t i = 0; i < countShaders; i++ ) + { + const size_t idxBinary = blobs[ i ]; + const uint32_t offThis = s_shaderOffsets[ idxBinary ]; + const uint8_t* rsi = &dxbc[ offThis ]; + const size_t len = s_shaderOffsets[ idxBinary + 1 ] - offThis; + const HRESULT hr = dev->CreateComputeShader( rsi, len, nullptr, &s_shaders[ i ] ); + if( SUCCEEDED( hr ) ) + continue; + + const uint64_t binaryBit = ( 1ull << idxBinary ); + if( 0 != ( binaryBit & fp64ShadersBitmap ) ) + continue; // This shader uses FP64 math, the support for that is optional. When not supported, CreateComputeShader method is expected to fail. + // TODO [low]: ideally, query for the support when creating the device, and don't even try creating these compute shaders + return hr; + } + + return S_OK; +} + +void DirectCompute::destroyComputeShaders() +{ + s_shaders.clear(); +} + +void DirectCompute::bindShader( eComputeShader shader ) +{ + context()->CSSetShader( s_shaders[ (uint16_t)shader ], nullptr, 0 ); +}
\ No newline at end of file |
