// // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // #include "libGLESv2/renderer/d3d/HLSLCompiler.h" #include "libGLESv2/Program.h" #include "libGLESv2/main.h" #include "common/utilities.h" #include "third_party/trace_event/trace_event.h" namespace rx { HLSLCompiler::HLSLCompiler() : mD3DCompilerModule(NULL), mD3DCompileFunc(NULL) { } HLSLCompiler::~HLSLCompiler() { release(); } bool HLSLCompiler::initialize() { TRACE_EVENT0("gpu", "initializeCompiler"); #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) { if (GetModuleHandleExA(0, d3dCompilerNames[i], &mD3DCompilerModule)) { break; } } #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES if (!mD3DCompilerModule) { // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL); } if (!mD3DCompilerModule) { ERR("No D3D compiler module found - aborting!\n"); return false; } mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); ASSERT(mD3DCompileFunc); return mD3DCompileFunc != NULL; } void HLSLCompiler::release() { if (mD3DCompilerModule) { FreeLibrary(mD3DCompilerModule); mD3DCompilerModule = NULL; mD3DCompileFunc = NULL; } } ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, const UINT optimizationFlags[], const char *flagNames[], int attempts) const { ASSERT(mD3DCompilerModule && mD3DCompileFunc); if (!hlsl) { return NULL; } pD3DCompile compileFunc = reinterpret_cast(mD3DCompileFunc); for (int i = 0; i < attempts; ++i) { ID3DBlob *errorMessage = NULL; ID3DBlob *binary = NULL; HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage); if (errorMessage) { const char *message = (const char*)errorMessage->GetBufferPointer(); infoLog.appendSanitized(message); TRACE("\n%s", hlsl); TRACE("\n%s", message); SafeRelease(errorMessage); } if (SUCCEEDED(result)) { return (ShaderBlob*)binary; } else { if (result == E_OUTOFMEMORY) { return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL); } infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]); if (i + 1 < attempts) { infoLog.append(" Retrying with %s.\n", flagNames[i + 1]); } } } return NULL; } }