Implemented Renderer11::compileToExecutable.

TRAC #22191 Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1529 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 04af90f0
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
#include "libEGL/Config.h" #include "libEGL/Config.h"
#include "libEGL/Display.h" #include "libEGL/Display.h"
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
namespace rx namespace rx
{ {
static const DXGI_FORMAT RenderTargetFormats[] = static const DXGI_FORMAT RenderTargetFormats[] =
...@@ -1129,8 +1133,118 @@ ShaderExecutable *Renderer11::loadExecutable(const DWORD *function, size_t lengt ...@@ -1129,8 +1133,118 @@ ShaderExecutable *Renderer11::loadExecutable(const DWORD *function, size_t lengt
ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type) ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
{ {
// TODO const char *profile = NULL;
UNIMPLEMENTED();
switch (type)
{
case GL_VERTEX_SHADER:
profile = "vs_4_0";
break;
case GL_FRAGMENT_SHADER:
profile = "ps_4_0";
break;
default:
UNREACHABLE();
return NULL;
}
ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile);
if (!binary)
return NULL;
ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
binary->Release();
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; return NULL;
} }
......
...@@ -149,6 +149,8 @@ class Renderer11 : public Renderer ...@@ -149,6 +149,8 @@ class Renderer11 : public Renderer
bool mDeviceLost; bool mDeviceLost;
ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile);
void initializeDevice(); void initializeDevice();
void releaseDeviceResources(); void releaseDeviceResources();
......
...@@ -2698,7 +2698,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha ...@@ -2698,7 +2698,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
} }
gl::D3DConstantTable *constantTable = NULL; gl::D3DConstantTable *constantTable = NULL;
ID3D10Blob *binary = compileToBinary(infoLog, shaderHLSL, profile, &constantTable); ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, &constantTable);
if (!binary) if (!binary)
return NULL; return NULL;
...@@ -2709,7 +2709,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha ...@@ -2709,7 +2709,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
} }
// Compiles the HLSL code of the attached shaders into executable binaries // Compiles the HLSL code of the attached shaders into executable binaries
ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, gl::D3DConstantTable **constantTable) ID3DBlob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, gl::D3DConstantTable **constantTable)
{ {
if (!hlsl) if (!hlsl)
{ {
...@@ -2756,8 +2756,8 @@ ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, c ...@@ -2756,8 +2756,8 @@ ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, c
for (int i = 0; i < sizeof(extraFlags) / sizeof(UINT); ++i) for (int i = 0; i < sizeof(extraFlags) / sizeof(UINT); ++i)
{ {
ID3D10Blob *errorMessage = NULL; ID3DBlob *errorMessage = NULL;
ID3D10Blob *binary = NULL; ID3DBlob *binary = NULL;
result = mD3DCompileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, result = mD3DCompileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
"main", profile, flags | extraFlags[i], 0, &binary, &errorMessage); "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
if (errorMessage) if (errorMessage)
...@@ -2789,7 +2789,7 @@ ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, c ...@@ -2789,7 +2789,7 @@ ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, c
{ {
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{ {
return error(GL_OUT_OF_MEMORY, (ID3D10Blob*) NULL); return error(GL_OUT_OF_MEMORY, (ID3DBlob*) NULL);
} }
infoLog.append("Warning: D3D shader compilation failed with "); infoLog.append("Warning: D3D shader compilation failed with ");
......
...@@ -184,7 +184,7 @@ class Renderer9 : public Renderer ...@@ -184,7 +184,7 @@ class Renderer9 : public Renderer
void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
ID3D10Blob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, gl::D3DConstantTable **constantTable); ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, gl::D3DConstantTable **constantTable);
D3DPOOL getBufferPool(DWORD usage) const; D3DPOOL getBufferPool(DWORD usage) const;
......
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