xref: /aosp_15_r20/external/angle/src/libANGLE/Compiler.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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