1 : //
2 : // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
3 : // Use of this source code is governed by a BSD-style license that can be
4 : // found in the LICENSE file.
5 : //
6 :
7 : //
8 : // Implement the top-level of interface to the compiler,
9 : // as defined in ShaderLang.h
10 : //
11 :
12 : #include "GLSLANG/ShaderLang.h"
13 :
14 : #include "compiler/InitializeDll.h"
15 : #include "compiler/preprocessor/length_limits.h"
16 : #include "compiler/ShHandle.h"
17 :
18 : //
19 : // This is the platform independent interface between an OGL driver
20 : // and the shading language compiler.
21 : //
22 :
23 0 : static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
24 : int expectedValue)
25 : {
26 0 : int activeUniformLimit = 0;
27 0 : ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
28 0 : int activeAttribLimit = 0;
29 0 : ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
30 0 : return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
31 : }
32 :
33 0 : static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
34 : {
35 0 : int mappedNameMaxLength = 0;
36 0 : ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
37 0 : return (expectedValue == mappedNameMaxLength);
38 : }
39 :
40 0 : static void getVariableInfo(ShShaderInfo varType,
41 : const ShHandle handle,
42 : int index,
43 : int* length,
44 : int* size,
45 : ShDataType* type,
46 : char* name,
47 : char* mappedName)
48 : {
49 0 : if (!handle || !size || !type || !name)
50 0 : return;
51 0 : ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
52 : (varType == SH_ACTIVE_UNIFORMS));
53 :
54 0 : TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
55 0 : TCompiler* compiler = base->getAsCompiler();
56 0 : if (compiler == 0)
57 0 : return;
58 :
59 : const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
60 0 : compiler->getAttribs() : compiler->getUniforms();
61 0 : if (index < 0 || index >= static_cast<int>(varList.size()))
62 0 : return;
63 :
64 0 : const TVariableInfo& varInfo = varList[index];
65 0 : if (length) *length = varInfo.name.size();
66 0 : *size = varInfo.size;
67 0 : *type = varInfo.type;
68 :
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 0 : int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
73 0 : ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
74 0 : strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
75 0 : if (mappedName) {
76 : // This size must match that queried by
77 : // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
78 0 : int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
79 0 : ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
80 0 : strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
81 : }
82 : }
83 :
84 : //
85 : // Driver must call this first, once, before doing any other
86 : // compiler operations.
87 : //
88 0 : int ShInitialize()
89 : {
90 0 : if (!InitProcess())
91 0 : return 0;
92 :
93 0 : return 1;
94 : }
95 :
96 : //
97 : // Cleanup symbol tables
98 : //
99 0 : int ShFinalize()
100 : {
101 0 : if (!DetachProcess())
102 0 : return 0;
103 :
104 0 : return 1;
105 : }
106 :
107 : //
108 : // Initialize built-in resources with minimum expected values.
109 : //
110 0 : void ShInitBuiltInResources(ShBuiltInResources* resources)
111 : {
112 : // Constants.
113 0 : resources->MaxVertexAttribs = 8;
114 0 : resources->MaxVertexUniformVectors = 128;
115 0 : resources->MaxVaryingVectors = 8;
116 0 : resources->MaxVertexTextureImageUnits = 0;
117 0 : resources->MaxCombinedTextureImageUnits = 8;
118 0 : resources->MaxTextureImageUnits = 8;
119 0 : resources->MaxFragmentUniformVectors = 16;
120 0 : resources->MaxDrawBuffers = 1;
121 :
122 : // Extensions.
123 0 : resources->OES_standard_derivatives = 0;
124 0 : resources->OES_EGL_image_external = 0;
125 0 : resources->ARB_texture_rectangle = 0;
126 0 : }
127 :
128 : //
129 : // Driver calls these to create and destroy compiler objects.
130 : //
131 0 : ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
132 : ShShaderOutput output,
133 : const ShBuiltInResources* resources)
134 : {
135 0 : if (!InitThread())
136 0 : return 0;
137 :
138 0 : TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
139 0 : TCompiler* compiler = base->getAsCompiler();
140 0 : if (compiler == 0)
141 0 : return 0;
142 :
143 : // Generate built-in symbol table.
144 0 : if (!compiler->Init(*resources)) {
145 0 : ShDestruct(base);
146 0 : return 0;
147 : }
148 :
149 0 : return reinterpret_cast<void*>(base);
150 : }
151 :
152 0 : void ShDestruct(ShHandle handle)
153 : {
154 0 : if (handle == 0)
155 0 : return;
156 :
157 0 : TShHandleBase* base = static_cast<TShHandleBase*>(handle);
158 :
159 0 : if (base->getAsCompiler())
160 0 : DeleteCompiler(base->getAsCompiler());
161 : }
162 :
163 : //
164 : // Do an actual compile on the given strings. The result is left
165 : // in the given compile object.
166 : //
167 : // Return: The return value of ShCompile is really boolean, indicating
168 : // success or failure.
169 : //
170 0 : int ShCompile(
171 : const ShHandle handle,
172 : const char* const shaderStrings[],
173 : const int numStrings,
174 : int compileOptions)
175 : {
176 0 : if (!InitThread())
177 0 : return 0;
178 :
179 0 : if (handle == 0)
180 0 : return 0;
181 :
182 0 : TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
183 0 : TCompiler* compiler = base->getAsCompiler();
184 0 : if (compiler == 0)
185 0 : return 0;
186 :
187 0 : bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
188 0 : return success ? 1 : 0;
189 : }
190 :
191 0 : void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
192 : {
193 0 : if (!handle || !params)
194 0 : return;
195 :
196 0 : TShHandleBase* base = static_cast<TShHandleBase*>(handle);
197 0 : TCompiler* compiler = base->getAsCompiler();
198 0 : if (!compiler) return;
199 :
200 0 : switch(pname)
201 : {
202 : case SH_INFO_LOG_LENGTH:
203 0 : *params = compiler->getInfoSink().info.size() + 1;
204 0 : break;
205 : case SH_OBJECT_CODE_LENGTH:
206 0 : *params = compiler->getInfoSink().obj.size() + 1;
207 0 : break;
208 : case SH_ACTIVE_UNIFORMS:
209 0 : *params = compiler->getUniforms().size();
210 0 : break;
211 : case SH_ACTIVE_UNIFORM_MAX_LENGTH:
212 0 : *params = 1 + MAX_SYMBOL_NAME_LEN;
213 0 : break;
214 : case SH_ACTIVE_ATTRIBUTES:
215 0 : *params = compiler->getAttribs().size();
216 0 : break;
217 : case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
218 0 : *params = 1 + MAX_SYMBOL_NAME_LEN;
219 0 : break;
220 : case SH_MAPPED_NAME_MAX_LENGTH:
221 : // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
222 : // handle array and struct dereferences.
223 0 : *params = 1 + MAX_SYMBOL_NAME_LEN;
224 0 : break;
225 0 : default: UNREACHABLE();
226 : }
227 : }
228 :
229 : //
230 : // Return any compiler log of messages for the application.
231 : //
232 0 : void ShGetInfoLog(const ShHandle handle, char* infoLog)
233 : {
234 0 : if (!handle || !infoLog)
235 0 : return;
236 :
237 0 : TShHandleBase* base = static_cast<TShHandleBase*>(handle);
238 0 : TCompiler* compiler = base->getAsCompiler();
239 0 : if (!compiler) return;
240 :
241 0 : TInfoSink& infoSink = compiler->getInfoSink();
242 0 : strcpy(infoLog, infoSink.info.c_str());
243 : }
244 :
245 : //
246 : // Return any object code.
247 : //
248 0 : void ShGetObjectCode(const ShHandle handle, char* objCode)
249 : {
250 0 : if (!handle || !objCode)
251 0 : return;
252 :
253 0 : TShHandleBase* base = static_cast<TShHandleBase*>(handle);
254 0 : TCompiler* compiler = base->getAsCompiler();
255 0 : if (!compiler) return;
256 :
257 0 : TInfoSink& infoSink = compiler->getInfoSink();
258 0 : strcpy(objCode, infoSink.obj.c_str());
259 : }
260 :
261 0 : void ShGetActiveAttrib(const ShHandle handle,
262 : int index,
263 : int* length,
264 : int* size,
265 : ShDataType* type,
266 : char* name,
267 : char* mappedName)
268 : {
269 : getVariableInfo(SH_ACTIVE_ATTRIBUTES,
270 0 : handle, index, length, size, type, name, mappedName);
271 0 : }
272 :
273 0 : void ShGetActiveUniform(const ShHandle handle,
274 : int index,
275 : int* length,
276 : int* size,
277 : ShDataType* type,
278 : char* name,
279 : char* mappedName)
280 : {
281 : getVariableInfo(SH_ACTIVE_UNIFORMS,
282 0 : handle, index, length, size, type, name, mappedName);
283 0 : }
|