diff options
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp | 675 |
1 files changed, 675 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp new file mode 100644 index 0000000000..3a947d3c09 --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp @@ -0,0 +1,675 @@ +// +// Copyright (c) 2002-2013 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. +// + +// +// Implement the top-level of interface to the compiler, +// as defined in ShaderLang.h +// + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/translator/Compiler.h" +#include "compiler/translator/InitializeDll.h" +#include "compiler/translator/length_limits.h" +#ifdef ANGLE_ENABLE_HLSL +# include "compiler/translator/TranslatorHLSL.h" +#endif // ANGLE_ENABLE_HLSL +#include "angle_gl.h" +#include "compiler/translator/VariablePacker.h" + +namespace sh +{ + +namespace +{ + +bool isInitialized = false; + +// +// This is the platform independent interface between an OGL driver +// and the shading language compiler. +// + +template <typename VarT> +const std::vector<VarT> *GetVariableList(const TCompiler *compiler); + +template <> +const std::vector<Uniform> *GetVariableList(const TCompiler *compiler) +{ + return &compiler->getUniforms(); +} + +template <> +const std::vector<Varying> *GetVariableList(const TCompiler *compiler) +{ + switch (compiler->getShaderType()) + { + case GL_VERTEX_SHADER: + return &compiler->getOutputVaryings(); + case GL_FRAGMENT_SHADER: + return &compiler->getInputVaryings(); + case GL_COMPUTE_SHADER: + ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty()); + return &compiler->getOutputVaryings(); + // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings + // on a geometry shader. + default: + return nullptr; + } +} + +template <> +const std::vector<Attribute> *GetVariableList(const TCompiler *compiler) +{ + return &compiler->getAttributes(); +} + +template <> +const std::vector<OutputVariable> *GetVariableList(const TCompiler *compiler) +{ + return &compiler->getOutputVariables(); +} + +template <> +const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler) +{ + return &compiler->getInterfaceBlocks(); +} + +TCompiler *GetCompilerFromHandle(ShHandle handle) +{ + if (!handle) + { + return nullptr; + } + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + return base->getAsCompiler(); +} + +template <typename VarT> +const std::vector<VarT> *GetShaderVariables(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + if (!compiler) + { + return nullptr; + } + + return GetVariableList<VarT>(compiler); +} + +#ifdef ANGLE_ENABLE_HLSL +TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle) +{ + if (!handle) + return nullptr; + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + return base->getAsTranslatorHLSL(); +} +#endif // ANGLE_ENABLE_HLSL + +GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType) +{ + switch (primitiveType) + { + case EptPoints: + return GL_POINTS; + case EptLines: + return GL_LINES; + case EptLinesAdjacency: + return GL_LINES_ADJACENCY_EXT; + case EptTriangles: + return GL_TRIANGLES; + case EptTrianglesAdjacency: + return GL_TRIANGLES_ADJACENCY_EXT; + + case EptLineStrip: + return GL_LINE_STRIP; + case EptTriangleStrip: + return GL_TRIANGLE_STRIP; + + case EptUndefined: + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +} // anonymous namespace + +// +// Driver must call this first, once, before doing any other compiler operations. +// Subsequent calls to this function are no-op. +// +bool Initialize() +{ + if (!isInitialized) + { + isInitialized = InitProcess(); + } + return isInitialized; +} + +// +// Cleanup symbol tables +// +bool Finalize() +{ + if (isInitialized) + { + DetachProcess(); + isInitialized = false; + } + return true; +} + +// +// Initialize built-in resources with minimum expected values. +// +void InitBuiltInResources(ShBuiltInResources *resources) +{ + // Make comparable. + memset(resources, 0, sizeof(*resources)); + + // Constants. + resources->MaxVertexAttribs = 8; + resources->MaxVertexUniformVectors = 128; + resources->MaxVaryingVectors = 8; + resources->MaxVertexTextureImageUnits = 0; + resources->MaxCombinedTextureImageUnits = 8; + resources->MaxTextureImageUnits = 8; + resources->MaxFragmentUniformVectors = 16; + resources->MaxDrawBuffers = 1; + + // Extensions. + resources->OES_standard_derivatives = 0; + resources->OES_EGL_image_external = 0; + resources->OES_EGL_image_external_essl3 = 0; + resources->NV_EGL_stream_consumer_external = 0; + resources->ARB_texture_rectangle = 0; + resources->EXT_blend_func_extended = 0; + resources->EXT_draw_buffers = 0; + resources->EXT_frag_depth = 0; + resources->EXT_shader_texture_lod = 0; + resources->WEBGL_debug_shader_precision = 0; + resources->EXT_shader_framebuffer_fetch = 0; + resources->NV_shader_framebuffer_fetch = 0; + resources->ARM_shader_framebuffer_fetch = 0; + resources->OVR_multiview = 0; + resources->OVR_multiview2 = 0; + resources->EXT_YUV_target = 0; + resources->EXT_geometry_shader = 0; + resources->OES_texture_storage_multisample_2d_array = 0; + resources->OES_texture_3D = 0; + resources->ANGLE_texture_multisample = 0; + resources->ANGLE_multi_draw = 0; + resources->ANGLE_base_vertex_base_instance = 0; + + resources->NV_draw_buffers = 0; + + // Disable highp precision in fragment shader by default. + resources->FragmentPrecisionHigh = 0; + + // GLSL ES 3.0 constants. + resources->MaxVertexOutputVectors = 16; + resources->MaxFragmentInputVectors = 15; + resources->MinProgramTexelOffset = -8; + resources->MaxProgramTexelOffset = 7; + + // Extensions constants. + resources->MaxDualSourceDrawBuffers = 0; + + resources->MaxViewsOVR = 4; + + // Disable name hashing by default. + resources->HashFunction = nullptr; + + resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC; + + resources->MaxExpressionComplexity = 256; + resources->MaxCallStackDepth = 256; + resources->MaxFunctionParameters = 1024; + + // ES 3.1 Revision 4, 7.2 Built-in Constants + + // ES 3.1, Revision 4, 8.13 Texture minification + // "The value of MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be less than or equal to the value of + // MIN_PROGRAM_TEXEL_OFFSET. The value of MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be greater than + // or equal to the value of MAX_PROGRAM_TEXEL_OFFSET" + resources->MinProgramTextureGatherOffset = -8; + resources->MaxProgramTextureGatherOffset = 7; + + resources->MaxImageUnits = 4; + resources->MaxVertexImageUniforms = 0; + resources->MaxFragmentImageUniforms = 0; + resources->MaxComputeImageUniforms = 4; + resources->MaxCombinedImageUniforms = 4; + + resources->MaxUniformLocations = 1024; + + resources->MaxCombinedShaderOutputResources = 4; + + resources->MaxComputeWorkGroupCount[0] = 65535; + resources->MaxComputeWorkGroupCount[1] = 65535; + resources->MaxComputeWorkGroupCount[2] = 65535; + resources->MaxComputeWorkGroupSize[0] = 128; + resources->MaxComputeWorkGroupSize[1] = 128; + resources->MaxComputeWorkGroupSize[2] = 64; + resources->MaxComputeUniformComponents = 512; + resources->MaxComputeTextureImageUnits = 16; + + resources->MaxComputeAtomicCounters = 8; + resources->MaxComputeAtomicCounterBuffers = 1; + + resources->MaxVertexAtomicCounters = 0; + resources->MaxFragmentAtomicCounters = 0; + resources->MaxCombinedAtomicCounters = 8; + resources->MaxAtomicCounterBindings = 1; + + resources->MaxVertexAtomicCounterBuffers = 0; + resources->MaxFragmentAtomicCounterBuffers = 0; + resources->MaxCombinedAtomicCounterBuffers = 1; + resources->MaxAtomicCounterBufferSize = 32; + + resources->MaxUniformBufferBindings = 32; + resources->MaxShaderStorageBufferBindings = 4; + + resources->MaxGeometryUniformComponents = 1024; + resources->MaxGeometryUniformBlocks = 12; + resources->MaxGeometryInputComponents = 64; + resources->MaxGeometryOutputComponents = 64; + resources->MaxGeometryOutputVertices = 256; + resources->MaxGeometryTotalOutputComponents = 1024; + resources->MaxGeometryTextureImageUnits = 16; + resources->MaxGeometryAtomicCounterBuffers = 0; + resources->MaxGeometryAtomicCounters = 0; + resources->MaxGeometryShaderStorageBlocks = 0; + resources->MaxGeometryShaderInvocations = 32; + resources->MaxGeometryImageUniforms = 0; +} + +// +// Driver calls these to create and destroy compiler objects. +// +ShHandle ConstructCompiler(sh::GLenum type, + ShShaderSpec spec, + ShShaderOutput output, + const ShBuiltInResources *resources) +{ + TShHandleBase *base = static_cast<TShHandleBase *>(ConstructCompiler(type, spec, output)); + if (base == nullptr) + { + return 0; + } + + TCompiler *compiler = base->getAsCompiler(); + if (compiler == nullptr) + { + return 0; + } + + // Generate built-in symbol table. + if (!compiler->Init(*resources)) + { + Destruct(base); + return 0; + } + + return base; +} + +void Destruct(ShHandle handle) +{ + if (handle == 0) + return; + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + + if (base->getAsCompiler()) + DeleteCompiler(base->getAsCompiler()); +} + +const std::string &GetBuiltInResourcesString(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return compiler->getBuiltInResourcesString(); +} + +// +// Do an actual compile on the given strings. The result is left +// in the given compile object. +// +// Return: The return value of ShCompile is really boolean, indicating +// success or failure. +// +bool Compile(const ShHandle handle, + const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + + return compiler->compile(shaderStrings, numStrings, compileOptions); +} + +void ClearResults(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + compiler->clearResults(); +} + +int GetShaderVersion(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return compiler->getShaderVersion(); +} + +ShShaderOutput GetShaderOutputType(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return compiler->getOutputType(); +} + +// +// Return any compiler log of messages for the application. +// +const std::string &GetInfoLog(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + + TInfoSink &infoSink = compiler->getInfoSink(); + return infoSink.info.str(); +} + +// +// Return any object code. +// +const std::string &GetObjectCode(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + + TInfoSink &infoSink = compiler->getInfoSink(); + return infoSink.obj.str(); +} + +const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return &(compiler->getNameMap()); +} + +const std::vector<Uniform> *GetUniforms(const ShHandle handle) +{ + return GetShaderVariables<Uniform>(handle); +} + +const std::vector<Varying> *GetInputVaryings(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + if (compiler == nullptr) + { + return nullptr; + } + return &compiler->getInputVaryings(); +} + +const std::vector<Varying> *GetOutputVaryings(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + if (compiler == nullptr) + { + return nullptr; + } + return &compiler->getOutputVaryings(); +} + +const std::vector<Varying> *GetVaryings(const ShHandle handle) +{ + return GetShaderVariables<Varying>(handle); +} + +const std::vector<Attribute> *GetAttributes(const ShHandle handle) +{ + return GetShaderVariables<Attribute>(handle); +} + +const std::vector<OutputVariable> *GetOutputVariables(const ShHandle handle) +{ + return GetShaderVariables<OutputVariable>(handle); +} + +const std::vector<InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle) +{ + return GetShaderVariables<InterfaceBlock>(handle); +} + +const std::vector<InterfaceBlock> *GetUniformBlocks(const ShHandle handle) +{ + ASSERT(handle); + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return &compiler->getUniformBlocks(); +} + +const std::vector<InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle) +{ + ASSERT(handle); + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return &compiler->getShaderStorageBlocks(); +} + +WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getComputeShaderLocalSize(); +} + +int GetVertexShaderNumViews(const ShHandle handle) +{ + ASSERT(handle); + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getNumViews(); +} + +bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables) +{ + return CheckVariablesInPackingLimits(maxVectors, variables); +} + +bool GetShaderStorageBlockRegister(const ShHandle handle, + const std::string &shaderStorageBlockName, + unsigned int *indexOut) +{ +#ifdef ANGLE_ENABLE_HLSL + ASSERT(indexOut); + + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); + + if (!translator->hasShaderStorageBlock(shaderStorageBlockName)) + { + return false; + } + + *indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName); + return true; +#else + return false; +#endif // ANGLE_ENABLE_HLSL +} + +bool GetUniformBlockRegister(const ShHandle handle, + const std::string &uniformBlockName, + unsigned int *indexOut) +{ +#ifdef ANGLE_ENABLE_HLSL + ASSERT(indexOut); + + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); + + if (!translator->hasUniformBlock(uniformBlockName)) + { + return false; + } + + *indexOut = translator->getUniformBlockRegister(uniformBlockName); + return true; +#else + return false; +#endif // ANGLE_ENABLE_HLSL +} + +const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle) +{ +#ifdef ANGLE_ENABLE_HLSL + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); + + return translator->getUniformRegisterMap(); +#else + return nullptr; +#endif // ANGLE_ENABLE_HLSL +} + +unsigned int GetReadonlyImage2DRegisterIndex(const ShHandle handle) +{ +#ifdef ANGLE_ENABLE_HLSL + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); + + return translator->getReadonlyImage2DRegisterIndex(); +#else + return 0; +#endif // ANGLE_ENABLE_HLSL +} + +unsigned int GetImage2DRegisterIndex(const ShHandle handle) +{ +#ifdef ANGLE_ENABLE_HLSL + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); + + return translator->getImage2DRegisterIndex(); +#else + return 0; +#endif // ANGLE_ENABLE_HLSL +} + +const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle) +{ +#ifdef ANGLE_ENABLE_HLSL + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); + + return translator->getUsedImage2DFunctionNames(); +#else + return nullptr; +#endif // ANGLE_ENABLE_HLSL +} + +bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getGeometryShaderInputPrimitiveType() != EptUndefined; +} + +bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getGeometryShaderOutputPrimitiveType() != EptUndefined; +} + +bool HasValidGeometryShaderMaxVertices(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getGeometryShaderMaxVertices() >= 0; +} + +GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType()); +} + +GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType()); +} + +int GetGeometryShaderInvocations(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getGeometryShaderInvocations(); +} + +int GetGeometryShaderMaxVertices(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + int maxVertices = compiler->getGeometryShaderMaxVertices(); + ASSERT(maxVertices >= 0); + return maxVertices; +} + +} // namespace sh |