blob: 6d954ca594544426ac435e8affcb1549e19bf3d5 [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
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000014#include "compiler/InitializeDll.h"
kbr@chromium.org22152112011-10-26 01:18:28 +000015#include "compiler/preprocessor/length_limits.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000016#include "compiler/ShHandle.h"
daniel@transgaming.com043da132012-12-20 21:12:22 +000017#include "compiler/TranslatorHLSL.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000018
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019//
20// This is the platform independent interface between an OGL driver
alokp@chromium.org774d7062010-07-21 18:55:45 +000021// and the shading language compiler.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022//
23
Zhenyao Mo74da9f22013-09-23 14:57:01 -040024static bool checkVariableMaxLengths(const ShHandle handle,
25 size_t expectedValue)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000026{
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000027 size_t activeUniformLimit = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000028 ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000029 size_t activeAttribLimit = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000030 ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
Zhenyao Mo74da9f22013-09-23 14:57:01 -040031 size_t varyingLimit = 0;
32 ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
33 return (expectedValue == activeUniformLimit &&
34 expectedValue == activeAttribLimit &&
35 expectedValue == varyingLimit);
kbr@chromium.org22152112011-10-26 01:18:28 +000036}
37
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000038static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
kbr@chromium.org22152112011-10-26 01:18:28 +000039{
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000040 size_t mappedNameMaxLength = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000041 ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
42 return (expectedValue == mappedNameMaxLength);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000043}
44
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000045//
Alok Priyadarshib11713f2013-08-01 16:02:39 -070046// Driver must call this first, once, before doing any other compiler operations.
47// Subsequent calls to this function are no-op.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048//
49int ShInitialize()
50{
Alok Priyadarshib11713f2013-08-01 16:02:39 -070051 static const bool kInitialized = InitProcess();
52 return kInitialized ? 1 : 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000053}
54
55//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000056// Cleanup symbol tables
57//
58int ShFinalize()
59{
Alok Priyadarshi8156b6b2013-09-23 14:56:58 -040060 DetachProcess();
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000061 return 1;
62}
63
64//
65// Initialize built-in resources with minimum expected values.
66//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000067void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000068{
69 // Constants.
70 resources->MaxVertexAttribs = 8;
71 resources->MaxVertexUniformVectors = 128;
72 resources->MaxVaryingVectors = 8;
73 resources->MaxVertexTextureImageUnits = 0;
74 resources->MaxCombinedTextureImageUnits = 8;
75 resources->MaxTextureImageUnits = 8;
76 resources->MaxFragmentUniformVectors = 16;
77 resources->MaxDrawBuffers = 1;
78
79 // Extensions.
80 resources->OES_standard_derivatives = 0;
zmo@google.com09c323a2011-08-12 18:22:25 +000081 resources->OES_EGL_image_external = 0;
kbr@chromium.org205fef32011-11-22 20:50:02 +000082 resources->ARB_texture_rectangle = 0;
shannon.woods@transgaming.com550cd092013-02-28 23:19:54 +000083 resources->EXT_draw_buffers = 0;
Jamie Madill2aeb26a2013-07-08 14:02:55 -040084 resources->EXT_frag_depth = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +000085
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +000086 // Disable highp precision in fragment shader by default.
87 resources->FragmentPrecisionHigh = 0;
88
shannonwoods@chromium.org74b86cf2013-05-30 00:02:58 +000089 // GLSL ES 3.0 constants.
90 resources->MaxVertexOutputVectors = 16;
91 resources->MaxFragmentInputVectors = 15;
92 resources->MinProgramTexelOffset = -8;
93 resources->MaxProgramTexelOffset = 7;
94
daniel@transgaming.comc23f4612012-11-28 19:42:57 +000095 // Disable name hashing by default.
96 resources->HashFunction = NULL;
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +000097
98 resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000099}
100
101//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000102// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000103//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000104ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
zmo@google.com5601ea02011-06-10 18:23:25 +0000105 ShShaderOutput output,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000106 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107{
zmo@google.com5601ea02011-06-10 18:23:25 +0000108 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000109 TCompiler* compiler = base->getAsCompiler();
110 if (compiler == 0)
111 return 0;
112
113 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000114 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000115 ShDestruct(base);
116 return 0;
117 }
118
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119 return reinterpret_cast<void*>(base);
120}
121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122void ShDestruct(ShHandle handle)
123{
124 if (handle == 0)
125 return;
126
127 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
128
129 if (base->getAsCompiler())
130 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131}
132
133//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000134// Do an actual compile on the given strings. The result is left
135// in the given compile object.
136//
137// Return: The return value of ShCompile is really boolean, indicating
138// success or failure.
139//
140int ShCompile(
141 const ShHandle handle,
142 const char* const shaderStrings[],
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000143 size_t numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000144 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000145{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000146 if (handle == 0)
147 return 0;
148
149 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
150 TCompiler* compiler = base->getAsCompiler();
151 if (compiler == 0)
152 return 0;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000153
alokp@chromium.org07620a52010-09-23 17:53:56 +0000154 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155 return success ? 1 : 0;
156}
157
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000158void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000159{
160 if (!handle || !params)
161 return;
162
163 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
164 TCompiler* compiler = base->getAsCompiler();
165 if (!compiler) return;
166
167 switch(pname)
168 {
169 case SH_INFO_LOG_LENGTH:
170 *params = compiler->getInfoSink().info.size() + 1;
171 break;
172 case SH_OBJECT_CODE_LENGTH:
173 *params = compiler->getInfoSink().obj.size() + 1;
174 break;
175 case SH_ACTIVE_UNIFORMS:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000176 *params = compiler->getUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000177 break;
178 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000179 *params = 1 + MAX_SYMBOL_NAME_LEN;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000180 break;
181 case SH_ACTIVE_ATTRIBUTES:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000182 *params = compiler->getAttribs().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000183 break;
184 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000185 *params = 1 + MAX_SYMBOL_NAME_LEN;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000186 break;
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400187 case SH_VARYINGS:
188 *params = compiler->getVaryings().size();
189 break;
190 case SH_VARYING_MAX_LENGTH:
191 *params = 1 + MAX_SYMBOL_NAME_LEN;
192 break;
zmo@google.comfd747b82011-04-23 01:30:07 +0000193 case SH_MAPPED_NAME_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000194 // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
195 // handle array and struct dereferences.
196 *params = 1 + MAX_SYMBOL_NAME_LEN;
zmo@google.comfd747b82011-04-23 01:30:07 +0000197 break;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000198 case SH_NAME_MAX_LENGTH:
199 *params = 1 + MAX_SYMBOL_NAME_LEN;
200 break;
201 case SH_HASHED_NAME_MAX_LENGTH:
202 if (compiler->getHashFunction() == NULL) {
203 *params = 0;
204 } else {
205 // 64 bits hashing output requires 16 bytes for hex
206 // representation.
207 const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
208 *params = 16 + sizeof(HashedNamePrefix);
209 }
210 break;
211 case SH_HASHED_NAMES_COUNT:
212 *params = compiler->getNameMap().size();
213 break;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000214 case SH_SHADER_VERSION:
215 *params = compiler->getShaderVersion();
216 break;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000217 default: UNREACHABLE();
218 }
219}
220
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000221//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000222// Return any compiler log of messages for the application.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000224void ShGetInfoLog(const ShHandle handle, char* infoLog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000226 if (!handle || !infoLog)
227 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228
229 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000230 TCompiler* compiler = base->getAsCompiler();
231 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000232
alokp@chromium.org7beea402010-09-15 21:18:34 +0000233 TInfoSink& infoSink = compiler->getInfoSink();
234 strcpy(infoLog, infoSink.info.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235}
236
237//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000238// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000240void ShGetObjectCode(const ShHandle handle, char* objCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000241{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000242 if (!handle || !objCode)
243 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244
245 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000246 TCompiler* compiler = base->getAsCompiler();
247 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248
alokp@chromium.org7beea402010-09-15 21:18:34 +0000249 TInfoSink& infoSink = compiler->getInfoSink();
250 strcpy(objCode, infoSink.obj.c_str());
251}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400253void ShGetVariableInfo(const ShHandle handle,
254 ShShaderInfo varType,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000255 int index,
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000256 size_t* length,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000257 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000258 ShDataType* type,
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400259 ShPrecisionType* precision,
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400260 int* staticUse,
zmo@google.comfd747b82011-04-23 01:30:07 +0000261 char* name,
262 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000263{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400264 if (!handle || !size || !type || !precision || !staticUse || !name)
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400265 return;
266 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
267 (varType == SH_ACTIVE_UNIFORMS) ||
268 (varType == SH_VARYINGS));
alokp@chromium.org7beea402010-09-15 21:18:34 +0000269
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400270 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
271 TCompiler* compiler = base->getAsCompiler();
272 if (compiler == 0)
273 return;
274
275 const TVariableInfoList& varList =
276 varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() :
277 (varType == SH_ACTIVE_UNIFORMS ? compiler->getUniforms() :
278 compiler->getVaryings());
279 if (index < 0 || index >= static_cast<int>(varList.size()))
280 return;
281
282 const TVariableInfo& varInfo = varList[index];
283 if (length) *length = varInfo.name.size();
284 *size = varInfo.size;
285 *type = varInfo.type;
286 switch (varInfo.precision) {
287 case EbpLow:
288 *precision = SH_PRECISION_LOWP;
289 break;
290 case EbpMedium:
291 *precision = SH_PRECISION_MEDIUMP;
292 break;
293 case EbpHigh:
294 *precision = SH_PRECISION_HIGHP;
295 break;
296 default:
Zhenyao Mofa3c3462013-09-23 14:57:04 -0400297 // Some types does not support precision, for example, boolean.
298 *precision = SH_PRECISION_UNDEFINED;
299 break;
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400300 }
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400301 *staticUse = varInfo.staticUse ? 1 : 0;
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400302
303 // This size must match that queried by
304 // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
305 // in ShGetInfo, below.
306 size_t variableLength = 1 + MAX_SYMBOL_NAME_LEN;
307 ASSERT(checkVariableMaxLengths(handle, variableLength));
308 strncpy(name, varInfo.name.c_str(), variableLength);
309 name[variableLength - 1] = 0;
310 if (mappedName) {
311 // This size must match that queried by
312 // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
313 size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
314 ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
315 strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
316 mappedName[maxMappedNameLength - 1] = 0;
317 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000318}
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000319
320void ShGetNameHashingEntry(const ShHandle handle,
321 int index,
322 char* name,
323 char* hashedName)
324{
325 if (!handle || !name || !hashedName || index < 0)
326 return;
327
328 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
329 TCompiler* compiler = base->getAsCompiler();
330 if (!compiler) return;
331
332 const NameMap& nameMap = compiler->getNameMap();
333 if (index >= static_cast<int>(nameMap.size()))
334 return;
335
336 NameMap::const_iterator it = nameMap.begin();
337 for (int i = 0; i < index; ++i)
338 ++it;
339
340 size_t len = it->first.length() + 1;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000341 size_t max_len = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000342 ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000343 if (len > max_len) {
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000344 ASSERT(false);
345 len = max_len;
346 }
347 strncpy(name, it->first.c_str(), len);
348 // To be on the safe side in case the source is longer than expected.
daniel@transgaming.com75cb6892013-02-01 03:20:26 +0000349 name[len - 1] = '\0';
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000350
351 len = it->second.length() + 1;
352 max_len = 0;
353 ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000354 if (len > max_len) {
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000355 ASSERT(false);
356 len = max_len;
357 }
358 strncpy(hashedName, it->second.c_str(), len);
359 // To be on the safe side in case the source is longer than expected.
daniel@transgaming.com75cb6892013-02-01 03:20:26 +0000360 hashedName[len - 1] = '\0';
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000361}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000362
363void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
364{
365 if (!handle || !params)
366 return;
367
368 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
369 TranslatorHLSL* translator = base->getAsTranslatorHLSL();
370 if (!translator) return;
371
372 switch(pname)
373 {
374 case SH_ACTIVE_UNIFORMS_ARRAY:
375 *params = (void*)&translator->getUniforms();
376 break;
shannonwoods@chromium.org3f68bf02013-05-30 00:12:43 +0000377 case SH_ACTIVE_INTERFACE_BLOCKS_ARRAY:
378 *params = (void*)&translator->getInterfaceBlocks();
379 break;
Jamie Madill46131a32013-06-20 11:55:50 -0400380 case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY:
381 *params = (void*)&translator->getOutputVariables();
382 break;
Jamie Madilldefb6742013-06-20 11:55:51 -0400383 case SH_ACTIVE_ATTRIBUTES_ARRAY:
384 *params = (void*)&translator->getAttributes();
385 break;
Jamie Madill47fdd132013-08-30 13:21:04 -0400386 case SH_ACTIVE_VARYINGS_ARRAY:
387 *params = (void*)&translator->getVaryings();
388 break;
daniel@transgaming.com043da132012-12-20 21:12:22 +0000389 default: UNREACHABLE();
390 }
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000391}