summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp1091
1 files changed, 1091 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..abc680656a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp
@@ -0,0 +1,1091 @@
+//
+// Copyright 2002 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/glslang_wrapper.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;
+
+// glslang can only be initialized/finalized once per process. Otherwise, the following EGL commands
+// will call GlslangFinalize() without ever being able to GlslangInitialize() again, leading to
+// crashes since GlslangFinalize() cleans up glslang for the entire process.
+// dpy1 = eglGetPlatformDisplay() |
+// eglInitialize(dpy1) | GlslangInitialize()
+// dpy2 = eglGetPlatformDisplay() |
+// eglInitialize(dpy2) | GlslangInitialize()
+// eglTerminate(dpy2) | GlslangFinalize()
+// eglInitialize(dpy1) | Display::isInitialized() == true, no GlslangInitialize()
+int initializeGlslangRefCount = 0;
+
+//
+// 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<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;
+ }
+}
+
+GLenum GetTessellationShaderTypeEnum(sh::TLayoutTessEvaluationType type)
+{
+ switch (type)
+ {
+ case EtetTriangles:
+ return GL_TRIANGLES;
+ case EtetQuads:
+ return GL_QUADS;
+ case EtetIsolines:
+ return GL_ISOLINES;
+ case EtetEqualSpacing:
+ return GL_EQUAL;
+ case EtetFractionalEvenSpacing:
+ return GL_FRACTIONAL_EVEN;
+ case EtetFractionalOddSpacing:
+ return GL_FRACTIONAL_ODD;
+ case EtetCw:
+ return GL_CW;
+ case EtetCcw:
+ return GL_CCW;
+ case EtetPointMode:
+ return GL_TESS_GEN_POINT_MODE;
+
+ case EtetUndefined:
+ 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->EXT_shader_framebuffer_fetch = 0;
+ resources->EXT_shader_framebuffer_fetch_non_coherent = 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_geometry_shader = 0;
+ resources->EXT_gpu_shader5 = 0;
+ resources->OES_shader_io_blocks = 0;
+ resources->EXT_shader_io_blocks = 0;
+ resources->EXT_shader_non_constant_global_initializers = 0;
+ resources->NV_shader_noperspective_interpolation = 0;
+ resources->OES_texture_storage_multisample_2d_array = 0;
+ resources->OES_texture_3D = 0;
+ resources->ANGLE_shader_pixel_local_storage = 0;
+ resources->ANGLE_texture_multisample = 0;
+ resources->ANGLE_multi_draw = 0;
+ resources->ANGLE_base_vertex_base_instance = 0;
+ resources->ANGLE_base_vertex_base_instance_shader_builtin = 0;
+ resources->WEBGL_video_texture = 0;
+ resources->APPLE_clip_distance = 0;
+ resources->OES_texture_cube_map_array = 0;
+ resources->EXT_texture_cube_map_array = 0;
+ resources->EXT_shadow_samplers = 0;
+ resources->OES_shader_multisample_interpolation = 0;
+ resources->NV_draw_buffers = 0;
+ resources->OES_shader_image_atomic = 0;
+ resources->EXT_tessellation_shader = 0;
+ resources->OES_texture_buffer = 0;
+ resources->EXT_texture_buffer = 0;
+ resources->OES_sample_variables = 0;
+ resources->EXT_clip_cull_distance = 0;
+ resources->KHR_blend_equation_advanced = 0;
+
+ resources->MaxClipDistances = 8;
+ resources->MaxCullDistances = 8;
+ resources->MaxCombinedClipAndCullDistances = 8;
+
+ // 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->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;
+
+ resources->MaxTessControlInputComponents = 64;
+ resources->MaxTessControlOutputComponents = 64;
+ resources->MaxTessControlTextureImageUnits = 16;
+ resources->MaxTessControlUniformComponents = 1024;
+ resources->MaxTessControlTotalOutputComponents = 2048;
+ resources->MaxTessControlImageUniforms = 0;
+ resources->MaxTessControlAtomicCounters = 0;
+ resources->MaxTessControlAtomicCounterBuffers = 0;
+
+ resources->MaxTessPatchComponents = 120;
+ resources->MaxPatchVertices = 32;
+ resources->MaxTessGenLevel = 64;
+
+ resources->MaxTessEvaluationInputComponents = 64;
+ resources->MaxTessEvaluationOutputComponents = 64;
+ resources->MaxTessEvaluationTextureImageUnits = 16;
+ resources->MaxTessEvaluationUniformComponents = 1024;
+ resources->MaxTessEvaluationImageUniforms = 0;
+ resources->MaxTessEvaluationAtomicCounters = 0;
+ resources->MaxTessEvaluationAtomicCounterBuffers = 0;
+
+ resources->SubPixelBits = 8;
+
+ resources->MaxSamples = 4;
+}
+
+//
+// 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());
+}
+
+ShBuiltInResources GetBuiltInResources(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResources();
+}
+
+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,
+ const 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();
+}
+
+//
+// Return any object binary code.
+//
+const BinaryBlob &GetObjectBinaryBlob(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.getBinary();
+}
+
+const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return &(compiler->getNameMap());
+}
+
+const std::vector<ShaderVariable> *GetUniforms(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getUniforms();
+}
+
+const std::vector<ShaderVariable> *GetInputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getInputVaryings();
+}
+
+const std::vector<ShaderVariable> *GetOutputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVaryings();
+}
+
+const std::vector<ShaderVariable> *GetVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+
+ 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;
+ }
+}
+
+const std::vector<ShaderVariable> *GetAttributes(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getAttributes();
+}
+
+const std::vector<ShaderVariable> *GetOutputVariables(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVariables();
+}
+
+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 EnablesPerSampleShading(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return false;
+ }
+ return compiler->enablesPerSampleShading();
+}
+
+uint32_t GetShaderSpecConstUsageBits(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return 0;
+ }
+ return compiler->getSpecConstUsageBits().bits();
+}
+
+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
+}
+
+bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
+ const std::string &uniformBlockName)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->shouldUniformBlockUseStructuredBuffer(uniformBlockName);
+#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
+}
+
+const std::set<std::string> *GetSlowCompilingUniformBlockSet(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getSlowCompilingUniformBlockSet();
+#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 HasDiscardInFragmentShader(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getShaderType() == GL_FRAGMENT_SHADER && compiler->hasDiscard();
+}
+
+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;
+}
+
+bool HasValidTessGenMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputPrimitiveType() != EtetUndefined;
+}
+
+bool HasValidTessGenSpacing(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputVertexSpacingType() != EtetUndefined;
+}
+
+bool HasValidTessGenVertexOrder(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputOrderingType() != EtetUndefined;
+}
+
+bool HasValidTessGenPointMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputPointType() != EtetUndefined;
+}
+
+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;
+}
+
+int GetTessControlShaderVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ int vertices = compiler->getTessControlShaderOutputVertices();
+ return vertices;
+}
+
+GLenum GetTessGenMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPrimitiveType());
+}
+
+GLenum GetTessGenSpacing(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputVertexSpacingType());
+}
+
+GLenum GetTessGenVertexOrder(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputOrderingType());
+}
+
+GLenum GetTessGenPointMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPointType());
+}
+
+unsigned int GetShaderSharedMemorySize(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ unsigned int sharedMemorySize = compiler->getSharedMemorySize();
+ return sharedMemorySize;
+}
+
+uint32_t GetAdvancedBlendEquations(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ return compiler->getAdvancedBlendEquations().bits();
+}
+
+void InitializeGlslang()
+{
+ if (initializeGlslangRefCount == 0)
+ {
+ GlslangInitialize();
+ }
+ ++initializeGlslangRefCount;
+ ASSERT(initializeGlslangRefCount < std::numeric_limits<int>::max());
+}
+
+void FinalizeGlslang()
+{
+ --initializeGlslangRefCount;
+ ASSERT(initializeGlslangRefCount >= 0);
+ if (initializeGlslangRefCount == 0)
+ {
+ GlslangFinalize();
+ }
+}
+
+// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
+// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
+// use by the underlying implementation). u is short for user-defined.
+const char kUserDefinedNamePrefix[] = "_u";
+
+namespace vk
+{
+// Interface block name containing the aggregate default uniforms
+const char kDefaultUniformsNameVS[] = "defaultUniformsVS";
+const char kDefaultUniformsNameTCS[] = "defaultUniformsTCS";
+const char kDefaultUniformsNameTES[] = "defaultUniformsTES";
+const char kDefaultUniformsNameGS[] = "defaultUniformsGS";
+const char kDefaultUniformsNameFS[] = "defaultUniformsFS";
+const char kDefaultUniformsNameCS[] = "defaultUniformsCS";
+
+// Interface block and variable names containing driver uniforms
+const char kDriverUniformsBlockName[] = "ANGLEUniformBlock";
+const char kDriverUniformsVarName[] = "ANGLEUniforms";
+
+// Interface block array name used for atomic counter emulation
+const char kAtomicCountersBlockName[] = "ANGLEAtomicCounters";
+
+const char kXfbEmulationGetOffsetsFunctionName[] = "ANGLEGetXfbOffsets";
+const char kXfbEmulationCaptureFunctionName[] = "ANGLECaptureXfb";
+const char kXfbEmulationBufferBlockName[] = "ANGLEXfbBuffer";
+const char kXfbEmulationBufferName[] = "ANGLEXfb";
+const char kXfbEmulationBufferFieldName[] = "xfbOut";
+
+const char kTransformPositionFunctionName[] = "ANGLETransformPosition";
+
+const char kXfbExtensionPositionOutName[] = "ANGLEXfbPosition";
+
+// EXT_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch_non_coherent
+const char kInputAttachmentName[] = "ANGLEInputAttachment";
+
+} // namespace vk
+
+const char *BlockLayoutTypeToString(BlockLayoutType type)
+{
+ switch (type)
+ {
+ case BlockLayoutType::BLOCKLAYOUT_STD140:
+ return "std140";
+ case BlockLayoutType::BLOCKLAYOUT_STD430:
+ return "std430";
+ case BlockLayoutType::BLOCKLAYOUT_PACKED:
+ return "packed";
+ case BlockLayoutType::BLOCKLAYOUT_SHARED:
+ return "shared";
+ default:
+ return "invalid";
+ }
+}
+
+const char *BlockTypeToString(BlockType type)
+{
+ switch (type)
+ {
+ case BlockType::BLOCK_BUFFER:
+ return "buffer";
+ case BlockType::BLOCK_UNIFORM:
+ return "uniform";
+ default:
+ return "invalid";
+ }
+}
+
+const char *InterpolationTypeToString(InterpolationType type)
+{
+ switch (type)
+ {
+ case InterpolationType::INTERPOLATION_SMOOTH:
+ return "smooth";
+ case InterpolationType::INTERPOLATION_CENTROID:
+ return "centroid";
+ case InterpolationType::INTERPOLATION_SAMPLE:
+ return "sample";
+ case InterpolationType::INTERPOLATION_FLAT:
+ return "flat";
+ case InterpolationType::INTERPOLATION_NOPERSPECTIVE:
+ return "noperspective";
+ default:
+ return "invalid";
+ }
+}
+} // namespace sh
+
+ShCompileOptions::ShCompileOptions()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+ShCompileOptions::ShCompileOptions(const ShCompileOptions &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+ShCompileOptions &ShCompileOptions::operator=(const ShCompileOptions &other)
+{
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+}
+
+ShBuiltInResources::ShBuiltInResources()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+ShBuiltInResources::ShBuiltInResources(const ShBuiltInResources &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+ShBuiltInResources &ShBuiltInResources::operator=(const ShBuiltInResources &other)
+{
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+}