diff --git a/BeefySysLib/platform/win/DXRenderDevice.cpp b/BeefySysLib/platform/win/DXRenderDevice.cpp index 3ed1ddf4..8601b6e5 100644 --- a/BeefySysLib/platform/win/DXRenderDevice.cpp +++ b/BeefySysLib/platform/win/DXRenderDevice.cpp @@ -21,13 +21,16 @@ USING_NS_BF; +#pragma warning (disable:4996) + +#pragma comment(lib, "d3d10.lib") #pragma comment(lib, "d3d11.lib") //#pragma comment(lib, "d3d11_1.lib") //#pragma comment(lib, "d3dx11.lib") #pragma comment(lib, "d2d1.lib") //#pragma comment(lib, "dxerr.lib") #pragma comment(lib, "dxgi.lib") -#pragma comment(lib, "D3DCompiler.lib") +//#pragma comment(lib, "D3DCompiler.lib") /// @@ -1569,59 +1572,103 @@ Texture* DXRenderDevice::CreateDynTexture(int width, int height) return aTexture; } -class ID3DX11ThreadPump; extern "C" -typedef HRESULT (WINAPI* Func_D3DX11CompileFromFileA)(LPCSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, - LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); +typedef HRESULT (WINAPI* Func_D3DX10CompileFromFileW)(LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs); + +static Func_D3DX10CompileFromFileW gFunc_D3DX10CompileFromFileW; + +static bool LoadDXShader(const StringImpl& filePath, const StringImpl& entry, const StringImpl& profile, ID3D10Blob** outBuffer) +{ + HRESULT hr; + String outObj = filePath + "_" + entry + "_" + profile; + + bool useCache = false; + auto srcDate = ::BfpFile_GetTime_LastWrite(filePath.c_str()); + auto cacheDate = ::BfpFile_GetTime_LastWrite(outObj.c_str()); + if (cacheDate >= srcDate) + useCache = true; + + if (!useCache) + { + if (gFunc_D3DX10CompileFromFileW == NULL) + { + auto lib = LoadLibraryA("D3DCompiler_47.dll"); + if (lib != NULL) + gFunc_D3DX10CompileFromFileW = (Func_D3DX10CompileFromFileW)::GetProcAddress(lib, "D3DCompileFromFile"); + } + + if (gFunc_D3DX10CompileFromFileW == NULL) + useCache = true; + } + + if (!useCache) + { + if (gFunc_D3DX10CompileFromFileW == NULL) + { + auto lib = LoadLibraryA("D3DCompiler_47.dll"); + if (lib != NULL) + gFunc_D3DX10CompileFromFileW = (Func_D3DX10CompileFromFileW)::GetProcAddress(lib, "D3DCompileFromFile"); + } + + ID3D10Blob* errorMessage = NULL; + auto dxResult = gFunc_D3DX10CompileFromFileW(UTF8Decode(filePath).c_str(), NULL, NULL, entry.c_str(), profile.c_str(), + D3D10_SHADER_DEBUG | D3D10_SHADER_ENABLE_STRICTNESS, 0, outBuffer, &errorMessage); + + if (DXFAILED(dxResult)) + { + if (errorMessage != NULL) + { + BF_FATAL(StrFormat("Vertex shader load failed: %s", (char*)errorMessage->GetBufferPointer()).c_str()); + errorMessage->Release(); + } + else + BF_FATAL("Shader load failed"); + return false; + } + + auto ptr = (*outBuffer)->GetBufferPointer(); + int size = (int)(*outBuffer)->GetBufferSize(); + + FILE* fp = fopen(outObj.c_str(), "wb"); + if (fp != NULL) + { + fwrite(ptr, 1, size, fp); + fclose(fp); + } + return true; + } + + FILE* fp = fopen(outObj.c_str(), "rb"); + if (fp == NULL) + { + BF_FATAL("Failed to load compiled shader"); + return false; + } + + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + fseek(fp, 0, SEEK_SET); + D3D10CreateBlob(size, outBuffer); + auto ptr = (*outBuffer)->GetBufferPointer(); + fread(ptr, 1, size, fp); + fclose(fp); + + return true; +} Shader* DXRenderDevice::LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) { BP_ZONE("DXRenderDevice::LoadShader"); - HRESULT hr; + //HRESULT hr; ID3D10Blob* errorMessage = NULL; ID3D10Blob* vertexShaderBuffer = NULL; ID3D10Blob* pixelShaderBuffer = NULL; - auto dxResult = D3DCompileFromFile(UTF8Decode(fileName + ".fx").c_str(), - NULL, NULL, - "VS", - "vs_4_0", - D3D10_SHADER_DEBUG | D3D10_SHADER_ENABLE_STRICTNESS, - 0, - &vertexShaderBuffer, - &errorMessage); - if (DXFAILED(dxResult)) - { - if (errorMessage != NULL) - { - BF_FATAL(StrFormat("Vertex shader load failed: %s", (char*)errorMessage->GetBufferPointer()).c_str()); - errorMessage->Release(); - } - else - BF_FATAL("Vertex load failed"); - return NULL; - } - - if (DXFAILED(D3DCompileFromFile(UTF8Decode(fileName + ".fx").c_str(), - NULL, NULL, - "PS", - "ps_4_0", - D3D10_SHADER_DEBUG | D3D10_SHADER_ENABLE_STRICTNESS, - 0, - &pixelShaderBuffer, - &errorMessage))) - { - if (errorMessage != NULL) - { - BF_FATAL(StrFormat("Pixel shader load failed: %s", (char*) errorMessage->GetBufferPointer()).c_str()); - errorMessage->Release(); - } - else - BF_FATAL("Vertex load failed"); - return NULL; - } + LoadDXShader(fileName + ".fx", "VS", "vs_4_0", &vertexShaderBuffer); + LoadDXShader(fileName + ".fx", "PS", "ps_4_0", &pixelShaderBuffer); DXShader* dxShader = new DXShader();