blob: 8aed31bc4e9cfad9954c610102d9cf1b23d3490a [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com043da132012-12-20 21:12:22 +00002// Copyright (c) 2002-2012 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
kbr@chromium.org22152112011-10-26 01:18:28 +000024static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
25 int expectedValue)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000026{
kbr@chromium.org22152112011-10-26 01:18:28 +000027 int activeUniformLimit = 0;
28 ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
29 int activeAttribLimit = 0;
30 ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
31 return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
32}
33
34static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
35{
36 int mappedNameMaxLength = 0;
37 ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
38 return (expectedValue == mappedNameMaxLength);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000039}
40
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000041static void getVariableInfo(ShShaderInfo varType,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000042 const ShHandle handle,
43 int index,
44 int* length,
45 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000046 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +000047 char* name,
48 char* mappedName)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000049{
50 if (!handle || !size || !type || !name)
51 return;
52 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
53 (varType == SH_ACTIVE_UNIFORMS));
54
55 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
56 TCompiler* compiler = base->getAsCompiler();
57 if (compiler == 0)
58 return;
59
60 const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
61 compiler->getAttribs() : compiler->getUniforms();
62 if (index < 0 || index >= static_cast<int>(varList.size()))
63 return;
64
65 const TVariableInfo& varInfo = varList[index];
66 if (length) *length = varInfo.name.size();
67 *size = varInfo.size;
68 *type = varInfo.type;
kbr@chromium.org22152112011-10-26 01:18:28 +000069
70 // This size must match that queried by
71 // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
72 // in ShGetInfo, below.
73 int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
74 ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
75 strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
jacob.benoit.1@gmail.comb45306b2012-05-07 02:12:34 +000076 name[activeUniformAndAttribLength - 1] = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000077 if (mappedName) {
78 // This size must match that queried by
79 // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
80 int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
81 ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
82 strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
jacob.benoit.1@gmail.comb45306b2012-05-07 02:12:34 +000083 mappedName[maxMappedNameLength - 1] = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000084 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000085}
86
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000087//
88// Driver must call this first, once, before doing any other
alokp@chromium.org774d7062010-07-21 18:55:45 +000089// compiler operations.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090//
91int ShInitialize()
92{
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000093 if (!InitProcess())
94 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000095
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000096 return 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097}
98
99//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000100// Cleanup symbol tables
101//
102int ShFinalize()
103{
104 if (!DetachProcess())
105 return 0;
106
107 return 1;
108}
109
110//
111// Initialize built-in resources with minimum expected values.
112//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000113void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000114{
115 // Constants.
116 resources->MaxVertexAttribs = 8;
117 resources->MaxVertexUniformVectors = 128;
118 resources->MaxVaryingVectors = 8;
119 resources->MaxVertexTextureImageUnits = 0;
120 resources->MaxCombinedTextureImageUnits = 8;
121 resources->MaxTextureImageUnits = 8;
122 resources->MaxFragmentUniformVectors = 16;
123 resources->MaxDrawBuffers = 1;
124
125 // Extensions.
126 resources->OES_standard_derivatives = 0;
zmo@google.com09c323a2011-08-12 18:22:25 +0000127 resources->OES_EGL_image_external = 0;
kbr@chromium.org205fef32011-11-22 20:50:02 +0000128 resources->ARB_texture_rectangle = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000129
130 // Disable name hashing by default.
131 resources->HashFunction = NULL;
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000132
133 resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000134}
135
136//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000137// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000139ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
zmo@google.com5601ea02011-06-10 18:23:25 +0000140 ShShaderOutput output,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000141 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000142{
143 if (!InitThread())
144 return 0;
145
zmo@google.com5601ea02011-06-10 18:23:25 +0000146 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000147 TCompiler* compiler = base->getAsCompiler();
148 if (compiler == 0)
149 return 0;
150
151 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000152 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000153 ShDestruct(base);
154 return 0;
155 }
156
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157 return reinterpret_cast<void*>(base);
158}
159
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160void ShDestruct(ShHandle handle)
161{
162 if (handle == 0)
163 return;
164
165 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
166
167 if (base->getAsCompiler())
168 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169}
170
171//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000172// Do an actual compile on the given strings. The result is left
173// in the given compile object.
174//
175// Return: The return value of ShCompile is really boolean, indicating
176// success or failure.
177//
178int ShCompile(
179 const ShHandle handle,
180 const char* const shaderStrings[],
181 const int numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000182 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183{
184 if (!InitThread())
185 return 0;
186
187 if (handle == 0)
188 return 0;
189
190 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
191 TCompiler* compiler = base->getAsCompiler();
192 if (compiler == 0)
193 return 0;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000194
alokp@chromium.org07620a52010-09-23 17:53:56 +0000195 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196 return success ? 1 : 0;
197}
198
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000199void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000200{
201 if (!handle || !params)
202 return;
203
204 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
205 TCompiler* compiler = base->getAsCompiler();
206 if (!compiler) return;
207
208 switch(pname)
209 {
210 case SH_INFO_LOG_LENGTH:
211 *params = compiler->getInfoSink().info.size() + 1;
212 break;
213 case SH_OBJECT_CODE_LENGTH:
214 *params = compiler->getInfoSink().obj.size() + 1;
215 break;
216 case SH_ACTIVE_UNIFORMS:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000217 *params = compiler->getUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000218 break;
219 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000220 *params = 1 + MAX_SYMBOL_NAME_LEN;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000221 break;
222 case SH_ACTIVE_ATTRIBUTES:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000223 *params = compiler->getAttribs().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000224 break;
225 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000226 *params = 1 + MAX_SYMBOL_NAME_LEN;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000227 break;
zmo@google.comfd747b82011-04-23 01:30:07 +0000228 case SH_MAPPED_NAME_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000229 // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
230 // handle array and struct dereferences.
231 *params = 1 + MAX_SYMBOL_NAME_LEN;
zmo@google.comfd747b82011-04-23 01:30:07 +0000232 break;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000233 case SH_NAME_MAX_LENGTH:
234 *params = 1 + MAX_SYMBOL_NAME_LEN;
235 break;
236 case SH_HASHED_NAME_MAX_LENGTH:
237 if (compiler->getHashFunction() == NULL) {
238 *params = 0;
239 } else {
240 // 64 bits hashing output requires 16 bytes for hex
241 // representation.
242 const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
243 *params = 16 + sizeof(HashedNamePrefix);
244 }
245 break;
246 case SH_HASHED_NAMES_COUNT:
247 *params = compiler->getNameMap().size();
248 break;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000249 default: UNREACHABLE();
250 }
251}
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//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000256void ShGetInfoLog(const ShHandle handle, char* infoLog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000258 if (!handle || !infoLog)
259 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260
261 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000262 TCompiler* compiler = base->getAsCompiler();
263 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264
alokp@chromium.org7beea402010-09-15 21:18:34 +0000265 TInfoSink& infoSink = compiler->getInfoSink();
266 strcpy(infoLog, infoSink.info.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267}
268
269//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000270// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000272void ShGetObjectCode(const ShHandle handle, char* objCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000274 if (!handle || !objCode)
275 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276
277 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000278 TCompiler* compiler = base->getAsCompiler();
279 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000280
alokp@chromium.org7beea402010-09-15 21:18:34 +0000281 TInfoSink& infoSink = compiler->getInfoSink();
282 strcpy(objCode, infoSink.obj.c_str());
283}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000284
alokp@chromium.org7beea402010-09-15 21:18:34 +0000285void ShGetActiveAttrib(const ShHandle handle,
286 int index,
287 int* length,
288 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000289 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +0000290 char* name,
291 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000292{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000293 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
zmo@google.comfd747b82011-04-23 01:30:07 +0000294 handle, index, length, size, type, name, mappedName);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000295}
296
297void ShGetActiveUniform(const ShHandle handle,
298 int index,
299 int* length,
300 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000301 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +0000302 char* name,
303 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000304{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000305 getVariableInfo(SH_ACTIVE_UNIFORMS,
zmo@google.comfd747b82011-04-23 01:30:07 +0000306 handle, index, length, size, type, name, mappedName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307}
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000308
309void ShGetNameHashingEntry(const ShHandle handle,
310 int index,
311 char* name,
312 char* hashedName)
313{
314 if (!handle || !name || !hashedName || index < 0)
315 return;
316
317 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
318 TCompiler* compiler = base->getAsCompiler();
319 if (!compiler) return;
320
321 const NameMap& nameMap = compiler->getNameMap();
322 if (index >= static_cast<int>(nameMap.size()))
323 return;
324
325 NameMap::const_iterator it = nameMap.begin();
326 for (int i = 0; i < index; ++i)
327 ++it;
328
329 size_t len = it->first.length() + 1;
330 int max_len = 0;
331 ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
332 if (static_cast<int>(len) > max_len) {
333 ASSERT(false);
334 len = max_len;
335 }
336 strncpy(name, it->first.c_str(), len);
337 // To be on the safe side in case the source is longer than expected.
338 name[len] = '\0';
339
340 len = it->second.length() + 1;
341 max_len = 0;
342 ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
343 if (static_cast<int>(len) > max_len) {
344 ASSERT(false);
345 len = max_len;
346 }
347 strncpy(hashedName, it->second.c_str(), len);
348 // To be on the safe side in case the source is longer than expected.
349 hashedName[len] = '\0';
350}
daniel@transgaming.com043da132012-12-20 21:12:22 +0000351
352void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
353{
354 if (!handle || !params)
355 return;
356
357 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
358 TranslatorHLSL* translator = base->getAsTranslatorHLSL();
359 if (!translator) return;
360
361 switch(pname)
362 {
363 case SH_ACTIVE_UNIFORMS_ARRAY:
364 *params = (void*)&translator->getUniforms();
365 break;
366 default: UNREACHABLE();
367 }
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000368}