Commit 492a7e43 by Geoff Lang

Encapulate the ESSL compiler into a GL object that is per-context.

* Allows for multiple contexts have to have different client versions, caps and extensions without causing shader compilation failures. BUG=angle:823 Change-Id: I523679e90be031b0b7fa385d46d6839b1cf3029f Reviewed-on: https://chromium-review.googlesource.com/227710Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 797ff4c0
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Compiler.cpp: implements the gl::Compiler class.
#include "libANGLE/Compiler.h"
#include "libANGLE/renderer/CompilerImpl.h"
#include "common/debug.h"
namespace gl
{
Compiler::Compiler(rx::CompilerImpl *impl)
: mCompiler(impl)
{
ASSERT(mCompiler);
}
Compiler::~Compiler()
{
SafeDelete(mCompiler);
}
Error Compiler::release()
{
return mCompiler->release();
}
rx::CompilerImpl *Compiler::getImplementation()
{
return mCompiler;
}
}
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Compiler.h: Defines the gl::Compiler class, abstracting the ESSL compiler
// that a GL context holds.
#ifndef LIBANGLE_COMPILER_H_
#define LIBANGLE_COMPILER_H_
#include "libANGLE/Error.h"
namespace rx
{
class CompilerImpl;
}
namespace gl
{
class Compiler final
{
public:
explicit Compiler(rx::CompilerImpl *impl);
~Compiler();
Error release();
rx::CompilerImpl *getImplementation();
private:
rx::CompilerImpl *mCompiler;
};
}
#endif // LIBANGLE_COMPILER_H_
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "common/utilities.h" #include "common/utilities.h"
#include "common/platform.h" #include "common/platform.h"
#include "libANGLE/Compiler.h"
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/Fence.h" #include "libANGLE/Fence.h"
...@@ -118,6 +119,8 @@ Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *r ...@@ -118,6 +119,8 @@ Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *r
mResetStatus = GL_NO_ERROR; mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT); mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess; mRobustAccess = robustAccess;
mCompiler = new Compiler(mRenderer->createCompiler(getData()));
} }
Context::~Context() Context::~Context()
...@@ -160,6 +163,8 @@ Context::~Context() ...@@ -160,6 +163,8 @@ Context::~Context()
{ {
mResourceManager->release(); mResourceManager->release();
} }
SafeDelete(mCompiler);
} }
void Context::makeCurrent(egl::Surface *surface) void Context::makeCurrent(egl::Surface *surface)
...@@ -759,6 +764,11 @@ Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const ...@@ -759,6 +764,11 @@ Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
return mState.getSamplerTexture(sampler, type); return mState.getSamplerTexture(sampler, type);
} }
Compiler *Context::getCompiler() const
{
return mCompiler;
}
void Context::getBooleanv(GLenum pname, GLboolean *params) void Context::getBooleanv(GLenum pname, GLboolean *params)
{ {
switch (pname) switch (pname)
...@@ -1606,11 +1616,6 @@ Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY ...@@ -1606,11 +1616,6 @@ Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY
dstX0, dstY0, dstX1, dstY1, mask, filter); dstX0, dstY0, dstX1, dstY1, mask, filter);
} }
void Context::releaseShaderCompiler()
{
mRenderer->releaseShaderCompiler();
}
void Context::initCaps(GLuint clientVersion) void Context::initCaps(GLuint clientVersion)
{ {
mCaps = mRenderer->getRendererCaps(); mCaps = mRenderer->getRendererCaps();
......
...@@ -40,6 +40,7 @@ class Surface; ...@@ -40,6 +40,7 @@ class Surface;
namespace gl namespace gl
{ {
class Compiler;
class Shader; class Shader;
class Program; class Program;
class Texture; class Texture;
...@@ -159,6 +160,8 @@ class Context ...@@ -159,6 +160,8 @@ class Context
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
Compiler *getCompiler() const;
bool isSampler(GLuint samplerName) const; bool isSampler(GLuint samplerName) const;
void getBooleanv(GLenum pname, GLboolean *params); void getBooleanv(GLenum pname, GLboolean *params);
...@@ -215,8 +218,6 @@ class Context ...@@ -215,8 +218,6 @@ class Context
Data getData() const; Data getData() const;
void releaseShaderCompiler();
private: private:
DISALLOW_COPY_AND_ASSIGN(Context); DISALLOW_COPY_AND_ASSIGN(Context);
...@@ -238,6 +239,9 @@ class Context ...@@ -238,6 +239,9 @@ class Context
TextureCapsMap mTextureCaps; TextureCapsMap mTextureCaps;
Extensions mExtensions; Extensions mExtensions;
// Shader compiler
Compiler *mCompiler;
rx::Renderer *const mRenderer; rx::Renderer *const mRenderer;
State mState; State mState;
......
...@@ -94,7 +94,7 @@ GLuint ResourceManager::createShader(const gl::Data &data, GLenum type) ...@@ -94,7 +94,7 @@ GLuint ResourceManager::createShader(const gl::Data &data, GLenum type)
if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
{ {
mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle); mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
} }
else UNREACHABLE(); else UNREACHABLE();
......
...@@ -131,9 +131,9 @@ void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, ...@@ -131,9 +131,9 @@ void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length,
getSourceImpl(debugInfo, bufSize, length, buffer); getSourceImpl(debugInfo, bufSize, length, buffer);
} }
void Shader::compile(const gl::Data &data) void Shader::compile(Compiler *compiler)
{ {
mCompiled = mShader->compile(data, mSource); mCompiled = mShader->compile(compiler, mSource);
} }
void Shader::addRef() void Shader::addRef()
......
...@@ -29,6 +29,7 @@ class ShaderImpl; ...@@ -29,6 +29,7 @@ class ShaderImpl;
namespace gl namespace gl
{ {
class Compiler;
class ResourceManager; class ResourceManager;
struct Data; struct Data;
...@@ -75,7 +76,7 @@ class Shader ...@@ -75,7 +76,7 @@ class Shader
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const; void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const;
void compile(const gl::Data &data); void compile(Compiler *compiler);
bool isCompiled() const { return mCompiled; } bool isCompiled() const { return mCompiled; }
void addRef(); void addRef();
......
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CompilerImpl.h: Defines the rx::CompilerImpl class, an implementation interface
// for the gl::Compiler object.
#include "libANGLE/Error.h"
#ifndef LIBANGLE_RENDERER_COMPILERIMPL_H_
#define LIBANGLE_RENDERER_COMPILERIMPL_H_
namespace rx
{
class CompilerImpl
{
public:
CompilerImpl() {}
virtual ~CompilerImpl() {}
virtual gl::Error release() = 0;
};
}
#endif // LIBANGLE_RENDERER_COMPILERIMPL_H_
...@@ -49,6 +49,7 @@ class TransformFeedbackImpl; ...@@ -49,6 +49,7 @@ class TransformFeedbackImpl;
class RenderbufferImpl; class RenderbufferImpl;
class DefaultAttachmentImpl; class DefaultAttachmentImpl;
class FramebufferImpl; class FramebufferImpl;
class CompilerImpl;
struct TranslatedIndexData; struct TranslatedIndexData;
struct Workarounds; struct Workarounds;
class SwapChain; class SwapChain;
...@@ -102,12 +103,10 @@ class Renderer ...@@ -102,12 +103,10 @@ class Renderer
virtual bool getPostSubBufferSupport() const = 0; virtual bool getPostSubBufferSupport() const = 0;
// Shader creation // Shader creation
virtual ShaderImpl *createShader(const gl::Data &data, GLenum type) = 0; virtual CompilerImpl *createCompiler(const gl::Data &data) = 0;
virtual ShaderImpl *createShader(GLenum type) = 0;
virtual ProgramImpl *createProgram() = 0; virtual ProgramImpl *createProgram() = 0;
// Shader operations
virtual void releaseShaderCompiler() = 0;
// Framebuffer creation // Framebuffer creation
virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) = 0; virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) = 0;
virtual FramebufferImpl *createFramebuffer() = 0; virtual FramebufferImpl *createFramebuffer() = 0;
......
...@@ -23,7 +23,7 @@ class ShaderImpl ...@@ -23,7 +23,7 @@ class ShaderImpl
ShaderImpl() { } ShaderImpl() { }
virtual ~ShaderImpl() { } virtual ~ShaderImpl() { }
virtual bool compile(const gl::Data &data, const std::string &source) = 0; virtual bool compile(gl::Compiler *compiler, const std::string &source) = 0;
virtual const std::string &getInfoLog() const = 0; virtual const std::string &getInfoLog() const = 0;
virtual const std::string &getTranslatedSource() const = 0; virtual const std::string &getTranslatedSource() const = 0;
virtual std::string getDebugInfo() const = 0; virtual std::string getDebugInfo() const = 0;
......
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CompilerD3D.cpp: Implementation of the rx::CompilerD3D class.
#include "libANGLE/renderer/d3d/CompilerD3D.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Data.h"
#include "common/debug.h"
namespace rx
{
// Global count of active shader compiler handles. Needed to know when to call ShInitialize and ShFinalize.
static size_t activeCompilerHandles = 0;
CompilerD3D::CompilerD3D(const gl::Data &data, ShShaderOutput outputType)
: mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC),
mOutputType(outputType),
mResources(),
mFragmentCompiler(NULL),
mVertexCompiler(NULL)
{
ASSERT(data.clientVersion == 2 || data.clientVersion == 3);
const gl::Caps &caps = *data.caps;
const gl::Extensions &extensions = *data.extensions;
ShInitBuiltInResources(&mResources);
mResources.MaxVertexAttribs = caps.maxVertexAttributes;
mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
mResources.MaxVaryingVectors = caps.maxVaryingVectors;
mResources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits;
mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
mResources.MaxTextureImageUnits = caps.maxTextureImageUnits;
mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
mResources.MaxDrawBuffers = caps.maxDrawBuffers;
mResources.OES_standard_derivatives = extensions.standardDerivatives;
mResources.EXT_draw_buffers = extensions.drawBuffers;
mResources.EXT_shader_texture_lod = 1;
// resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
mResources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
mResources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
// GLSL ES 3.0 constants
mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
mResources.MinProgramTexelOffset = caps.minProgramTexelOffset;
mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
}
CompilerD3D::~CompilerD3D()
{
release();
}
CompilerD3D *CompilerD3D::makeCompilerD3D(CompilerImpl *compiler)
{
ASSERT(HAS_DYNAMIC_TYPE(CompilerD3D*, compiler));
return static_cast<CompilerD3D*>(compiler);
}
gl::Error CompilerD3D::release()
{
if (mFragmentCompiler)
{
ShDestruct(mFragmentCompiler);
mFragmentCompiler = NULL;
ASSERT(activeCompilerHandles > 0);
activeCompilerHandles--;
}
if (mVertexCompiler)
{
ShDestruct(mVertexCompiler);
mVertexCompiler = NULL;
ASSERT(activeCompilerHandles > 0);
activeCompilerHandles--;
}
if (activeCompilerHandles == 0)
{
ShFinalize();
}
return gl::Error(GL_NO_ERROR);
}
ShHandle CompilerD3D::getCompilerHandle(GLenum type)
{
ShHandle *compiler = NULL;
switch (type)
{
case GL_VERTEX_SHADER:
compiler = &mVertexCompiler;
break;
case GL_FRAGMENT_SHADER:
compiler = &mFragmentCompiler;
break;
default:
UNREACHABLE();
return NULL;
}
if (!(*compiler))
{
if (activeCompilerHandles == 0)
{
ShInitialize();
}
*compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources);
activeCompilerHandles++;
}
return *compiler;
}
}
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CompilerD3D.h: Defines the rx::CompilerD3D class, an implementation of rx::CompilerImpl.
#ifndef LIBANGLE_RENDERER_COMPILERD3D_H_
#define LIBANGLE_RENDERER_COMPILERD3D_H_
#include "libANGLE/renderer/CompilerImpl.h"
#include "libANGLE/Caps.h"
#include "GLSLANG/ShaderLang.h"
namespace gl
{
struct Data;
}
namespace rx
{
class CompilerD3D : public CompilerImpl
{
public:
CompilerD3D(const gl::Data &data, ShShaderOutput outputType);
virtual ~CompilerD3D();
static CompilerD3D *makeCompilerD3D(CompilerImpl *compiler);
gl::Error release() override;
ShHandle getCompilerHandle(GLenum type);
private:
ShShaderSpec mSpec;
ShShaderOutput mOutputType;
ShBuiltInResources mResources;
ShHandle mFragmentCompiler;
ShHandle mVertexCompiler;
};
}
#endif // LIBANGLE_RENDERER_COMPILERD3D_H_
...@@ -1352,7 +1352,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad ...@@ -1352,7 +1352,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
if (uniform.staticUse) if (uniform.staticUse)
{ {
defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); defineUniformBase(vertexShaderD3D, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
} }
} }
...@@ -1362,7 +1362,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad ...@@ -1362,7 +1362,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
if (uniform.staticUse) if (uniform.staticUse)
{ {
defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); defineUniformBase(fragmentShaderD3D, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
} }
} }
...@@ -1386,17 +1386,17 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad ...@@ -1386,17 +1386,17 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
return true; return true;
} }
void ProgramD3D::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister) void ProgramD3D::defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister)
{ {
ShShaderOutput outputType = ShaderD3D::getCompilerOutputType(shader); ShShaderOutput outputType = shader->getCompilerOutputType();
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
encoder.skipRegisters(uniformRegister); encoder.skipRegisters(uniformRegister);
defineUniform(shader, uniform, uniform.name, &encoder); defineUniform(shader, uniform, uniform.name, &encoder);
} }
void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform,
const std::string &fullName, sh::HLSLBlockEncoder *encoder) const std::string &fullName, sh::HLSLBlockEncoder *encoder)
{ {
if (uniform.isStruct()) if (uniform.isStruct())
{ {
...@@ -1438,11 +1438,11 @@ void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, ...@@ -1438,11 +1438,11 @@ void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
ASSERT(linkedUniform->registerElement == encoder->getCurrentElement()); ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
if (shader == GL_FRAGMENT_SHADER) if (shader->getShaderType() == GL_FRAGMENT_SHADER)
{ {
linkedUniform->psRegisterIndex = encoder->getCurrentRegister(); linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
} }
else if (shader == GL_VERTEX_SHADER) else if (shader->getShaderType() == GL_VERTEX_SHADER)
{ {
linkedUniform->vsRegisterIndex = encoder->getCurrentRegister(); linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
} }
......
...@@ -176,8 +176,8 @@ class ProgramD3D : public ProgramImpl ...@@ -176,8 +176,8 @@ class ProgramD3D : public ProgramImpl
GLenum textureType; GLenum textureType;
}; };
void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister); void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
sh::HLSLBlockEncoder *encoder); sh::HLSLBlockEncoder *encoder);
bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps); bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
......
...@@ -134,7 +134,6 @@ class RendererD3D : public Renderer ...@@ -134,7 +134,6 @@ class RendererD3D : public Renderer
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0; virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0;
// Shader operations // Shader operations
virtual void releaseShaderCompiler() = 0;
virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0; bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0;
......
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. // ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
#include "libANGLE/Shader.h" #include "libANGLE/Shader.h"
#include "libANGLE/Compiler.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h"
#include "libANGLE/features.h" #include "libANGLE/features.h"
#include "common/utilities.h" #include "common/utilities.h"
...@@ -56,9 +58,6 @@ void FilterInactiveVariables(std::vector<VarT> *variableList) ...@@ -56,9 +58,6 @@ void FilterInactiveVariables(std::vector<VarT> *variableList)
} }
} }
void *ShaderD3D::mFragmentCompiler = NULL;
void *ShaderD3D::mVertexCompiler = NULL;
template <typename VarT> template <typename VarT>
const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList) const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList)
{ {
...@@ -66,13 +65,11 @@ const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableLis ...@@ -66,13 +65,11 @@ const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableLis
return variableList; return variableList;
} }
ShaderD3D::ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer) ShaderD3D::ShaderD3D(GLenum type)
: mType(type), : mShaderType(type),
mRenderer(renderer),
mShaderVersion(100) mShaderVersion(100)
{ {
uncompile(); uncompile();
initializeCompiler(data);
} }
ShaderD3D::~ShaderD3D() ShaderD3D::~ShaderD3D()
...@@ -93,68 +90,11 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl) ...@@ -93,68 +90,11 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl)
std::string ShaderD3D::getDebugInfo() const std::string ShaderD3D::getDebugInfo() const
{ {
return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mType) + " SHADER END\n"; return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mShaderType) + " SHADER END\n";
}
// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
void ShaderD3D::initializeCompiler(const gl::Data &data)
{
if (!mFragmentCompiler)
{
bool result = ShInitialize();
if (result)
{
ShShaderSpec specVersion = (data.clientVersion >= 3) ? SH_GLES3_SPEC : SH_GLES2_SPEC;
ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
const gl::Caps &caps = *data.caps;
const gl::Extensions &extensions = *data.extensions;
resources.MaxVertexAttribs = caps.maxVertexAttributes;
resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
resources.MaxVaryingVectors = caps.maxVaryingVectors;
resources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits;
resources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
resources.MaxTextureImageUnits = caps.maxTextureImageUnits;
resources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
resources.MaxDrawBuffers = caps.maxDrawBuffers;
resources.OES_standard_derivatives = extensions.standardDerivatives;
resources.EXT_draw_buffers = extensions.drawBuffers;
resources.EXT_shader_texture_lod = 1;
resources.EXT_shader_framebuffer_fetch = 0;
resources.NV_shader_framebuffer_fetch = 0;
resources.ARM_shader_framebuffer_fetch = 0;
// resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
// GLSL ES 3.0 constants
resources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
resources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
resources.MinProgramTexelOffset = caps.minProgramTexelOffset;
resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, specVersion, hlslVersion, &resources);
mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, specVersion, hlslVersion, &resources);
}
}
} }
void ShaderD3D::releaseCompiler()
{
ShDestruct(mFragmentCompiler);
ShDestruct(mVertexCompiler);
mFragmentCompiler = NULL;
mVertexCompiler = NULL;
ShFinalize(); void ShaderD3D::parseVaryings(ShHandle compiler)
}
void ShaderD3D::parseVaryings(void *compiler)
{ {
if (!mHlsl.empty()) if (!mHlsl.empty())
{ {
...@@ -192,6 +132,7 @@ void ShaderD3D::resetVaryingsRegisterAssignment() ...@@ -192,6 +132,7 @@ void ShaderD3D::resetVaryingsRegisterAssignment()
void ShaderD3D::uncompile() void ShaderD3D::uncompile()
{ {
// set by compileToHLSL // set by compileToHLSL
mCompilerOutputType = SH_ESSL_OUTPUT;
mHlsl.clear(); mHlsl.clear();
mInfoLog.clear(); mInfoLog.clear();
...@@ -216,11 +157,8 @@ void ShaderD3D::uncompile() ...@@ -216,11 +157,8 @@ void ShaderD3D::uncompile()
mDebugInfo.clear(); mDebugInfo.clear();
} }
void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::string &source) void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source)
{ {
// ensure the compiler is loaded
initializeCompiler(data);
int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
std::string sourcePath; std::string sourcePath;
...@@ -256,12 +194,7 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s ...@@ -256,12 +194,7 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s
mShaderVersion = ShGetShaderVersion(compiler); mShaderVersion = ShGetShaderVersion(compiler);
if (mShaderVersion == 300 && data.clientVersion < 3) if (result)
{
mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
TRACE("\n%s", mInfoLog.c_str());
}
else if (result)
{ {
mHlsl = ShGetObjectCode(compiler); mHlsl = ShGetObjectCode(compiler);
...@@ -383,62 +316,48 @@ unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName) ...@@ -383,62 +316,48 @@ unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName)
return mInterfaceBlockRegisterMap.find(blockName)->second; return mInterfaceBlockRegisterMap.find(blockName)->second;
} }
void *ShaderD3D::getCompiler() GLenum ShaderD3D::getShaderType() const
{ {
if (mType == GL_VERTEX_SHADER) return mShaderType;
{
return mVertexCompiler;
}
else
{
ASSERT(mType == GL_FRAGMENT_SHADER);
return mFragmentCompiler;
}
} }
ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader) ShShaderOutput ShaderD3D::getCompilerOutputType() const
{ {
void *compiler = NULL; return mCompilerOutputType;
switch (shader)
{
case GL_VERTEX_SHADER: compiler = mVertexCompiler; break;
case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
default: UNREACHABLE(); return SH_HLSL9_OUTPUT;
}
return ShGetShaderOutputType(compiler);
} }
bool ShaderD3D::compile(const gl::Data &data, const std::string &source) bool ShaderD3D::compile(gl::Compiler *compiler, const std::string &source)
{ {
uncompile(); uncompile();
void *compiler = getCompiler(); CompilerD3D *compilerD3D = CompilerD3D::makeCompilerD3D(compiler->getImplementation());
ShHandle compilerHandle = compilerD3D->getCompilerHandle(mShaderType);
mCompilerOutputType = ShGetShaderOutputType(compilerHandle);
compileToHLSL(data, compiler, source); compileToHLSL(compilerHandle, source);
if (mType == GL_VERTEX_SHADER) if (mShaderType == GL_VERTEX_SHADER)
{ {
parseAttributes(compiler); parseAttributes(compilerHandle);
} }
parseVaryings(compiler); parseVaryings(compilerHandle);
if (mType == GL_FRAGMENT_SHADER) if (mShaderType == GL_FRAGMENT_SHADER)
{ {
std::sort(mVaryings.begin(), mVaryings.end(), compareVarying); std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
const std::string &hlsl = getTranslatedSource(); const std::string &hlsl = getTranslatedSource();
if (!hlsl.empty()) if (!hlsl.empty())
{ {
mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compiler)); mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compilerHandle));
FilterInactiveVariables(&mActiveOutputVariables); FilterInactiveVariables(&mActiveOutputVariables);
} }
} }
#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED #if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
mDebugInfo += std::string("// ") + GetShaderTypeString(mType) + " SHADER BEGIN\n"; mDebugInfo += std::string("// ") + GetShaderTypeString(mShaderType) + " SHADER BEGIN\n";
mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n"; mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n";
mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n"; mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n";
// Successive steps will append more info // Successive steps will append more info
...@@ -449,7 +368,7 @@ bool ShaderD3D::compile(const gl::Data &data, const std::string &source) ...@@ -449,7 +368,7 @@ bool ShaderD3D::compile(const gl::Data &data, const std::string &source)
return !getTranslatedSource().empty(); return !getTranslatedSource().empty();
} }
void ShaderD3D::parseAttributes(void *compiler) void ShaderD3D::parseAttributes(ShHandle compiler)
{ {
const std::string &hlsl = getTranslatedSource(); const std::string &hlsl = getTranslatedSource();
if (!hlsl.empty()) if (!hlsl.empty())
......
...@@ -25,7 +25,7 @@ class ShaderD3D : public ShaderImpl ...@@ -25,7 +25,7 @@ class ShaderD3D : public ShaderImpl
friend class DynamicHLSL; friend class DynamicHLSL;
public: public:
ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer); ShaderD3D(GLenum type);
virtual ~ShaderD3D(); virtual ~ShaderD3D();
static ShaderD3D *makeShaderD3D(ShaderImpl *impl); static ShaderD3D *makeShaderD3D(ShaderImpl *impl);
...@@ -48,28 +48,22 @@ class ShaderD3D : public ShaderImpl ...@@ -48,28 +48,22 @@ class ShaderD3D : public ShaderImpl
bool usesDepthRange() const { return mUsesDepthRange; } bool usesDepthRange() const { return mUsesDepthRange; }
bool usesPointSize() const { return mUsesPointSize; } bool usesPointSize() const { return mUsesPointSize; }
static void releaseCompiler(); GLenum getShaderType() const;
static ShShaderOutput getCompilerOutputType(GLenum shader); ShShaderOutput getCompilerOutputType() const;
virtual bool compile(const gl::Data &data, const std::string &source); virtual bool compile(gl::Compiler *compiler, const std::string &source);
private: private:
DISALLOW_COPY_AND_ASSIGN(ShaderD3D); DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
void compileToHLSL(const gl::Data &data, void *compiler, const std::string &source); void compileToHLSL(ShHandle compiler, const std::string &source);
void parseVaryings(void *compiler); void parseVaryings(ShHandle compiler);
void initializeCompiler(const gl::Data &data); void parseAttributes(ShHandle compiler);
void parseAttributes(void *compiler);
void *getCompiler();
static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y); static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y);
static void *mFragmentCompiler; GLenum mShaderType;
static void *mVertexCompiler;
GLenum mType;
RendererD3D *mRenderer;
int mShaderVersion; int mShaderVersion;
...@@ -85,6 +79,7 @@ class ShaderD3D : public ShaderImpl ...@@ -85,6 +79,7 @@ class ShaderD3D : public ShaderImpl
bool mUsesDiscardRewriting; bool mUsesDiscardRewriting;
bool mUsesNestedBreak; bool mUsesNestedBreak;
ShShaderOutput mCompilerOutputType;
std::string mHlsl; std::string mHlsl;
std::string mInfoLog; std::string mInfoLog;
std::string mDebugInfo; std::string mDebugInfo;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/State.h" #include "libANGLE/State.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/ProgramD3D.h"
...@@ -1924,7 +1925,6 @@ void Renderer11::release() ...@@ -1924,7 +1925,6 @@ void Renderer11::release()
{ {
RendererD3D::cleanup(); RendererD3D::cleanup();
releaseShaderCompiler();
releaseDeviceResources(); releaseDeviceResources();
SafeRelease(mDxgiFactory); SafeRelease(mDxgiFactory);
...@@ -2483,19 +2483,19 @@ FramebufferImpl *Renderer11::createFramebuffer() ...@@ -2483,19 +2483,19 @@ FramebufferImpl *Renderer11::createFramebuffer()
return new Framebuffer11(this); return new Framebuffer11(this);
} }
ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type) CompilerImpl *Renderer11::createCompiler(const gl::Data &data)
{ {
return new ShaderD3D(data, type, this); return new CompilerD3D(data, SH_HLSL11_OUTPUT);
} }
ProgramImpl *Renderer11::createProgram() ShaderImpl *Renderer11::createShader(GLenum type)
{ {
return new ProgramD3D(this); return new ShaderD3D(type);
} }
void Renderer11::releaseShaderCompiler() ProgramImpl *Renderer11::createProgram()
{ {
ShaderD3D::releaseCompiler(); return new ProgramD3D(this);
} }
gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type, gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type,
......
...@@ -141,11 +141,11 @@ class Renderer11 : public RendererD3D ...@@ -141,11 +141,11 @@ class Renderer11 : public RendererD3D
virtual FramebufferImpl *createFramebuffer() override; virtual FramebufferImpl *createFramebuffer() override;
// Shader creation // Shader creation
virtual ShaderImpl *createShader(const gl::Data &data, GLenum type); virtual CompilerImpl *createCompiler(const gl::Data &data);
virtual ShaderImpl *createShader(GLenum type);
virtual ProgramImpl *createProgram(); virtual ProgramImpl *createProgram();
// Shader operations // Shader operations
void releaseShaderCompiler() override;
virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers, ShaderExecutable **outExecutable); bool separatedOutputBuffers, ShaderExecutable **outExecutable);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "libANGLE/Texture.h" #include "libANGLE/Texture.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/features.h" #include "libANGLE/features.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/ProgramD3D.h"
...@@ -158,7 +159,6 @@ void Renderer9::release() ...@@ -158,7 +159,6 @@ void Renderer9::release()
{ {
RendererD3D::cleanup(); RendererD3D::cleanup();
releaseShaderCompiler();
releaseDeviceResources(); releaseDeviceResources();
SafeRelease(mDevice); SafeRelease(mDevice);
...@@ -2899,19 +2899,19 @@ FramebufferImpl *Renderer9::createFramebuffer() ...@@ -2899,19 +2899,19 @@ FramebufferImpl *Renderer9::createFramebuffer()
return new Framebuffer9(this); return new Framebuffer9(this);
} }
ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type) CompilerImpl *Renderer9::createCompiler(const gl::Data &data)
{ {
return new ShaderD3D(data, type, this); return new CompilerD3D(data, SH_HLSL9_OUTPUT);
} }
ProgramImpl *Renderer9::createProgram() ShaderImpl *Renderer9::createShader(GLenum type)
{ {
return new ProgramD3D(this); return new ShaderD3D(type);
} }
void Renderer9::releaseShaderCompiler() ProgramImpl *Renderer9::createProgram()
{ {
ShaderD3D::releaseCompiler(); return new ProgramD3D(this);
} }
gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type, gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type,
......
...@@ -147,11 +147,11 @@ class Renderer9 : public RendererD3D ...@@ -147,11 +147,11 @@ class Renderer9 : public RendererD3D
virtual FramebufferImpl *createFramebuffer() override; virtual FramebufferImpl *createFramebuffer() override;
// Shader creation // Shader creation
virtual ShaderImpl *createShader(const gl::Data &data, GLenum type); virtual CompilerImpl *createCompiler(const gl::Data &data);
virtual ShaderImpl *createShader(GLenum type);
virtual ProgramImpl *createProgram(); virtual ProgramImpl *createProgram();
// Shader operations // Shader operations
void releaseShaderCompiler() override;
virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers, ShaderExecutable **outExecutable); bool separatedOutputBuffers, ShaderExecutable **outExecutable);
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
'libANGLE/Buffer.h', 'libANGLE/Buffer.h',
'libANGLE/Caps.cpp', 'libANGLE/Caps.cpp',
'libANGLE/Caps.h', 'libANGLE/Caps.h',
'libANGLE/Compiler.cpp',
'libANGLE/Compiler.h',
'libANGLE/Config.cpp', 'libANGLE/Config.cpp',
'libANGLE/Config.h', 'libANGLE/Config.h',
'libANGLE/Constants.h', 'libANGLE/Constants.h',
...@@ -106,6 +108,7 @@ ...@@ -106,6 +108,7 @@
'libANGLE/queryconversions.cpp', 'libANGLE/queryconversions.cpp',
'libANGLE/queryconversions.h', 'libANGLE/queryconversions.h',
'libANGLE/renderer/BufferImpl.h', 'libANGLE/renderer/BufferImpl.h',
'libANGLE/renderer/CompilerImpl.h',
'libANGLE/renderer/DisplayImpl.cpp', 'libANGLE/renderer/DisplayImpl.cpp',
'libANGLE/renderer/DisplayImpl.h', 'libANGLE/renderer/DisplayImpl.h',
'libANGLE/renderer/FenceImpl.h', 'libANGLE/renderer/FenceImpl.h',
...@@ -158,6 +161,8 @@ ...@@ -158,6 +161,8 @@
[ [
'libANGLE/renderer/d3d/BufferD3D.cpp', 'libANGLE/renderer/d3d/BufferD3D.cpp',
'libANGLE/renderer/d3d/BufferD3D.h', 'libANGLE/renderer/d3d/BufferD3D.h',
'libANGLE/renderer/d3d/CompilerD3D.cpp',
'libANGLE/renderer/d3d/CompilerD3D.h',
'libANGLE/renderer/d3d/DisplayD3D.cpp', 'libANGLE/renderer/d3d/DisplayD3D.cpp',
'libANGLE/renderer/d3d/DisplayD3D.h', 'libANGLE/renderer/d3d/DisplayD3D.h',
'libANGLE/renderer/d3d/DynamicHLSL.cpp', 'libANGLE/renderer/d3d/DynamicHLSL.cpp',
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/Compiler.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/Framebuffer.h" #include "libANGLE/Framebuffer.h"
...@@ -705,7 +706,7 @@ void GL_APIENTRY CompileShader(GLuint shader) ...@@ -705,7 +706,7 @@ void GL_APIENTRY CompileShader(GLuint shader)
} }
} }
shaderObject->compile(context->getData()); shaderObject->compile(context->getCompiler());
} }
} }
...@@ -3333,7 +3334,13 @@ void GL_APIENTRY ReleaseShaderCompiler(void) ...@@ -3333,7 +3334,13 @@ void GL_APIENTRY ReleaseShaderCompiler(void)
if (context) if (context)
{ {
context->releaseShaderCompiler(); Compiler *compiler = context->getCompiler();
Error error = compiler->release();
if (error.isError())
{
context->recordError(error);
return;
}
} }
} }
......
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