Line data Source code
1 : //
2 : // Copyright (c) 2002-2013 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/TranslatorHLSL.h"
19 : #endif // ANGLE_ENABLE_HLSL
20 : #include "compiler/translator/VariablePacker.h"
21 : #include "angle_gl.h"
22 :
23 : using namespace sh;
24 :
25 : namespace
26 : {
27 :
28 : bool isInitialized = false;
29 :
30 : //
31 : // This is the platform independent interface between an OGL driver
32 : // and the shading language compiler.
33 : //
34 :
35 : template <typename VarT>
36 : const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
37 :
38 : template <>
39 0 : const std::vector<Uniform> *GetVariableList(const TCompiler *compiler)
40 : {
41 0 : return &compiler->getUniforms();
42 : }
43 :
44 : template <>
45 0 : const std::vector<Varying> *GetVariableList(const TCompiler *compiler)
46 : {
47 0 : return &compiler->getVaryings();
48 : }
49 :
50 : template <>
51 0 : const std::vector<Attribute> *GetVariableList(const TCompiler *compiler)
52 : {
53 0 : return &compiler->getAttributes();
54 : }
55 :
56 : template <>
57 0 : const std::vector<OutputVariable> *GetVariableList(const TCompiler *compiler)
58 : {
59 0 : return &compiler->getOutputVariables();
60 : }
61 :
62 : template <>
63 0 : const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler)
64 : {
65 0 : return &compiler->getInterfaceBlocks();
66 : }
67 :
68 : template <typename VarT>
69 0 : const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
70 : {
71 0 : if (!handle)
72 : {
73 0 : return NULL;
74 : }
75 :
76 0 : TShHandleBase* base = static_cast<TShHandleBase*>(handle);
77 0 : TCompiler* compiler = base->getAsCompiler();
78 0 : if (!compiler)
79 : {
80 0 : return NULL;
81 : }
82 :
83 0 : return GetVariableList<VarT>(compiler);
84 : }
85 :
86 0 : TCompiler *GetCompilerFromHandle(ShHandle handle)
87 : {
88 0 : if (!handle)
89 0 : return NULL;
90 0 : TShHandleBase *base = static_cast<TShHandleBase *>(handle);
91 0 : return base->getAsCompiler();
92 : }
93 :
94 : #ifdef ANGLE_ENABLE_HLSL
95 0 : TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
96 : {
97 0 : if (!handle)
98 0 : return NULL;
99 0 : TShHandleBase *base = static_cast<TShHandleBase *>(handle);
100 0 : return base->getAsTranslatorHLSL();
101 : }
102 : #endif // ANGLE_ENABLE_HLSL
103 :
104 : } // anonymous namespace
105 :
106 : //
107 : // Driver must call this first, once, before doing any other compiler operations.
108 : // Subsequent calls to this function are no-op.
109 : //
110 0 : bool ShInitialize()
111 : {
112 0 : if (!isInitialized)
113 : {
114 0 : isInitialized = InitProcess();
115 : }
116 0 : return isInitialized;
117 : }
118 :
119 : //
120 : // Cleanup symbol tables
121 : //
122 0 : bool ShFinalize()
123 : {
124 0 : if (isInitialized)
125 : {
126 0 : DetachProcess();
127 0 : isInitialized = false;
128 : }
129 0 : return true;
130 : }
131 :
132 : //
133 : // Initialize built-in resources with minimum expected values.
134 : //
135 0 : void ShInitBuiltInResources(ShBuiltInResources* resources)
136 : {
137 : // Make comparable.
138 0 : memset(resources, 0, sizeof(*resources));
139 :
140 : // Constants.
141 0 : resources->MaxVertexAttribs = 8;
142 0 : resources->MaxVertexUniformVectors = 128;
143 0 : resources->MaxVaryingVectors = 8;
144 0 : resources->MaxVertexTextureImageUnits = 0;
145 0 : resources->MaxCombinedTextureImageUnits = 8;
146 0 : resources->MaxTextureImageUnits = 8;
147 0 : resources->MaxFragmentUniformVectors = 16;
148 0 : resources->MaxDrawBuffers = 1;
149 :
150 : // Extensions.
151 0 : resources->OES_standard_derivatives = 0;
152 0 : resources->OES_EGL_image_external = 0;
153 0 : resources->OES_EGL_image_external_essl3 = 0;
154 0 : resources->NV_EGL_stream_consumer_external = 0;
155 0 : resources->ARB_texture_rectangle = 0;
156 0 : resources->EXT_blend_func_extended = 0;
157 0 : resources->EXT_draw_buffers = 0;
158 0 : resources->EXT_frag_depth = 0;
159 0 : resources->EXT_shader_texture_lod = 0;
160 0 : resources->WEBGL_debug_shader_precision = 0;
161 0 : resources->EXT_shader_framebuffer_fetch = 0;
162 0 : resources->NV_shader_framebuffer_fetch = 0;
163 0 : resources->ARM_shader_framebuffer_fetch = 0;
164 :
165 0 : resources->NV_draw_buffers = 0;
166 :
167 : // Disable highp precision in fragment shader by default.
168 0 : resources->FragmentPrecisionHigh = 0;
169 :
170 : // GLSL ES 3.0 constants.
171 0 : resources->MaxVertexOutputVectors = 16;
172 0 : resources->MaxFragmentInputVectors = 15;
173 0 : resources->MinProgramTexelOffset = -8;
174 0 : resources->MaxProgramTexelOffset = 7;
175 :
176 : // Extensions constants.
177 0 : resources->MaxDualSourceDrawBuffers = 0;
178 :
179 : // Disable name hashing by default.
180 0 : resources->HashFunction = NULL;
181 :
182 0 : resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
183 :
184 0 : resources->MaxExpressionComplexity = 256;
185 0 : resources->MaxCallStackDepth = 256;
186 0 : resources->MaxFunctionParameters = 1024;
187 :
188 : // ES 3.1 Revision 4, 7.2 Built-in Constants
189 0 : resources->MaxImageUnits = 4;
190 0 : resources->MaxVertexImageUniforms = 0;
191 0 : resources->MaxFragmentImageUniforms = 0;
192 0 : resources->MaxComputeImageUniforms = 4;
193 0 : resources->MaxCombinedImageUniforms = 4;
194 :
195 0 : resources->MaxCombinedShaderOutputResources = 4;
196 :
197 0 : resources->MaxComputeWorkGroupCount[0] = 65535;
198 0 : resources->MaxComputeWorkGroupCount[1] = 65535;
199 0 : resources->MaxComputeWorkGroupCount[2] = 65535;
200 0 : resources->MaxComputeWorkGroupSize[0] = 128;
201 0 : resources->MaxComputeWorkGroupSize[1] = 128;
202 0 : resources->MaxComputeWorkGroupSize[2] = 64;
203 0 : resources->MaxComputeUniformComponents = 512;
204 0 : resources->MaxComputeTextureImageUnits = 16;
205 :
206 0 : resources->MaxComputeAtomicCounters = 8;
207 0 : resources->MaxComputeAtomicCounterBuffers = 1;
208 :
209 0 : resources->MaxVertexAtomicCounters = 0;
210 0 : resources->MaxFragmentAtomicCounters = 0;
211 0 : resources->MaxCombinedAtomicCounters = 8;
212 0 : resources->MaxAtomicCounterBindings = 1;
213 :
214 0 : resources->MaxVertexAtomicCounterBuffers = 0;
215 0 : resources->MaxFragmentAtomicCounterBuffers = 0;
216 0 : resources->MaxCombinedAtomicCounterBuffers = 1;
217 0 : resources->MaxAtomicCounterBufferSize = 32;
218 0 : }
219 :
220 : //
221 : // Driver calls these to create and destroy compiler objects.
222 : //
223 0 : ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec,
224 : ShShaderOutput output,
225 : const ShBuiltInResources* resources)
226 : {
227 0 : TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
228 0 : if (base == nullptr)
229 : {
230 0 : return 0;
231 : }
232 :
233 0 : TCompiler* compiler = base->getAsCompiler();
234 0 : if (compiler == nullptr)
235 : {
236 0 : return 0;
237 : }
238 :
239 : // Generate built-in symbol table.
240 0 : if (!compiler->Init(*resources))
241 : {
242 0 : sh::Destruct(base);
243 0 : return 0;
244 : }
245 :
246 0 : return reinterpret_cast<void*>(base);
247 : }
248 :
249 0 : void ShDestruct(ShHandle handle)
250 : {
251 0 : if (handle == 0)
252 0 : return;
253 :
254 0 : TShHandleBase* base = static_cast<TShHandleBase*>(handle);
255 :
256 0 : if (base->getAsCompiler())
257 0 : DeleteCompiler(base->getAsCompiler());
258 : }
259 :
260 0 : const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
261 : {
262 0 : TCompiler *compiler = GetCompilerFromHandle(handle);
263 0 : ASSERT(compiler);
264 0 : return compiler->getBuiltInResourcesString();
265 : }
266 :
267 : //
268 : // Do an actual compile on the given strings. The result is left
269 : // in the given compile object.
270 : //
271 : // Return: The return value of ShCompile is really boolean, indicating
272 : // success or failure.
273 : //
274 0 : bool ShCompile(const ShHandle handle,
275 : const char *const shaderStrings[],
276 : size_t numStrings,
277 : ShCompileOptions compileOptions)
278 : {
279 0 : TCompiler *compiler = GetCompilerFromHandle(handle);
280 0 : ASSERT(compiler);
281 :
282 0 : return compiler->compile(shaderStrings, numStrings, compileOptions);
283 : }
284 :
285 0 : void ShClearResults(const ShHandle handle)
286 : {
287 0 : TCompiler *compiler = GetCompilerFromHandle(handle);
288 0 : ASSERT(compiler);
289 0 : compiler->clearResults();
290 0 : }
291 :
292 0 : int ShGetShaderVersion(const ShHandle handle)
293 : {
294 0 : TCompiler* compiler = GetCompilerFromHandle(handle);
295 0 : ASSERT(compiler);
296 0 : return compiler->getShaderVersion();
297 : }
298 :
299 0 : ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
300 : {
301 0 : TCompiler* compiler = GetCompilerFromHandle(handle);
302 0 : ASSERT(compiler);
303 0 : return compiler->getOutputType();
304 : }
305 :
306 : //
307 : // Return any compiler log of messages for the application.
308 : //
309 0 : const std::string &ShGetInfoLog(const ShHandle handle)
310 : {
311 0 : TCompiler *compiler = GetCompilerFromHandle(handle);
312 0 : ASSERT(compiler);
313 :
314 0 : TInfoSink &infoSink = compiler->getInfoSink();
315 0 : return infoSink.info.str();
316 : }
317 :
318 : //
319 : // Return any object code.
320 : //
321 0 : const std::string &ShGetObjectCode(const ShHandle handle)
322 : {
323 0 : TCompiler *compiler = GetCompilerFromHandle(handle);
324 0 : ASSERT(compiler);
325 :
326 0 : TInfoSink &infoSink = compiler->getInfoSink();
327 0 : return infoSink.obj.str();
328 : }
329 :
330 0 : const std::map<std::string, std::string> *ShGetNameHashingMap(
331 : const ShHandle handle)
332 : {
333 0 : TCompiler *compiler = GetCompilerFromHandle(handle);
334 0 : ASSERT(compiler);
335 0 : return &(compiler->getNameMap());
336 : }
337 :
338 0 : const std::vector<Uniform> *ShGetUniforms(const ShHandle handle)
339 : {
340 0 : return GetShaderVariables<Uniform>(handle);
341 : }
342 :
343 0 : const std::vector<Varying> *ShGetVaryings(const ShHandle handle)
344 : {
345 0 : return GetShaderVariables<Varying>(handle);
346 : }
347 :
348 0 : const std::vector<Attribute> *ShGetAttributes(const ShHandle handle)
349 : {
350 0 : return GetShaderVariables<Attribute>(handle);
351 : }
352 :
353 0 : const std::vector<OutputVariable> *ShGetOutputVariables(const ShHandle handle)
354 : {
355 0 : return GetShaderVariables<OutputVariable>(handle);
356 : }
357 :
358 0 : const std::vector<InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
359 : {
360 0 : return GetShaderVariables<InterfaceBlock>(handle);
361 : }
362 :
363 0 : WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle)
364 : {
365 0 : ASSERT(handle);
366 :
367 0 : TShHandleBase *base = static_cast<TShHandleBase *>(handle);
368 0 : TCompiler *compiler = base->getAsCompiler();
369 0 : ASSERT(compiler);
370 :
371 0 : return compiler->getComputeShaderLocalSize();
372 : }
373 :
374 0 : bool ShCheckVariablesWithinPackingLimits(int maxVectors,
375 : const std::vector<ShaderVariable> &variables)
376 : {
377 0 : VariablePacker packer;
378 0 : return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
379 : }
380 :
381 0 : bool ShGetInterfaceBlockRegister(const ShHandle handle,
382 : const std::string &interfaceBlockName,
383 : unsigned int *indexOut)
384 : {
385 : #ifdef ANGLE_ENABLE_HLSL
386 0 : ASSERT(indexOut);
387 :
388 0 : TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
389 0 : ASSERT(translator);
390 :
391 0 : if (!translator->hasInterfaceBlock(interfaceBlockName))
392 : {
393 0 : return false;
394 : }
395 :
396 0 : *indexOut = translator->getInterfaceBlockRegister(interfaceBlockName);
397 0 : return true;
398 : #else
399 : return false;
400 : #endif // ANGLE_ENABLE_HLSL
401 : }
402 :
403 0 : const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandle handle)
404 : {
405 : #ifdef ANGLE_ENABLE_HLSL
406 0 : TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
407 0 : ASSERT(translator);
408 :
409 0 : return translator->getUniformRegisterMap();
410 : #else
411 : return nullptr;
412 : #endif // ANGLE_ENABLE_HLSL
413 : }
414 :
415 : namespace sh
416 : {
417 0 : bool Initialize()
418 : {
419 0 : return ShInitialize();
420 : }
421 :
422 0 : bool Finalize()
423 : {
424 0 : return ShFinalize();
425 : }
426 :
427 0 : void InitBuiltInResources(ShBuiltInResources *resources)
428 : {
429 0 : ShInitBuiltInResources(resources);
430 0 : }
431 :
432 0 : const std::string &GetBuiltInResourcesString(const ShHandle handle)
433 : {
434 0 : return ShGetBuiltInResourcesString(handle);
435 : }
436 :
437 0 : ShHandle ConstructCompiler(sh::GLenum type,
438 : ShShaderSpec spec,
439 : ShShaderOutput output,
440 : const ShBuiltInResources *resources)
441 : {
442 0 : return ShConstructCompiler(type, spec, output, resources);
443 : }
444 :
445 0 : void Destruct(ShHandle handle)
446 : {
447 0 : return ShDestruct(handle);
448 : }
449 :
450 0 : bool Compile(const ShHandle handle,
451 : const char *const shaderStrings[],
452 : size_t numStrings,
453 : ShCompileOptions compileOptions)
454 : {
455 0 : return ShCompile(handle, shaderStrings, numStrings, compileOptions);
456 : }
457 :
458 0 : void ClearResults(const ShHandle handle)
459 : {
460 0 : return ShClearResults(handle);
461 : }
462 :
463 0 : int GetShaderVersion(const ShHandle handle)
464 : {
465 0 : return ShGetShaderVersion(handle);
466 : }
467 :
468 0 : ShShaderOutput GetShaderOutputType(const ShHandle handle)
469 : {
470 0 : return ShGetShaderOutputType(handle);
471 : }
472 :
473 0 : const std::string &GetInfoLog(const ShHandle handle)
474 : {
475 0 : return ShGetInfoLog(handle);
476 : }
477 :
478 0 : const std::string &GetObjectCode(const ShHandle handle)
479 : {
480 0 : return ShGetObjectCode(handle);
481 : }
482 :
483 0 : const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
484 : {
485 0 : return ShGetNameHashingMap(handle);
486 : }
487 :
488 0 : const std::vector<sh::Uniform> *GetUniforms(const ShHandle handle)
489 : {
490 0 : return ShGetUniforms(handle);
491 : }
492 0 : const std::vector<sh::Varying> *GetVaryings(const ShHandle handle)
493 : {
494 0 : return ShGetVaryings(handle);
495 : }
496 0 : const std::vector<sh::Attribute> *GetAttributes(const ShHandle handle)
497 : {
498 0 : return ShGetAttributes(handle);
499 : }
500 :
501 0 : const std::vector<sh::OutputVariable> *GetOutputVariables(const ShHandle handle)
502 : {
503 0 : return ShGetOutputVariables(handle);
504 : }
505 0 : const std::vector<sh::InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle)
506 : {
507 0 : return ShGetInterfaceBlocks(handle);
508 : }
509 :
510 0 : sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle)
511 : {
512 0 : return ShGetComputeShaderLocalGroupSize(handle);
513 : }
514 :
515 0 : bool CheckVariablesWithinPackingLimits(int maxVectors,
516 : const std::vector<sh::ShaderVariable> &variables)
517 : {
518 0 : return ShCheckVariablesWithinPackingLimits(maxVectors, variables);
519 : }
520 :
521 0 : bool GetInterfaceBlockRegister(const ShHandle handle,
522 : const std::string &interfaceBlockName,
523 : unsigned int *indexOut)
524 : {
525 0 : return ShGetInterfaceBlockRegister(handle, interfaceBlockName, indexOut);
526 : }
527 :
528 0 : const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
529 : {
530 0 : return ShGetUniformRegisterMap(handle);
531 : }
532 :
533 : } // namespace sh
|