1 //
2 // Copyright (c) 2002-2010 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/ShHandle.h"
16
17 //
18 // This is the platform independent interface between an OGL driver
19 // and the shading language compiler.
20 //
21
getVariableMaxLength(const TVariableInfoList & varList)22 static int getVariableMaxLength(const TVariableInfoList& varList)
23 {
24 TString::size_type maxLen = 0;
25 for (TVariableInfoList::const_iterator i = varList.begin();
26 i != varList.end(); ++i)
27 {
28 maxLen = std::max(maxLen, i->name.size());
29 }
30 // Add 1 to include null-termination character.
31 return static_cast<int>(maxLen) + 1;
32 }
33
getVariableInfo(ShShaderInfo varType,const ShHandle handle,int index,int * length,int * size,ShDataType * type,char * name)34 static void getVariableInfo(ShShaderInfo varType,
35 const ShHandle handle,
36 int index,
37 int* length,
38 int* size,
39 ShDataType* type,
40 char* name)
41 {
42 if (!handle || !size || !type || !name)
43 return;
44 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
45 (varType == SH_ACTIVE_UNIFORMS));
46
47 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
48 TCompiler* compiler = base->getAsCompiler();
49 if (compiler == 0)
50 return;
51
52 const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
53 compiler->getAttribs() : compiler->getUniforms();
54 if (index < 0 || index >= static_cast<int>(varList.size()))
55 return;
56
57 const TVariableInfo& varInfo = varList[index];
58 if (length) *length = varInfo.name.size();
59 *size = varInfo.size;
60 *type = varInfo.type;
61 strcpy(name, varInfo.name.c_str());
62 }
63
64 //
65 // Driver must call this first, once, before doing any other
66 // compiler operations.
67 //
ShInitialize()68 int ShInitialize()
69 {
70 if (!InitProcess())
71 return 0;
72
73 return 1;
74 }
75
76 //
77 // Cleanup symbol tables
78 //
ShFinalize()79 int ShFinalize()
80 {
81 if (!DetachProcess())
82 return 0;
83
84 return 1;
85 }
86
87 //
88 // Initialize built-in resources with minimum expected values.
89 //
ShInitBuiltInResources(ShBuiltInResources * resources)90 void ShInitBuiltInResources(ShBuiltInResources* resources)
91 {
92 // Constants.
93 resources->MaxVertexAttribs = 8;
94 resources->MaxVertexUniformVectors = 128;
95 resources->MaxVaryingVectors = 8;
96 resources->MaxVertexTextureImageUnits = 0;
97 resources->MaxCombinedTextureImageUnits = 8;
98 resources->MaxTextureImageUnits = 8;
99 resources->MaxFragmentUniformVectors = 16;
100 resources->MaxDrawBuffers = 1;
101
102 // Extensions.
103 resources->OES_standard_derivatives = 0;
104 }
105
106 //
107 // Driver calls these to create and destroy compiler objects.
108 //
ShConstructCompiler(ShShaderType type,ShShaderSpec spec,const ShBuiltInResources * resources)109 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
110 const ShBuiltInResources* resources)
111 {
112 if (!InitThread())
113 return 0;
114
115 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
116 TCompiler* compiler = base->getAsCompiler();
117 if (compiler == 0)
118 return 0;
119
120 // Generate built-in symbol table.
121 if (!compiler->Init(*resources)) {
122 ShDestruct(base);
123 return 0;
124 }
125
126 return reinterpret_cast<void*>(base);
127 }
128
ShDestruct(ShHandle handle)129 void ShDestruct(ShHandle handle)
130 {
131 if (handle == 0)
132 return;
133
134 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
135
136 if (base->getAsCompiler())
137 DeleteCompiler(base->getAsCompiler());
138 }
139
140 //
141 // Do an actual compile on the given strings. The result is left
142 // in the given compile object.
143 //
144 // Return: The return value of ShCompile is really boolean, indicating
145 // success or failure.
146 //
ShCompile(const ShHandle handle,const char * const shaderStrings[],const int numStrings,int compileOptions)147 int ShCompile(
148 const ShHandle handle,
149 const char* const shaderStrings[],
150 const int numStrings,
151 int compileOptions)
152 {
153 if (!InitThread())
154 return 0;
155
156 if (handle == 0)
157 return 0;
158
159 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
160 TCompiler* compiler = base->getAsCompiler();
161 if (compiler == 0)
162 return 0;
163
164 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
165 return success ? 1 : 0;
166 }
167
ShGetInfo(const ShHandle handle,ShShaderInfo pname,int * params)168 void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
169 {
170 if (!handle || !params)
171 return;
172
173 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
174 TCompiler* compiler = base->getAsCompiler();
175 if (!compiler) return;
176
177 switch(pname)
178 {
179 case SH_INFO_LOG_LENGTH:
180 *params = compiler->getInfoSink().info.size() + 1;
181 break;
182 case SH_OBJECT_CODE_LENGTH:
183 *params = compiler->getInfoSink().obj.size() + 1;
184 break;
185 case SH_ACTIVE_UNIFORMS:
186 *params = compiler->getUniforms().size();
187 break;
188 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
189 *params = getVariableMaxLength(compiler->getUniforms());
190 break;
191 case SH_ACTIVE_ATTRIBUTES:
192 *params = compiler->getAttribs().size();
193 break;
194 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
195 *params = getVariableMaxLength(compiler->getAttribs());
196 break;
197
198 default: UNREACHABLE();
199 }
200 }
201
202 //
203 // Return any compiler log of messages for the application.
204 //
ShGetInfoLog(const ShHandle handle,char * infoLog)205 void ShGetInfoLog(const ShHandle handle, char* infoLog)
206 {
207 if (!handle || !infoLog)
208 return;
209
210 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
211 TCompiler* compiler = base->getAsCompiler();
212 if (!compiler) return;
213
214 TInfoSink& infoSink = compiler->getInfoSink();
215 strcpy(infoLog, infoSink.info.c_str());
216 }
217
218 //
219 // Return any object code.
220 //
ShGetObjectCode(const ShHandle handle,char * objCode)221 void ShGetObjectCode(const ShHandle handle, char* objCode)
222 {
223 if (!handle || !objCode)
224 return;
225
226 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
227 TCompiler* compiler = base->getAsCompiler();
228 if (!compiler) return;
229
230 TInfoSink& infoSink = compiler->getInfoSink();
231 strcpy(objCode, infoSink.obj.c_str());
232 }
233
ShGetActiveAttrib(const ShHandle handle,int index,int * length,int * size,ShDataType * type,char * name)234 void ShGetActiveAttrib(const ShHandle handle,
235 int index,
236 int* length,
237 int* size,
238 ShDataType* type,
239 char* name)
240 {
241 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
242 handle, index, length, size, type, name);
243 }
244
ShGetActiveUniform(const ShHandle handle,int index,int * length,int * size,ShDataType * type,char * name)245 void ShGetActiveUniform(const ShHandle handle,
246 int index,
247 int* length,
248 int* size,
249 ShDataType* type,
250 char* name)
251 {
252 getVariableInfo(SH_ACTIVE_UNIFORMS,
253 handle, index, length, size, type, name);
254 }
255