зеркало из https://github.com/AvaloniaUI/angle.git
Lazily load the HLSL compiler DLL.
If the user is loading resources straight from the disk with the binary shader cache, they shouldn't need to load the compiler DLL at all. Note: might be a good idea to track more statistics here. BUG=angleproject:1014 Change-Id: Ie75dcce3eb249347c545f1bbca7d0977df7addee Reviewed-on: https://chromium-review.googlesource.com/282554 Reviewed-by: Kenneth Russell <kbr@chromium.org> Tested-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
e0f623a40a
Коммит
a8bb9cdc7d
|
@ -106,9 +106,10 @@ CompileConfig::CompileConfig(UINT flags, const std::string &name)
|
|||
}
|
||||
|
||||
HLSLCompiler::HLSLCompiler()
|
||||
: mD3DCompilerModule(NULL),
|
||||
mD3DCompileFunc(NULL),
|
||||
mD3DDisassembleFunc(NULL)
|
||||
: mInitialized(false),
|
||||
mD3DCompilerModule(nullptr),
|
||||
mD3DCompileFunc(nullptr),
|
||||
mD3DDisassembleFunc(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -117,8 +118,13 @@ HLSLCompiler::~HLSLCompiler()
|
|||
release();
|
||||
}
|
||||
|
||||
bool HLSLCompiler::initialize()
|
||||
gl::Error HLSLCompiler::initialize()
|
||||
{
|
||||
if (mInitialized)
|
||||
{
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
TRACE_EVENT0("gpu.angle", "HLSLCompiler::initialize");
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
|
||||
|
@ -142,8 +148,7 @@ bool HLSLCompiler::initialize()
|
|||
|
||||
if (!mD3DCompilerModule)
|
||||
{
|
||||
ERR("No D3D compiler module found - aborting!\n");
|
||||
return false;
|
||||
return gl::Error(GL_INVALID_OPERATION, "No D3D compiler module found - aborting!\n");
|
||||
}
|
||||
|
||||
mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
|
||||
|
@ -155,29 +160,42 @@ bool HLSLCompiler::initialize()
|
|||
#else
|
||||
// D3D Shader compiler is linked already into this module, so the export
|
||||
// can be directly assigned.
|
||||
mD3DCompilerModule = NULL;
|
||||
mD3DCompilerModule = nullptr;
|
||||
mD3DCompileFunc = reinterpret_cast<pD3DCompile>(D3DCompile);
|
||||
mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(D3DDisassemble);
|
||||
#endif
|
||||
|
||||
return mD3DCompileFunc != NULL;
|
||||
if (mD3DCompileFunc == nullptr)
|
||||
{
|
||||
return gl::Error(GL_INVALID_OPERATION, "Error finding D3DCompile entry point");
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
void HLSLCompiler::release()
|
||||
{
|
||||
if (mD3DCompilerModule)
|
||||
if (mInitialized)
|
||||
{
|
||||
FreeLibrary(mD3DCompilerModule);
|
||||
mD3DCompilerModule = NULL;
|
||||
mD3DCompileFunc = NULL;
|
||||
mD3DDisassembleFunc = NULL;
|
||||
mD3DCompilerModule = nullptr;
|
||||
mD3DCompileFunc = nullptr;
|
||||
mD3DDisassembleFunc = nullptr;
|
||||
mInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
|
||||
const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
|
||||
ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const
|
||||
ID3DBlob **outCompiledBlob, std::string *outDebugInfo)
|
||||
{
|
||||
gl::Error error = initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
ASSERT(mD3DCompilerModule);
|
||||
#endif
|
||||
|
@ -192,14 +210,14 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
|
|||
}
|
||||
#endif
|
||||
|
||||
const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL;
|
||||
const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : nullptr;
|
||||
|
||||
for (size_t i = 0; i < configs.size(); ++i)
|
||||
{
|
||||
ID3DBlob *errorMessage = NULL;
|
||||
ID3DBlob *binary = NULL;
|
||||
ID3DBlob *errorMessage = nullptr;
|
||||
ID3DBlob *binary = nullptr;
|
||||
|
||||
HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(),
|
||||
HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, nullptr, "main", profile.c_str(),
|
||||
configs[i].flags, 0, &binary, &errorMessage);
|
||||
|
||||
if (errorMessage)
|
||||
|
@ -217,7 +235,7 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
|
|||
// some very long shaders have trouble deciding which loops to unroll and
|
||||
// turning off forced unrolls allows them to compile properly.
|
||||
{
|
||||
macros = NULL; // Disable [loop] and [flatten]
|
||||
macros = nullptr; // Disable [loop] and [flatten]
|
||||
|
||||
// Retry without changing compiler flags
|
||||
i--;
|
||||
|
@ -255,52 +273,64 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
|
|||
}
|
||||
}
|
||||
|
||||
(*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n";
|
||||
std::string disassembly;
|
||||
error = disassembleBinary(binary, &disassembly);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
(*outDebugInfo) += "\n" + disassembly + "\n// ASSEMBLY END\n";
|
||||
#endif
|
||||
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
else
|
||||
|
||||
if (result == E_OUTOFMEMORY)
|
||||
{
|
||||
if (result == E_OUTOFMEMORY)
|
||||
{
|
||||
*outCompiledBlob = NULL;
|
||||
return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result);
|
||||
}
|
||||
*outCompiledBlob = nullptr;
|
||||
return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result);
|
||||
}
|
||||
|
||||
infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags.";
|
||||
infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags.";
|
||||
|
||||
if (i + 1 < configs.size())
|
||||
{
|
||||
infoLog << " Retrying with " << configs[i + 1].name;
|
||||
}
|
||||
if (i + 1 < configs.size())
|
||||
{
|
||||
infoLog << " Retrying with " << configs[i + 1].name;
|
||||
}
|
||||
}
|
||||
|
||||
// None of the configurations succeeded in compiling this shader but the compiler is still intact
|
||||
*outCompiledBlob = NULL;
|
||||
*outCompiledBlob = nullptr;
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const
|
||||
gl::Error HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary, std::string *disassemblyOut)
|
||||
{
|
||||
gl::Error error = initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
// Retrieve disassembly
|
||||
UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING;
|
||||
ID3DBlob *disassembly = NULL;
|
||||
ID3DBlob *disassembly = nullptr;
|
||||
pD3DDisassemble disassembleFunc = reinterpret_cast<pD3DDisassemble>(mD3DDisassembleFunc);
|
||||
LPCVOID buffer = shaderBinary->GetBufferPointer();
|
||||
SIZE_T bufSize = shaderBinary->GetBufferSize();
|
||||
HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly);
|
||||
|
||||
std::string asmSrc;
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
asmSrc = reinterpret_cast<const char*>(disassembly->GetBufferPointer());
|
||||
*disassemblyOut = std::string(reinterpret_cast<const char*>(disassembly->GetBufferPointer()));
|
||||
}
|
||||
else
|
||||
{
|
||||
*disassemblyOut = "";
|
||||
}
|
||||
|
||||
SafeRelease(disassembly);
|
||||
|
||||
return asmSrc;
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,18 +32,20 @@ class HLSLCompiler : angle::NonCopyable
|
|||
HLSLCompiler();
|
||||
~HLSLCompiler();
|
||||
|
||||
bool initialize();
|
||||
void release();
|
||||
|
||||
// Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob
|
||||
// even if no GL errors are returned.
|
||||
gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
|
||||
const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
|
||||
ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const;
|
||||
ID3DBlob **outCompiledBlob, std::string *outDebugInfo);
|
||||
|
||||
std::string disassembleBinary(ID3DBlob* shaderBinary) const;
|
||||
gl::Error disassembleBinary(ID3DBlob *shaderBinary, std::string *disassemblyOut);
|
||||
|
||||
private:
|
||||
gl::Error initialize();
|
||||
|
||||
bool mInitialized;
|
||||
HMODULE mD3DCompilerModule;
|
||||
pD3DCompile mD3DCompileFunc;
|
||||
pD3DDisassemble mD3DDisassembleFunc;
|
||||
|
|
|
@ -343,13 +343,6 @@ egl::Error Renderer11::initialize()
|
|||
{
|
||||
double loadDLLsBegin = ANGLEPlatformCurrent()->currentTime();
|
||||
|
||||
if (!mCompiler.initialize())
|
||||
{
|
||||
return egl::Error(EGL_NOT_INITIALIZED,
|
||||
D3D11_INIT_COMPILER_ERROR,
|
||||
"Failed to initialize compiler.");
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr;
|
||||
{
|
||||
|
|
|
@ -171,13 +171,6 @@ void Renderer9::release()
|
|||
|
||||
egl::Error Renderer9::initialize()
|
||||
{
|
||||
if (!mCompiler.initialize())
|
||||
{
|
||||
return egl::Error(EGL_NOT_INITIALIZED,
|
||||
D3D9_INIT_COMPILER_ERROR,
|
||||
"Compiler failed to initialize.");
|
||||
}
|
||||
|
||||
TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9");
|
||||
mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче