blob: 5613919ea111daf313b68b510574db37191dd571 [file] [log] [blame]
#include "precompiled.h"
#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<CompileFuncPtr>(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<pD3DCompile>(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 ");
infoLog.append(flagNames[i]);
infoLog.append(" flags.");
if (i + 1 < attempts)
{
infoLog.append(" Retrying with ");
infoLog.append(flagNames[i + 1]);
infoLog.append(".\n");
}
}
}
return NULL;
}
}