• 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/Context.h"
13 #include "libANGLE/Display.h"
14 #include "libANGLE/State.h"
15 #include "libANGLE/renderer/CompilerImpl.h"
16 #include "libANGLE/renderer/GLImplFactory.h"
17 
18 namespace gl
19 {
20 
21 namespace
22 {
23 
24 // To know when to call sh::Initialize and sh::Finalize.
25 size_t gActiveCompilers = 0;
26 
SelectShaderSpec(GLint majorVersion,GLint minorVersion,bool isWebGL,EGLenum clientType)27 ShShaderSpec SelectShaderSpec(GLint majorVersion,
28                               GLint minorVersion,
29                               bool isWebGL,
30                               EGLenum clientType)
31 {
32     // For Desktop GL
33     if (clientType == EGL_OPENGL_API)
34     {
35         return SH_GL_COMPATIBILITY_SPEC;
36     }
37 
38     if (majorVersion >= 3)
39     {
40         switch (minorVersion)
41         {
42             case 2:
43                 ASSERT(!isWebGL);
44                 return SH_GLES3_2_SPEC;
45             case 1:
46                 return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
47             case 0:
48                 return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
49             default:
50                 UNREACHABLE();
51         }
52     }
53 
54     // GLES1 emulation: Use GLES3 shader spec.
55     if (!isWebGL && majorVersion == 1)
56     {
57         return SH_GLES3_SPEC;
58     }
59 
60     return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
61 }
62 
63 }  // anonymous namespace
64 
Compiler(rx::GLImplFactory * implFactory,const State & state,egl::Display * display)65 Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Display *display)
66     : mImplementation(implFactory->createCompiler()),
67       mSpec(SelectShaderSpec(state.getClientMajorVersion(),
68                              state.getClientMinorVersion(),
69                              state.isWebGL(),
70                              state.getClientType())),
71       mOutputType(mImplementation->getTranslatorOutputType()),
72       mResources()
73 {
74     // TODO(http://anglebug.com/3819): Update for GL version specific validation
75     ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
76            state.getClientMajorVersion() == 3 || state.getClientMajorVersion() == 4);
77 
78     const gl::Caps &caps             = state.getCaps();
79     const gl::Extensions &extensions = state.getExtensions();
80 
81     {
82         std::lock_guard<std::mutex> lock(display->getDisplayGlobalMutex());
83         if (gActiveCompilers == 0)
84         {
85             sh::Initialize();
86         }
87         ++gActiveCompilers;
88     }
89 
90     sh::InitBuiltInResources(&mResources);
91     mResources.MaxVertexAttribs             = caps.maxVertexAttributes;
92     mResources.MaxVertexUniformVectors      = caps.maxVertexUniformVectors;
93     mResources.MaxVaryingVectors            = caps.maxVaryingVectors;
94     mResources.MaxVertexTextureImageUnits   = caps.maxShaderTextureImageUnits[ShaderType::Vertex];
95     mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
96     mResources.MaxTextureImageUnits         = caps.maxShaderTextureImageUnits[ShaderType::Fragment];
97     mResources.MaxFragmentUniformVectors    = caps.maxFragmentUniformVectors;
98     mResources.MaxDrawBuffers               = caps.maxDrawBuffers;
99     mResources.OES_standard_derivatives     = extensions.standardDerivativesOES;
100     mResources.EXT_draw_buffers             = extensions.drawBuffersEXT;
101     mResources.EXT_shader_texture_lod       = extensions.shaderTextureLodEXT;
102     mResources.EXT_shader_non_constant_global_initializers =
103         extensions.shaderNonConstantGlobalInitializersEXT;
104     mResources.OES_EGL_image_external          = extensions.EGLImageExternalOES;
105     mResources.OES_EGL_image_external_essl3    = extensions.EGLImageExternalEssl3OES;
106     mResources.NV_EGL_stream_consumer_external = extensions.EGLStreamConsumerExternalNV;
107     mResources.NV_shader_noperspective_interpolation =
108         extensions.shaderNoperspectiveInterpolationNV;
109     mResources.ARB_texture_rectangle = extensions.textureRectangleANGLE;
110     mResources.EXT_gpu_shader5       = extensions.gpuShader5EXT;
111     mResources.OES_shader_io_blocks  = extensions.shaderIoBlocksOES;
112     mResources.EXT_shader_io_blocks  = extensions.shaderIoBlocksEXT;
113     mResources.OES_texture_storage_multisample_2d_array =
114         extensions.textureStorageMultisample2dArrayOES;
115     mResources.OES_texture_3D            = extensions.texture3DOES;
116     mResources.ANGLE_texture_multisample = extensions.textureMultisampleANGLE;
117     mResources.ANGLE_multi_draw          = extensions.multiDrawANGLE;
118     mResources.ANGLE_base_vertex_base_instance_shader_builtin =
119         extensions.baseVertexBaseInstanceShaderBuiltinANGLE;
120     mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE;
121     // OES_shader_multisample_interpolation
122     mResources.OES_shader_multisample_interpolation = extensions.shaderMultisampleInterpolationOES;
123     mResources.OES_shader_image_atomic              = extensions.shaderImageAtomicOES;
124     // TODO: use shader precision caps to determine if high precision is supported?
125     mResources.FragmentPrecisionHigh = 1;
126     mResources.EXT_frag_depth        = extensions.fragDepthEXT;
127 
128     // OVR_multiview state
129     mResources.OVR_multiview = extensions.multiviewOVR;
130 
131     // OVR_multiview2 state
132     mResources.OVR_multiview2 = extensions.multiview2OVR;
133     mResources.MaxViewsOVR    = caps.maxViews;
134 
135     // EXT_multisampled_render_to_texture and EXT_multisampled_render_to_texture2
136     mResources.EXT_multisampled_render_to_texture  = extensions.multisampledRenderToTextureEXT;
137     mResources.EXT_multisampled_render_to_texture2 = extensions.multisampledRenderToTexture2EXT;
138 
139     // WEBGL_video_texture
140     mResources.WEBGL_video_texture = extensions.videoTextureWEBGL;
141 
142     // OES_texture_cube_map_array
143     mResources.OES_texture_cube_map_array = extensions.textureCubeMapArrayOES;
144     mResources.EXT_texture_cube_map_array = extensions.textureCubeMapArrayEXT;
145 
146     // EXT_shadow_samplers
147     mResources.EXT_shadow_samplers = extensions.shadowSamplersEXT;
148 
149     // OES_texture_buffer
150     mResources.OES_texture_buffer = extensions.textureBufferOES;
151     mResources.EXT_texture_buffer = extensions.textureBufferEXT;
152 
153     // GL_EXT_YUV_target
154     mResources.EXT_YUV_target = extensions.YUVTargetEXT;
155 
156     mResources.EXT_shader_framebuffer_fetch_non_coherent =
157         extensions.shaderFramebufferFetchNonCoherentEXT;
158 
159     mResources.EXT_shader_framebuffer_fetch = extensions.shaderFramebufferFetchEXT;
160 
161     // GL_EXT_clip_cull_distance
162     mResources.EXT_clip_cull_distance = extensions.clipCullDistanceEXT;
163 
164     // GL_EXT_primitive_bounding_box
165     mResources.EXT_primitive_bounding_box = extensions.primitiveBoundingBoxEXT;
166 
167     // GL_OES_primitive_bounding_box
168     mResources.OES_primitive_bounding_box = extensions.primitiveBoundingBoxOES;
169 
170     // GLSL ES 3.0 constants
171     mResources.MaxVertexOutputVectors  = caps.maxVertexOutputComponents / 4;
172     mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
173     mResources.MinProgramTexelOffset   = caps.minProgramTexelOffset;
174     mResources.MaxProgramTexelOffset   = caps.maxProgramTexelOffset;
175 
176     // EXT_blend_func_extended
177     mResources.EXT_blend_func_extended  = extensions.blendFuncExtendedEXT;
178     mResources.MaxDualSourceDrawBuffers = caps.maxDualSourceDrawBuffers;
179 
180     // APPLE_clip_distance/EXT_clip_cull_distance
181     mResources.MaxClipDistances                = caps.maxClipDistances;
182     mResources.MaxCullDistances                = caps.maxCullDistances;
183     mResources.MaxCombinedClipAndCullDistances = caps.maxCombinedClipAndCullDistances;
184 
185     // OES_sample_variables
186     mResources.OES_sample_variables = extensions.sampleVariablesOES;
187     mResources.MaxSamples           = caps.maxSamples;
188 
189     // ANDROID_extension_pack_es31a
190     mResources.ANDROID_extension_pack_es31a = extensions.extensionPackEs31aANDROID;
191 
192     // KHR_blend_equation_advanced
193     mResources.KHR_blend_equation_advanced = extensions.blendEquationAdvancedKHR;
194 
195     // GLSL ES 3.1 constants
196     mResources.MaxProgramTextureGatherOffset    = caps.maxProgramTextureGatherOffset;
197     mResources.MinProgramTextureGatherOffset    = caps.minProgramTextureGatherOffset;
198     mResources.MaxImageUnits                    = caps.maxImageUnits;
199     mResources.MaxVertexImageUniforms           = caps.maxShaderImageUniforms[ShaderType::Vertex];
200     mResources.MaxFragmentImageUniforms         = caps.maxShaderImageUniforms[ShaderType::Fragment];
201     mResources.MaxComputeImageUniforms          = caps.maxShaderImageUniforms[ShaderType::Compute];
202     mResources.MaxCombinedImageUniforms         = caps.maxCombinedImageUniforms;
203     mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
204     mResources.MaxUniformLocations              = caps.maxUniformLocations;
205 
206     for (size_t index = 0u; index < 3u; ++index)
207     {
208         mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
209         mResources.MaxComputeWorkGroupSize[index]  = caps.maxComputeWorkGroupSize[index];
210     }
211 
212     mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute];
213     mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute];
214 
215     mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute];
216     mResources.MaxComputeAtomicCounterBuffers =
217         caps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
218 
219     mResources.MaxVertexAtomicCounters   = caps.maxShaderAtomicCounters[ShaderType::Vertex];
220     mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment];
221     mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
222     mResources.MaxAtomicCounterBindings  = caps.maxAtomicCounterBufferBindings;
223     mResources.MaxVertexAtomicCounterBuffers =
224         caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
225     mResources.MaxFragmentAtomicCounterBuffers =
226         caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
227     mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
228     mResources.MaxAtomicCounterBufferSize      = caps.maxAtomicCounterBufferSize;
229 
230     mResources.MaxUniformBufferBindings       = caps.maxUniformBufferBindings;
231     mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
232 
233     // Needed by point size clamping workaround
234     mResources.MaxPointSize = caps.maxAliasedPointSize;
235 
236     if (state.getClientMajorVersion() == 2 && !extensions.drawBuffersEXT)
237     {
238         mResources.MaxDrawBuffers = 1;
239     }
240 
241     // Geometry Shader constants
242     mResources.EXT_geometry_shader          = extensions.geometryShaderEXT;
243     mResources.OES_geometry_shader          = extensions.geometryShaderOES;
244     mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry];
245     mResources.MaxGeometryUniformBlocks     = caps.maxShaderUniformBlocks[ShaderType::Geometry];
246     mResources.MaxGeometryInputComponents   = caps.maxGeometryInputComponents;
247     mResources.MaxGeometryOutputComponents  = caps.maxGeometryOutputComponents;
248     mResources.MaxGeometryOutputVertices    = caps.maxGeometryOutputVertices;
249     mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
250     mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
251 
252     mResources.MaxGeometryAtomicCounterBuffers =
253         caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
254     mResources.MaxGeometryAtomicCounters      = caps.maxShaderAtomicCounters[ShaderType::Geometry];
255     mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
256     mResources.MaxGeometryShaderInvocations   = caps.maxGeometryShaderInvocations;
257     mResources.MaxGeometryImageUniforms       = caps.maxShaderImageUniforms[ShaderType::Geometry];
258 
259     // Tessellation Shader constants
260     mResources.EXT_tessellation_shader        = extensions.tessellationShaderEXT;
261     mResources.MaxTessControlInputComponents  = caps.maxTessControlInputComponents;
262     mResources.MaxTessControlOutputComponents = caps.maxTessControlOutputComponents;
263     mResources.MaxTessControlTextureImageUnits =
264         caps.maxShaderTextureImageUnits[ShaderType::TessControl];
265     mResources.MaxTessControlUniformComponents =
266         caps.maxShaderUniformComponents[ShaderType::TessControl];
267     mResources.MaxTessControlTotalOutputComponents = caps.maxTessControlTotalOutputComponents;
268     mResources.MaxTessControlImageUniforms  = caps.maxShaderImageUniforms[ShaderType::TessControl];
269     mResources.MaxTessControlAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::TessControl];
270     mResources.MaxTessControlAtomicCounterBuffers =
271         caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
272 
273     mResources.MaxTessPatchComponents = caps.maxTessPatchComponents;
274     mResources.MaxPatchVertices       = caps.maxPatchVertices;
275     mResources.MaxTessGenLevel        = caps.maxTessGenLevel;
276 
277     mResources.MaxTessEvaluationInputComponents  = caps.maxTessEvaluationInputComponents;
278     mResources.MaxTessEvaluationOutputComponents = caps.maxTessEvaluationOutputComponents;
279     mResources.MaxTessEvaluationTextureImageUnits =
280         caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation];
281     mResources.MaxTessEvaluationUniformComponents =
282         caps.maxShaderUniformComponents[ShaderType::TessEvaluation];
283     mResources.MaxTessEvaluationImageUniforms =
284         caps.maxShaderImageUniforms[ShaderType::TessEvaluation];
285     mResources.MaxTessEvaluationAtomicCounters =
286         caps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
287     mResources.MaxTessEvaluationAtomicCounterBuffers =
288         caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
289 
290     // Subpixel bits.
291     mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
292 
293     // Direct-to-metal constants:
294     mResources.DriverUniformsBindingIndex    = caps.driverUniformsBindingIndex;
295     mResources.DefaultUniformsBindingIndex   = caps.defaultUniformsBindingIndex;
296     mResources.UBOArgumentBufferBindingIndex = caps.UBOArgumentBufferBindingIndex;
297 }
298 
299 Compiler::~Compiler() = default;
300 
onDestroy(const Context * context)301 void Compiler::onDestroy(const Context *context)
302 {
303     std::lock_guard<std::mutex> lock(context->getDisplay()->getDisplayGlobalMutex());
304     for (auto &pool : mPools)
305     {
306         for (ShCompilerInstance &instance : pool)
307         {
308             instance.destroy();
309         }
310     }
311     --gActiveCompilers;
312     if (gActiveCompilers == 0)
313     {
314         sh::Finalize();
315     }
316 }
317 
getInstance(ShaderType type)318 ShCompilerInstance Compiler::getInstance(ShaderType type)
319 {
320     ASSERT(type != ShaderType::InvalidEnum);
321     auto &pool = mPools[type];
322     if (pool.empty())
323     {
324         ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
325         ASSERT(handle);
326         return ShCompilerInstance(handle, mOutputType, type);
327     }
328     else
329     {
330         ShCompilerInstance instance = std::move(pool.back());
331         pool.pop_back();
332         return instance;
333     }
334 }
335 
putInstance(ShCompilerInstance && instance)336 void Compiler::putInstance(ShCompilerInstance &&instance)
337 {
338     static constexpr size_t kMaxPoolSize = 32;
339     auto &pool                           = mPools[instance.getShaderType()];
340     if (pool.size() < kMaxPoolSize)
341     {
342         pool.push_back(std::move(instance));
343     }
344     else
345     {
346         instance.destroy();
347     }
348 }
349 
ShCompilerInstance()350 ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {}
351 
ShCompilerInstance(ShHandle handle,ShShaderOutput outputType,ShaderType shaderType)352 ShCompilerInstance::ShCompilerInstance(ShHandle handle,
353                                        ShShaderOutput outputType,
354                                        ShaderType shaderType)
355     : mHandle(handle), mOutputType(outputType), mShaderType(shaderType)
356 {}
357 
~ShCompilerInstance()358 ShCompilerInstance::~ShCompilerInstance()
359 {
360     ASSERT(mHandle == nullptr);
361 }
362 
destroy()363 void ShCompilerInstance::destroy()
364 {
365     if (mHandle != nullptr)
366     {
367         sh::Destruct(mHandle);
368         mHandle = nullptr;
369     }
370 }
371 
ShCompilerInstance(ShCompilerInstance && other)372 ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other)
373     : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType)
374 {
375     other.mHandle = nullptr;
376 }
377 
operator =(ShCompilerInstance && other)378 ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other)
379 {
380     mHandle       = other.mHandle;
381     mOutputType   = other.mOutputType;
382     mShaderType   = other.mShaderType;
383     other.mHandle = nullptr;
384     return *this;
385 }
386 
getHandle()387 ShHandle ShCompilerInstance::getHandle()
388 {
389     return mHandle;
390 }
391 
getShaderType() const392 ShaderType ShCompilerInstance::getShaderType() const
393 {
394     return mShaderType;
395 }
396 
getBuiltinResourcesString()397 const std::string &ShCompilerInstance::getBuiltinResourcesString()
398 {
399     return sh::GetBuiltInResourcesString(mHandle);
400 }
401 
getShaderOutputType() const402 ShShaderOutput ShCompilerInstance::getShaderOutputType() const
403 {
404     return mOutputType;
405 }
406 
407 }  // namespace gl
408