blob: ab56538c1ebb8f41c15a152cbbdc29e938c1c3b8 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
kbr@chromium.org22152112011-10-26 01:18:28 +00002// Copyright (c) 2002-2011 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.com4f39fd92010-03-08 20:26:45 +000017
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000018//
19// This is the platform independent interface between an OGL driver
alokp@chromium.org774d7062010-07-21 18:55:45 +000020// and the shading language compiler.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000021//
22
kbr@chromium.org22152112011-10-26 01:18:28 +000023static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
24 int expectedValue)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000025{
kbr@chromium.org22152112011-10-26 01:18:28 +000026 int activeUniformLimit = 0;
27 ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
28 int activeAttribLimit = 0;
29 ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
30 return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
31}
32
33static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
34{
35 int mappedNameMaxLength = 0;
36 ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
37 return (expectedValue == mappedNameMaxLength);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000038}
39
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000040static void getVariableInfo(ShShaderInfo varType,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000041 const ShHandle handle,
42 int index,
43 int* length,
44 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000045 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +000046 char* name,
47 char* mappedName)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000048{
49 if (!handle || !size || !type || !name)
50 return;
51 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
52 (varType == SH_ACTIVE_UNIFORMS));
53
54 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
55 TCompiler* compiler = base->getAsCompiler();
56 if (compiler == 0)
57 return;
58
59 const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
60 compiler->getAttribs() : compiler->getUniforms();
61 if (index < 0 || index >= static_cast<int>(varList.size()))
62 return;
63
64 const TVariableInfo& varInfo = varList[index];
65 if (length) *length = varInfo.name.size();
66 *size = varInfo.size;
67 *type = varInfo.type;
kbr@chromium.org22152112011-10-26 01:18:28 +000068
69 // This size must match that queried by
70 // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
71 // in ShGetInfo, below.
72 int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
73 ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
74 strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
jacob.benoit.1@gmail.comb45306b2012-05-07 02:12:34 +000075 name[activeUniformAndAttribLength - 1] = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000076 if (mappedName) {
77 // This size must match that queried by
78 // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
79 int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
80 ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
81 strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
jacob.benoit.1@gmail.comb45306b2012-05-07 02:12:34 +000082 mappedName[maxMappedNameLength - 1] = 0;
kbr@chromium.org22152112011-10-26 01:18:28 +000083 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000084}
85
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086//
87// Driver must call this first, once, before doing any other
alokp@chromium.org774d7062010-07-21 18:55:45 +000088// compiler operations.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089//
90int ShInitialize()
91{
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000092 if (!InitProcess())
93 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000095 return 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000096}
97
98//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000099// Cleanup symbol tables
100//
101int ShFinalize()
102{
103 if (!DetachProcess())
104 return 0;
105
106 return 1;
107}
108
109//
110// Initialize built-in resources with minimum expected values.
111//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000112void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000113{
114 // Constants.
115 resources->MaxVertexAttribs = 8;
116 resources->MaxVertexUniformVectors = 128;
117 resources->MaxVaryingVectors = 8;
118 resources->MaxVertexTextureImageUnits = 0;
119 resources->MaxCombinedTextureImageUnits = 8;
120 resources->MaxTextureImageUnits = 8;
121 resources->MaxFragmentUniformVectors = 16;
122 resources->MaxDrawBuffers = 1;
123
124 // Extensions.
125 resources->OES_standard_derivatives = 0;
zmo@google.com09c323a2011-08-12 18:22:25 +0000126 resources->OES_EGL_image_external = 0;
kbr@chromium.org205fef32011-11-22 20:50:02 +0000127 resources->ARB_texture_rectangle = 0;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000128
129 // Disable name hashing by default.
130 resources->HashFunction = NULL;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000131}
132
133//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000134// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000136ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
zmo@google.com5601ea02011-06-10 18:23:25 +0000137 ShShaderOutput output,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000138 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000139{
140 if (!InitThread())
141 return 0;
142
zmo@google.com5601ea02011-06-10 18:23:25 +0000143 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000144 TCompiler* compiler = base->getAsCompiler();
145 if (compiler == 0)
146 return 0;
147
148 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000149 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000150 ShDestruct(base);
151 return 0;
152 }
153
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000154 return reinterpret_cast<void*>(base);
155}
156
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157void ShDestruct(ShHandle handle)
158{
159 if (handle == 0)
160 return;
161
162 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
163
164 if (base->getAsCompiler())
165 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166}
167
168//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169// Do an actual compile on the given strings. The result is left
170// in the given compile object.
171//
172// Return: The return value of ShCompile is really boolean, indicating
173// success or failure.
174//
175int ShCompile(
176 const ShHandle handle,
177 const char* const shaderStrings[],
178 const int numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000179 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180{
181 if (!InitThread())
182 return 0;
183
184 if (handle == 0)
185 return 0;
186
187 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
188 TCompiler* compiler = base->getAsCompiler();
189 if (compiler == 0)
190 return 0;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000191
alokp@chromium.org07620a52010-09-23 17:53:56 +0000192 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193 return success ? 1 : 0;
194}
195
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000196void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000197{
198 if (!handle || !params)
199 return;
200
201 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
202 TCompiler* compiler = base->getAsCompiler();
203 if (!compiler) return;
204
205 switch(pname)
206 {
207 case SH_INFO_LOG_LENGTH:
208 *params = compiler->getInfoSink().info.size() + 1;
209 break;
210 case SH_OBJECT_CODE_LENGTH:
211 *params = compiler->getInfoSink().obj.size() + 1;
212 break;
213 case SH_ACTIVE_UNIFORMS:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000214 *params = compiler->getUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000215 break;
216 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000217 *params = 1 + MAX_SYMBOL_NAME_LEN;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000218 break;
219 case SH_ACTIVE_ATTRIBUTES:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000220 *params = compiler->getAttribs().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000221 break;
222 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000223 *params = 1 + MAX_SYMBOL_NAME_LEN;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000224 break;
zmo@google.comfd747b82011-04-23 01:30:07 +0000225 case SH_MAPPED_NAME_MAX_LENGTH:
kbr@chromium.org22152112011-10-26 01:18:28 +0000226 // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
227 // handle array and struct dereferences.
228 *params = 1 + MAX_SYMBOL_NAME_LEN;
zmo@google.comfd747b82011-04-23 01:30:07 +0000229 break;
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000230 case SH_NAME_MAX_LENGTH:
231 *params = 1 + MAX_SYMBOL_NAME_LEN;
232 break;
233 case SH_HASHED_NAME_MAX_LENGTH:
234 if (compiler->getHashFunction() == NULL) {
235 *params = 0;
236 } else {
237 // 64 bits hashing output requires 16 bytes for hex
238 // representation.
239 const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
240 *params = 16 + sizeof(HashedNamePrefix);
241 }
242 break;
243 case SH_HASHED_NAMES_COUNT:
244 *params = compiler->getNameMap().size();
245 break;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000246 default: UNREACHABLE();
247 }
248}
249
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000250//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000251// Return any compiler log of messages for the application.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000253void ShGetInfoLog(const ShHandle handle, char* infoLog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000254{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000255 if (!handle || !infoLog)
256 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257
258 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000259 TCompiler* compiler = base->getAsCompiler();
260 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000261
alokp@chromium.org7beea402010-09-15 21:18:34 +0000262 TInfoSink& infoSink = compiler->getInfoSink();
263 strcpy(infoLog, infoSink.info.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264}
265
266//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000267// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000269void ShGetObjectCode(const ShHandle handle, char* objCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000270{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000271 if (!handle || !objCode)
272 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273
274 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000275 TCompiler* compiler = base->getAsCompiler();
276 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277
alokp@chromium.org7beea402010-09-15 21:18:34 +0000278 TInfoSink& infoSink = compiler->getInfoSink();
279 strcpy(objCode, infoSink.obj.c_str());
280}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281
alokp@chromium.org7beea402010-09-15 21:18:34 +0000282void ShGetActiveAttrib(const ShHandle handle,
283 int index,
284 int* length,
285 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000286 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +0000287 char* name,
288 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000289{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000290 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
zmo@google.comfd747b82011-04-23 01:30:07 +0000291 handle, index, length, size, type, name, mappedName);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000292}
293
294void ShGetActiveUniform(const ShHandle handle,
295 int index,
296 int* length,
297 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000298 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +0000299 char* name,
300 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000301{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000302 getVariableInfo(SH_ACTIVE_UNIFORMS,
zmo@google.comfd747b82011-04-23 01:30:07 +0000303 handle, index, length, size, type, name, mappedName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304}
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000305
306void ShGetNameHashingEntry(const ShHandle handle,
307 int index,
308 char* name,
309 char* hashedName)
310{
311 if (!handle || !name || !hashedName || index < 0)
312 return;
313
314 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
315 TCompiler* compiler = base->getAsCompiler();
316 if (!compiler) return;
317
318 const NameMap& nameMap = compiler->getNameMap();
319 if (index >= static_cast<int>(nameMap.size()))
320 return;
321
322 NameMap::const_iterator it = nameMap.begin();
323 for (int i = 0; i < index; ++i)
324 ++it;
325
326 size_t len = it->first.length() + 1;
327 int max_len = 0;
328 ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
329 if (static_cast<int>(len) > max_len) {
330 ASSERT(false);
331 len = max_len;
332 }
333 strncpy(name, it->first.c_str(), len);
334 // To be on the safe side in case the source is longer than expected.
335 name[len] = '\0';
336
337 len = it->second.length() + 1;
338 max_len = 0;
339 ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
340 if (static_cast<int>(len) > max_len) {
341 ASSERT(false);
342 len = max_len;
343 }
344 strncpy(hashedName, it->second.c_str(), len);
345 // To be on the safe side in case the source is longer than expected.
346 hashedName[len] = '\0';
347}