Move HLSL compilation to Renderer.

TRAC #22205 Signed-off-by: Daniel Koch Signed-off-by: Geoff Lang Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1546 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent be281b08
......@@ -6,6 +6,8 @@
// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
#include "libGLESv2/main.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/Renderer9.h"
#include "libGLESv2/renderer/Renderer11.h"
......@@ -15,6 +17,152 @@
#define ANGLE_ENABLE_D3D11 0
#endif
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
namespace rx
{
Renderer::Renderer(egl::Display *display) : mDisplay(display)
{
mD3dCompilerModule = NULL;
mD3DCompileFunc = NULL;
}
Renderer::~Renderer()
{
if (mD3dCompilerModule)
{
FreeLibrary(mD3dCompilerModule);
mD3dCompilerModule = NULL;
}
}
bool Renderer::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 TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
for (int i = 0; i < sizeof(d3dCompilerNames) / sizeof(*d3dCompilerNames); ++i)
{
if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule))
{
break;
}
}
#else
// Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
if (!mD3dCompilerModule)
{
ERR("No D3D compiler module found - aborting!\n");
return false;
}
mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3dCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
return mD3DCompileFunc != NULL;
}
// Compiles HLSL code into executable binaries
ID3DBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, bool alternateFlags)
{
if (!hlsl)
{
return NULL;
}
HRESULT result = S_OK;
UINT flags = 0;
std::string sourceText;
if (gl::perfActive())
{
flags |= D3DCOMPILE_DEBUG;
#ifdef NDEBUG
flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
#else
flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
std::string sourcePath = getTempPath();
sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
else
{
flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
sourceText = hlsl;
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
const static UINT extraFlags[] =
{
0,
D3DCOMPILE_AVOID_FLOW_CONTROL,
D3DCOMPILE_PREFER_FLOW_CONTROL
};
const static char * const extraFlagNames[] =
{
"default",
"avoid flow control",
"prefer flow control"
};
int attempts = (alternateFlags ? sizeof(extraFlags) / sizeof(UINT) : 1);
for (int i = 0; i < attempts; ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
result = mD3DCompileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
"main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
if (errorMessage)
{
const char *message = (const char*)errorMessage->GetBufferPointer();
infoLog.appendSanitized(message);
TRACE("\n%s", hlsl);
TRACE("\n%s", message);
errorMessage->Release();
errorMessage = NULL;
}
if (SUCCEEDED(result))
{
return binary;
}
else
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (ID3DBlob*) NULL);
}
infoLog.append("Warning: D3D shader compilation failed with ");
infoLog.append(extraFlagNames[i]);
infoLog.append(" flags.");
if (i + 1 < attempts)
{
infoLog.append(" Retrying with ");
infoLog.append(extraFlagNames[i + 1]);
infoLog.append(".\n");
}
}
}
return NULL;
}
}
extern "C"
{
......
......@@ -16,6 +16,8 @@
#define EGLAPI
#include <EGL/egl.h>
#include <D3Dcompiler.h>
#include "libGLESv2/Texture.h"
#include "libGLESv2/angletypes.h"
......@@ -65,8 +67,8 @@ struct ConfigDesc
class Renderer
{
public:
explicit Renderer(egl::Display *display) : mDisplay(display) {};
virtual ~Renderer() {};
explicit Renderer(egl::Display *display);
virtual ~Renderer();
virtual EGLint initialize() = 0;
virtual bool resetDevice() = 0;
......@@ -165,11 +167,16 @@ class Renderer
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type) = 0;
protected:
bool initializeCompiler();
ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, bool alternateFlags);
egl::Display *mDisplay;
private:
DISALLOW_COPY_AND_ASSIGN(Renderer);
HMODULE mD3dCompilerModule;
pD3DCompile mD3DCompileFunc;
};
}
......
......@@ -23,10 +23,6 @@
#include "libEGL/Config.h"
#include "libEGL/Display.h"
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
namespace rx
{
static const DXGI_FORMAT RenderTargetFormats[] =
......@@ -43,7 +39,6 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(
{
mD3d11Module = NULL;
mDxgiModule = NULL;
mD3dCompilerModule = NULL;
mDeviceLost = false;
......@@ -92,12 +87,6 @@ Renderer11::~Renderer11()
FreeLibrary(mDxgiModule);
mDxgiModule = NULL;
}
if (mD3dCompilerModule)
{
FreeLibrary(mD3dCompilerModule);
mD3dCompilerModule = NULL;
}
}
Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
......@@ -108,6 +97,11 @@ Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
EGLint Renderer11::initialize()
{
if (!initializeCompiler())
{
return EGL_NOT_INITIALIZED;
}
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
......@@ -184,31 +178,6 @@ EGLint Renderer11::initialize()
return EGL_NOT_INITIALIZED;
}
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
// Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
for (int i = 0; i < sizeof(d3dCompilerNames) / sizeof(*d3dCompilerNames); ++i)
{
if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule))
{
break;
}
}
#else
// Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
if (!mD3dCompilerModule)
{
terminate();
return false;
}
mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3dCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
initializeDevice();
return EGL_SUCCESS;
......@@ -1244,7 +1213,7 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
return NULL;
}
ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile);
ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
if (!binary)
return NULL;
......@@ -1254,96 +1223,6 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
return executable;
}
// Compiles the HLSL code of the attached shaders into executable binaries
ID3DBlob *Renderer11::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile)
{
if (!hlsl)
{
return NULL;
}
HRESULT result = S_OK;
UINT flags = 0;
std::string sourceText;
if (gl::perfActive())
{
flags |= D3DCOMPILE_DEBUG;
#ifdef NDEBUG
flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
#else
flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
std::string sourcePath = getTempPath();
sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
else
{
flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
sourceText = hlsl;
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
const static UINT extraFlags[] =
{
0,
// D3DCOMPILE_AVOID_FLOW_CONTROL,
// D3DCOMPILE_PREFER_FLOW_CONTROL
};
const static char * const extraFlagNames[] =
{
"default",
"avoid flow control",
"prefer flow control"
};
for (int i = 0; i < sizeof(extraFlags) / sizeof(UINT); ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
result = mD3DCompileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
"main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
if (errorMessage)
{
const char *message = (const char*)errorMessage->GetBufferPointer();
infoLog.appendSanitized(message);
TRACE("\n%s", hlsl);
TRACE("\n%s", message);
errorMessage->Release();
errorMessage = NULL;
}
if (SUCCEEDED(result))
{
return binary;
}
else
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (ID3DBlob*) NULL);
}
infoLog.append("Warning: D3D shader compilation failed with ");
infoLog.append(extraFlagNames[i]);
infoLog.append(" flags.");
if (i + 1 < sizeof(extraFlagNames) / sizeof(char*))
{
infoLog.append(" Retrying with ");
infoLog.append(extraFlagNames[i + 1]);
infoLog.append(".\n");
}
}
}
return NULL;
}
bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
bool blitRenderTarget, bool blitDepthStencil)
{
......
......@@ -144,13 +144,8 @@ class Renderer11 : public Renderer
HMODULE mDxgiModule;
HDC mDc;
HMODULE mD3dCompilerModule;
pD3DCompile mD3DCompileFunc;
bool mDeviceLost;
ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile);
void initializeDevice();
void releaseDeviceResources();
......
......@@ -39,10 +39,6 @@
#define ANGLE_ENABLE_D3D9EX 1
#endif // !defined(ANGLE_ENABLE_D3D9EX)
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
namespace rx
{
static const D3DFORMAT RenderTargetFormats[] =
......@@ -73,8 +69,6 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Rend
{
mD3d9Module = NULL;
mD3dCompilerModule = NULL;
mD3d9 = NULL;
mD3d9Ex = NULL;
mDevice = NULL;
......@@ -148,12 +142,6 @@ Renderer9::~Renderer9()
mD3d9Module = NULL;
}
if (mD3dCompilerModule)
{
FreeLibrary(mD3dCompilerModule);
mD3dCompilerModule = NULL;
}
while (!mMultiSampleSupport.empty())
{
delete [] mMultiSampleSupport.begin()->second;
......@@ -169,6 +157,11 @@ Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
EGLint Renderer9::initialize()
{
if (!initializeCompiler())
{
return EGL_NOT_INITIALIZED;
}
if (mSoftwareDevice)
{
mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
......@@ -207,31 +200,6 @@ EGLint Renderer9::initialize()
return EGL_NOT_INITIALIZED;
}
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
// Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
for (int i = 0; i < sizeof(d3dCompilerNames) / sizeof(*d3dCompilerNames); ++i)
{
if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule))
{
break;
}
}
#else
// Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
if (!mD3dCompilerModule)
{
terminate();
return false;
}
mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3dCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
if (mDc != NULL)
{
// UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
......@@ -2697,7 +2665,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
return NULL;
}
ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile);
ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, true);
if (!binary)
return NULL;
......@@ -2715,96 +2683,6 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
return executable;
}
// Compiles the HLSL code of the attached shaders into executable binaries
ID3DBlob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile)
{
if (!hlsl)
{
return NULL;
}
HRESULT result = S_OK;
UINT flags = 0;
std::string sourceText;
if (gl::perfActive())
{
flags |= D3DCOMPILE_DEBUG;
#ifdef NDEBUG
flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
#else
flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
std::string sourcePath = getTempPath();
sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
else
{
flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
sourceText = hlsl;
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
const static UINT extraFlags[] =
{
0,
D3DCOMPILE_AVOID_FLOW_CONTROL,
D3DCOMPILE_PREFER_FLOW_CONTROL
};
const static char * const extraFlagNames[] =
{
"default",
"avoid flow control",
"prefer flow control"
};
for (int i = 0; i < sizeof(extraFlags) / sizeof(UINT); ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
result = mD3DCompileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
"main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
if (errorMessage)
{
const char *message = (const char*)errorMessage->GetBufferPointer();
infoLog.appendSanitized(message);
TRACE("\n%s", hlsl);
TRACE("\n%s", message);
errorMessage->Release();
errorMessage = NULL;
}
if (SUCCEEDED(result))
{
return binary;
}
else
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (ID3DBlob*) NULL);
}
infoLog.append("Warning: D3D shader compilation failed with ");
infoLog.append(extraFlagNames[i]);
infoLog.append(" flags.");
if (i + 1 < sizeof(extraFlagNames) / sizeof(char*))
{
infoLog.append(" Retrying with ");
infoLog.append(extraFlagNames[i + 1]);
infoLog.append(".\n");
}
}
}
return NULL;
}
bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
return mBlit->boxFilter(source, dest);
......
......@@ -20,7 +20,6 @@
#include <EGL/egl.h>
#include <d3d9.h>
#include <D3Dcompiler.h>
#include "common/angleutils.h"
#include "libGLESv2/Context.h"
......@@ -184,16 +183,11 @@ class Renderer9 : public Renderer
void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile);
D3DPOOL getBufferPool(DWORD usage) const;
HMODULE mD3d9Module;
HDC mDc;
HMODULE mD3dCompilerModule;
pD3DCompile mD3DCompileFunc;
void initializeDevice();
D3DPRESENT_PARAMETERS getDefaultPresentParameters();
void releaseDeviceResources();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment