void Shader::parseVaryings(void *compiler) { if (!mHlsl.empty()) { std::vector<Varying> *activeVaryings; ShGetInfoPointer(compiler, SH_ACTIVE_VARYINGS_ARRAY, reinterpret_cast<void**>(&activeVaryings)); for (size_t varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++) { mVaryings.push_back(PackedVarying((*activeVaryings)[varyingIndex])); } mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT") != std::string::npos; mUsesFragColor = mHlsl.find("GL_USES_FRAG_COLOR") != std::string::npos; mUsesFragData = mHlsl.find("GL_USES_FRAG_DATA") != std::string::npos; mUsesFragCoord = mHlsl.find("GL_USES_FRAG_COORD") != std::string::npos; mUsesFrontFacing = mHlsl.find("GL_USES_FRONT_FACING") != std::string::npos; mUsesPointSize = mHlsl.find("GL_USES_POINT_SIZE") != std::string::npos; mUsesPointCoord = mHlsl.find("GL_USES_POINT_COORD") != std::string::npos; mUsesDepthRange = mHlsl.find("GL_USES_DEPTH_RANGE") != std::string::npos; mUsesFragDepth = mHlsl.find("GL_USES_FRAG_DEPTH") != std::string::npos; mUsesDiscardRewriting = mHlsl.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; mUsesNestedBreak = mHlsl.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; } }
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); } }
void VertexShader::parseAttributes() { const std::string &hlsl = getHLSL(); if (!hlsl.empty()) { void *activeAttributes; ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes); mActiveAttributes = *(std::vector<Attribute>*)activeAttributes; } }
void FragmentShader::compile() { uncompile(); compileToHLSL(mFragmentCompiler); parseVaryings(mFragmentCompiler); std::sort(mVaryings.begin(), mVaryings.end(), compareVarying); const std::string &hlsl = getHLSL(); if (!hlsl.empty()) { void *activeOutputVariables; ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables); mActiveOutputVariables = *(std::vector<Attribute>*)activeOutputVariables; } }
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()); } }