Move compileToBinary to Renderer

Trac #22155 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens The body of compileToBinary was moved to Renderer9 and the ProgramBinary simply calls compileToExecutable which does both the compilation to binary and creation of the shaders which are then wrapped into a ShaderExecutable and then returned. git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1503 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent c68fa87f
......@@ -19,10 +19,6 @@
#include <string>
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
namespace gl
{
std::string str(int i)
......@@ -1032,106 +1028,6 @@ void ProgramBinary::applyUniforms()
}
}
// Compiles the HLSL code of the attached shaders into executable binaries
ID3D10Blob *ProgramBinary::compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, D3DConstantTable **constantTable)
{
if (!hlsl)
{
return NULL;
}
HRESULT result = S_OK;
UINT flags = 0;
std::string sourceText;
if (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)
{
ID3D10Blob *errorMessage = NULL;
ID3D10Blob *binary = NULL;
result = mRenderer->compileShaderSource(hlsl, g_fakepath, profile, flags | extraFlags[i], &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))
{
D3DConstantTable *table = new D3DConstantTable(binary->GetBufferPointer(), binary->GetBufferSize());
if (table->error())
{
delete table;
binary->Release();
return NULL;
}
*constantTable = table;
return binary;
}
else
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (ID3D10Blob*) 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;
}
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)
......@@ -1925,19 +1821,18 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
return false;
}
const char *vertexProfile = mRenderer->getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0";
const char *pixelProfile = mRenderer->getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0";
bool success = true;
D3DConstantTable *constantTableVS = NULL;
D3DConstantTable *constantTablePS = NULL;
ID3D10Blob *vertexBinary = compileToBinary(infoLog, vertexHLSL.c_str(), vertexProfile, &constantTableVS);
ID3D10Blob *pixelBinary = compileToBinary(infoLog, pixelHLSL.c_str(), pixelProfile, &constantTablePS);
rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), GL_VERTEX_SHADER);
rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), GL_FRAGMENT_SHADER);
if (vertexBinary && pixelBinary)
if (vertexExecutable && pixelExecutable)
{
mVertexExecutable = mRenderer->createVertexShader((DWORD*)vertexBinary->GetBufferPointer(), vertexBinary->GetBufferSize());
mPixelExecutable = mRenderer->createPixelShader((DWORD*)pixelBinary->GetBufferPointer(), pixelBinary->GetBufferSize());
rx::ShaderExecutable9 *vshader9 = rx::ShaderExecutable9::makeShaderExecutable9(vertexExecutable);
rx::ShaderExecutable9 *pshader9 = rx::ShaderExecutable9::makeShaderExecutable9(pixelExecutable);
mVertexExecutable = vshader9->getVertexShader();
mPixelExecutable = pshader9->getPixelShader();
if (!mPixelExecutable || !mVertexExecutable)
{
......@@ -1948,17 +1843,15 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
infoLog.append("Failed to create D3D shaders.");
success = false;
}
constantTableVS = vshader9->getConstantTable();
constantTablePS = pshader9->getConstantTable();
}
else
{
success = false;
}
if (vertexBinary) vertexBinary->Release();
if (pixelBinary) pixelBinary->Release();
vertexBinary = NULL;
pixelBinary = NULL;
if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
{
success = false;
......@@ -1971,8 +1864,8 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
success = false;
}
}
delete constantTableVS;
delete constantTablePS;
delete vertexExecutable;
delete pixelExecutable;
// these uniforms are searched as already-decorated because gl_ and dx_
// are reserved prefixes, and do not receive additional decoration
......
......@@ -24,6 +24,8 @@
#include "libGLESv2/mathutil.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/renderer/ShaderExecutable9.h"
namespace gl
{
class FragmentShader;
......@@ -166,8 +168,6 @@ class ProgramBinary : public RefCountObject
private:
DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
ID3D10Blob *compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, D3DConstantTable **constantTable);
int packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader);
bool linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader);
......
......@@ -19,6 +19,8 @@
#include "libGLESv2/Texture.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/renderer/ShaderExecutable.h"
const int versionWindowsVista = MAKEWORD(0x00, 0x06);
const int versionWindows7 = MAKEWORD(0x01, 0x06);
......@@ -39,6 +41,7 @@ class Display;
namespace gl
{
class InfoLog;
class ProgramBinary;
class VertexAttribute;
class Buffer;
......@@ -141,6 +144,7 @@ class Renderer
virtual GLsizei getMaxSupportedSamples() const = 0;
// Pixel operations
virtual bool copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source) = 0;
virtual bool copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source) = 0;
......@@ -154,9 +158,13 @@ class Renderer
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) = 0;
// RenderTarget creation
virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0;
virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) = 0;
// Shader operations
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type) = 0;
protected:
egl::Display *mDisplay;
......
......@@ -829,6 +829,13 @@ RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum forma
return NULL;
}
ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
{
// TODO
UNIMPLEMENTED();
return NULL;
}
bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
bool blitRenderTarget, bool blitDepthStencil)
{
......
......@@ -111,6 +111,7 @@ class Renderer11 : public Renderer
virtual GLsizei getMaxSupportedSamples() const;
// Pixel operations
virtual bool copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source);
virtual bool copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source);
......@@ -124,9 +125,13 @@ class Renderer11 : public Renderer
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
// RenderTarget creation
virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth);
// Shader operations
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type);
// D3D11-renderer specific methods
ID3D11Device *getDevice() { return mDevice; }
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
......
......@@ -18,6 +18,7 @@
#include "libGLESv2/VertexDataManager.h"
#include "libGLESv2/renderer/Renderer9.h"
#include "libGLESv2/renderer/renderer9_utils.h"
#include "libGLESv2/renderer/ShaderExecutable9.h"
#include "libGLESv2/renderer/SwapChain9.h"
#include "libGLESv2/renderer/TextureStorage.h"
#include "libGLESv2/renderer/Image.h"
......@@ -38,6 +39,10 @@
#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[] =
......@@ -2627,6 +2632,157 @@ RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format
return renderTarget;
}
ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
{
const char *profile = NULL;
switch (type)
{
case GL_VERTEX_SHADER:
profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0";
break;
case GL_FRAGMENT_SHADER:
profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0";
break;
default:
UNREACHABLE();
return NULL;
}
gl::D3DConstantTable *constantTable = NULL;
ID3D10Blob *binary = compileToBinary(infoLog, shaderHLSL, profile, &constantTable);
if (!binary)
return NULL;
ShaderExecutable9 *executable = NULL;
switch (type)
{
case GL_VERTEX_SHADER:
{
IDirect3DVertexShader9 *vshader = createVertexShader((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize());
if (vshader)
{
executable = new ShaderExecutable9(vshader, constantTable);
}
}
break;
case GL_FRAGMENT_SHADER:
{
IDirect3DPixelShader9 *pshader = createPixelShader((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize());
if (pshader)
{
executable = new ShaderExecutable9(pshader, constantTable);
}
}
break;
default:
UNREACHABLE();
break;
}
return executable;
}
// 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)
{
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)
{
ID3D10Blob *errorMessage = NULL;
ID3D10Blob *binary = NULL;
result = compileShaderSource(hlsl, gl::g_fakepath, profile, flags | extraFlags[i], &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))
{
gl::D3DConstantTable *table = new gl::D3DConstantTable(binary->GetBufferPointer(), binary->GetBufferSize());
if (table->error())
{
delete table;
binary->Release();
return NULL;
}
*constantTable = table;
return binary;
}
else
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (ID3D10Blob*) 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);
......
......@@ -31,6 +31,7 @@
namespace gl
{
class D3DConstantTable;
class VertexDataManager;
class StreamingIndexBuffer;
struct TranslatedAttribute;
......@@ -151,6 +152,7 @@ class Renderer9 : public Renderer
D3DFORMAT ConvertTextureInternalFormat(GLint internalformat);
// Pixel operations
virtual bool copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source);
virtual bool copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source);
......@@ -164,9 +166,14 @@ class Renderer9 : public Renderer
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
// RenderTarget creation
virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth);
// Shader operations
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type);
// D3D9-renderer specific methods
bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
D3DPOOL getTexturePool(DWORD usage) const;
......@@ -179,6 +186,8 @@ 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);
D3DPOOL getBufferPool(DWORD usage) const;
HMODULE mD3d9Module;
......
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