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 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 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 // 68 int ShInitialize() 69 { 70 if (!InitProcess()) 71 return 0; 72 73 return 1; 74 } 75 76 // 77 // Cleanup symbol tables 78 // 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 // 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 // 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 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 // 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 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 // 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 // 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 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 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