• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Compiler.cpp: implements the gl::Compiler class.
8 
9 #include "libANGLE/Compiler.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/State.h"
13 #include "libANGLE/renderer/CompilerImpl.h"
14 #include "libANGLE/renderer/GLImplFactory.h"
15 
16 namespace gl
17 {
18 
19 namespace
20 {
21 
22 // To know when to call sh::Initialize and sh::Finalize.
23 size_t gActiveCompilers = 0;
24 
SelectShaderSpec(GLint majorVersion,GLint minorVersion,bool isWebGL,EGLenum clientType)25 ShShaderSpec SelectShaderSpec(GLint majorVersion,
26                               GLint minorVersion,
27                               bool isWebGL,
28                               EGLenum clientType)
29 {
30     // For Desktop GL
31     if (clientType == EGL_OPENGL_API)
32     {
33         return SH_GL_COMPATIBILITY_SPEC;
34     }
35 
36     if (majorVersion >= 3)
37     {
38         if (minorVersion == 1)
39         {
40             return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
41         }
42         else
43         {
44             return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
45         }
46     }
47 
48     // GLES1 emulation: Use GLES3 shader spec.
49     if (!isWebGL && majorVersion == 1)
50     {
51         return SH_GLES3_SPEC;
52     }
53 
54     return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
55 }
56 
57 }  // anonymous namespace
58 
Compiler(rx::GLImplFactory * implFactory,const State & state)59 Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state)
60     : mImplementation(implFactory->createCompiler()),
61       mSpec(SelectShaderSpec(state.getClientMajorVersion(),
62                              state.getClientMinorVersion(),
63                              state.getExtensions().webglCompatibility,
64                              state.getClientType())),
65       mOutputType(mImplementation->getTranslatorOutputType()),
66       mResources()
67 {
68     // TODO(http://anglebug.com/3819): Update for GL version specific validation
69     ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
70            state.getClientMajorVersion() == 3 || state.getClientMajorVersion() == 4);
71 
72     const gl::Caps &caps             = state.getCaps();
73     const gl::Extensions &extensions = state.getExtensions();
74 
75     if (gActiveCompilers == 0)
76     {
77         sh::Initialize();
78     }
79     ++gActiveCompilers;
80 
81     sh::InitBuiltInResources(&mResources);
82     mResources.MaxVertexAttribs             = caps.maxVertexAttributes;
83     mResources.MaxVertexUniformVectors      = caps.maxVertexUniformVectors;
84     mResources.MaxVaryingVectors            = caps.maxVaryingVectors;
85     mResources.MaxVertexTextureImageUnits   = caps.maxShaderTextureImageUnits[ShaderType::Vertex];
86     mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
87     mResources.MaxTextureImageUnits         = caps.maxShaderTextureImageUnits[ShaderType::Fragment];
88     mResources.MaxFragmentUniformVectors    = caps.maxFragmentUniformVectors;
89     mResources.MaxDrawBuffers               = caps.maxDrawBuffers;
90     mResources.OES_standard_derivatives     = extensions.standardDerivativesOES;
91     mResources.EXT_draw_buffers             = extensions.drawBuffers;
92     mResources.EXT_shader_texture_lod       = extensions.shaderTextureLOD;
93     mResources.EXT_shader_non_constant_global_initializers =
94         extensions.shaderNonConstGlobalInitializersEXT;
95     mResources.OES_EGL_image_external                = extensions.eglImageExternalOES;
96     mResources.OES_EGL_image_external_essl3          = extensions.eglImageExternalEssl3OES;
97     mResources.NV_EGL_stream_consumer_external       = extensions.eglStreamConsumerExternalNV;
98     mResources.NV_shader_noperspective_interpolation = extensions.noperspectiveInterpolationNV;
99     mResources.ARB_texture_rectangle                 = extensions.textureRectangle;
100     mResources.EXT_gpu_shader5                       = extensions.gpuShader5EXT;
101     mResources.OES_texture_storage_multisample_2d_array =
102         extensions.textureStorageMultisample2DArrayOES;
103     mResources.OES_texture_3D                  = extensions.texture3DOES;
104     mResources.ANGLE_texture_multisample       = extensions.textureMultisample;
105     mResources.ANGLE_multi_draw                = extensions.multiDraw;
106     mResources.ANGLE_base_vertex_base_instance = extensions.baseVertexBaseInstance;
107     mResources.APPLE_clip_distance             = extensions.clipDistanceAPPLE;
108 
109     // TODO: use shader precision caps to determine if high precision is supported?
110     mResources.FragmentPrecisionHigh = 1;
111     mResources.EXT_frag_depth        = extensions.fragDepth;
112 
113     // OVR_multiview state
114     mResources.OVR_multiview = extensions.multiview;
115 
116     // OVR_multiview2 state
117     mResources.OVR_multiview2 = extensions.multiview2;
118     mResources.MaxViewsOVR    = extensions.maxViews;
119 
120     // EXT_multisampled_render_to_texture
121     mResources.EXT_multisampled_render_to_texture = extensions.multisampledRenderToTexture;
122 
123     // WEBGL_video_texture
124     mResources.WEBGL_video_texture = extensions.webglVideoTexture;
125 
126     // OES_texture_cube_map_array
127     mResources.OES_texture_cube_map_array = extensions.textureCubeMapArrayOES;
128     mResources.EXT_texture_cube_map_array = extensions.textureCubeMapArrayEXT;
129 
130     // GLSL ES 3.0 constants
131     mResources.MaxVertexOutputVectors  = caps.maxVertexOutputComponents / 4;
132     mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
133     mResources.MinProgramTexelOffset   = caps.minProgramTexelOffset;
134     mResources.MaxProgramTexelOffset   = caps.maxProgramTexelOffset;
135 
136     // EXT_blend_func_extended
137     mResources.EXT_blend_func_extended  = extensions.blendFuncExtended;
138     mResources.MaxDualSourceDrawBuffers = extensions.maxDualSourceDrawBuffers;
139 
140     // APPLE_clip_distance/EXT_clip_cull_distance
141     mResources.MaxClipDistances = caps.maxClipDistances;
142 
143     // GLSL ES 3.1 constants
144     mResources.MaxProgramTextureGatherOffset    = caps.maxProgramTextureGatherOffset;
145     mResources.MinProgramTextureGatherOffset    = caps.minProgramTextureGatherOffset;
146     mResources.MaxImageUnits                    = caps.maxImageUnits;
147     mResources.MaxVertexImageUniforms           = caps.maxShaderImageUniforms[ShaderType::Vertex];
148     mResources.MaxFragmentImageUniforms         = caps.maxShaderImageUniforms[ShaderType::Fragment];
149     mResources.MaxComputeImageUniforms          = caps.maxShaderImageUniforms[ShaderType::Compute];
150     mResources.MaxCombinedImageUniforms         = caps.maxCombinedImageUniforms;
151     mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
152     mResources.MaxUniformLocations              = caps.maxUniformLocations;
153 
154     for (size_t index = 0u; index < 3u; ++index)
155     {
156         mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
157         mResources.MaxComputeWorkGroupSize[index]  = caps.maxComputeWorkGroupSize[index];
158     }
159 
160     mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute];
161     mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute];
162 
163     mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute];
164     mResources.MaxComputeAtomicCounterBuffers =
165         caps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
166 
167     mResources.MaxVertexAtomicCounters   = caps.maxShaderAtomicCounters[ShaderType::Vertex];
168     mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment];
169     mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
170     mResources.MaxAtomicCounterBindings  = caps.maxAtomicCounterBufferBindings;
171     mResources.MaxVertexAtomicCounterBuffers =
172         caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
173     mResources.MaxFragmentAtomicCounterBuffers =
174         caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
175     mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
176     mResources.MaxAtomicCounterBufferSize      = caps.maxAtomicCounterBufferSize;
177 
178     mResources.MaxUniformBufferBindings       = caps.maxUniformBufferBindings;
179     mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
180 
181     // Needed by point size clamping workaround
182     mResources.MaxPointSize = caps.maxAliasedPointSize;
183 
184     if (state.getClientMajorVersion() == 2 && !extensions.drawBuffers)
185     {
186         mResources.MaxDrawBuffers = 1;
187     }
188 
189     // Geometry Shader constants
190     mResources.EXT_geometry_shader          = extensions.geometryShader;
191     mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry];
192     mResources.MaxGeometryUniformBlocks     = caps.maxShaderUniformBlocks[ShaderType::Geometry];
193     mResources.MaxGeometryInputComponents   = caps.maxGeometryInputComponents;
194     mResources.MaxGeometryOutputComponents  = caps.maxGeometryOutputComponents;
195     mResources.MaxGeometryOutputVertices    = caps.maxGeometryOutputVertices;
196     mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
197     mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
198 
199     mResources.MaxGeometryAtomicCounterBuffers =
200         caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
201     mResources.MaxGeometryAtomicCounters      = caps.maxShaderAtomicCounters[ShaderType::Geometry];
202     mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
203     mResources.MaxGeometryShaderInvocations   = caps.maxGeometryShaderInvocations;
204     mResources.MaxGeometryImageUniforms       = caps.maxShaderImageUniforms[ShaderType::Geometry];
205 
206     // Subpixel bits.
207     mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
208 }
209 
~Compiler()210 Compiler::~Compiler()
211 {
212     for (auto &pool : mPools)
213     {
214         for (ShCompilerInstance &instance : pool)
215         {
216             instance.destroy();
217         }
218     }
219     --gActiveCompilers;
220     if (gActiveCompilers == 0)
221     {
222         sh::Finalize();
223     }
224 }
225 
getInstance(ShaderType type)226 ShCompilerInstance Compiler::getInstance(ShaderType type)
227 {
228     ASSERT(type != ShaderType::InvalidEnum);
229     auto &pool = mPools[type];
230     if (pool.empty())
231     {
232         ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
233         ASSERT(handle);
234         return ShCompilerInstance(handle, mOutputType, type);
235     }
236     else
237     {
238         ShCompilerInstance instance = std::move(pool.back());
239         pool.pop_back();
240         return instance;
241     }
242 }
243 
putInstance(ShCompilerInstance && instance)244 void Compiler::putInstance(ShCompilerInstance &&instance)
245 {
246     static constexpr size_t kMaxPoolSize = 32;
247     auto &pool                           = mPools[instance.getShaderType()];
248     if (pool.size() < kMaxPoolSize)
249     {
250         pool.push_back(std::move(instance));
251     }
252     else
253     {
254         instance.destroy();
255     }
256 }
257 
ShCompilerInstance()258 ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {}
259 
ShCompilerInstance(ShHandle handle,ShShaderOutput outputType,ShaderType shaderType)260 ShCompilerInstance::ShCompilerInstance(ShHandle handle,
261                                        ShShaderOutput outputType,
262                                        ShaderType shaderType)
263     : mHandle(handle), mOutputType(outputType), mShaderType(shaderType)
264 {}
265 
~ShCompilerInstance()266 ShCompilerInstance::~ShCompilerInstance()
267 {
268     ASSERT(mHandle == nullptr);
269 }
270 
destroy()271 void ShCompilerInstance::destroy()
272 {
273     if (mHandle != nullptr)
274     {
275         sh::Destruct(mHandle);
276         mHandle = nullptr;
277     }
278 }
279 
ShCompilerInstance(ShCompilerInstance && other)280 ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other)
281     : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType)
282 {
283     other.mHandle = nullptr;
284 }
285 
operator =(ShCompilerInstance && other)286 ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other)
287 {
288     mHandle       = other.mHandle;
289     mOutputType   = other.mOutputType;
290     mShaderType   = other.mShaderType;
291     other.mHandle = nullptr;
292     return *this;
293 }
294 
getHandle()295 ShHandle ShCompilerInstance::getHandle()
296 {
297     return mHandle;
298 }
299 
getShaderType() const300 ShaderType ShCompilerInstance::getShaderType() const
301 {
302     return mShaderType;
303 }
304 
getBuiltinResourcesString()305 const std::string &ShCompilerInstance::getBuiltinResourcesString()
306 {
307     return sh::GetBuiltInResourcesString(mHandle);
308 }
309 
getShaderOutputType() const310 ShShaderOutput ShCompilerInstance::getShaderOutputType() const
311 {
312     return mOutputType;
313 }
314 
315 }  // namespace gl
316