summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Compiler.cpp')
-rw-r--r--gfx/angle/checkout/src/libANGLE/Compiler.cpp422
1 files changed, 422 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Compiler.cpp b/gfx/angle/checkout/src/libANGLE/Compiler.cpp
new file mode 100644
index 0000000000..a838f27ed6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Compiler.cpp
@@ -0,0 +1,422 @@
+//
+// Copyright 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 "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/State.h"
+#include "libANGLE/renderer/CompilerImpl.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+
+namespace gl
+{
+
+namespace
+{
+
+// To know when to call sh::Initialize and sh::Finalize.
+size_t gActiveCompilers = 0;
+
+} // anonymous namespace
+
+Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Display *display)
+ : mImplementation(implFactory->createCompiler()),
+ mSpec(SelectShaderSpec(state)),
+ mOutputType(mImplementation->getTranslatorOutputType()),
+ mResources()
+{
+ // TODO(http://anglebug.com/3819): Update for GL version specific validation
+ ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
+ state.getClientMajorVersion() == 3 || state.getClientMajorVersion() == 4);
+
+ {
+ std::lock_guard<std::mutex> lock(display->getDisplayGlobalMutex());
+ if (gActiveCompilers == 0)
+ {
+ sh::Initialize();
+ }
+ ++gActiveCompilers;
+ }
+
+ const Caps &caps = state.getCaps();
+ const Extensions &extensions = state.getExtensions();
+
+ sh::InitBuiltInResources(&mResources);
+ mResources.MaxVertexAttribs = caps.maxVertexAttributes;
+ mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
+ mResources.MaxVaryingVectors = caps.maxVaryingVectors;
+ mResources.MaxVertexTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Vertex];
+ mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
+ mResources.MaxTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Fragment];
+ mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
+ mResources.MaxDrawBuffers = caps.maxDrawBuffers;
+ mResources.OES_standard_derivatives = extensions.standardDerivativesOES;
+ mResources.EXT_draw_buffers = extensions.drawBuffersEXT;
+ mResources.EXT_shader_texture_lod = extensions.shaderTextureLodEXT;
+ mResources.EXT_shader_non_constant_global_initializers =
+ extensions.shaderNonConstantGlobalInitializersEXT;
+ mResources.OES_EGL_image_external = extensions.EGLImageExternalOES;
+ mResources.OES_EGL_image_external_essl3 = extensions.EGLImageExternalEssl3OES;
+ mResources.NV_EGL_stream_consumer_external = extensions.EGLStreamConsumerExternalNV;
+ mResources.NV_shader_noperspective_interpolation =
+ extensions.shaderNoperspectiveInterpolationNV;
+ mResources.ARB_texture_rectangle = extensions.textureRectangleANGLE;
+ mResources.EXT_gpu_shader5 = extensions.gpuShader5EXT;
+ mResources.OES_shader_io_blocks = extensions.shaderIoBlocksOES;
+ mResources.EXT_shader_io_blocks = extensions.shaderIoBlocksEXT;
+ mResources.OES_texture_storage_multisample_2d_array =
+ extensions.textureStorageMultisample2dArrayOES;
+ mResources.OES_texture_3D = extensions.texture3DOES;
+ mResources.ANGLE_base_vertex_base_instance_shader_builtin =
+ extensions.baseVertexBaseInstanceShaderBuiltinANGLE;
+ mResources.ANGLE_multi_draw = extensions.multiDrawANGLE;
+ mResources.ANGLE_shader_pixel_local_storage = extensions.shaderPixelLocalStorageANGLE;
+ mResources.ANGLE_texture_multisample = extensions.textureMultisampleANGLE;
+ mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE;
+ // OES_shader_multisample_interpolation
+ mResources.OES_shader_multisample_interpolation = extensions.shaderMultisampleInterpolationOES;
+ mResources.OES_shader_image_atomic = extensions.shaderImageAtomicOES;
+ // TODO: use shader precision caps to determine if high precision is supported?
+ mResources.FragmentPrecisionHigh = 1;
+ mResources.EXT_frag_depth = extensions.fragDepthEXT;
+
+ // OVR_multiview state
+ mResources.OVR_multiview = extensions.multiviewOVR;
+
+ // OVR_multiview2 state
+ mResources.OVR_multiview2 = extensions.multiview2OVR;
+ mResources.MaxViewsOVR = caps.maxViews;
+
+ // EXT_multisampled_render_to_texture and EXT_multisampled_render_to_texture2
+ mResources.EXT_multisampled_render_to_texture = extensions.multisampledRenderToTextureEXT;
+ mResources.EXT_multisampled_render_to_texture2 = extensions.multisampledRenderToTexture2EXT;
+
+ // WEBGL_video_texture
+ mResources.WEBGL_video_texture = extensions.videoTextureWEBGL;
+
+ // OES_texture_cube_map_array
+ mResources.OES_texture_cube_map_array = extensions.textureCubeMapArrayOES;
+ mResources.EXT_texture_cube_map_array = extensions.textureCubeMapArrayEXT;
+
+ // EXT_shadow_samplers
+ mResources.EXT_shadow_samplers = extensions.shadowSamplersEXT;
+
+ // OES_texture_buffer
+ mResources.OES_texture_buffer = extensions.textureBufferOES;
+ mResources.EXT_texture_buffer = extensions.textureBufferEXT;
+
+ // GL_EXT_YUV_target
+ mResources.EXT_YUV_target = extensions.YUVTargetEXT;
+
+ mResources.EXT_shader_framebuffer_fetch_non_coherent =
+ extensions.shaderFramebufferFetchNonCoherentEXT;
+
+ mResources.EXT_shader_framebuffer_fetch = extensions.shaderFramebufferFetchEXT;
+
+ // GL_EXT_clip_cull_distance
+ mResources.EXT_clip_cull_distance = extensions.clipCullDistanceEXT;
+
+ // GL_EXT_primitive_bounding_box
+ mResources.EXT_primitive_bounding_box = extensions.primitiveBoundingBoxEXT;
+
+ // GL_OES_primitive_bounding_box
+ mResources.OES_primitive_bounding_box = extensions.primitiveBoundingBoxOES;
+
+ // GLSL ES 3.0 constants
+ mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
+ mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
+ mResources.MinProgramTexelOffset = caps.minProgramTexelOffset;
+ mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
+
+ // EXT_blend_func_extended
+ mResources.EXT_blend_func_extended = extensions.blendFuncExtendedEXT;
+ mResources.MaxDualSourceDrawBuffers = caps.maxDualSourceDrawBuffers;
+
+ // APPLE_clip_distance/EXT_clip_cull_distance
+ mResources.MaxClipDistances = caps.maxClipDistances;
+ mResources.MaxCullDistances = caps.maxCullDistances;
+ mResources.MaxCombinedClipAndCullDistances = caps.maxCombinedClipAndCullDistances;
+
+ // ANGLE_shader_pixel_local_storage.
+ mResources.MaxPixelLocalStoragePlanes = caps.maxPixelLocalStoragePlanes;
+ mResources.MaxColorAttachmentsWithActivePixelLocalStorage =
+ caps.maxColorAttachmentsWithActivePixelLocalStorage;
+ mResources.MaxCombinedDrawBuffersAndPixelLocalStoragePlanes =
+ caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes;
+
+ // OES_sample_variables
+ mResources.OES_sample_variables = extensions.sampleVariablesOES;
+ mResources.MaxSamples = caps.maxSamples;
+
+ // ANDROID_extension_pack_es31a
+ mResources.ANDROID_extension_pack_es31a = extensions.extensionPackEs31aANDROID;
+
+ // KHR_blend_equation_advanced
+ mResources.KHR_blend_equation_advanced = extensions.blendEquationAdvancedKHR;
+
+ // GLSL ES 3.1 constants
+ mResources.MaxProgramTextureGatherOffset = caps.maxProgramTextureGatherOffset;
+ mResources.MinProgramTextureGatherOffset = caps.minProgramTextureGatherOffset;
+ mResources.MaxImageUnits = caps.maxImageUnits;
+ mResources.MaxVertexImageUniforms = caps.maxShaderImageUniforms[ShaderType::Vertex];
+ mResources.MaxFragmentImageUniforms = caps.maxShaderImageUniforms[ShaderType::Fragment];
+ mResources.MaxComputeImageUniforms = caps.maxShaderImageUniforms[ShaderType::Compute];
+ mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms;
+ mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
+ mResources.MaxUniformLocations = caps.maxUniformLocations;
+
+ for (size_t index = 0u; index < 3u; ++index)
+ {
+ mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
+ mResources.MaxComputeWorkGroupSize[index] = caps.maxComputeWorkGroupSize[index];
+ }
+
+ mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute];
+ mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute];
+
+ mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute];
+ mResources.MaxComputeAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
+
+ mResources.MaxVertexAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Vertex];
+ mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment];
+ mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
+ mResources.MaxAtomicCounterBindings = caps.maxAtomicCounterBufferBindings;
+ mResources.MaxVertexAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
+ mResources.MaxFragmentAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
+ mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
+ mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize;
+
+ mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings;
+ mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
+
+ // Needed by point size clamping workaround
+ mResources.MaxPointSize = caps.maxAliasedPointSize;
+
+ if (state.getClientMajorVersion() == 2 && !extensions.drawBuffersEXT)
+ {
+ mResources.MaxDrawBuffers = 1;
+ }
+
+ // Geometry Shader constants
+ mResources.EXT_geometry_shader = extensions.geometryShaderEXT;
+ mResources.OES_geometry_shader = extensions.geometryShaderOES;
+ mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry];
+ mResources.MaxGeometryUniformBlocks = caps.maxShaderUniformBlocks[ShaderType::Geometry];
+ mResources.MaxGeometryInputComponents = caps.maxGeometryInputComponents;
+ mResources.MaxGeometryOutputComponents = caps.maxGeometryOutputComponents;
+ mResources.MaxGeometryOutputVertices = caps.maxGeometryOutputVertices;
+ mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
+ mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
+
+ mResources.MaxGeometryAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
+ mResources.MaxGeometryAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Geometry];
+ mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
+ mResources.MaxGeometryShaderInvocations = caps.maxGeometryShaderInvocations;
+ mResources.MaxGeometryImageUniforms = caps.maxShaderImageUniforms[ShaderType::Geometry];
+
+ // Tessellation Shader constants
+ mResources.EXT_tessellation_shader = extensions.tessellationShaderEXT;
+ mResources.MaxTessControlInputComponents = caps.maxTessControlInputComponents;
+ mResources.MaxTessControlOutputComponents = caps.maxTessControlOutputComponents;
+ mResources.MaxTessControlTextureImageUnits =
+ caps.maxShaderTextureImageUnits[ShaderType::TessControl];
+ mResources.MaxTessControlUniformComponents =
+ caps.maxShaderUniformComponents[ShaderType::TessControl];
+ mResources.MaxTessControlTotalOutputComponents = caps.maxTessControlTotalOutputComponents;
+ mResources.MaxTessControlImageUniforms = caps.maxShaderImageUniforms[ShaderType::TessControl];
+ mResources.MaxTessControlAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::TessControl];
+ mResources.MaxTessControlAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
+
+ mResources.MaxTessPatchComponents = caps.maxTessPatchComponents;
+ mResources.MaxPatchVertices = caps.maxPatchVertices;
+ mResources.MaxTessGenLevel = caps.maxTessGenLevel;
+
+ mResources.MaxTessEvaluationInputComponents = caps.maxTessEvaluationInputComponents;
+ mResources.MaxTessEvaluationOutputComponents = caps.maxTessEvaluationOutputComponents;
+ mResources.MaxTessEvaluationTextureImageUnits =
+ caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationUniformComponents =
+ caps.maxShaderUniformComponents[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationImageUniforms =
+ caps.maxShaderImageUniforms[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationAtomicCounters =
+ caps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
+
+ // Subpixel bits.
+ mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
+}
+
+Compiler::~Compiler() = default;
+
+void Compiler::onDestroy(const Context *context)
+{
+ std::lock_guard<std::mutex> lock(context->getDisplay()->getDisplayGlobalMutex());
+ for (auto &pool : mPools)
+ {
+ for (ShCompilerInstance &instance : pool)
+ {
+ instance.destroy();
+ }
+ }
+ --gActiveCompilers;
+ if (gActiveCompilers == 0)
+ {
+ sh::Finalize();
+ }
+}
+
+ShCompilerInstance Compiler::getInstance(ShaderType type)
+{
+ ASSERT(type != ShaderType::InvalidEnum);
+ auto &pool = mPools[type];
+ if (pool.empty())
+ {
+ ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
+ ASSERT(handle);
+ return ShCompilerInstance(handle, mOutputType, type);
+ }
+ else
+ {
+ ShCompilerInstance instance = std::move(pool.back());
+ pool.pop_back();
+ return instance;
+ }
+}
+
+void Compiler::putInstance(ShCompilerInstance &&instance)
+{
+ static constexpr size_t kMaxPoolSize = 32;
+ auto &pool = mPools[instance.getShaderType()];
+ if (pool.size() < kMaxPoolSize)
+ {
+ pool.push_back(std::move(instance));
+ }
+ else
+ {
+ instance.destroy();
+ }
+}
+
+ShShaderSpec Compiler::SelectShaderSpec(const State &state)
+{
+ const EGLenum clientType = state.getClientType();
+ const EGLint profileMask = state.getProfileMask();
+ const GLint majorVersion = state.getClientMajorVersion();
+ const GLint minorVersion = state.getClientMinorVersion();
+ bool isWebGL = state.isWebGL();
+
+ // For Desktop GL
+ if (clientType == EGL_OPENGL_API)
+ {
+ if ((profileMask & EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT) != 0)
+ {
+ return SH_GL_CORE_SPEC;
+ }
+ else
+ {
+ return SH_GL_COMPATIBILITY_SPEC;
+ }
+ }
+
+ if (majorVersion >= 3)
+ {
+ switch (minorVersion)
+ {
+ case 2:
+ ASSERT(!isWebGL);
+ return SH_GLES3_2_SPEC;
+ case 1:
+ return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
+ case 0:
+ return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // GLES1 emulation: Use GLES3 shader spec.
+ if (!isWebGL && majorVersion == 1)
+ {
+ return SH_GLES3_SPEC;
+ }
+
+ return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
+}
+
+ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {}
+
+ShCompilerInstance::ShCompilerInstance(ShHandle handle,
+ ShShaderOutput outputType,
+ ShaderType shaderType)
+ : mHandle(handle), mOutputType(outputType), mShaderType(shaderType)
+{}
+
+ShCompilerInstance::~ShCompilerInstance()
+{
+ ASSERT(mHandle == nullptr);
+}
+
+void ShCompilerInstance::destroy()
+{
+ if (mHandle != nullptr)
+ {
+ sh::Destruct(mHandle);
+ mHandle = nullptr;
+ }
+}
+
+ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other)
+ : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType)
+{
+ other.mHandle = nullptr;
+}
+
+ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other)
+{
+ mHandle = other.mHandle;
+ mOutputType = other.mOutputType;
+ mShaderType = other.mShaderType;
+ other.mHandle = nullptr;
+ return *this;
+}
+
+ShHandle ShCompilerInstance::getHandle()
+{
+ return mHandle;
+}
+
+ShaderType ShCompilerInstance::getShaderType() const
+{
+ return mShaderType;
+}
+
+ShBuiltInResources ShCompilerInstance::getBuiltInResources() const
+{
+ return sh::GetBuiltInResources(mHandle);
+}
+
+const std::string &ShCompilerInstance::getBuiltinResourcesString() const
+{
+ return sh::GetBuiltInResourcesString(mHandle);
+}
+
+ShShaderOutput ShCompilerInstance::getShaderOutputType() const
+{
+ return mOutputType;
+}
+
+} // namespace gl