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 @@
#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[] =
......@@ -1129,8 +1133,118 @@ ShaderExecutable *Renderer11::loadExecutable(const DWORD *function, size_t lengt
ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
{
// TODO
UNIMPLEMENTED();
const char *profile = NULL;
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;
}
......
......@@ -149,6 +149,8 @@ class Renderer11 : public Renderer
bool mDeviceLost;
ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile);
void initializeDevice();
void releaseDeviceResources();
......
......@@ -2698,7 +2698,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
}
gl::D3DConstantTable *constantTable = NULL;
ID3D10Blob *binary = compileToBinary(infoLog, shaderHLSL, profile, &constantTable);
ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, &constantTable);
if (!binary)
return NULL;
......@@ -2709,7 +2709,7 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
}
// 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)
{
......@@ -2756,8 +2756,8 @@ ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, c
for (int i = 0; i < sizeof(extraFlags) / sizeof(UINT); ++i)
{
ID3D10Blob *errorMessage = NULL;
ID3D10Blob *binary = NULL;
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)
......@@ -2789,7 +2789,7 @@ ID3D10Blob *Renderer9::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, c
{
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 ");
......
......@@ -184,7 +184,7 @@ class Renderer9 : public Renderer
void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
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;
......
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