blob: c5eaf30071f8b02533afa275e1edda05bc6dcdf4 [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
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000034static void getVariableInfo(ShShaderInfo varType,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000035 const ShHandle handle,
36 int index,
37 int* length,
38 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000039 ShDataType* type,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000040 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//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000090void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000091{
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.org4888ceb2010-10-01 21:13:12 +0000109ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
110 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111{
112 if (!InitThread())
113 return 0;
114
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000115 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000116 TCompiler* compiler = base->getAsCompiler();
117 if (compiler == 0)
118 return 0;
119
120 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000121 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000122 ShDestruct(base);
123 return 0;
124 }
125
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000126 return reinterpret_cast<void*>(base);
127}
128
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000129void 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());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138}
139
140//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141// 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//
147int ShCompile(
148 const ShHandle handle,
149 const char* const shaderStrings[],
150 const int numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000151 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152{
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;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164 GlobalPoolAllocator.push();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000165
alokp@chromium.org07620a52010-09-23 17:53:56 +0000166 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000168 //
169 // Throw away all the temporary memory used by the compilation process.
170 //
171 GlobalPoolAllocator.pop();
172
173 return success ? 1 : 0;
174}
175
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000176void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000177{
178 if (!handle || !params)
179 return;
180
181 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
182 TCompiler* compiler = base->getAsCompiler();
183 if (!compiler) return;
184
185 switch(pname)
186 {
187 case SH_INFO_LOG_LENGTH:
188 *params = compiler->getInfoSink().info.size() + 1;
189 break;
190 case SH_OBJECT_CODE_LENGTH:
191 *params = compiler->getInfoSink().obj.size() + 1;
192 break;
193 case SH_ACTIVE_UNIFORMS:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000194 *params = compiler->getUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000195 break;
196 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000197 *params = getVariableMaxLength(compiler->getUniforms());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000198 break;
199 case SH_ACTIVE_ATTRIBUTES:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000200 *params = compiler->getAttribs().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000201 break;
202 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000203 *params = getVariableMaxLength(compiler->getAttribs());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000204 break;
205
206 default: UNREACHABLE();
207 }
208}
209
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000211// Return any compiler log of messages for the application.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000212//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000213void ShGetInfoLog(const ShHandle handle, char* infoLog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000215 if (!handle || !infoLog)
216 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000217
218 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000219 TCompiler* compiler = base->getAsCompiler();
220 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000221
alokp@chromium.org7beea402010-09-15 21:18:34 +0000222 TInfoSink& infoSink = compiler->getInfoSink();
223 strcpy(infoLog, infoSink.info.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000224}
225
226//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000227// Return any object code.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228//
alokp@chromium.org7beea402010-09-15 21:18:34 +0000229void ShGetObjectCode(const ShHandle handle, char* objCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000230{
alokp@chromium.org7beea402010-09-15 21:18:34 +0000231 if (!handle || !objCode)
232 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233
234 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000235 TCompiler* compiler = base->getAsCompiler();
236 if (!compiler) return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237
alokp@chromium.org7beea402010-09-15 21:18:34 +0000238 TInfoSink& infoSink = compiler->getInfoSink();
239 strcpy(objCode, infoSink.obj.c_str());
240}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000241
alokp@chromium.org7beea402010-09-15 21:18:34 +0000242void ShGetActiveAttrib(const ShHandle handle,
243 int index,
244 int* length,
245 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000246 ShDataType* type,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000247 char* name)
248{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000249 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
250 handle, index, length, size, type, name);
alokp@chromium.org7beea402010-09-15 21:18:34 +0000251}
252
253void ShGetActiveUniform(const ShHandle handle,
254 int index,
255 int* length,
256 int* size,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000257 ShDataType* type,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000258 char* name)
259{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000260 getVariableInfo(SH_ACTIVE_UNIFORMS,
261 handle, index, length, size, type, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000262}
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000263