blob: 65a4d9b870c4a4c588c46fb9f58fe39d02443afc [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,
zmo@google.comfd747b82011-04-23 01:30:07 +000040 char* name,
41 char* mappedName)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000042{
43 if (!handle || !size || !type || !name)
44 return;
45 ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
46 (varType == SH_ACTIVE_UNIFORMS));
47
48 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
49 TCompiler* compiler = base->getAsCompiler();
50 if (compiler == 0)
51 return;
52
53 const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
54 compiler->getAttribs() : compiler->getUniforms();
55 if (index < 0 || index >= static_cast<int>(varList.size()))
56 return;
57
58 const TVariableInfo& varInfo = varList[index];
59 if (length) *length = varInfo.name.size();
60 *size = varInfo.size;
61 *type = varInfo.type;
62 strcpy(name, varInfo.name.c_str());
zmo@google.comfd747b82011-04-23 01:30:07 +000063 if (mappedName)
64 strcpy(mappedName, varInfo.mappedName.c_str());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000065}
66
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000067//
68// Driver must call this first, once, before doing any other
alokp@chromium.org774d7062010-07-21 18:55:45 +000069// compiler operations.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070//
71int ShInitialize()
72{
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000073 if (!InitProcess())
74 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075
alokp@chromium.org34b99cd2010-07-27 18:37:55 +000076 return 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000077}
78
79//
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000080// Cleanup symbol tables
81//
82int ShFinalize()
83{
84 if (!DetachProcess())
85 return 0;
86
87 return 1;
88}
89
90//
91// Initialize built-in resources with minimum expected values.
92//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000093void ShInitBuiltInResources(ShBuiltInResources* resources)
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000094{
95 // Constants.
96 resources->MaxVertexAttribs = 8;
97 resources->MaxVertexUniformVectors = 128;
98 resources->MaxVaryingVectors = 8;
99 resources->MaxVertexTextureImageUnits = 0;
100 resources->MaxCombinedTextureImageUnits = 8;
101 resources->MaxTextureImageUnits = 8;
102 resources->MaxFragmentUniformVectors = 16;
103 resources->MaxDrawBuffers = 1;
104
105 // Extensions.
106 resources->OES_standard_derivatives = 0;
zmo@google.com09c323a2011-08-12 18:22:25 +0000107 resources->OES_EGL_image_external = 0;
alokp@chromium.org94a86ad2010-08-25 20:02:11 +0000108}
109
110//
alokp@chromium.org774d7062010-07-21 18:55:45 +0000111// Driver calls these to create and destroy compiler objects.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112//
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000113ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
zmo@google.com5601ea02011-06-10 18:23:25 +0000114 ShShaderOutput output,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000115 const ShBuiltInResources* resources)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000116{
117 if (!InitThread())
118 return 0;
119
zmo@google.com5601ea02011-06-10 18:23:25 +0000120 TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000121 TCompiler* compiler = base->getAsCompiler();
122 if (compiler == 0)
123 return 0;
124
125 // Generate built-in symbol table.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000126 if (!compiler->Init(*resources)) {
alokp@chromium.orge4249f02010-07-26 18:13:52 +0000127 ShDestruct(base);
128 return 0;
129 }
130
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131 return reinterpret_cast<void*>(base);
132}
133
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000134void ShDestruct(ShHandle handle)
135{
136 if (handle == 0)
137 return;
138
139 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
140
141 if (base->getAsCompiler())
142 DeleteCompiler(base->getAsCompiler());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143}
144
145//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000146// Do an actual compile on the given strings. The result is left
147// in the given compile object.
148//
149// Return: The return value of ShCompile is really boolean, indicating
150// success or failure.
151//
152int ShCompile(
153 const ShHandle handle,
154 const char* const shaderStrings[],
155 const int numStrings,
alokp@chromium.org7beea402010-09-15 21:18:34 +0000156 int compileOptions)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157{
158 if (!InitThread())
159 return 0;
160
161 if (handle == 0)
162 return 0;
163
164 TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
165 TCompiler* compiler = base->getAsCompiler();
166 if (compiler == 0)
167 return 0;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000168
alokp@chromium.org07620a52010-09-23 17:53:56 +0000169 bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000170 return success ? 1 : 0;
171}
172
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000173void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000174{
175 if (!handle || !params)
176 return;
177
178 TShHandleBase* base = static_cast<TShHandleBase*>(handle);
179 TCompiler* compiler = base->getAsCompiler();
180 if (!compiler) return;
181
182 switch(pname)
183 {
184 case SH_INFO_LOG_LENGTH:
185 *params = compiler->getInfoSink().info.size() + 1;
186 break;
187 case SH_OBJECT_CODE_LENGTH:
188 *params = compiler->getInfoSink().obj.size() + 1;
189 break;
190 case SH_ACTIVE_UNIFORMS:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000191 *params = compiler->getUniforms().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000192 break;
193 case SH_ACTIVE_UNIFORM_MAX_LENGTH:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000194 *params = getVariableMaxLength(compiler->getUniforms());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000195 break;
196 case SH_ACTIVE_ATTRIBUTES:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000197 *params = compiler->getAttribs().size();
alokp@chromium.org7beea402010-09-15 21:18:34 +0000198 break;
199 case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000200 *params = getVariableMaxLength(compiler->getAttribs());
alokp@chromium.org7beea402010-09-15 21:18:34 +0000201 break;
zmo@google.comfd747b82011-04-23 01:30:07 +0000202 case SH_MAPPED_NAME_MAX_LENGTH:
203 *params = compiler->getMappedNameMaxLength();
204 break;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000205 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,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000245 ShDataType* type,
zmo@google.comfd747b82011-04-23 01:30:07 +0000246 char* name,
247 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000248{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000249 getVariableInfo(SH_ACTIVE_ATTRIBUTES,
zmo@google.comfd747b82011-04-23 01:30:07 +0000250 handle, index, length, size, type, name, mappedName);
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,
zmo@google.comfd747b82011-04-23 01:30:07 +0000258 char* name,
259 char* mappedName)
alokp@chromium.org7beea402010-09-15 21:18:34 +0000260{
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000261 getVariableInfo(SH_ACTIVE_UNIFORMS,
zmo@google.comfd747b82011-04-23 01:30:07 +0000262 handle, index, length, size, type, name, mappedName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263}