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