• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 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 //
8 // Implement the top-level of interface to the compiler,
9 // as defined in ShaderLang.h
10 //
11 
12 #include "GLSLANG/ShaderLang.h"
13 
14 #include "compiler/translator/Compiler.h"
15 #include "compiler/translator/InitializeDll.h"
16 #include "compiler/translator/glslang_wrapper.h"
17 #include "compiler/translator/length_limits.h"
18 #ifdef ANGLE_ENABLE_HLSL
19 #    include "compiler/translator/TranslatorHLSL.h"
20 #endif  // ANGLE_ENABLE_HLSL
21 #include "angle_gl.h"
22 #include "compiler/translator/VariablePacker.h"
23 
24 namespace sh
25 {
26 
27 namespace
28 {
29 
30 bool isInitialized = false;
31 
32 // glslang can only be initialized/finalized once per process. Otherwise, the following EGL commands
33 // will call GlslangFinalize() without ever being able to GlslangInitialize() again, leading to
34 // crashes since GlslangFinalize() cleans up glslang for the entire process.
35 //   dpy1 = eglGetPlatformDisplay()   |
36 //   eglInitialize(dpy1)              | GlslangInitialize()
37 //   dpy2 = eglGetPlatformDisplay()   |
38 //   eglInitialize(dpy2)              | GlslangInitialize()
39 //   eglTerminate(dpy2)               | GlslangFinalize()
40 //   eglInitialize(dpy1)              | Display::isInitialized() == true, no GlslangInitialize()
41 int initializeGlslangRefCount = 0;
42 
43 //
44 // This is the platform independent interface between an OGL driver
45 // and the shading language compiler.
46 //
47 
48 template <typename VarT>
49 const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
50 
51 template <>
GetVariableList(const TCompiler * compiler)52 const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler)
53 {
54     return &compiler->getInterfaceBlocks();
55 }
56 
GetCompilerFromHandle(ShHandle handle)57 TCompiler *GetCompilerFromHandle(ShHandle handle)
58 {
59     if (!handle)
60     {
61         return nullptr;
62     }
63 
64     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
65     return base->getAsCompiler();
66 }
67 
68 template <typename VarT>
GetShaderVariables(const ShHandle handle)69 const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
70 {
71     TCompiler *compiler = GetCompilerFromHandle(handle);
72     if (!compiler)
73     {
74         return nullptr;
75     }
76 
77     return GetVariableList<VarT>(compiler);
78 }
79 
80 #ifdef ANGLE_ENABLE_HLSL
GetTranslatorHLSLFromHandle(ShHandle handle)81 TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
82 {
83     if (!handle)
84         return nullptr;
85     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
86     return base->getAsTranslatorHLSL();
87 }
88 #endif  // ANGLE_ENABLE_HLSL
89 
GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType)90 GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType)
91 {
92     switch (primitiveType)
93     {
94         case EptPoints:
95             return GL_POINTS;
96         case EptLines:
97             return GL_LINES;
98         case EptLinesAdjacency:
99             return GL_LINES_ADJACENCY_EXT;
100         case EptTriangles:
101             return GL_TRIANGLES;
102         case EptTrianglesAdjacency:
103             return GL_TRIANGLES_ADJACENCY_EXT;
104 
105         case EptLineStrip:
106             return GL_LINE_STRIP;
107         case EptTriangleStrip:
108             return GL_TRIANGLE_STRIP;
109 
110         case EptUndefined:
111         default:
112             UNREACHABLE();
113             return GL_INVALID_VALUE;
114     }
115 }
116 
GetTessellationShaderTypeEnum(sh::TLayoutTessEvaluationType type)117 GLenum GetTessellationShaderTypeEnum(sh::TLayoutTessEvaluationType type)
118 {
119     switch (type)
120     {
121         case EtetTriangles:
122             return GL_TRIANGLES;
123         case EtetQuads:
124             return GL_QUADS;
125         case EtetIsolines:
126             return GL_ISOLINES;
127         case EtetEqualSpacing:
128             return GL_EQUAL;
129         case EtetFractionalEvenSpacing:
130             return GL_FRACTIONAL_EVEN;
131         case EtetFractionalOddSpacing:
132             return GL_FRACTIONAL_ODD;
133         case EtetCw:
134             return GL_CW;
135         case EtetCcw:
136             return GL_CCW;
137         case EtetPointMode:
138             return GL_TESS_GEN_POINT_MODE;
139 
140         case EtetUndefined:
141         default:
142             UNREACHABLE();
143             return GL_INVALID_VALUE;
144     }
145 }
146 
147 }  // anonymous namespace
148 
149 //
150 // Driver must call this first, once, before doing any other compiler operations.
151 // Subsequent calls to this function are no-op.
152 //
Initialize()153 bool Initialize()
154 {
155     if (!isInitialized)
156     {
157         isInitialized = InitProcess();
158     }
159     return isInitialized;
160 }
161 
162 //
163 // Cleanup symbol tables
164 //
Finalize()165 bool Finalize()
166 {
167     if (isInitialized)
168     {
169         DetachProcess();
170         isInitialized = false;
171     }
172     return true;
173 }
174 
175 //
176 // Initialize built-in resources with minimum expected values.
177 //
InitBuiltInResources(ShBuiltInResources * resources)178 void InitBuiltInResources(ShBuiltInResources *resources)
179 {
180     // Make comparable.
181     memset(resources, 0, sizeof(*resources));
182 
183     // Constants.
184     resources->MaxVertexAttribs             = 8;
185     resources->MaxVertexUniformVectors      = 128;
186     resources->MaxVaryingVectors            = 8;
187     resources->MaxVertexTextureImageUnits   = 0;
188     resources->MaxCombinedTextureImageUnits = 8;
189     resources->MaxTextureImageUnits         = 8;
190     resources->MaxFragmentUniformVectors    = 16;
191     resources->MaxDrawBuffers               = 1;
192 
193     // Extensions.
194     resources->OES_standard_derivatives                       = 0;
195     resources->OES_EGL_image_external                         = 0;
196     resources->OES_EGL_image_external_essl3                   = 0;
197     resources->NV_EGL_stream_consumer_external                = 0;
198     resources->ARB_texture_rectangle                          = 0;
199     resources->EXT_blend_func_extended                        = 0;
200     resources->EXT_draw_buffers                               = 0;
201     resources->EXT_frag_depth                                 = 0;
202     resources->EXT_shader_texture_lod                         = 0;
203     resources->EXT_shader_framebuffer_fetch                   = 0;
204     resources->EXT_shader_framebuffer_fetch_non_coherent      = 0;
205     resources->NV_shader_framebuffer_fetch                    = 0;
206     resources->ARM_shader_framebuffer_fetch                   = 0;
207     resources->OVR_multiview                                  = 0;
208     resources->OVR_multiview2                                 = 0;
209     resources->EXT_YUV_target                                 = 0;
210     resources->EXT_geometry_shader                            = 0;
211     resources->OES_geometry_shader                            = 0;
212     resources->EXT_gpu_shader5                                = 0;
213     resources->OES_shader_io_blocks                           = 0;
214     resources->EXT_shader_io_blocks                           = 0;
215     resources->EXT_shader_non_constant_global_initializers    = 0;
216     resources->NV_shader_noperspective_interpolation          = 0;
217     resources->OES_texture_storage_multisample_2d_array       = 0;
218     resources->OES_texture_3D                                 = 0;
219     resources->ANGLE_texture_multisample                      = 0;
220     resources->ANGLE_multi_draw                               = 0;
221     resources->ANGLE_base_vertex_base_instance                = 0;
222     resources->ANGLE_base_vertex_base_instance_shader_builtin = 0;
223     resources->WEBGL_video_texture                            = 0;
224     resources->APPLE_clip_distance                            = 0;
225     resources->OES_texture_cube_map_array                     = 0;
226     resources->EXT_texture_cube_map_array                     = 0;
227     resources->EXT_shadow_samplers                            = 0;
228     resources->OES_shader_multisample_interpolation           = 0;
229     resources->NV_draw_buffers                                = 0;
230     resources->OES_shader_image_atomic                        = 0;
231     resources->EXT_tessellation_shader                        = 0;
232     resources->OES_texture_buffer                             = 0;
233     resources->EXT_texture_buffer                             = 0;
234     resources->OES_sample_variables                           = 0;
235     resources->EXT_clip_cull_distance                         = 0;
236 
237     resources->MaxClipDistances                = 8;
238     resources->MaxCullDistances                = 8;
239     resources->MaxCombinedClipAndCullDistances = 8;
240 
241     // Disable highp precision in fragment shader by default.
242     resources->FragmentPrecisionHigh = 0;
243 
244     // GLSL ES 3.0 constants.
245     resources->MaxVertexOutputVectors  = 16;
246     resources->MaxFragmentInputVectors = 15;
247     resources->MinProgramTexelOffset   = -8;
248     resources->MaxProgramTexelOffset   = 7;
249 
250     // Extensions constants.
251     resources->MaxDualSourceDrawBuffers = 0;
252 
253     resources->MaxViewsOVR = 4;
254 
255     // Disable name hashing by default.
256     resources->HashFunction = nullptr;
257 
258     resources->MaxExpressionComplexity = 256;
259     resources->MaxCallStackDepth       = 256;
260     resources->MaxFunctionParameters   = 1024;
261 
262     // ES 3.1 Revision 4, 7.2 Built-in Constants
263 
264     // ES 3.1, Revision 4, 8.13 Texture minification
265     // "The value of MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be less than or equal to the value of
266     // MIN_PROGRAM_TEXEL_OFFSET. The value of MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be greater than
267     // or equal to the value of MAX_PROGRAM_TEXEL_OFFSET"
268     resources->MinProgramTextureGatherOffset = -8;
269     resources->MaxProgramTextureGatherOffset = 7;
270 
271     resources->MaxImageUnits            = 4;
272     resources->MaxVertexImageUniforms   = 0;
273     resources->MaxFragmentImageUniforms = 0;
274     resources->MaxComputeImageUniforms  = 4;
275     resources->MaxCombinedImageUniforms = 4;
276 
277     resources->MaxUniformLocations = 1024;
278 
279     resources->MaxCombinedShaderOutputResources = 4;
280 
281     resources->MaxComputeWorkGroupCount[0] = 65535;
282     resources->MaxComputeWorkGroupCount[1] = 65535;
283     resources->MaxComputeWorkGroupCount[2] = 65535;
284     resources->MaxComputeWorkGroupSize[0]  = 128;
285     resources->MaxComputeWorkGroupSize[1]  = 128;
286     resources->MaxComputeWorkGroupSize[2]  = 64;
287     resources->MaxComputeUniformComponents = 512;
288     resources->MaxComputeTextureImageUnits = 16;
289 
290     resources->MaxComputeAtomicCounters       = 8;
291     resources->MaxComputeAtomicCounterBuffers = 1;
292 
293     resources->MaxVertexAtomicCounters   = 0;
294     resources->MaxFragmentAtomicCounters = 0;
295     resources->MaxCombinedAtomicCounters = 8;
296     resources->MaxAtomicCounterBindings  = 1;
297 
298     resources->MaxVertexAtomicCounterBuffers   = 0;
299     resources->MaxFragmentAtomicCounterBuffers = 0;
300     resources->MaxCombinedAtomicCounterBuffers = 1;
301     resources->MaxAtomicCounterBufferSize      = 32;
302 
303     resources->MaxUniformBufferBindings       = 32;
304     resources->MaxShaderStorageBufferBindings = 4;
305 
306     resources->MaxGeometryUniformComponents     = 1024;
307     resources->MaxGeometryUniformBlocks         = 12;
308     resources->MaxGeometryInputComponents       = 64;
309     resources->MaxGeometryOutputComponents      = 64;
310     resources->MaxGeometryOutputVertices        = 256;
311     resources->MaxGeometryTotalOutputComponents = 1024;
312     resources->MaxGeometryTextureImageUnits     = 16;
313     resources->MaxGeometryAtomicCounterBuffers  = 0;
314     resources->MaxGeometryAtomicCounters        = 0;
315     resources->MaxGeometryShaderStorageBlocks   = 0;
316     resources->MaxGeometryShaderInvocations     = 32;
317     resources->MaxGeometryImageUniforms         = 0;
318 
319     resources->MaxTessControlInputComponents       = 64;
320     resources->MaxTessControlOutputComponents      = 64;
321     resources->MaxTessControlTextureImageUnits     = 16;
322     resources->MaxTessControlUniformComponents     = 1024;
323     resources->MaxTessControlTotalOutputComponents = 2048;
324     resources->MaxTessControlImageUniforms         = 0;
325     resources->MaxTessControlAtomicCounters        = 0;
326     resources->MaxTessControlAtomicCounterBuffers  = 0;
327 
328     resources->MaxTessPatchComponents = 120;
329     resources->MaxPatchVertices       = 32;
330     resources->MaxTessGenLevel        = 64;
331 
332     resources->MaxTessEvaluationInputComponents      = 64;
333     resources->MaxTessEvaluationOutputComponents     = 64;
334     resources->MaxTessEvaluationTextureImageUnits    = 16;
335     resources->MaxTessEvaluationUniformComponents    = 1024;
336     resources->MaxTessEvaluationImageUniforms        = 0;
337     resources->MaxTessEvaluationAtomicCounters       = 0;
338     resources->MaxTessEvaluationAtomicCounterBuffers = 0;
339 
340     resources->SubPixelBits = 8;
341 
342     resources->MaxSamples = 4;
343 }
344 
345 //
346 // Driver calls these to create and destroy compiler objects.
347 //
ConstructCompiler(sh::GLenum type,ShShaderSpec spec,ShShaderOutput output,const ShBuiltInResources * resources)348 ShHandle ConstructCompiler(sh::GLenum type,
349                            ShShaderSpec spec,
350                            ShShaderOutput output,
351                            const ShBuiltInResources *resources)
352 {
353     TShHandleBase *base = static_cast<TShHandleBase *>(ConstructCompiler(type, spec, output));
354     if (base == nullptr)
355     {
356         return 0;
357     }
358 
359     TCompiler *compiler = base->getAsCompiler();
360     if (compiler == nullptr)
361     {
362         return 0;
363     }
364 
365     // Generate built-in symbol table.
366     if (!compiler->Init(*resources))
367     {
368         Destruct(base);
369         return 0;
370     }
371 
372     return base;
373 }
374 
Destruct(ShHandle handle)375 void Destruct(ShHandle handle)
376 {
377     if (handle == 0)
378         return;
379 
380     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
381 
382     if (base->getAsCompiler())
383         DeleteCompiler(base->getAsCompiler());
384 }
385 
GetBuiltInResourcesString(const ShHandle handle)386 const std::string &GetBuiltInResourcesString(const ShHandle handle)
387 {
388     TCompiler *compiler = GetCompilerFromHandle(handle);
389     ASSERT(compiler);
390     return compiler->getBuiltInResourcesString();
391 }
392 
393 //
394 // Do an actual compile on the given strings.  The result is left
395 // in the given compile object.
396 //
397 // Return:  The return value of ShCompile is really boolean, indicating
398 // success or failure.
399 //
Compile(const ShHandle handle,const char * const shaderStrings[],size_t numStrings,ShCompileOptions compileOptions)400 bool Compile(const ShHandle handle,
401              const char *const shaderStrings[],
402              size_t numStrings,
403              ShCompileOptions compileOptions)
404 {
405     TCompiler *compiler = GetCompilerFromHandle(handle);
406     ASSERT(compiler);
407 
408     return compiler->compile(shaderStrings, numStrings, compileOptions);
409 }
410 
ClearResults(const ShHandle handle)411 void ClearResults(const ShHandle handle)
412 {
413     TCompiler *compiler = GetCompilerFromHandle(handle);
414     ASSERT(compiler);
415     compiler->clearResults();
416 }
417 
GetShaderVersion(const ShHandle handle)418 int GetShaderVersion(const ShHandle handle)
419 {
420     TCompiler *compiler = GetCompilerFromHandle(handle);
421     ASSERT(compiler);
422     return compiler->getShaderVersion();
423 }
424 
GetShaderOutputType(const ShHandle handle)425 ShShaderOutput GetShaderOutputType(const ShHandle handle)
426 {
427     TCompiler *compiler = GetCompilerFromHandle(handle);
428     ASSERT(compiler);
429     return compiler->getOutputType();
430 }
431 
432 //
433 // Return any compiler log of messages for the application.
434 //
GetInfoLog(const ShHandle handle)435 const std::string &GetInfoLog(const ShHandle handle)
436 {
437     TCompiler *compiler = GetCompilerFromHandle(handle);
438     ASSERT(compiler);
439 
440     TInfoSink &infoSink = compiler->getInfoSink();
441     return infoSink.info.str();
442 }
443 
444 //
445 // Return any object code.
446 //
GetObjectCode(const ShHandle handle)447 const std::string &GetObjectCode(const ShHandle handle)
448 {
449     TCompiler *compiler = GetCompilerFromHandle(handle);
450     ASSERT(compiler);
451 
452     TInfoSink &infoSink = compiler->getInfoSink();
453     return infoSink.obj.str();
454 }
455 
456 //
457 // Return any object binary code.
458 //
GetObjectBinaryBlob(const ShHandle handle)459 const BinaryBlob &GetObjectBinaryBlob(const ShHandle handle)
460 {
461     TCompiler *compiler = GetCompilerFromHandle(handle);
462     ASSERT(compiler);
463 
464     TInfoSink &infoSink = compiler->getInfoSink();
465     return infoSink.obj.getBinary();
466 }
467 
GetNameHashingMap(const ShHandle handle)468 const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
469 {
470     TCompiler *compiler = GetCompilerFromHandle(handle);
471     ASSERT(compiler);
472     return &(compiler->getNameMap());
473 }
474 
GetUniforms(const ShHandle handle)475 const std::vector<ShaderVariable> *GetUniforms(const ShHandle handle)
476 {
477     TCompiler *compiler = GetCompilerFromHandle(handle);
478     if (!compiler)
479     {
480         return nullptr;
481     }
482     return &compiler->getUniforms();
483 }
484 
GetInputVaryings(const ShHandle handle)485 const std::vector<ShaderVariable> *GetInputVaryings(const ShHandle handle)
486 {
487     TCompiler *compiler = GetCompilerFromHandle(handle);
488     if (compiler == nullptr)
489     {
490         return nullptr;
491     }
492     return &compiler->getInputVaryings();
493 }
494 
GetOutputVaryings(const ShHandle handle)495 const std::vector<ShaderVariable> *GetOutputVaryings(const ShHandle handle)
496 {
497     TCompiler *compiler = GetCompilerFromHandle(handle);
498     if (compiler == nullptr)
499     {
500         return nullptr;
501     }
502     return &compiler->getOutputVaryings();
503 }
504 
GetVaryings(const ShHandle handle)505 const std::vector<ShaderVariable> *GetVaryings(const ShHandle handle)
506 {
507     TCompiler *compiler = GetCompilerFromHandle(handle);
508     if (compiler == nullptr)
509     {
510         return nullptr;
511     }
512 
513     switch (compiler->getShaderType())
514     {
515         case GL_VERTEX_SHADER:
516             return &compiler->getOutputVaryings();
517         case GL_FRAGMENT_SHADER:
518             return &compiler->getInputVaryings();
519         case GL_COMPUTE_SHADER:
520             ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty());
521             return &compiler->getOutputVaryings();
522         // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings
523         // on a geometry shader.
524         default:
525             return nullptr;
526     }
527 }
528 
GetAttributes(const ShHandle handle)529 const std::vector<ShaderVariable> *GetAttributes(const ShHandle handle)
530 {
531     TCompiler *compiler = GetCompilerFromHandle(handle);
532     if (!compiler)
533     {
534         return nullptr;
535     }
536     return &compiler->getAttributes();
537 }
538 
GetOutputVariables(const ShHandle handle)539 const std::vector<ShaderVariable> *GetOutputVariables(const ShHandle handle)
540 {
541     TCompiler *compiler = GetCompilerFromHandle(handle);
542     if (!compiler)
543     {
544         return nullptr;
545     }
546     return &compiler->getOutputVariables();
547 }
548 
GetInterfaceBlocks(const ShHandle handle)549 const std::vector<InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle)
550 {
551     return GetShaderVariables<InterfaceBlock>(handle);
552 }
553 
GetUniformBlocks(const ShHandle handle)554 const std::vector<InterfaceBlock> *GetUniformBlocks(const ShHandle handle)
555 {
556     ASSERT(handle);
557     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
558     TCompiler *compiler = base->getAsCompiler();
559     ASSERT(compiler);
560 
561     return &compiler->getUniformBlocks();
562 }
563 
GetShaderStorageBlocks(const ShHandle handle)564 const std::vector<InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle)
565 {
566     ASSERT(handle);
567     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
568     TCompiler *compiler = base->getAsCompiler();
569     ASSERT(compiler);
570 
571     return &compiler->getShaderStorageBlocks();
572 }
573 
GetComputeShaderLocalGroupSize(const ShHandle handle)574 WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle)
575 {
576     ASSERT(handle);
577 
578     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
579     TCompiler *compiler = base->getAsCompiler();
580     ASSERT(compiler);
581 
582     return compiler->getComputeShaderLocalSize();
583 }
584 
GetVertexShaderNumViews(const ShHandle handle)585 int GetVertexShaderNumViews(const ShHandle handle)
586 {
587     ASSERT(handle);
588     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
589     TCompiler *compiler = base->getAsCompiler();
590     ASSERT(compiler);
591 
592     return compiler->getNumViews();
593 }
594 
HasEarlyFragmentTestsOptimization(const ShHandle handle)595 bool HasEarlyFragmentTestsOptimization(const ShHandle handle)
596 {
597     TCompiler *compiler = GetCompilerFromHandle(handle);
598     if (compiler == nullptr)
599     {
600         return false;
601     }
602     return compiler->isEarlyFragmentTestsOptimized();
603 }
604 
GetShaderSpecConstUsageBits(const ShHandle handle)605 uint32_t GetShaderSpecConstUsageBits(const ShHandle handle)
606 {
607     TCompiler *compiler = GetCompilerFromHandle(handle);
608     if (compiler == nullptr)
609     {
610         return 0;
611     }
612     return compiler->getSpecConstUsageBits().bits();
613 }
614 
CheckVariablesWithinPackingLimits(int maxVectors,const std::vector<ShaderVariable> & variables)615 bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables)
616 {
617     return CheckVariablesInPackingLimits(maxVectors, variables);
618 }
619 
GetShaderStorageBlockRegister(const ShHandle handle,const std::string & shaderStorageBlockName,unsigned int * indexOut)620 bool GetShaderStorageBlockRegister(const ShHandle handle,
621                                    const std::string &shaderStorageBlockName,
622                                    unsigned int *indexOut)
623 {
624 #ifdef ANGLE_ENABLE_HLSL
625     ASSERT(indexOut);
626 
627     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
628     ASSERT(translator);
629 
630     if (!translator->hasShaderStorageBlock(shaderStorageBlockName))
631     {
632         return false;
633     }
634 
635     *indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName);
636     return true;
637 #else
638     return false;
639 #endif  // ANGLE_ENABLE_HLSL
640 }
641 
GetUniformBlockRegister(const ShHandle handle,const std::string & uniformBlockName,unsigned int * indexOut)642 bool GetUniformBlockRegister(const ShHandle handle,
643                              const std::string &uniformBlockName,
644                              unsigned int *indexOut)
645 {
646 #ifdef ANGLE_ENABLE_HLSL
647     ASSERT(indexOut);
648 
649     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
650     ASSERT(translator);
651 
652     if (!translator->hasUniformBlock(uniformBlockName))
653     {
654         return false;
655     }
656 
657     *indexOut = translator->getUniformBlockRegister(uniformBlockName);
658     return true;
659 #else
660     return false;
661 #endif  // ANGLE_ENABLE_HLSL
662 }
663 
ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,const std::string & uniformBlockName)664 bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
665                                            const std::string &uniformBlockName)
666 {
667 #ifdef ANGLE_ENABLE_HLSL
668     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
669     ASSERT(translator);
670 
671     return translator->shouldUniformBlockUseStructuredBuffer(uniformBlockName);
672 #else
673     return false;
674 #endif  // ANGLE_ENABLE_HLSL
675 }
676 
GetUniformRegisterMap(const ShHandle handle)677 const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
678 {
679 #ifdef ANGLE_ENABLE_HLSL
680     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
681     ASSERT(translator);
682 
683     return translator->getUniformRegisterMap();
684 #else
685     return nullptr;
686 #endif  // ANGLE_ENABLE_HLSL
687 }
688 
GetSlowCompilingUniformBlockSet(const ShHandle handle)689 const std::set<std::string> *GetSlowCompilingUniformBlockSet(const ShHandle handle)
690 {
691 #ifdef ANGLE_ENABLE_HLSL
692     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
693     ASSERT(translator);
694 
695     return translator->getSlowCompilingUniformBlockSet();
696 #else
697     return nullptr;
698 #endif  // ANGLE_ENABLE_HLSL
699 }
700 
GetReadonlyImage2DRegisterIndex(const ShHandle handle)701 unsigned int GetReadonlyImage2DRegisterIndex(const ShHandle handle)
702 {
703 #ifdef ANGLE_ENABLE_HLSL
704     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
705     ASSERT(translator);
706 
707     return translator->getReadonlyImage2DRegisterIndex();
708 #else
709     return 0;
710 #endif  // ANGLE_ENABLE_HLSL
711 }
712 
GetImage2DRegisterIndex(const ShHandle handle)713 unsigned int GetImage2DRegisterIndex(const ShHandle handle)
714 {
715 #ifdef ANGLE_ENABLE_HLSL
716     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
717     ASSERT(translator);
718 
719     return translator->getImage2DRegisterIndex();
720 #else
721     return 0;
722 #endif  // ANGLE_ENABLE_HLSL
723 }
724 
GetUsedImage2DFunctionNames(const ShHandle handle)725 const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle)
726 {
727 #ifdef ANGLE_ENABLE_HLSL
728     TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
729     ASSERT(translator);
730 
731     return translator->getUsedImage2DFunctionNames();
732 #else
733     return nullptr;
734 #endif  // ANGLE_ENABLE_HLSL
735 }
736 
HasValidGeometryShaderInputPrimitiveType(const ShHandle handle)737 bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle)
738 {
739     ASSERT(handle);
740 
741     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
742     TCompiler *compiler = base->getAsCompiler();
743     ASSERT(compiler);
744 
745     return compiler->getGeometryShaderInputPrimitiveType() != EptUndefined;
746 }
747 
HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle)748 bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle)
749 {
750     ASSERT(handle);
751 
752     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
753     TCompiler *compiler = base->getAsCompiler();
754     ASSERT(compiler);
755 
756     return compiler->getGeometryShaderOutputPrimitiveType() != EptUndefined;
757 }
758 
HasValidGeometryShaderMaxVertices(const ShHandle handle)759 bool HasValidGeometryShaderMaxVertices(const ShHandle handle)
760 {
761     ASSERT(handle);
762 
763     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
764     TCompiler *compiler = base->getAsCompiler();
765     ASSERT(compiler);
766 
767     return compiler->getGeometryShaderMaxVertices() >= 0;
768 }
769 
HasValidTessGenMode(const ShHandle handle)770 bool HasValidTessGenMode(const ShHandle handle)
771 {
772     ASSERT(handle);
773 
774     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
775     TCompiler *compiler = base->getAsCompiler();
776     ASSERT(compiler);
777 
778     return compiler->getTessEvaluationShaderInputPrimitiveType() != EtetUndefined;
779 }
780 
HasValidTessGenSpacing(const ShHandle handle)781 bool HasValidTessGenSpacing(const ShHandle handle)
782 {
783     ASSERT(handle);
784 
785     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
786     TCompiler *compiler = base->getAsCompiler();
787     ASSERT(compiler);
788 
789     return compiler->getTessEvaluationShaderInputVertexSpacingType() != EtetUndefined;
790 }
791 
HasValidTessGenVertexOrder(const ShHandle handle)792 bool HasValidTessGenVertexOrder(const ShHandle handle)
793 {
794     ASSERT(handle);
795 
796     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
797     TCompiler *compiler = base->getAsCompiler();
798     ASSERT(compiler);
799 
800     return compiler->getTessEvaluationShaderInputOrderingType() != EtetUndefined;
801 }
802 
HasValidTessGenPointMode(const ShHandle handle)803 bool HasValidTessGenPointMode(const ShHandle handle)
804 {
805     ASSERT(handle);
806 
807     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
808     TCompiler *compiler = base->getAsCompiler();
809     ASSERT(compiler);
810 
811     return compiler->getTessEvaluationShaderInputPointType() != EtetUndefined;
812 }
813 
GetGeometryShaderInputPrimitiveType(const ShHandle handle)814 GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle)
815 {
816     ASSERT(handle);
817 
818     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
819     TCompiler *compiler = base->getAsCompiler();
820     ASSERT(compiler);
821 
822     return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType());
823 }
824 
GetGeometryShaderOutputPrimitiveType(const ShHandle handle)825 GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle)
826 {
827     ASSERT(handle);
828 
829     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
830     TCompiler *compiler = base->getAsCompiler();
831     ASSERT(compiler);
832 
833     return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType());
834 }
835 
GetGeometryShaderInvocations(const ShHandle handle)836 int GetGeometryShaderInvocations(const ShHandle handle)
837 {
838     ASSERT(handle);
839 
840     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
841     TCompiler *compiler = base->getAsCompiler();
842     ASSERT(compiler);
843 
844     return compiler->getGeometryShaderInvocations();
845 }
846 
GetGeometryShaderMaxVertices(const ShHandle handle)847 int GetGeometryShaderMaxVertices(const ShHandle handle)
848 {
849     ASSERT(handle);
850 
851     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
852     TCompiler *compiler = base->getAsCompiler();
853     ASSERT(compiler);
854 
855     int maxVertices = compiler->getGeometryShaderMaxVertices();
856     ASSERT(maxVertices >= 0);
857     return maxVertices;
858 }
859 
GetTessControlShaderVertices(const ShHandle handle)860 int GetTessControlShaderVertices(const ShHandle handle)
861 {
862     ASSERT(handle);
863 
864     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
865     TCompiler *compiler = base->getAsCompiler();
866     ASSERT(compiler);
867 
868     int vertices = compiler->getTessControlShaderOutputVertices();
869     return vertices;
870 }
871 
GetTessGenMode(const ShHandle handle)872 GLenum GetTessGenMode(const ShHandle handle)
873 {
874     ASSERT(handle);
875 
876     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
877     TCompiler *compiler = base->getAsCompiler();
878     ASSERT(compiler);
879 
880     return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPrimitiveType());
881 }
882 
GetTessGenSpacing(const ShHandle handle)883 GLenum GetTessGenSpacing(const ShHandle handle)
884 {
885     ASSERT(handle);
886 
887     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
888     TCompiler *compiler = base->getAsCompiler();
889     ASSERT(compiler);
890 
891     return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputVertexSpacingType());
892 }
893 
GetTessGenVertexOrder(const ShHandle handle)894 GLenum GetTessGenVertexOrder(const ShHandle handle)
895 {
896     ASSERT(handle);
897 
898     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
899     TCompiler *compiler = base->getAsCompiler();
900     ASSERT(compiler);
901 
902     return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputOrderingType());
903 }
904 
GetTessGenPointMode(const ShHandle handle)905 GLenum GetTessGenPointMode(const ShHandle handle)
906 {
907     ASSERT(handle);
908 
909     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
910     TCompiler *compiler = base->getAsCompiler();
911     ASSERT(compiler);
912 
913     return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPointType());
914 }
915 
GetShaderSharedMemorySize(const ShHandle handle)916 unsigned int GetShaderSharedMemorySize(const ShHandle handle)
917 {
918     ASSERT(handle);
919 
920     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
921     TCompiler *compiler = base->getAsCompiler();
922     ASSERT(compiler);
923 
924     unsigned int sharedMemorySize = compiler->getSharedMemorySize();
925     return sharedMemorySize;
926 }
927 
InitializeGlslang()928 void InitializeGlslang()
929 {
930     if (initializeGlslangRefCount == 0)
931     {
932         GlslangInitialize();
933     }
934     ++initializeGlslangRefCount;
935     ASSERT(initializeGlslangRefCount < std::numeric_limits<int>::max());
936 }
937 
FinalizeGlslang()938 void FinalizeGlslang()
939 {
940     --initializeGlslangRefCount;
941     ASSERT(initializeGlslangRefCount >= 0);
942     if (initializeGlslangRefCount == 0)
943     {
944         GlslangFinalize();
945     }
946 }
947 
948 // Can't prefix with just _ because then we might introduce a double underscore, which is not safe
949 // in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
950 // use by the underlying implementation). u is short for user-defined.
951 const char kUserDefinedNamePrefix[] = "_u";
952 
953 namespace vk
954 {
955 // Interface block name containing the aggregate default uniforms
956 const char kDefaultUniformsNameVS[]  = "defaultUniformsVS";
957 const char kDefaultUniformsNameTCS[] = "defaultUniformsTCS";
958 const char kDefaultUniformsNameTES[] = "defaultUniformsTES";
959 const char kDefaultUniformsNameGS[]  = "defaultUniformsGS";
960 const char kDefaultUniformsNameFS[]  = "defaultUniformsFS";
961 const char kDefaultUniformsNameCS[]  = "defaultUniformsCS";
962 
963 // Interface block and variable names containing driver uniforms
964 const char kDriverUniformsBlockName[] = "ANGLEUniformBlock";
965 const char kDriverUniformsVarName[]   = "ANGLEUniforms";
966 
967 // Interface block array name used for atomic counter emulation
968 const char kAtomicCountersBlockName[] = "ANGLEAtomicCounters";
969 
970 const char kLineRasterEmulationPosition[] = "ANGLEPosition";
971 
972 const char kXfbEmulationGetOffsetsFunctionName[] = "ANGLEGetXfbOffsets";
973 const char kXfbEmulationCaptureFunctionName[]    = "ANGLECaptureXfb";
974 const char kXfbEmulationBufferBlockName[]        = "ANGLEXfbBuffer";
975 const char kXfbEmulationBufferName[]             = "ANGLEXfb";
976 const char kXfbEmulationBufferFieldName[]        = "xfbOut";
977 
978 const char kXfbExtensionPositionOutName[] = "ANGLEXfbPosition";
979 
980 // EXT_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch_non_coherent
981 const char kInputAttachmentName[] = "ANGLEInputAttachment";
982 
983 }  // namespace vk
984 
BlockLayoutTypeToString(BlockLayoutType type)985 const char *BlockLayoutTypeToString(BlockLayoutType type)
986 {
987     switch (type)
988     {
989         case BlockLayoutType::BLOCKLAYOUT_STD140:
990             return "std140";
991         case BlockLayoutType::BLOCKLAYOUT_STD430:
992             return "std430";
993         case BlockLayoutType::BLOCKLAYOUT_PACKED:
994             return "packed";
995         case BlockLayoutType::BLOCKLAYOUT_SHARED:
996             return "shared";
997         default:
998             return "invalid";
999     }
1000 }
1001 
BlockTypeToString(BlockType type)1002 const char *BlockTypeToString(BlockType type)
1003 {
1004     switch (type)
1005     {
1006         case BlockType::BLOCK_BUFFER:
1007             return "buffer";
1008         case BlockType::BLOCK_UNIFORM:
1009             return "uniform";
1010         default:
1011             return "invalid";
1012     }
1013 }
1014 
InterpolationTypeToString(InterpolationType type)1015 const char *InterpolationTypeToString(InterpolationType type)
1016 {
1017     switch (type)
1018     {
1019         case InterpolationType::INTERPOLATION_SMOOTH:
1020             return "smooth";
1021         case InterpolationType::INTERPOLATION_CENTROID:
1022             return "centroid";
1023         case InterpolationType::INTERPOLATION_SAMPLE:
1024             return "sample";
1025         case InterpolationType::INTERPOLATION_FLAT:
1026             return "flat";
1027         case InterpolationType::INTERPOLATION_NOPERSPECTIVE:
1028             return "noperspective";
1029         default:
1030             return "invalid";
1031     }
1032 }
1033 }  // namespace sh
1034