void Shader::compileToHLSL(void *compiler) { if (isCompiled() || !mSource) { return; } TRACE("\n%s", mSource); delete[] mInfoLog; mInfoLog = NULL; int result = ShCompile(compiler, &mSource, 1, SH_OBJECT_CODE); if (result) { int objCodeLen = 0; ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); mHlsl = new char[objCodeLen]; ShGetObjectCode(compiler, mHlsl); TRACE("\n%s", mHlsl); } else { int infoLogLen = 0; ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); mInfoLog = new char[infoLogLen]; ShGetInfoLog(compiler, mInfoLog); TRACE("\n%s", mInfoLog); } }
void Shader::compileToHLSL(void *compiler) { // ensure we don't pass a NULL source to the compiler const char *source = "\0"; if (mSource) { source = mSource; } // ensure the compiler is loaded initializeCompiler(); int compileOptions = SH_OBJECT_CODE; std::string sourcePath; if (perfActive()) { sourcePath = ""; writeFile(sourcePath.c_str(), source, strlen(source)); compileOptions |= SH_LINE_DIRECTIVES; } int result; if (sourcePath.empty()) { result = ShCompile(compiler, &source, 1, compileOptions); } else { const char* sourceStrings[2] = { sourcePath.c_str(), source }; result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH); } if (result) { size_t objCodeLen = 0; ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); mHlsl = new char[objCodeLen]; ShGetObjectCode(compiler, mHlsl); void *activeUniforms; ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms); mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms; } else { size_t infoLogLen = 0; ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); mInfoLog = new char[infoLogLen]; ShGetInfoLog(compiler, mInfoLog); TRACE("\n%s", mInfoLog); } }
static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle, size_t expectedValue) { size_t activeUniformLimit = 0; ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit); size_t activeAttribLimit = 0; ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit); return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit); }
void Shader::compileToHLSL(void *compiler) { if (isCompiled() || !mSource) { return; } delete[] mInfoLog; mInfoLog = NULL; int compileOptions = SH_OBJECT_CODE; std::string sourcePath; if (perfActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), mSource, strlen(mSource)); compileOptions |= SH_LINE_DIRECTIVES; } int result; if (sourcePath.empty()) { result = ShCompile(compiler, &mSource, 1, compileOptions); } else { const char* sourceStrings[2] = { sourcePath.c_str(), mSource }; result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH); } if (result) { int objCodeLen = 0; ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); mHlsl = new char[objCodeLen]; ShGetObjectCode(compiler, mHlsl); } else { int infoLogLen = 0; ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); mInfoLog = new char[infoLogLen]; ShGetInfoLog(compiler, mInfoLog); TRACE("\n%s", mInfoLog); } }
bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog) { if (!builtCompilers) { m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, m_shaderOutput, &m_resources); m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, m_shaderOutput, &m_resources); if (!m_fragmentCompiler || !m_vertexCompiler) { cleanupCompilers(); return false; } builtCompilers = true; } ShHandle compiler; if (shaderType == SHADER_TYPE_VERTEX) compiler = m_vertexCompiler; else compiler = m_fragmentCompiler; const char* const shaderSourceStrings[] = { shaderSource }; bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE); if (!validateSuccess) { int logSize = 0; ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize); if (logSize > 1) { OwnArrayPtr<char> logBuffer = adoptArrayPtr(new char[logSize]); if (logBuffer) { ShGetInfoLog(compiler, logBuffer.get()); shaderValidationLog = logBuffer.get(); } } return false; } int translationLength = 0; ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &translationLength); if (translationLength > 1) { OwnArrayPtr<char> translationBuffer = adoptArrayPtr(new char[translationLength]); if (!translationBuffer) return false; ShGetObjectCode(compiler, translationBuffer.get()); translatedShaderSource = translationBuffer.get(); } return true; }
void ShGetNameHashingEntry(const ShHandle handle, int index, char* name, char* hashedName) { if (!handle || !name || !hashedName || index < 0) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; const NameMap& nameMap = compiler->getNameMap(); if (index >= static_cast<int>(nameMap.size())) return; NameMap::const_iterator it = nameMap.begin(); for (int i = 0; i < index; ++i) ++it; size_t len = it->first.length() + 1; size_t max_len = 0; ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len); if (len > max_len) { ASSERT(false); len = max_len; } strncpy(name, it->first.c_str(), len); // To be on the safe side in case the source is longer than expected. name[len - 1] = '\0'; len = it->second.length() + 1; max_len = 0; ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len); if (len > max_len) { ASSERT(false); len = max_len; } strncpy(hashedName, it->second.c_str(), len); // To be on the safe side in case the source is longer than expected. hashedName[len - 1] = '\0'; }
ShShaderOutput Shader::getCompilerOutputType(GLenum shader) { void *compiler = NULL; switch (shader) { case GL_VERTEX_SHADER: compiler = mVertexCompiler; break; case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break; default: UNREACHABLE(); return SH_HLSL9_OUTPUT; } size_t outputType = 0; ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType); return static_cast<ShShaderOutput>(outputType); }
int main(int argc, char* argv[]) { TFailCode failCode = ESuccess; int compileOptions = 0; int numCompiles = 0; ShHandle vertexCompiler = 0; ShHandle fragmentCompiler = 0; char* buffer = 0; int bufferLen = 0; int numAttribs = 0, numUniforms = 0; ShShaderSpec spec = SH_GLES2_SPEC; ShShaderOutput output = SH_ESSL_OUTPUT; ShInitialize(); ShBuiltInResources resources; GenerateResources(&resources); argc--; argv++; for (; (argc >= 1) && (failCode == ESuccess); argc--, argv++) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'i': compileOptions |= SH_INTERMEDIATE_TREE; break; case 'm': compileOptions |= SH_MAP_LONG_VARIABLE_NAMES; break; case 'o': compileOptions |= SH_OBJECT_CODE; break; case 'u': compileOptions |= SH_ATTRIBUTES_UNIFORMS; break; case 'l': compileOptions |= SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX; break; case 'e': compileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS; break; case 'd': compileOptions |= SH_DEPENDENCY_GRAPH; break; case 't': compileOptions |= SH_TIMING_RESTRICTIONS; break; case 's': if (argv[0][2] == '=') { switch (argv[0][3]) { case 'e': spec = SH_GLES2_SPEC; break; case 'w': spec = SH_WEBGL_SPEC; break; case 'c': spec = SH_CSS_SHADERS_SPEC; break; default: failCode = EFailUsage; } } else { failCode = EFailUsage; } break; case 'b': if (argv[0][2] == '=') { switch (argv[0][3]) { case 'e': output = SH_ESSL_OUTPUT; break; case 'g': output = SH_GLSL_OUTPUT; break; case 'h': output = SH_HLSL_OUTPUT; break; default: failCode = EFailUsage; } } else { failCode = EFailUsage; } break; case 'x': if (argv[0][2] == '=') { switch (argv[0][3]) { case 'i': resources.OES_EGL_image_external = 1; break; case 'd': resources.OES_standard_derivatives = 1; break; case 'r': resources.ARB_texture_rectangle = 1; break; default: failCode = EFailUsage; } } else { failCode = EFailUsage; } break; default: failCode = EFailUsage; } } else { ShHandle compiler = 0; switch (FindShaderType(argv[0])) { case SH_VERTEX_SHADER: if (vertexCompiler == 0) vertexCompiler = ShConstructCompiler( SH_VERTEX_SHADER, spec, output, &resources); compiler = vertexCompiler; break; case SH_FRAGMENT_SHADER: if (fragmentCompiler == 0) fragmentCompiler = ShConstructCompiler( SH_FRAGMENT_SHADER, spec, output, &resources); compiler = fragmentCompiler; break; default: break; } if (compiler) { bool compiled = CompileFile(argv[0], compiler, compileOptions); LogMsg("BEGIN", "COMPILER", numCompiles, "INFO LOG"); ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &bufferLen); buffer = (char*) realloc(buffer, bufferLen * sizeof(char)); ShGetInfoLog(compiler, buffer); puts(buffer); LogMsg("END", "COMPILER", numCompiles, "INFO LOG"); printf("\n\n"); if (compiled && (compileOptions & SH_OBJECT_CODE)) { LogMsg("BEGIN", "COMPILER", numCompiles, "OBJ CODE"); ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &bufferLen); buffer = (char*) realloc(buffer, bufferLen * sizeof(char)); ShGetObjectCode(compiler, buffer); puts(buffer); LogMsg("END", "COMPILER", numCompiles, "OBJ CODE"); printf("\n\n"); } if (compiled && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) { LogMsg("BEGIN", "COMPILER", numCompiles, "ACTIVE ATTRIBS"); PrintActiveVariables(compiler, SH_ACTIVE_ATTRIBUTES, (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) != 0); LogMsg("END", "COMPILER", numCompiles, "ACTIVE ATTRIBS"); printf("\n\n"); LogMsg("BEGIN", "COMPILER", numCompiles, "ACTIVE UNIFORMS"); PrintActiveVariables(compiler, SH_ACTIVE_UNIFORMS, (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) != 0); LogMsg("END", "COMPILER", numCompiles, "ACTIVE UNIFORMS"); printf("\n\n"); } if (!compiled) failCode = EFailCompile; ++numCompiles; } else { failCode = EFailCompilerCreate; } } } if ((vertexCompiler == 0) && (fragmentCompiler == 0)) failCode = EFailUsage; if (failCode == EFailUsage) usage(); if (vertexCompiler) ShDestruct(vertexCompiler); if (fragmentCompiler) ShDestruct(fragmentCompiler); if (buffer) free(buffer); ShFinalize(); return failCode; }
void PrintActiveVariables(ShHandle compiler, ShShaderInfo varType, bool mapLongVariableNames) { int nameSize = 0; switch (varType) { case SH_ACTIVE_ATTRIBUTES: ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameSize); break; case SH_ACTIVE_UNIFORMS: ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &nameSize); break; default: assert(0); } if (nameSize <= 1) return; char* name = new char[nameSize]; char* mappedName = NULL; if (mapLongVariableNames) { int mappedNameSize = 0; ShGetInfo(compiler, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameSize); mappedName = new char[mappedNameSize]; } int activeVars = 0, size = 0; ShDataType type = SH_NONE; const char* typeName = NULL; ShGetInfo(compiler, varType, &activeVars); for (int i = 0; i < activeVars; ++i) { switch (varType) { case SH_ACTIVE_ATTRIBUTES: ShGetActiveAttrib(compiler, i, NULL, &size, &type, name, mappedName); break; case SH_ACTIVE_UNIFORMS: ShGetActiveUniform(compiler, i, NULL, &size, &type, name, mappedName); break; default: assert(0); } switch (type) { case SH_FLOAT: typeName = "GL_FLOAT"; break; case SH_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break; case SH_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break; case SH_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break; case SH_INT: typeName = "GL_INT"; break; case SH_INT_VEC2: typeName = "GL_INT_VEC2"; break; case SH_INT_VEC3: typeName = "GL_INT_VEC3"; break; case SH_INT_VEC4: typeName = "GL_INT_VEC4"; break; case SH_BOOL: typeName = "GL_BOOL"; break; case SH_BOOL_VEC2: typeName = "GL_BOOL_VEC2"; break; case SH_BOOL_VEC3: typeName = "GL_BOOL_VEC3"; break; case SH_BOOL_VEC4: typeName = "GL_BOOL_VEC4"; break; case SH_FLOAT_MAT2: typeName = "GL_FLOAT_MAT2"; break; case SH_FLOAT_MAT3: typeName = "GL_FLOAT_MAT3"; break; case SH_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break; case SH_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break; case SH_SAMPLER_CUBE: typeName = "GL_SAMPLER_CUBE"; break; case SH_SAMPLER_EXTERNAL_OES: typeName = "GL_SAMPLER_EXTERNAL_OES"; break; default: assert(0); } printf("%d: name:%s type:%s size:%d", i, name, typeName, size); if (mapLongVariableNames) printf(" mapped name:%s", mappedName); printf("\n"); } delete [] name; if (mappedName) delete [] mappedName; }
static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue) { size_t mappedNameMaxLength = 0; ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength); return (expectedValue == mappedNameMaxLength); }
void Shader::compileToHLSL(void *compiler) { // ensure the compiler is loaded initializeCompiler(); int compileOptions = SH_OBJECT_CODE; std::string sourcePath; if (perfActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), mSource.c_str(), mSource.length()); compileOptions |= SH_LINE_DIRECTIVES; } int result; if (sourcePath.empty()) { const char* sourceStrings[] = { mSource.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); } else { const char* sourceStrings[] = { sourcePath.c_str(), mSource.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } size_t shaderVersion = 100; ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion); mShaderVersion = static_cast<int>(shaderVersion); if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3) { mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts"; TRACE("\n%s", mInfoLog.c_str()); } else if (result) { size_t objCodeLen = 0; ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); char* outputHLSL = new char[objCodeLen]; ShGetObjectCode(compiler, outputHLSL); #ifdef _DEBUG std::ostringstream hlslStream; hlslStream << "// GLSL\n"; hlslStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = mSource.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); hlslStream << "// " << mSource.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } hlslStream << "\n\n"; hlslStream << outputHLSL; mHlsl = hlslStream.str(); #else mHlsl = outputHLSL; #endif delete[] outputHLSL; void *activeUniforms; ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms); mActiveUniforms = *(std::vector<Uniform>*)activeUniforms; void *activeInterfaceBlocks; ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks); mActiveInterfaceBlocks = *(std::vector<InterfaceBlock>*)activeInterfaceBlocks; } else { size_t infoLogLen = 0; ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); char* infoLog = new char[infoLogLen]; ShGetInfoLog(compiler, infoLog); mInfoLog = infoLog; TRACE("\n%s", mInfoLog.c_str()); } }
void PrintActiveVariables(ShHandle compiler, ShShaderInfo varType) { size_t nameSize = 0; switch (varType) { case SH_ACTIVE_ATTRIBUTES: ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameSize); break; case SH_ACTIVE_UNIFORMS: ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &nameSize); break; default: assert(0); } if (nameSize <= 1) return; char* name = new char[nameSize]; size_t activeVars = 0; int size = 0; sh::GLenum type = GL_NONE; ShPrecisionType precision = SH_PRECISION_UNDEFINED; int staticUse = 0; const char* typeName = NULL; ShGetInfo(compiler, varType, &activeVars); for (size_t i = 0; i < activeVars; ++i) { switch (varType) { case SH_ACTIVE_ATTRIBUTES: ShGetVariableInfo(compiler, SH_ACTIVE_ATTRIBUTES, static_cast<int>(i), NULL, &size, &type, &precision, &staticUse, name, NULL); break; case SH_ACTIVE_UNIFORMS: ShGetVariableInfo(compiler, SH_ACTIVE_UNIFORMS, static_cast<int>(i), NULL, &size, &type, &precision, &staticUse, name, NULL); break; default: assert(0); } switch (type) { case GL_FLOAT: typeName = "GL_FLOAT"; break; case GL_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break; case GL_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break; case GL_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break; case GL_INT: typeName = "GL_INT"; break; case GL_INT_VEC2: typeName = "GL_INT_VEC2"; break; case GL_INT_VEC3: typeName = "GL_INT_VEC3"; break; case GL_INT_VEC4: typeName = "GL_INT_VEC4"; break; case GL_UNSIGNED_INT: typeName = "GL_UNSIGNED_INT"; break; case GL_UNSIGNED_INT_VEC2: typeName = "GL_UNSIGNED_INT_VEC2"; break; case GL_UNSIGNED_INT_VEC3: typeName = "GL_UNSIGNED_INT_VEC3"; break; case GL_UNSIGNED_INT_VEC4: typeName = "GL_UNSIGNED_INT_VEC4"; break; case GL_BOOL: typeName = "GL_BOOL"; break; case GL_BOOL_VEC2: typeName = "GL_BOOL_VEC2"; break; case GL_BOOL_VEC3: typeName = "GL_BOOL_VEC3"; break; case GL_BOOL_VEC4: typeName = "GL_BOOL_VEC4"; break; case GL_FLOAT_MAT2: typeName = "GL_FLOAT_MAT2"; break; case GL_FLOAT_MAT3: typeName = "GL_FLOAT_MAT3"; break; case GL_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break; case GL_FLOAT_MAT2x3: typeName = "GL_FLOAT_MAT2x3"; break; case GL_FLOAT_MAT3x2: typeName = "GL_FLOAT_MAT3x2"; break; case GL_FLOAT_MAT4x2: typeName = "GL_FLOAT_MAT4x2"; break; case GL_FLOAT_MAT2x4: typeName = "GL_FLOAT_MAT2x4"; break; case GL_FLOAT_MAT3x4: typeName = "GL_FLOAT_MAT3x4"; break; case GL_FLOAT_MAT4x3: typeName = "GL_FLOAT_MAT4x3"; break; case GL_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break; case GL_SAMPLER_CUBE: typeName = "GL_SAMPLER_CUBE"; break; case GL_SAMPLER_EXTERNAL_OES: typeName = "GL_SAMPLER_EXTERNAL_OES"; break; default: assert(0); } printf("%lu: name:%s type:%s size:%d\n", i, name, typeName, size); } delete [] name; }
inline static ANGLEGetInfoType getValidationResultValue(const ShHandle compiler, ShShaderInfo shaderInfo) { ANGLEGetInfoType value = 0; ShGetInfo(compiler, shaderInfo, &value); return value; }
inline static int getValidationResultValue(const ShHandle compiler, ShShaderInfo shaderInfo) { int value = -1; ShGetInfo(compiler, shaderInfo, &value); return value; }