Commit dad5ed39 by Geoff Lang

Refactor HLSL compilation out of Renderer.

This moves the start-up and tear-down code for D3DCompiler.dll into an object that Renderer9 and Renderer11 use. This will help future efforts to remove references to HLSL at the GL/Renderer interface level. BUG=angle:558 Change-Id: I18fcf9b237265d69c1d7d2ea345696c8fd31df29 Reviewed-on: https://chromium-review.googlesource.com/185568Tested-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8664b063
......@@ -244,6 +244,7 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough3d11vs.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui3dps.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3dui11ps.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\IndexBuffer9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\renderer9_utils.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.h"/>
......@@ -253,8 +254,8 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\SwapChain9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\formatutils9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Query9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\TextureStorage9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\BufferStorage9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Renderer9.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\RenderTarget9.h"/>
......@@ -344,6 +345,7 @@
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Renderer11.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\RenderStateCache.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\BufferStorage11.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\renderer9_utils.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Image9.cpp"/>
......
......@@ -19,6 +19,9 @@
<Filter Include="src\libGLESv2\renderer\d3d11\shaders\compiled">
<UniqueIdentifier>{F444E9E6-7D51-0546-F1E4-B6C8FCDA5FC6}</UniqueIdentifier>
</Filter>
<Filter Include="src\libGLESv2\renderer\d3d">
<UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
</Filter>
<Filter Include="src\libGLESv2\renderer\d3d9">
<UniqueIdentifier>{8BB193D2-4A8B-A094-A81E-D5E262AB1F92}</UniqueIdentifier>
</Filter>
......@@ -618,6 +621,12 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3dui11ps.h">
<Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
</ClInclude>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClInclude>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.cpp">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClCompile>
......@@ -672,9 +681,6 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Query9.h">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClInclude>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.h">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClInclude>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\TextureStorage9.h">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClInclude>
......@@ -690,6 +696,9 @@
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\SwapChain9.cpp">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClCompile>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.h">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClInclude>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\BufferStorage9.h">
<Filter>src\libGLESv2\renderer\d3d9</Filter>
</ClInclude>
......
......@@ -26,147 +26,9 @@ namespace rx
Renderer::Renderer(egl::Display *display) : mDisplay(display)
{
mD3dCompilerModule = NULL;
mD3DCompileFunc = NULL;
mCurrentClientVersion = 2;
}
Renderer::~Renderer()
{
if (mD3dCompilerModule)
{
FreeLibrary(mD3dCompilerModule);
mD3dCompilerModule = NULL;
}
}
bool Renderer::initializeCompiler()
{
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 TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
{
if (GetModuleHandleEx(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<pCompileFunc>(GetProcAddress(mD3dCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
return mD3DCompileFunc != NULL;
}
// Compiles HLSL code into executable binaries
ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, 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 |= optimizationFlags;
#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 |= optimizationFlags;
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 ? ArraySize(extraFlags) : 1;
pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
for (int i = 0; i < attempts; ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
result = compileFunc(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);
SafeRelease(errorMessage);
}
if (SUCCEEDED(result))
{
return (ShaderBlob*)binary;
}
else
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) 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"
......
......@@ -65,9 +65,6 @@ class Image;
class TextureStorage;
class UniformStorage;
typedef void * ShaderBlob;
typedef void (*pCompileFunc)();
struct ConfigDesc
{
GLenum renderTargetFormat;
......@@ -101,7 +98,6 @@ class Renderer
{
public:
explicit Renderer(egl::Display *display);
virtual ~Renderer();
virtual EGLint initialize() = 0;
virtual bool resetDevice() = 0;
......@@ -276,16 +272,11 @@ class Renderer
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
protected:
bool initializeCompiler();
ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags);
egl::Display *mDisplay;
private:
DISALLOW_COPY_AND_ASSIGN(Renderer);
HMODULE mD3dCompilerModule;
pCompileFunc mD3DCompileFunc;
int mCurrentClientVersion;
};
......
#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 TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
{
if (GetModuleHandleEx(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,
unsigned int optimizationFlags, bool alternateFlags) const
{
ASSERT(mD3DCompilerModule && mD3DCompileFunc);
if (!hlsl)
{
return NULL;
}
HRESULT result = S_OK;
UINT flags = 0;
std::string sourceText;
if (gl::perfActive())
{
flags |= D3DCOMPILE_DEBUG;
#ifdef NDEBUG
flags |= optimizationFlags;
#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 |= optimizationFlags;
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 ? ArraySize(extraFlags) : 1;
pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
for (int i = 0; i < attempts; ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
result = compileFunc(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);
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(extraFlagNames[i]);
infoLog.append(" flags.");
if (i + 1 < attempts)
{
infoLog.append(" Retrying with ");
infoLog.append(extraFlagNames[i + 1]);
infoLog.append(".\n");
}
}
}
return NULL;
}
}
#ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
#define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
#include "common/angleutils.h"
#include <windows.h>
namespace gl
{
class InfoLog;
}
namespace rx
{
typedef void* ShaderBlob;
typedef void(*CompileFuncPtr)();
class HLSLCompiler
{
public:
HLSLCompiler();
~HLSLCompiler();
bool initialize();
void release();
ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
unsigned int optimizationFlags, bool alternateFlags) const;
private:
DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
HMODULE mD3DCompilerModule;
CompileFuncPtr mD3DCompileFunc;
};
}
#endif // LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
......@@ -113,7 +113,7 @@ Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
EGLint Renderer11::initialize()
{
if (!initializeCompiler())
if (!mCompiler.initialize())
{
return EGL_NOT_INITIALIZED;
}
......@@ -1800,6 +1800,8 @@ void Renderer11::release()
FreeLibrary(mDxgiModule);
mDxgiModule = NULL;
}
mCompiler.release();
}
bool Renderer11::resetDevice()
......@@ -2837,7 +2839,7 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
return NULL;
}
ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
if (!binary)
{
return NULL;
......
......@@ -14,6 +14,7 @@
#include "common/mathutil.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
#include "libGLESv2/renderer/d3d11/RenderStateCache.h"
#include "libGLESv2/renderer/d3d11/InputLayoutCache.h"
#include "libGLESv2/renderer/RenderTarget.h"
......@@ -250,6 +251,8 @@ class Renderer11 : public Renderer
HMODULE mDxgiModule;
HDC mDc;
HLSLCompiler mCompiler;
bool mDeviceLost;
void initializeDevice();
......
......@@ -156,6 +156,8 @@ void Renderer9::deinitialize()
SafeRelease(mD3d9);
SafeRelease(mD3d9Ex);
mCompiler.release();
if (mDeviceWindow)
{
DestroyWindow(mDeviceWindow);
......@@ -173,7 +175,7 @@ Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
EGLint Renderer9::initialize()
{
if (!initializeCompiler())
if (!mCompiler.initialize())
{
return EGL_NOT_INITIALIZED;
}
......@@ -3348,7 +3350,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
// Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
UINT optimizationFlags = (workaround == ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER ? D3DCOMPILE_SKIP_OPTIMIZATION : ANGLE_COMPILE_OPTIMIZATION_LEVEL);
ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true);
ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true);
if (!binary)
{
return NULL;
......
......@@ -11,6 +11,7 @@
#include "common/angleutils.h"
#include "common/mathutil.h"
#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
#include "libGLESv2/renderer/d3d9/ShaderCache.h"
#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h"
#include "libGLESv2/renderer/Renderer.h"
......@@ -261,6 +262,8 @@ class Renderer9 : public Renderer
IDirect3DDevice9 *mDevice;
IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
HLSLCompiler mCompiler;
Blit9 *mBlit;
HWND mDeviceWindow;
......
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