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