• 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 
108     // TODO: use shader precision caps to determine if high precision is supported?
109     mResources.FragmentPrecisionHigh = 1;
110     mResources.EXT_frag_depth        = extensions.fragDepth;
111 
112     // OVR_multiview state
113     mResources.OVR_multiview = extensions.multiview;
114 
115     // OVR_multiview2 state
116     mResources.OVR_multiview2 = extensions.multiview2;
117     mResources.MaxViewsOVR    = extensions.maxViews;
118 
119     // EXT_multisampled_render_to_texture
120     mResources.EXT_multisampled_render_to_texture = extensions.multisampledRenderToTexture;
121 
122     // WEBGL_video_texture
123     mResources.WEBGL_video_texture = extensions.webglVideoTexture;
124 
125     // GLSL ES 3.0 constants
126     mResources.MaxVertexOutputVectors  = caps.maxVertexOutputComponents / 4;
127     mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
128     mResources.MinProgramTexelOffset   = caps.minProgramTexelOffset;
129     mResources.MaxProgramTexelOffset   = caps.maxProgramTexelOffset;
130 
131     // EXT_blend_func_extended
132     mResources.EXT_blend_func_extended  = extensions.blendFuncExtended;
133     mResources.MaxDualSourceDrawBuffers = extensions.maxDualSourceDrawBuffers;
134 
135     // GLSL ES 3.1 constants
136     mResources.MaxProgramTextureGatherOffset    = caps.maxProgramTextureGatherOffset;
137     mResources.MinProgramTextureGatherOffset    = caps.minProgramTextureGatherOffset;
138     mResources.MaxImageUnits                    = caps.maxImageUnits;
139     mResources.MaxVertexImageUniforms           = caps.maxShaderImageUniforms[ShaderType::Vertex];
140     mResources.MaxFragmentImageUniforms         = caps.maxShaderImageUniforms[ShaderType::Fragment];
141     mResources.MaxComputeImageUniforms          = caps.maxShaderImageUniforms[ShaderType::Compute];
142     mResources.MaxCombinedImageUniforms         = caps.maxCombinedImageUniforms;
143     mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
144     mResources.MaxUniformLocations              = caps.maxUniformLocations;
145 
146     for (size_t index = 0u; index < 3u; ++index)
147     {
148         mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
149         mResources.MaxComputeWorkGroupSize[index]  = caps.maxComputeWorkGroupSize[index];
150     }
151 
152     mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute];
153     mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute];
154 
155     mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute];
156     mResources.MaxComputeAtomicCounterBuffers =
157         caps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
158 
159     mResources.MaxVertexAtomicCounters   = caps.maxShaderAtomicCounters[ShaderType::Vertex];
160     mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment];
161     mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
162     mResources.MaxAtomicCounterBindings  = caps.maxAtomicCounterBufferBindings;
163     mResources.MaxVertexAtomicCounterBuffers =
164         caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
165     mResources.MaxFragmentAtomicCounterBuffers =
166         caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
167     mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
168     mResources.MaxAtomicCounterBufferSize      = caps.maxAtomicCounterBufferSize;
169 
170     mResources.MaxUniformBufferBindings       = caps.maxUniformBufferBindings;
171     mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
172 
173     // Needed by point size clamping workaround
174     mResources.MaxPointSize = caps.maxAliasedPointSize;
175 
176     if (state.getClientMajorVersion() == 2 && !extensions.drawBuffers)
177     {
178         mResources.MaxDrawBuffers = 1;
179     }
180 
181     // Geometry Shader constants
182     mResources.EXT_geometry_shader          = extensions.geometryShader;
183     mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry];
184     mResources.MaxGeometryUniformBlocks     = caps.maxShaderUniformBlocks[ShaderType::Geometry];
185     mResources.MaxGeometryInputComponents   = caps.maxGeometryInputComponents;
186     mResources.MaxGeometryOutputComponents  = caps.maxGeometryOutputComponents;
187     mResources.MaxGeometryOutputVertices    = caps.maxGeometryOutputVertices;
188     mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
189     mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
190 
191     mResources.MaxGeometryAtomicCounterBuffers =
192         caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
193     mResources.MaxGeometryAtomicCounters      = caps.maxShaderAtomicCounters[ShaderType::Geometry];
194     mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
195     mResources.MaxGeometryShaderInvocations   = caps.maxGeometryShaderInvocations;
196     mResources.MaxGeometryImageUniforms       = caps.maxShaderImageUniforms[ShaderType::Geometry];
197 
198     // Subpixel bits.
199     mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
200 }
201 
~Compiler()202 Compiler::~Compiler()
203 {
204     for (auto &pool : mPools)
205     {
206         for (ShCompilerInstance &instance : pool)
207         {
208             instance.destroy();
209         }
210     }
211     --gActiveCompilers;
212     if (gActiveCompilers == 0)
213     {
214         sh::Finalize();
215     }
216 }
217 
getInstance(ShaderType type)218 ShCompilerInstance Compiler::getInstance(ShaderType type)
219 {
220     ASSERT(type != ShaderType::InvalidEnum);
221     auto &pool = mPools[type];
222     if (pool.empty())
223     {
224         ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
225         ASSERT(handle);
226         return ShCompilerInstance(handle, mOutputType, type);
227     }
228     else
229     {
230         ShCompilerInstance instance = std::move(pool.back());
231         pool.pop_back();
232         return instance;
233     }
234 }
235 
putInstance(ShCompilerInstance && instance)236 void Compiler::putInstance(ShCompilerInstance &&instance)
237 {
238     static constexpr size_t kMaxPoolSize = 32;
239     auto &pool                           = mPools[instance.getShaderType()];
240     if (pool.size() < kMaxPoolSize)
241     {
242         pool.push_back(std::move(instance));
243     }
244     else
245     {
246         instance.destroy();
247     }
248 }
249 
ShCompilerInstance()250 ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {}
251 
ShCompilerInstance(ShHandle handle,ShShaderOutput outputType,ShaderType shaderType)252 ShCompilerInstance::ShCompilerInstance(ShHandle handle,
253                                        ShShaderOutput outputType,
254                                        ShaderType shaderType)
255     : mHandle(handle), mOutputType(outputType), mShaderType(shaderType)
256 {}
257 
~ShCompilerInstance()258 ShCompilerInstance::~ShCompilerInstance()
259 {
260     ASSERT(mHandle == nullptr);
261 }
262 
destroy()263 void ShCompilerInstance::destroy()
264 {
265     if (mHandle != nullptr)
266     {
267         sh::Destruct(mHandle);
268         mHandle = nullptr;
269     }
270 }
271 
ShCompilerInstance(ShCompilerInstance && other)272 ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other)
273     : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType)
274 {
275     other.mHandle = nullptr;
276 }
277 
operator =(ShCompilerInstance && other)278 ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other)
279 {
280     mHandle       = other.mHandle;
281     mOutputType   = other.mOutputType;
282     mShaderType   = other.mShaderType;
283     other.mHandle = nullptr;
284     return *this;
285 }
286 
getHandle()287 ShHandle ShCompilerInstance::getHandle()
288 {
289     return mHandle;
290 }
291 
getShaderType() const292 ShaderType ShCompilerInstance::getShaderType() const
293 {
294     return mShaderType;
295 }
296 
getBuiltinResourcesString()297 const std::string &ShCompilerInstance::getBuiltinResourcesString()
298 {
299     return sh::GetBuiltInResourcesString(mHandle);
300 }
301 
getShaderOutputType() const302 ShShaderOutput ShCompilerInstance::getShaderOutputType() const
303 {
304     return mOutputType;
305 }
306 
307 }  // namespace gl
308