blob: 144ef90b566a834f564d3f3b9cf94a1ebfd0becc [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 -040040static bool CheckVariableMaxLengths(const ShHandle handle,
Zhenyao Mo74da9f22013-09-23 14:57:01 -040041 size_t expectedValue)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000042{
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000043 size_t activeUniformLimit = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000044 ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000045 size_t activeAttribLimit = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000046 ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
Zhenyao Mo74da9f22013-09-23 14:57:01 -040047 size_t varyingLimit = 0;
48 ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
49 return (expectedValue == activeUniformLimit &&
50 expectedValue == activeAttribLimit &&
51 expectedValue == varyingLimit);
kbr@chromium.org22152112011-10-26 01:18:28 +000052}
53
Jamie Madille294bb82014-07-17 14:16:26 -040054bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
kbr@chromium.org22152112011-10-26 01:18:28 +000055{
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +000056 size_t mappedNameMaxLength = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000057 ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
58 return (expectedValue == mappedNameMaxLength);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000059}
60
Jamie Madilla718c1e2014-07-02 15:31:22 -040061template <typename VarT>
Jamie Madille294bb82014-07-17 14:16:26 -040062const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
Jamie Madilla718c1e2014-07-02 15:31:22 -040063{
64 if (index < 0 || static_cast<size_t>(index) >= infoList.size())
65 {
66 return NULL;
67 }
68
69 return &infoList[index];
70}
71
Jamie Madille294bb82014-07-17 14:16:26 -040072const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
Jamie Madilla718c1e2014-07-02 15:31:22 -040073{
74 switch (varType)
75 {
76 case SH_ACTIVE_ATTRIBUTES:
Jamie Madilled27c722014-07-02 15:31:23 -040077 return ReturnVariable(compiler->getAttributes(), index);
Jamie Madilla718c1e2014-07-02 15:31:22 -040078 case SH_ACTIVE_UNIFORMS:
Jamie Madill23a8a432014-07-09 13:27:42 -040079 return ReturnVariable(compiler->getExpandedUniforms(), index);
Jamie Madilla718c1e2014-07-02 15:31:22 -040080 case SH_VARYINGS:
Jamie Madill23a8a432014-07-09 13:27:42 -040081 return ReturnVariable(compiler->getExpandedVaryings(), index);
Jamie Madilla718c1e2014-07-02 15:31:22 -040082 default:
83 UNREACHABLE();
84 return NULL;
85 }
86}
87
Jamie Madille294bb82014-07-17 14:16:26 -040088ShPrecisionType ConvertPrecision(sh::GLenum precision)
Jamie Madilla718c1e2014-07-02 15:31:22 -040089{
90 switch (precision)
91 {
92 case GL_HIGH_FLOAT:
93 case GL_HIGH_INT:
94 return SH_PRECISION_HIGHP;
95 case GL_MEDIUM_FLOAT:
96 case GL_MEDIUM_INT:
Jamie Madill1da63af2014-07-03 15:00:53 -040097 return SH_PRECISION_MEDIUMP;
Jamie Madilla718c1e2014-07-02 15:31:22 -040098 case GL_LOW_FLOAT:
99 case GL_LOW_INT:
Jamie Madill1da63af2014-07-03 15:00:53 -0400100 return SH_PRECISION_LOWP;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400101 default:
Jamie Madilla718c1e2014-07-02 15:31:22 -0400102 return SH_PRECISION_UNDEFINED;
103 }
104}
105
Jamie Madille294bb82014-07-17 14:16:26 -0400106template <typename VarT>
107const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
108
109template <>
110const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
111{
112 return &compiler->getUniforms();
113}
114
115template <>
116const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
117{
118 return &compiler->getVaryings();
119}
120
121template <>
122const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType)
123{
124 return (variableType == SHADERVAR_ATTRIBUTE ?
125 &compiler->getAttributes() :
126 &compiler->getOutputVariables());
127}
128
129template <>
130const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
131{
132 return &compiler->getInterfaceBlocks();
133}
134
135template <typename VarT>
136const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariableType variableType)
137{
138 if (!handle)
139 {
140 return NULL;
141 }
142
143 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
144 TCompiler* compiler = base->getAsCompiler();
145 if (!compiler)
146 {
147 return NULL;
148 }
149
150 return GetVariableList<VarT>(compiler, variableType);
151}
152
153}
154
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155//
Alok Priyadarshib11713f2013-08-01 16:02:39 -0700156// Driver must call this first, once, before doing any other compiler operations.
157// Subsequent calls to this function are no-op.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158//
159int ShInitialize()
160{
Jamie Madill477bc782014-02-26 09:54:17 -0500161 if (!isInitialized)
162 {
163 isInitialized = InitProcess();
164 }
Jamie Madillb4d192c2014-02-26 09:54:10 -0500165 return isInitialized ? 1 : 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166}
167
168//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000169// Cleanup symbol tables
170//
171int ShFinalize()
172{
Geoff Langf20f0202014-04-28 11:02:07 -0400173 if (isInitialized)
174 {
175 DetachProcess();
176 isInitialized = false;
177 }
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000178 return 1;
179}
180
181//
182// Initialize built-in resources with minimum expected values.
183//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000184void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000185{
Kimmo Kinnunen7c1cfd62014-10-15 14:59:57 +0300186 // Make comparable.
187 memset(resources, 0, sizeof(*resources));
188
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000189 // Constants.
190 resources->MaxVertexAttribs = 8;
191 resources->MaxVertexUniformVectors = 128;
192 resources->MaxVaryingVectors = 8;
193 resources->MaxVertexTextureImageUnits = 0;
194 resources->MaxCombinedTextureImageUnits = 8;
195 resources->MaxTextureImageUnits = 8;
196 resources->MaxFragmentUniformVectors = 16;
197 resources->MaxDrawBuffers = 1;
198
199 // Extensions.
200 resources->OES_standard_derivatives = 0;
zmo@google.com09c323a2011-08-12 18:22:25 +0000201 resources->OES_EGL_image_external = 0;
kbr@chromium.org205fef32011-11-22 20:50:02 +0000202 resources->ARB_texture_rectangle = 0;
shannon.woods@transgaming.com550cd092013-02-28 23:19:54 +0000203 resources->EXT_draw_buffers = 0;
Jamie Madill2aeb26a2013-07-08 14:02:55 -0400204 resources->EXT_frag_depth = 0;
Nicolas Capens46485082014-04-15 13:12:50 -0400205 resources->EXT_shader_texture_lod = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000206
Olli Etuahoe61209a2014-09-26 12:01:17 +0300207 resources->NV_draw_buffers = 0;
208
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000209 // Disable highp precision in fragment shader by default.
210 resources->FragmentPrecisionHigh = 0;
211
shannonwoods@chromium.org74b86cf2013-05-30 00:02:58 +0000212 // GLSL ES 3.0 constants.
213 resources->MaxVertexOutputVectors = 16;
214 resources->MaxFragmentInputVectors = 15;
215 resources->MinProgramTexelOffset = -8;
216 resources->MaxProgramTexelOffset = 7;
217
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000218 // Disable name hashing by default.
219 resources->HashFunction = NULL;
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000220
221 resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
Nicolas Capens7d649a02014-02-07 11:24:32 -0500222
223 resources->MaxExpressionComplexity = 256;
224 resources->MaxCallStackDepth = 256;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000225}
226
227//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000228// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000229//
Jamie Madill183bde52014-07-02 15:31:19 -0400230ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec,
zmo@google.com5601ea02011-06-10 18:23:25 +0000231 ShShaderOutput output,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000232 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233{
zmo@google.com5601ea02011-06-10 18:23:25 +0000234 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000235 TCompiler* compiler = base->getAsCompiler();
236 if (compiler == 0)
237 return 0;
238
239 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000240 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000241 ShDestruct(base);
242 return 0;
243 }
244
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000245 return reinterpret_cast<void*>(base);
246}
247
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248void ShDestruct(ShHandle handle)
249{
250 if (handle == 0)
251 return;
252
253 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
254
255 if (base->getAsCompiler())
256 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257}
258
Shannon Woods2d76e5f2014-05-16 17:46:41 -0400259void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
260{
261 if (!handle || !outString)
262 {
263 return;
264 }
265
266 TShHandleBase *base = static_cast<TShHandleBase*>(handle);
267 TCompiler *compiler = base->getAsCompiler();
268 if (!compiler)
269 {
270 return;
271 }
272
273 strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
274 outString[outStringLen - 1] = '\0';
275}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276//
Shannon Woods2d76e5f2014-05-16 17:46:41 -0400277// Do an actual compile on the given strings. The result is left
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000278// in the given compile object.
279//
280// Return: The return value of ShCompile is really boolean, indicating
281// success or failure.
282//
283int ShCompile(
284 const ShHandle handle,
285 const char* const shaderStrings[],
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000286 size_t numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000287 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000288{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000289 if (handle == 0)
290 return 0;
291
292 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
293 TCompiler* compiler = base->getAsCompiler();
294 if (compiler == 0)
295 return 0;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000296
alokp@chromium.org07620a52010-09-23 17:53:56 +0000297 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298 return success ? 1 : 0;
299}
300
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000301void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000302{
303 if (!handle || !params)
304 return;
305
306 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
307 TCompiler* compiler = base->getAsCompiler();
308 if (!compiler) return;
309
310 switch(pname)
311 {
312 case SH_INFO_LOG_LENGTH:
313 *params = compiler->getInfoSink().info.size() + 1;
314 break;
315 case SH_OBJECT_CODE_LENGTH:
316 *params = compiler->getInfoSink().obj.size() + 1;
317 break;
318 case SH_ACTIVE_UNIFORMS:
Jamie Madill23a8a432014-07-09 13:27:42 -0400319 *params = compiler->getExpandedUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000320 break;
321 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700322 *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000323 break;
324 case SH_ACTIVE_ATTRIBUTES:
Jamie Madilled27c722014-07-02 15:31:23 -0400325 *params = compiler->getAttributes().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000326 break;
327 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700328 *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000329 break;
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400330 case SH_VARYINGS:
Jamie Madill23a8a432014-07-09 13:27:42 -0400331 *params = compiler->getExpandedVaryings().size();
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400332 break;
333 case SH_VARYING_MAX_LENGTH:
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700334 *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400335 break;
zmo@google.comfd747b82011-04-23 01:30:07 +0000336 case SH_MAPPED_NAME_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000337 // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
338 // handle array and struct dereferences.
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700339 *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
zmo@google.comfd747b82011-04-23 01:30:07 +0000340 break;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000341 case SH_NAME_MAX_LENGTH:
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700342 *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000343 break;
344 case SH_HASHED_NAME_MAX_LENGTH:
345 if (compiler->getHashFunction() == NULL) {
346 *params = 0;
347 } else {
348 // 64 bits hashing output requires 16 bytes for hex
349 // representation.
350 const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
Geoff Langcebb5aa2014-04-07 14:13:40 -0400351 (void)HashedNamePrefix;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000352 *params = 16 + sizeof(HashedNamePrefix);
353 }
354 break;
355 case SH_HASHED_NAMES_COUNT:
356 *params = compiler->getNameMap().size();
357 break;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000358 case SH_SHADER_VERSION:
359 *params = compiler->getShaderVersion();
360 break;
Shannon Woods2d76e5f2014-05-16 17:46:41 -0400361 case SH_RESOURCES_STRING_LENGTH:
362 *params = compiler->getBuiltInResourcesString().length() + 1;
363 break;
Jamie Madill68fe74a2014-05-27 12:56:01 -0400364 case SH_OUTPUT_TYPE:
365 *params = compiler->getOutputType();
366 break;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000367 default: UNREACHABLE();
368 }
369}
370
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000371//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000372// Return any compiler log of messages for the application.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000373//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000374void ShGetInfoLog(const ShHandle handle, char* infoLog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000375{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000376 if (!handle || !infoLog)
377 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000378
379 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000380 TCompiler* compiler = base->getAsCompiler();
381 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000382
alokp@chromium.org7beea402010-09-15 21:18:34 +0000383 TInfoSink& infoSink = compiler->getInfoSink();
384 strcpy(infoLog, infoSink.info.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000385}
386
387//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000388// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000389//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000390void ShGetObjectCode(const ShHandle handle, char* objCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000392 if (!handle || !objCode)
393 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000394
395 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000396 TCompiler* compiler = base->getAsCompiler();
397 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000398
alokp@chromium.org7beea402010-09-15 21:18:34 +0000399 TInfoSink& infoSink = compiler->getInfoSink();
400 strcpy(objCode, infoSink.obj.c_str());
401}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000402
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400403void ShGetVariableInfo(const ShHandle handle,
404 ShShaderInfo varType,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000405 int index,
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000406 size_t* length,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000407 int* size,
Jamie Madill183bde52014-07-02 15:31:19 -0400408 sh::GLenum* type,
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400409 ShPrecisionType* precision,
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400410 int* staticUse,
zmo@google.comfd747b82011-04-23 01:30:07 +0000411 char* name,
412 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000413{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400414 if (!handle || !size || !type || !precision || !staticUse || !name)
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400415 return;
416 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
417 (varType == SH_ACTIVE_UNIFORMS) ||
418 (varType == SH_VARYINGS));
alokp@chromium.org7beea402010-09-15 21:18:34 +0000419
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400420 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
421 TCompiler* compiler = base->getAsCompiler();
422 if (compiler == 0)
423 return;
424
Jamie Madilla718c1e2014-07-02 15:31:22 -0400425 const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
426 if (!varInfo)
427 {
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400428 return;
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400429 }
Jamie Madilla718c1e2014-07-02 15:31:22 -0400430
431 if (length) *length = varInfo->name.size();
432 *size = varInfo->elementCount();
433 *type = varInfo->type;
434 *precision = ConvertPrecision(varInfo->precision);
435 *staticUse = varInfo->staticUse ? 1 : 0;
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400436
437 // This size must match that queried by
438 // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
439 // in ShGetInfo, below.
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700440 size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
Jamie Madille294bb82014-07-17 14:16:26 -0400441 ASSERT(CheckVariableMaxLengths(handle, variableLength));
Jamie Madilla718c1e2014-07-02 15:31:22 -0400442 strncpy(name, varInfo->name.c_str(), variableLength);
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400443 name[variableLength - 1] = 0;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400444 if (mappedName)
445 {
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400446 // This size must match that queried by
447 // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
Zhenyao Mo7faf1a12014-04-25 18:03:56 -0700448 size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
Jamie Madille294bb82014-07-17 14:16:26 -0400449 ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
Jamie Madilla718c1e2014-07-02 15:31:22 -0400450 strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400451 mappedName[maxMappedNameLength - 1] = 0;
452 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000453}
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000454
455void ShGetNameHashingEntry(const ShHandle handle,
456 int index,
457 char* name,
458 char* hashedName)
459{
460 if (!handle || !name || !hashedName || index < 0)
461 return;
462
463 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
464 TCompiler* compiler = base->getAsCompiler();
465 if (!compiler) return;
466
467 const NameMap& nameMap = compiler->getNameMap();
468 if (index >= static_cast<int>(nameMap.size()))
469 return;
470
471 NameMap::const_iterator it = nameMap.begin();
472 for (int i = 0; i < index; ++i)
473 ++it;
474
475 size_t len = it->first.length() + 1;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000476 size_t max_len = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000477 ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000478 if (len > max_len) {
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000479 ASSERT(false);
480 len = max_len;
481 }
482 strncpy(name, it->first.c_str(), len);
483 // To be on the safe side in case the source is longer than expected.
daniel@transgaming.com75cb6892013-02-01 03:20:26 +0000484 name[len - 1] = '\0';
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000485
486 len = it->second.length() + 1;
487 max_len = 0;
488 ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000489 if (len > max_len) {
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000490 ASSERT(false);
491 len = max_len;
492 }
493 strncpy(hashedName, it->second.c_str(), len);
494 // To be on the safe side in case the source is longer than expected.
daniel@transgaming.com75cb6892013-02-01 03:20:26 +0000495 hashedName[len - 1] = '\0';
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000496}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000497
Jamie Madille294bb82014-07-17 14:16:26 -0400498const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
daniel@transgaming.com043da132012-12-20 21:12:22 +0000499{
Jamie Madille294bb82014-07-17 14:16:26 -0400500 return GetShaderVariables<sh::Uniform>(handle, SHADERVAR_UNIFORM);
501}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000502
Jamie Madille294bb82014-07-17 14:16:26 -0400503const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
504{
505 return GetShaderVariables<sh::Varying>(handle, SHADERVAR_VARYING);
506}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000507
Jamie Madille294bb82014-07-17 14:16:26 -0400508const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle)
509{
510 return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_ATTRIBUTE);
511}
512
513const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle)
514{
515 return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_OUTPUTVARIABLE);
516}
517
518const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
519{
520 return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000521}
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400522
523int ShCheckVariablesWithinPackingLimits(
524 int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
525{
526 if (varInfoArraySize == 0)
527 return 1;
528 ASSERT(varInfoArray);
Jamie Madilla718c1e2014-07-02 15:31:22 -0400529 std::vector<sh::ShaderVariable> variables;
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400530 for (size_t ii = 0; ii < varInfoArraySize; ++ii)
531 {
Jamie Madilla3fe2b42014-07-18 10:33:13 -0400532 sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size);
Zhenyao Moa15f3e82013-09-23 14:57:08 -0400533 variables.push_back(var);
534 }
535 VariablePacker packer;
536 return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
537}
Jamie Madill4e1fd412014-07-10 17:50:10 -0400538
539bool ShGetInterfaceBlockRegister(const ShHandle handle,
540 const char *interfaceBlockName,
541 unsigned int *indexOut)
542{
543 if (!handle || !interfaceBlockName || !indexOut)
544 {
545 return false;
546 }
547
548 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
549 TranslatorHLSL* translator = base->getAsTranslatorHLSL();
550 if (!translator)
551 {
552 return false;
553 }
554
555 if (!translator->hasInterfaceBlock(interfaceBlockName))
556 {
557 return false;
558 }
559
560 *indexOut = translator->getInterfaceBlockRegister(interfaceBlockName);
561 return true;
562}
Jamie Madill9fe25e92014-07-18 10:33:08 -0400563
564bool ShGetUniformRegister(const ShHandle handle,
565 const char *uniformName,
566 unsigned int *indexOut)
567{
568 if (!handle || !uniformName || !indexOut)
569 {
570 return false;
571 }
572
573 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
574 TranslatorHLSL* translator = base->getAsTranslatorHLSL();
575 if (!translator)
576 {
577 return false;
578 }
579
580 if (!translator->hasUniform(uniformName))
581 {
582 return false;
583 }
584
585 *indexOut = translator->getUniformRegister(uniformName);
586 return true;
587}