// // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // // Implement the top-level of interface to the compiler, // as defined in ShaderLang.h // #include "GLSLANG/ShaderLang.h" #include "compiler/InitializeDll.h" #include "compiler/ShHandle.h" // // This is the platform independent interface between an OGL driver // and the shading language compiler. // static int getVariableMaxLength(const TVariableInfoList& varList) { TString::size_type maxLen = 0; for (TVariableInfoList::const_iterator i = varList.begin(); i != varList.end(); ++i) { maxLen = std::max(maxLen, i->name.size()); } // Add 1 to include null-termination character. return static_cast(maxLen) + 1; } static void getVariableInfo(ShShaderInfo varType, const ShHandle handle, int index, int* length, int* size, ShDataType* type, char* name) { if (!handle || !size || !type || !name) return; ASSERT((varType == SH_ACTIVE_ATTRIBUTES) || (varType == SH_ACTIVE_UNIFORMS)); TShHandleBase* base = reinterpret_cast(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return; const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() : compiler->getUniforms(); if (index < 0 || index >= static_cast(varList.size())) return; const TVariableInfo& varInfo = varList[index]; if (length) *length = varInfo.name.size(); *size = varInfo.size; *type = varInfo.type; strcpy(name, varInfo.name.c_str()); } // // Driver must call this first, once, before doing any other // compiler operations. // int ShInitialize() { if (!InitProcess()) return 0; return 1; } // // Cleanup symbol tables // int ShFinalize() { if (!DetachProcess()) return 0; return 1; } // // Initialize built-in resources with minimum expected values. // void ShInitBuiltInResources(ShBuiltInResources* resources) { // Constants. resources->MaxVertexAttribs = 8; resources->MaxVertexUniformVectors = 128; resources->MaxVaryingVectors = 8; resources->MaxVertexTextureImageUnits = 0; resources->MaxCombinedTextureImageUnits = 8; resources->MaxTextureImageUnits = 8; resources->MaxFragmentUniformVectors = 16; resources->MaxDrawBuffers = 1; // Extensions. resources->OES_standard_derivatives = 0; } // // Driver calls these to create and destroy compiler objects. // ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources* resources) { if (!InitThread()) return 0; TShHandleBase* base = static_cast(ConstructCompiler(type, spec)); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; // Generate built-in symbol table. if (!compiler->Init(*resources)) { ShDestruct(base); return 0; } return reinterpret_cast(base); } void ShDestruct(ShHandle handle) { if (handle == 0) return; TShHandleBase* base = static_cast(handle); if (base->getAsCompiler()) DeleteCompiler(base->getAsCompiler()); } // // Do an actual compile on the given strings. The result is left // in the given compile object. // // Return: The return value of ShCompile is really boolean, indicating // success or failure. // int ShCompile( const ShHandle handle, const char* const shaderStrings[], const int numStrings, int compileOptions) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; bool success = compiler->compile(shaderStrings, numStrings, compileOptions); return success ? 1 : 0; } void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params) { if (!handle || !params) return; TShHandleBase* base = static_cast(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; switch(pname) { case SH_INFO_LOG_LENGTH: *params = compiler->getInfoSink().info.size() + 1; break; case SH_OBJECT_CODE_LENGTH: *params = compiler->getInfoSink().obj.size() + 1; break; case SH_ACTIVE_UNIFORMS: *params = compiler->getUniforms().size(); break; case SH_ACTIVE_UNIFORM_MAX_LENGTH: *params = getVariableMaxLength(compiler->getUniforms()); break; case SH_ACTIVE_ATTRIBUTES: *params = compiler->getAttribs().size(); break; case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = getVariableMaxLength(compiler->getAttribs()); break; default: UNREACHABLE(); } } // // Return any compiler log of messages for the application. // void ShGetInfoLog(const ShHandle handle, char* infoLog) { if (!handle || !infoLog) return; TShHandleBase* base = static_cast(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; TInfoSink& infoSink = compiler->getInfoSink(); strcpy(infoLog, infoSink.info.c_str()); } // // Return any object code. // void ShGetObjectCode(const ShHandle handle, char* objCode) { if (!handle || !objCode) return; TShHandleBase* base = static_cast(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; TInfoSink& infoSink = compiler->getInfoSink(); strcpy(objCode, infoSink.obj.c_str()); } void ShGetActiveAttrib(const ShHandle handle, int index, int* length, int* size, ShDataType* type, char* name) { getVariableInfo(SH_ACTIVE_ATTRIBUTES, handle, index, length, size, type, name); } void ShGetActiveUniform(const ShHandle handle, int index, int* length, int* size, ShDataType* type, char* name) { getVariableInfo(SH_ACTIVE_UNIFORMS, handle, index, length, size, type, name); }