blob: f99a245bf60b46b669475c3923518dace7dd39f3 [file] [log] [blame]
Jamie Madillea247592014-08-28 10:37:08 -04001//
2// Copyright 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Langdad5ed32014-02-10 12:59:17 -05007#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
Jamie Madillea247592014-08-28 10:37:08 -04008
9#include "libGLESv2/common_includes.h"
Geoff Langdad5ed32014-02-10 12:59:17 -050010#include "libGLESv2/Program.h"
11#include "libGLESv2/main.h"
12
13#include "common/utilities.h"
14
15#include "third_party/trace_event/trace_event.h"
16
17namespace rx
18{
19
20HLSLCompiler::HLSLCompiler()
21 : mD3DCompilerModule(NULL),
22 mD3DCompileFunc(NULL)
23{
24}
25
26HLSLCompiler::~HLSLCompiler()
27{
28 release();
29}
30
31bool HLSLCompiler::initialize()
32{
33 TRACE_EVENT0("gpu", "initializeCompiler");
34#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
35 // Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
Jamie Madill07d49ef2014-07-25 11:52:38 -040036 static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
Geoff Langdad5ed32014-02-10 12:59:17 -050037
38 for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
39 {
Jamie Madill07d49ef2014-07-25 11:52:38 -040040 if (GetModuleHandleExA(0, d3dCompilerNames[i], &mD3DCompilerModule))
Geoff Langdad5ed32014-02-10 12:59:17 -050041 {
42 break;
43 }
44 }
45#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
46
47 if (!mD3DCompilerModule)
48 {
49 // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
50 mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
51 }
52
53 if (!mD3DCompilerModule)
54 {
55 ERR("No D3D compiler module found - aborting!\n");
56 return false;
57 }
58
59 mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
60 ASSERT(mD3DCompileFunc);
61
62 return mD3DCompileFunc != NULL;
63}
64
65void HLSLCompiler::release()
66{
67 if (mD3DCompilerModule)
68 {
69 FreeLibrary(mD3DCompilerModule);
70 mD3DCompilerModule = NULL;
71 mD3DCompileFunc = NULL;
72 }
73}
74
75ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
Nicolas Capens93faad92014-05-10 12:14:13 -040076 const UINT optimizationFlags[], const char *flagNames[], int attempts) const
Geoff Langdad5ed32014-02-10 12:59:17 -050077{
78 ASSERT(mD3DCompilerModule && mD3DCompileFunc);
79
80 if (!hlsl)
81 {
82 return NULL;
83 }
84
Geoff Langdad5ed32014-02-10 12:59:17 -050085 pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
86 for (int i = 0; i < attempts; ++i)
87 {
88 ID3DBlob *errorMessage = NULL;
89 ID3DBlob *binary = NULL;
90
Nicolas Capens93faad92014-05-10 12:14:13 -040091 HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage);
92
Geoff Langdad5ed32014-02-10 12:59:17 -050093 if (errorMessage)
94 {
95 const char *message = (const char*)errorMessage->GetBufferPointer();
96
97 infoLog.appendSanitized(message);
98 TRACE("\n%s", hlsl);
99 TRACE("\n%s", message);
100
101 SafeRelease(errorMessage);
102 }
103
104 if (SUCCEEDED(result))
105 {
106 return (ShaderBlob*)binary;
107 }
108 else
109 {
110 if (result == E_OUTOFMEMORY)
111 {
112 return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL);
113 }
114
Jamie Madill2c976a42014-08-04 11:37:53 -0400115 infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]);
116
Geoff Langdad5ed32014-02-10 12:59:17 -0500117 if (i + 1 < attempts)
118 {
Jamie Madill2c976a42014-08-04 11:37:53 -0400119 infoLog.append(" Retrying with %s.\n", flagNames[i + 1]);
Geoff Langdad5ed32014-02-10 12:59:17 -0500120 }
121 }
122 }
123
124 return NULL;
125}
126
127}