1#include "precompiled.h" 2#include "libGLESv2/renderer/d3d/HLSLCompiler.h" 3#include "libGLESv2/Program.h" 4#include "libGLESv2/main.h" 5 6#include "common/utilities.h" 7 8#include "third_party/trace_event/trace_event.h" 9 10namespace rx 11{ 12 13HLSLCompiler::HLSLCompiler() 14 : mD3DCompilerModule(NULL), 15 mD3DCompileFunc(NULL) 16{ 17} 18 19HLSLCompiler::~HLSLCompiler() 20{ 21 release(); 22} 23 24bool HLSLCompiler::initialize() 25{ 26 TRACE_EVENT0("gpu", "initializeCompiler"); 27#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) 28 // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. 29 static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; 30 31 for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) 32 { 33 if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3DCompilerModule)) 34 { 35 break; 36 } 37 } 38#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES 39 40 if (!mD3DCompilerModule) 41 { 42 // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. 43 mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL); 44 } 45 46 if (!mD3DCompilerModule) 47 { 48 ERR("No D3D compiler module found - aborting!\n"); 49 return false; 50 } 51 52 mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile")); 53 ASSERT(mD3DCompileFunc); 54 55 return mD3DCompileFunc != NULL; 56} 57 58void HLSLCompiler::release() 59{ 60 if (mD3DCompilerModule) 61 { 62 FreeLibrary(mD3DCompilerModule); 63 mD3DCompilerModule = NULL; 64 mD3DCompileFunc = NULL; 65 } 66} 67 68ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, 69 const UINT optimizationFlags[], const char *flagNames[], int attempts) const 70{ 71 ASSERT(mD3DCompilerModule && mD3DCompileFunc); 72 73 if (!hlsl) 74 { 75 return NULL; 76 } 77 78 pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); 79 for (int i = 0; i < attempts; ++i) 80 { 81 ID3DBlob *errorMessage = NULL; 82 ID3DBlob *binary = NULL; 83 84 HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage); 85 86 if (errorMessage) 87 { 88 const char *message = (const char*)errorMessage->GetBufferPointer(); 89 90 infoLog.appendSanitized(message); 91 TRACE("\n%s", hlsl); 92 TRACE("\n%s", message); 93 94 SafeRelease(errorMessage); 95 } 96 97 if (SUCCEEDED(result)) 98 { 99 return (ShaderBlob*)binary; 100 } 101 else 102 { 103 if (result == E_OUTOFMEMORY) 104 { 105 return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL); 106 } 107 108 infoLog.append("Warning: D3D shader compilation failed with "); 109 infoLog.append(flagNames[i]); 110 infoLog.append(" flags."); 111 if (i + 1 < attempts) 112 { 113 infoLog.append(" Retrying with "); 114 infoLog.append(flagNames[i + 1]); 115 infoLog.append(".\n"); 116 } 117 } 118 } 119 120 return NULL; 121} 122 123} 124