blob: bab6423d59957a3a5a8c2e22ff467109c759e394 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
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//
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"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000015#include "compiler/ShHandle.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000017//
18// This is the platform independent interface between an OGL driver
alokp@chromium.org774d7062010-07-21 18:55:45 +000019// and the shading language compiler.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020//
21
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000022static 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
34static void getVariableInfo(EShInfo varType,
35 const ShHandle handle,
36 int index,
37 int* length,
38 int* size,
39 EShDataType* 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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000064//
65// Driver must call this first, once, before doing any other
alokp@chromium.org774d7062010-07-21 18:55:45 +000066// compiler operations.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000067//
68int ShInitialize()
69{
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000070 if (!InitProcess())
71 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000073 return 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000074}
75
76//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000077// Cleanup symbol tables
78//
79int 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//
90void ShInitBuiltInResource(TBuiltInResource* 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//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000107// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108//
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000109ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110{
111 if (!InitThread())
112 return 0;
113
alokp@chromium.org29cd91a2010-07-16 19:30:45 +0000114 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000115 TCompiler* compiler = base->getAsCompiler();
116 if (compiler == 0)
117 return 0;
118
119 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000120 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000121 ShDestruct(base);
122 return 0;
123 }
124
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000125 return reinterpret_cast<void*>(base);
126}
127
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000128void ShDestruct(ShHandle handle)
129{
130 if (handle == 0)
131 return;
132
133 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
134
135 if (base->getAsCompiler())
136 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137}
138
139//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140// Do an actual compile on the given strings. The result is left
141// in the given compile object.
142//
143// Return: The return value of ShCompile is really boolean, indicating
144// success or failure.
145//
146int ShCompile(
147 const ShHandle handle,
148 const char* const shaderStrings[],
149 const int numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000150 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151{
152 if (!InitThread())
153 return 0;
154
155 if (handle == 0)
156 return 0;
157
158 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
159 TCompiler* compiler = base->getAsCompiler();
160 if (compiler == 0)
161 return 0;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000162
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000163 GlobalPoolAllocator.push();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164
alokp@chromium.org07620a52010-09-23 17:53:56 +0000165 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167 //
168 // Throw away all the temporary memory used by the compilation process.
169 //
170 GlobalPoolAllocator.pop();
171
172 return success ? 1 : 0;
173}
174
alokp@chromium.org7beea402010-09-15 21:18:34 +0000175void ShGetInfo(const ShHandle handle, EShInfo pname, int* params)
176{
177 if (!handle || !params)
178 return;
179
180 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
181 TCompiler* compiler = base->getAsCompiler();
182 if (!compiler) return;
183
184 switch(pname)
185 {
186 case SH_INFO_LOG_LENGTH:
187 *params = compiler->getInfoSink().info.size() + 1;
188 break;
189 case SH_OBJECT_CODE_LENGTH:
190 *params = compiler->getInfoSink().obj.size() + 1;
191 break;
192 case SH_ACTIVE_UNIFORMS:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000193 *params = compiler->getUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000194 break;
195 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000196 *params = getVariableMaxLength(compiler->getUniforms());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000197 break;
198 case SH_ACTIVE_ATTRIBUTES:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000199 *params = compiler->getAttribs().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000200 break;
201 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000202 *params = getVariableMaxLength(compiler->getAttribs());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000203 break;
204
205 default: UNREACHABLE();
206 }
207}
208
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000210// Return any compiler log of messages for the application.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000212void ShGetInfoLog(const ShHandle handle, char* infoLog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000213{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000214 if (!handle || !infoLog)
215 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000216
217 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000218 TCompiler* compiler = base->getAsCompiler();
219 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000220
alokp@chromium.org7beea402010-09-15 21:18:34 +0000221 TInfoSink& infoSink = compiler->getInfoSink();
222 strcpy(infoLog, infoSink.info.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223}
224
225//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000226// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000228void ShGetObjectCode(const ShHandle handle, char* objCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000229{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000230 if (!handle || !objCode)
231 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000232
233 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000234 TCompiler* compiler = base->getAsCompiler();
235 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236
alokp@chromium.org7beea402010-09-15 21:18:34 +0000237 TInfoSink& infoSink = compiler->getInfoSink();
238 strcpy(objCode, infoSink.obj.c_str());
239}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000240
alokp@chromium.org7beea402010-09-15 21:18:34 +0000241void ShGetActiveAttrib(const ShHandle handle,
242 int index,
243 int* length,
244 int* size,
245 EShDataType* type,
246 char* name)
247{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000248 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
249 handle, index, length, size, type, name);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000250}
251
252void ShGetActiveUniform(const ShHandle handle,
253 int index,
254 int* length,
255 int* size,
256 EShDataType* type,
257 char* name)
258{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000259 getVariableInfo(SH_ACTIVE_UNIFORMS,
260 handle, index, length, size, type, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000261}
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000262