blob: fc7357aeefdb7f46a51a5f5b6e143e37a60dbc57 [file] [log] [blame]
Geoff Langdad5ed32014-02-10 12:59:17 -05001#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.
Jamie Madill07d49ef2014-07-25 11:52:38 -040029 static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
Geoff Langdad5ed32014-02-10 12:59:17 -050030
31 for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
32 {
Jamie Madill07d49ef2014-07-25 11:52:38 -040033 if (GetModuleHandleExA(0, d3dCompilerNames[i], &mD3DCompilerModule))
Geoff Langdad5ed32014-02-10 12:59:17 -050034 {
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,
Nicolas Capens93faad92014-05-10 12:14:13 -040069 const UINT optimizationFlags[], const char *flagNames[], int attempts) const
Geoff Langdad5ed32014-02-10 12:59:17 -050070{
71 ASSERT(mD3DCompilerModule && mD3DCompileFunc);
72
73 if (!hlsl)
74 {
75 return NULL;
76 }
77
Geoff Langdad5ed32014-02-10 12:59:17 -050078 pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
79 for (int i = 0; i < attempts; ++i)
80 {
81 ID3DBlob *errorMessage = NULL;
82 ID3DBlob *binary = NULL;
83
Nicolas Capens93faad92014-05-10 12:14:13 -040084 HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage);
85
Geoff Langdad5ed32014-02-10 12:59:17 -050086 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
Jamie Madill2c976a42014-08-04 11:37:53 -0400108 infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]);
109
Geoff Langdad5ed32014-02-10 12:59:17 -0500110 if (i + 1 < attempts)
111 {
Jamie Madill2c976a42014-08-04 11:37:53 -0400112 infoLog.append(" Retrying with %s.\n", flagNames[i + 1]);
Geoff Langdad5ed32014-02-10 12:59:17 -0500113 }
114 }
115 }
116
117 return NULL;
118}
119
120}