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