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 22static 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(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// 68int ShInitialize() 69{ 70 if (!InitProcess()) 71 return 0; 72 73 return 1; 74} 75 76// 77// 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 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// 109ShHandle 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 129void 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// 147int 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 168void 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// 205void 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// 221void 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 234void 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 245void 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