blob: 03a9aefd054ff74c28116a364a43961b82d97211 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7//
alokp@chromium.org774d7062010-07-21 18:55:45 +00008// Implement the top-level of interface to the compiler,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00009// as defined in ShaderLang.h
10//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000012#include "GLSLANG/ShaderLang.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000013
Jamie Madilld4a3a312014-06-25 16:04:56 -040014#include "compiler/translator/Compiler.h"
Geoff Lang17732822013-08-29 13:46:49 -040015#include "compiler/translator/InitializeDll.h"
Jamie Madill5508f392014-02-20 13:31:36 -050016#include "compiler/translator/length_limits.h"
Geoff Lang17732822013-08-29 13:46:49 -040017#include "compiler/translator/TranslatorHLSL.h"
18#include "compiler/translator/VariablePacker.h"
Jamie Madilla718c1e2014-07-02 15:31:22 -040019#include "angle_gl.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020
Jamie Madille294bb82014-07-17 14:16:26 -040021namespace
22{
23
24enum ShaderVariableType
25{
26 SHADERVAR_UNIFORM,
27 SHADERVAR_VARYING,
28 SHADERVAR_ATTRIBUTE,
29 SHADERVAR_OUTPUTVARIABLE,
30 SHADERVAR_INTERFACEBLOCK
31};
32
33bool isInitialized = false;
Jamie Madillb4d192c2014-02-26 09:54:10 -050034
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035//
36// This is the platform independent interface between an OGL driver
alokp@chromium.org774d7062010-07-21 18:55:45 +000037// and the shading language compiler.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000038//
39
Jamie Madille294bb82014-07-17 14:16:26 -040040template <typename VarT>
41const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
42
43template <>
44const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
45{
46 return &compiler->getUniforms();
47}
48
49template <>
50const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
51{
52 return &compiler->getVaryings();
53}
54
55template <>
56const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType)
57{
58 return (variableType == SHADERVAR_ATTRIBUTE ?
59 &compiler->getAttributes() :
60 &compiler->getOutputVariables());
61}
62
63template <>
64const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
65{
66 return &compiler->getInterfaceBlocks();
67}
68
69template <typename VarT>
70const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariableType variableType)
71{
72 if (!handle)
73 {
74 return NULL;
75 }
76
77 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
78 TCompiler* compiler = base->getAsCompiler();
79 if (!compiler)
80 {
81 return NULL;
82 }
83
84 return GetVariableList<VarT>(compiler, variableType);
85}
86
Zhenyao Mo4de44cb2014-10-29 18:03:46 -070087TCompiler *GetCompilerFromHandle(ShHandle handle)
88{
89 if (!handle)
90 return NULL;
91 TShHandleBase *base = static_cast<TShHandleBase *>(handle);
92 return base->getAsCompiler();
Jamie Madille294bb82014-07-17 14:16:26 -040093}
94
Zhenyao Mo4de44cb2014-10-29 18:03:46 -070095TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
96{
97 if (!handle)
98 return NULL;
99 TShHandleBase *base = static_cast<TShHandleBase *>(handle);
100 return base->getAsTranslatorHLSL();
101}
102
103} // namespace anonymous
104
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105//
Alok Priyadarshib11713f2013-08-01 16:02:39 -0700106// Driver must call this first, once, before doing any other compiler operations.
107// Subsequent calls to this function are no-op.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108//
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700109bool ShInitialize()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110{
Jamie Madill477bc782014-02-26 09:54:17 -0500111 if (!isInitialized)
112 {
113 isInitialized = InitProcess();
114 }
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700115 return isInitialized;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000116}
117
118//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000119// Cleanup symbol tables
120//
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700121bool ShFinalize()
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000122{
Geoff Langf20f0202014-04-28 11:02:07 -0400123 if (isInitialized)
124 {
125 DetachProcess();
126 isInitialized = false;
127 }
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700128 return true;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000129}
130
131//
132// Initialize built-in resources with minimum expected values.
133//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000134void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000135{
Kimmo Kinnunen7c1cfd62014-10-15 14:59:57 +0300136 // Make comparable.
137 memset(resources, 0, sizeof(*resources));
138
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000139 // Constants.
140 resources->MaxVertexAttribs = 8;
141 resources->MaxVertexUniformVectors = 128;
142 resources->MaxVaryingVectors = 8;
143 resources->MaxVertexTextureImageUnits = 0;
144 resources->MaxCombinedTextureImageUnits = 8;
145 resources->MaxTextureImageUnits = 8;
146 resources->MaxFragmentUniformVectors = 16;
147 resources->MaxDrawBuffers = 1;
148
149 // Extensions.
150 resources->OES_standard_derivatives = 0;
zmo@google.com09c323a2011-08-12 18:22:25 +0000151 resources->OES_EGL_image_external = 0;
kbr@chromium.org205fef32011-11-22 20:50:02 +0000152 resources->ARB_texture_rectangle = 0;
shannon.woods@transgaming.com550cd092013-02-28 23:19:54 +0000153 resources->EXT_draw_buffers = 0;
Jamie Madill2aeb26a2013-07-08 14:02:55 -0400154 resources->EXT_frag_depth = 0;
Nicolas Capens46485082014-04-15 13:12:50 -0400155 resources->EXT_shader_texture_lod = 0;
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200156 resources->WEBGL_debug_shader_precision = 0;
Erik Dahlströmea7a2122014-11-17 16:15:57 +0100157 resources->EXT_shader_framebuffer_fetch = 0;
158 resources->NV_shader_framebuffer_fetch = 0;
159 resources->ARM_shader_framebuffer_fetch = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000160
Olli Etuahoe61209a2014-09-26 12:01:17 +0300161 resources->NV_draw_buffers = 0;
162
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000163 // Disable highp precision in fragment shader by default.
164 resources->FragmentPrecisionHigh = 0;
165
shannonwoods@chromium.org74b86cf2013-05-30 00:02:58 +0000166 // GLSL ES 3.0 constants.
167 resources->MaxVertexOutputVectors = 16;
168 resources->MaxFragmentInputVectors = 15;
169 resources->MinProgramTexelOffset = -8;
170 resources->MaxProgramTexelOffset = 7;
171
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000172 // Disable name hashing by default.
173 resources->HashFunction = NULL;
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000174
175 resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
Nicolas Capens7d649a02014-02-07 11:24:32 -0500176
177 resources->MaxExpressionComplexity = 256;
178 resources->MaxCallStackDepth = 256;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000179}
180
181//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000182// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183//
Jamie Madill183bde52014-07-02 15:31:19 -0400184ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec,
zmo@google.com5601ea02011-06-10 18:23:25 +0000185 ShShaderOutput output,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000186 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000187{
zmo@google.com5601ea02011-06-10 18:23:25 +0000188 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000189 TCompiler* compiler = base->getAsCompiler();
190 if (compiler == 0)
191 return 0;
192
193 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000194 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000195 ShDestruct(base);
196 return 0;
197 }
198
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000199 return reinterpret_cast<void*>(base);
200}
201
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202void ShDestruct(ShHandle handle)
203{
204 if (handle == 0)
205 return;
206
207 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
208
209 if (base->getAsCompiler())
210 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211}
212
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700213const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
Shannon Woods2d76e5f2014-05-16 17:46:41 -0400214{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700215 TCompiler *compiler = GetCompilerFromHandle(handle);
216 ASSERT(compiler);
217 return compiler->getBuiltInResourcesString();
Shannon Woods2d76e5f2014-05-16 17:46:41 -0400218}
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700219
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000220//
Shannon Woods2d76e5f2014-05-16 17:46:41 -0400221// Do an actual compile on the given strings. The result is left
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000222// in the given compile object.
223//
224// Return: The return value of ShCompile is really boolean, indicating
225// success or failure.
226//
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700227bool ShCompile(
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 const ShHandle handle,
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700229 const char *const shaderStrings[],
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000230 size_t numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000231 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000232{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700233 TCompiler *compiler = GetCompilerFromHandle(handle);
234 ASSERT(compiler);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700236 return compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237}
238
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700239int ShGetShaderVersion(const ShHandle handle)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000240{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700241 TCompiler* compiler = GetCompilerFromHandle(handle);
242 ASSERT(compiler);
243 return compiler->getShaderVersion();
244}
alokp@chromium.org7beea402010-09-15 21:18:34 +0000245
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700246ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
247{
248 TCompiler* compiler = GetCompilerFromHandle(handle);
249 ASSERT(compiler);
250 return compiler->getOutputType();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000251}
252
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000253//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000254// Return any compiler log of messages for the application.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000255//
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700256const std::string &ShGetInfoLog(const ShHandle handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700258 TCompiler *compiler = GetCompilerFromHandle(handle);
259 ASSERT(compiler);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700261 TInfoSink &infoSink = compiler->getInfoSink();
262 return infoSink.info.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263}
264
265//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000266// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267//
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700268const std::string &ShGetObjectCode(const ShHandle handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000269{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700270 TCompiler *compiler = GetCompilerFromHandle(handle);
271 ASSERT(compiler);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000272
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700273 TInfoSink &infoSink = compiler->getInfoSink();
274 return infoSink.obj.str();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000275}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700277const std::map<std::string, std::string> *ShGetNameHashingMap(
278 const ShHandle handle)
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000279{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700280 TCompiler *compiler = GetCompilerFromHandle(handle);
281 ASSERT(compiler);
282 return &(compiler->getNameMap());
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000283}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000284
Jamie Madille294bb82014-07-17 14:16:26 -0400285const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
daniel@transgaming.com043da132012-12-20 21:12:22 +0000286{
Jamie Madille294bb82014-07-17 14:16:26 -0400287 return GetShaderVariables<sh::Uniform>(handle, SHADERVAR_UNIFORM);
288}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000289
Jamie Madille294bb82014-07-17 14:16:26 -0400290const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
291{
292 return GetShaderVariables<sh::Varying>(handle, SHADERVAR_VARYING);
293}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000294
Jamie Madille294bb82014-07-17 14:16:26 -0400295const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle)
296{
297 return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_ATTRIBUTE);
298}
299
300const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle)
301{
302 return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_OUTPUTVARIABLE);
303}
304
305const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
306{
307 return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000308}
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400309
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700310bool ShCheckVariablesWithinPackingLimits(
311 int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400312{
313 if (varInfoArraySize == 0)
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700314 return true;
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400315 ASSERT(varInfoArray);
Jamie Madilla718c1e2014-07-02 15:31:22 -0400316 std::vector<sh::ShaderVariable> variables;
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400317 for (size_t ii = 0; ii < varInfoArraySize; ++ii)
318 {
Jamie Madilla3fe2b42014-07-18 10:33:13 -0400319 sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size);
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400320 variables.push_back(var);
321 }
322 VariablePacker packer;
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700323 return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400324}
Jamie Madill4e1fd412014-07-10 17:50:10 -0400325
326bool ShGetInterfaceBlockRegister(const ShHandle handle,
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700327 const std::string &interfaceBlockName,
Jamie Madill4e1fd412014-07-10 17:50:10 -0400328 unsigned int *indexOut)
329{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700330 ASSERT(indexOut);
Jamie Madill4e1fd412014-07-10 17:50:10 -0400331
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700332 TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
333 ASSERT(translator);
Jamie Madill4e1fd412014-07-10 17:50:10 -0400334
335 if (!translator->hasInterfaceBlock(interfaceBlockName))
336 {
337 return false;
338 }
339
340 *indexOut = translator->getInterfaceBlockRegister(interfaceBlockName);
341 return true;
342}
Jamie Madill9fe25e92014-07-18 10:33:08 -0400343
344bool ShGetUniformRegister(const ShHandle handle,
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700345 const std::string &uniformName,
Jamie Madill9fe25e92014-07-18 10:33:08 -0400346 unsigned int *indexOut)
347{
Zhenyao Mo4de44cb2014-10-29 18:03:46 -0700348 ASSERT(indexOut);
349 TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
350 ASSERT(translator);
Jamie Madill9fe25e92014-07-18 10:33:08 -0400351
352 if (!translator->hasUniform(uniformName))
353 {
354 return false;
355 }
356
357 *indexOut = translator->getUniformRegister(uniformName);
358 return true;
359}