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