/// Initializize the symbol table /// \param BuiltInStrings /// Pointer to built in strings. /// \param language /// Shading language to initialize symbol table for /// \param infoSink /// Information sink (for errors/warnings) /// \param symbolTables /// Array of symbol tables (one for each language) /// \param bUseGlobalSymbolTable /// Whether to use the global symbol table or the per-language symbol table /// \return /// True if succesfully initialized, false otherwise bool InitializeSymbolTable( TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, TSymbolTable* symbolTables, bool bUseGlobalSymbolTable ) { TIntermediate intermediate(infoSink); TSymbolTable* symbolTable; if ( bUseGlobalSymbolTable ) symbolTable = symbolTables; else symbolTable = &symbolTables[language]; TParseContext parseContext(*symbolTable, intermediate, language, infoSink); GlobalParseContext = &parseContext; setInitialState(); assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel()); // // Parse the built-ins. This should only happen once per // language symbol table. // // Push the symbol table to give it an initial scope. This // push should not have a corresponding pop, so that built-ins // are preserved, and the test for an empty table fails. // symbolTable->push(); //Initialize the Preprocessor int ret = InitPreprocessor(); if (ret) { infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor"); return false; } for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin(); i != BuiltInStrings[parseContext.language].end(); ++i) { const char* builtInShaders = (*i).c_str(); if (PaParseString(const_cast<char*>(builtInShaders), parseContext) != 0) { infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); return false; } } if ( !bUseGlobalSymbolTable ) { IdentifyBuiltIns(parseContext.language, *symbolTable); } FinalizePreprocessor(); return true; }
void operator()(Job &job, results &result) { map(job, result); intermediate(job, result); reduce(job, result); result.counters.actual_map_tasks = 1; result.counters.actual_reduce_tasks = 1; result.counters.num_result_files = job.number_of_partitions(); }
static bool InitializeSymbolTable( const TBuiltInStrings& builtInStrings, EShLanguage language, EShSpec spec, const TBuiltInResource& resources, TInfoSink& infoSink, TSymbolTable& symbolTable) { TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, intermediate, language, spec, infoSink); GlobalParseContext = &parseContext; setInitialState(); assert(symbolTable.isEmpty()); // // Parse the built-ins. This should only happen once per // language symbol table. // // Push the symbol table to give it an initial scope. This // push should not have a corresponding pop, so that built-ins // are preserved, and the test for an empty table fails. // symbolTable.push(); //Initialize the Preprocessor if (InitPreprocessor()) { infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor"); return false; } for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i) { const char* builtInShaders[1]; int builtInLengths[1]; builtInShaders[0] = (*i).c_str(); builtInLengths[0] = (int) (*i).size(); if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) { infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); return false; } } IdentifyBuiltIns(language, spec, resources, symbolTable); FinalizePreprocessor(); return true; }
QValidator::State KMimeTypeValidator::validate( QString &input, int& ) const { if ( input.isEmpty() ) return Intermediate; QRegExp acceptable( "[" ALLOWED_CHARS "]+/[" ALLOWED_CHARS "]+", Qt::CaseInsensitive ); if ( acceptable.exactMatch( input ) ) return Acceptable; QRegExp intermediate( "[" ALLOWED_CHARS "]*/?[" ALLOWED_CHARS "]*", Qt::CaseInsensitive ); if ( intermediate.exactMatch( input ) ) return Intermediate; return Invalid; }
double gsl_cdf_ugaussian_Pinv (const double P) { double r, x, pp; double dP = P - 0.5; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } if (fabs (dP) <= 0.425) { x = small (dP); return x; } pp = (P < 0.5) ? P : 1.0 - P; r = sqrt (-log (pp)); if (r <= 5.0) { x = intermediate (r); } else { x = tail (r); } if (P < 0.5) { return -x; } else { return x; } }
double gsl_cdf_ugaussian_Qinv (const double Q) { double r, x, pp; double dQ = Q - 0.5; if (Q == 1.0) { return GSL_NEGINF; } else if (Q == 0.0) { return GSL_POSINF; } if (fabs (dQ) <= 0.425) { x = small (dQ); return -x; } pp = (Q < 0.5) ? Q : 1.0 - Q; r = sqrt (-log (pp)); if (r <= 5.0) { x = intermediate (r); } else { x = tail (r); } if (Q < 0.5) { return x; } else { return -x; } }
// // Do a full compile on the given strings for a single compilation unit // forming a complete stage. The result of the machine dependent compilation // is left in the provided compile object. // // Return: The return value is really boolean, indicating // success (1) or failure (0). // int ShCompile( const ShHandle handle, const char* const shaderStrings[], const int numStrings, const int* inputLengths, const EShOptimizationLevel optLevel, const TBuiltInResource* resources, int /*debugOptions*/, int defaultVersion, // use 100 for ES environment, 110 for desktop bool forwardCompatible, // give errors for use of deprecated features EShMessages messages // warnings/errors/AST; things to print out ) { // Map the generic handle to the C++ object if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); TIntermediate intermediate(compiler->getLanguage()); bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, "", optLevel, resources, defaultVersion, ENoProfile, false, forwardCompatible, messages, intermediate); // // Call the machine dependent compiler // if (success && intermediate.getTreeRoot() && optLevel != EShOptNoGeneration) success = compiler->compile(intermediate.getTreeRoot(), intermediate.getVersion(), intermediate.getProfile()); intermediate.removeTree(); // Throw away all the temporary memory used by the compilation process. // The push was done in the CompileDeferred() call above. GetThreadPoolAllocator().pop(); return success ? 1 : 0; }
static void intermediate(register Ftw_t* ftw, register char* path) { register char* s; register char* t; register int c; if (!(ftw->info & FTW_D) || ftw->statb.st_nlink) { ftw->statb.st_nlink = 0; if (ftw->level > 1) intermediate(ftw->parent, path); s = path + ftw->pathlen; c = *s; *s = 0; t = ftw->path; ftw->path = path; act(ftw, state.actII); ftw->path = t; *s = c; } }
void BilinearFormUtility::computeStiffnessMatrix(FieldContainer<double> &stiffness, FieldContainer<double> &innerProductMatrix, FieldContainer<double> &optimalTestWeights) { // stiffness has dimensions (numCells, numTrialDofs, numTrialDofs) // innerProductMatrix has dim. (numCells, numTestDofs, numTestDofs) // optimalTestWeights has dim. (numCells, numTrialDofs, numTestDofs) // all this does is computes stiffness = weights^T * innerProductMatrix * weights int numCells = stiffness.dimension(0); int numTrialDofs = stiffness.dimension(1); int numTestDofs = innerProductMatrix.dimension(1); // check that all the dimensions are compatible: TEUCHOS_TEST_FOR_EXCEPTION( ( optimalTestWeights.dimension(0) != numCells ), std::invalid_argument, "stiffness.dimension(0) and optimalTestWeights.dimension(0) (numCells) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( optimalTestWeights.dimension(1) != numTrialDofs ), std::invalid_argument, "numTrialDofs and optimalTestWeights.dimension(1) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( optimalTestWeights.dimension(2) != numTestDofs ), std::invalid_argument, "numTestDofs and optimalTestWeights.dimension(2) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( innerProductMatrix.dimension(2) != innerProductMatrix.dimension(1) ), std::invalid_argument, "innerProductMatrix.dimension(1) and innerProductMatrix.dimension(2) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( stiffness.dimension(1) != stiffness.dimension(2) ), std::invalid_argument, "stiffness.dimension(1) and stiffness.dimension(2) do not match."); stiffness.initialize(0); for (int cellIndex=0; cellIndex < numCells; cellIndex++) { Epetra_SerialDenseMatrix weightsT(Copy, &optimalTestWeights(cellIndex,0,0), optimalTestWeights.dimension(2), // stride optimalTestWeights.dimension(2),optimalTestWeights.dimension(1)); Epetra_SerialDenseMatrix ipMatrixT(Copy, &innerProductMatrix(cellIndex,0,0), innerProductMatrix.dimension(2), // stride innerProductMatrix.dimension(2),innerProductMatrix.dimension(1)); Epetra_SerialDenseMatrix stiffT (View, &stiffness(cellIndex,0,0), stiffness.dimension(2), // stride stiffness.dimension(2),stiffness.dimension(1)); Epetra_SerialDenseMatrix intermediate( numTrialDofs, numTestDofs ); // account for the fact that SDM is column-major and FC is row-major: // (weightsT) * (ipMatrixT)^T * (weightsT)^T int success = intermediate.Multiply('T','T',1.0,weightsT,ipMatrixT,0.0); if (success != 0) { cout << "computeStiffnessMatrix: intermediate.Multiply() failed with error code " << success << endl; } success = stiffT.Multiply('N','N',1.0,intermediate,weightsT,0.0); // stiffT is technically the transpose of stiffness, but the construction A^T * B * A is symmetric even in general... if (success != 0) { cout << "computeStiffnessMatrix: stiffT.Multiply() failed with error code " << success << endl; } } if ( ! checkForZeroRowsAndColumns("stiffness",stiffness) ) { //cout << "stiffness: " << stiffness; } bool enforceNumericalSymmetry = false; if (enforceNumericalSymmetry) { for (unsigned int c=0; c < numCells; c++) for (unsigned int i=0; i < numTrialDofs; i++) for (unsigned int j=i+1; j < numTrialDofs; j++) { stiffness(c,i,j) = (stiffness(c,i,j) + stiffness(c,j,i)) / 2.0; stiffness(c,j,i) = stiffness(c,i,j); } } }
void Evaluator::multiply(const uint64_t *encrypted1, const uint64_t *encrypted2, uint64_t *destination) { // Extract encryption parameters. int coeff_count = poly_modulus_.coeff_count(); int coeff_bit_count = poly_modulus_.coeff_bit_count(); int coeff_uint64_count = divide_round_up(coeff_bit_count, bits_per_uint64); // Clear destatintion. set_zero_poly(coeff_count, coeff_uint64_count, destination); // Determine if FFT can be used. bool use_fft = polymod_.coeff_count_power_of_two() >= 0 && polymod_.is_one_zero_one(); if (use_fft) { // Use FFT to multiply polynomials. // Allocate polynomial to store product of two polynomials, with poly but no coeff modulo yet (and signed). int product_coeff_bit_count = coeff_bit_count + coeff_bit_count + get_significant_bit_count(static_cast<uint64_t>(coeff_count)) + 2; int product_coeff_uint64_count = divide_round_up(product_coeff_bit_count, bits_per_uint64); Pointer product(allocate_poly(coeff_count, product_coeff_uint64_count, pool_)); // Use FFT to multiply polynomials. set_zero_uint(product_coeff_uint64_count, get_poly_coeff(product.get(), coeff_count - 1, product_coeff_uint64_count)); fftmultiply_poly_poly_polymod(encrypted1, encrypted2, polymod_.coeff_count_power_of_two(), coeff_uint64_count, product_coeff_uint64_count, product.get(), pool_); // For each coefficient in product, multiply by plain_modulus and divide by coeff_modulus and then modulo by coeff_modulus. int plain_modulus_bit_count = plain_modulus_.significant_bit_count(); int plain_modulus_uint64_count = divide_round_up(plain_modulus_bit_count, bits_per_uint64); int intermediate_bit_count = product_coeff_bit_count + plain_modulus_bit_count - 1; int intermediate_uint64_count = divide_round_up(intermediate_bit_count, bits_per_uint64); Pointer intermediate(allocate_uint(intermediate_uint64_count, pool_)); Pointer quotient(allocate_uint(intermediate_uint64_count, pool_)); for (int coeff_index = 0; coeff_index < coeff_count; ++coeff_index) { uint64_t *product_coeff = get_poly_coeff(product.get(), coeff_index, product_coeff_uint64_count); bool coeff_is_negative = is_high_bit_set_uint(product_coeff, product_coeff_uint64_count); if (coeff_is_negative) { negate_uint(product_coeff, product_coeff_uint64_count, product_coeff); } multiply_uint_uint(product_coeff, product_coeff_uint64_count, plain_modulus_.pointer(), plain_modulus_uint64_count, intermediate_uint64_count, intermediate.get()); add_uint_uint(intermediate.get(), wide_coeff_modulus_div_two_.pointer(), intermediate_uint64_count, intermediate.get()); divide_uint_uint_inplace(intermediate.get(), wide_coeff_modulus_.pointer(), intermediate_uint64_count, quotient.get(), pool_); modulo_uint_inplace(quotient.get(), intermediate_uint64_count, mod_, pool_); uint64_t *dest_coeff = get_poly_coeff(destination, coeff_index, coeff_uint64_count); if (coeff_is_negative) { negate_uint_mod(quotient.get(), coeff_modulus_.pointer(), coeff_uint64_count, dest_coeff); } else { set_uint_uint(quotient.get(), coeff_uint64_count, dest_coeff); } } } else { // Use normal multiplication to multiply polynomials. // Allocate polynomial to store product of two polynomials, with no poly or coeff modulo yet. int product_coeff_count = coeff_count + coeff_count - 1; int product_coeff_bit_count = coeff_bit_count + coeff_bit_count + get_significant_bit_count(static_cast<uint64_t>(coeff_count)); int product_coeff_uint64_count = divide_round_up(product_coeff_bit_count, bits_per_uint64); Pointer product(allocate_poly(product_coeff_count, product_coeff_uint64_count, pool_)); // Multiply polynomials. multiply_poly_poly(encrypted1, coeff_count, coeff_uint64_count, encrypted2, coeff_count, coeff_uint64_count, product_coeff_count, product_coeff_uint64_count, product.get(), pool_); // For each coefficient in product, multiply by plain_modulus and divide by coeff_modulus and then modulo by coeff_modulus. int plain_modulus_bit_count = plain_modulus_.significant_bit_count(); int plain_modulus_uint64_count = divide_round_up(plain_modulus_bit_count, bits_per_uint64); int intermediate_bit_count = product_coeff_bit_count + plain_modulus_bit_count; int intermediate_uint64_count = divide_round_up(intermediate_bit_count, bits_per_uint64); Pointer intermediate(allocate_uint(intermediate_uint64_count, pool_)); Pointer quotient(allocate_uint(intermediate_uint64_count, pool_)); Pointer productmoded(allocate_poly(product_coeff_count, coeff_uint64_count, pool_)); for (int coeff_index = 0; coeff_index < product_coeff_count; ++coeff_index) { const uint64_t *product_coeff = get_poly_coeff(product.get(), coeff_index, product_coeff_uint64_count); multiply_uint_uint(product_coeff, product_coeff_uint64_count, plain_modulus_.pointer(), plain_modulus_uint64_count, intermediate_uint64_count, intermediate.get()); add_uint_uint(intermediate.get(), wide_coeff_modulus_div_two_.pointer(), intermediate_uint64_count, intermediate.get()); divide_uint_uint_inplace(intermediate.get(), wide_coeff_modulus_.pointer(), intermediate_uint64_count, quotient.get(), pool_); modulo_uint_inplace(quotient.get(), intermediate_uint64_count, mod_, pool_); uint64_t *productmoded_coeff = get_poly_coeff(productmoded.get(), coeff_index, coeff_uint64_count); set_uint_uint(quotient.get(), coeff_uint64_count, productmoded_coeff); } // Perform polynomial modulo. modulo_poly_inplace(productmoded.get(), product_coeff_count, polymod_, mod_, pool_); // Copy to destination. set_poly_poly(productmoded.get(), coeff_count, coeff_uint64_count, destination); } }
// // 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, const EShOptimizationLevel optLevel, const TBuiltInResource* resources, int debugOptions ) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; GlobalPoolAllocator.push(); compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); if (numStrings == 0) return 1; TIntermediate intermediate(compiler->infoSink); TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]); GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage()); TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink); parseContext.initializeExtensionBehavior(); GlobalParseContext = &parseContext; setInitialState(); InitPreprocessor(); // // Parse the application's shaders. All the following symbol table // work will be throw-away, so push a new allocation scope that can // be thrown away, then push a scope for the current shader's globals. // bool success = true; symbolTable.push(); if (!symbolTable.atGlobalLevel()) parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); if (parseContext.insertBuiltInArrayAtGlobalLevel()) success = false; int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext); if (ret) success = false; if (success && parseContext.treeRoot) { if (optLevel == EShOptNoGeneration) parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested."); else { success = intermediate.postProcess(parseContext.treeRoot, parseContext.language); if (success) { if (debugOptions & EDebugOpIntermediate) intermediate.outputTree(parseContext.treeRoot); // // Call the machine dependent compiler // if (! compiler->compile(parseContext.treeRoot)) success = false; } } } else if (!success) { parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; success = false; if (debugOptions & EDebugOpIntermediate) intermediate.outputTree(parseContext.treeRoot); } intermediate.remove(parseContext.treeRoot); // // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. // while (! symbolTable.atSharedBuiltInLevel()) symbolTable.pop(); FinalizePreprocessor(); // // Throw away all the temporary memory used by the compilation process. // GlobalPoolAllocator.pop(); return success ? 1 : 0; }
static void act(register Ftw_t* ftw, int op) { char* s; Sfio_t* fp; int i; int j; int k; int n; int r; switch (op) { case ACT_CMDARG: if ((i = cmdarg(state.cmd, ftw->path, ftw->pathlen)) >= state.errexit) exit(i); break; case ACT_CODE: if (findwrite(state.find, ftw->path, ftw->pathlen, (ftw->info & FTW_D) ? "system/dir" : (char*)0)) state.finderror = 1; break; case ACT_CODETYPE: fp = sfopen(NiL, PATH(ftw), "r"); if (findwrite(state.find, ftw->path, ftw->pathlen, magictype(state.magic, fp, PATH(ftw), &ftw->statb))) state.finderror = 1; if (fp) sfclose(fp); break; case ACT_EVAL: eval(state.action, ftw); break; case ACT_INTERMEDIATE: intermediate(ftw, ftw->path); break; case ACT_LIST: sfputr(sfstdout, ftw->path, '\n'); break; case ACT_SNAPSHOT: print(state.snapshot.tmp, ftw, state.snapshot.format.path); sfputc(state.snapshot.tmp, state.snapshot.format.delim); i = sfstrtell(state.snapshot.tmp); print(state.snapshot.tmp, ftw, state.snapshot.format.easy); j = sfstrtell(state.snapshot.tmp); s = sfstrbase(state.snapshot.tmp); r = SNAPSHOT_new; if (!state.snapshot.prev) k = 1; else { do { if (!(k = urlcmp(state.snapshot.prev, s, state.snapshot.format.delim))) { r = SNAPSHOT_changed; if (!(k = memcmp(state.snapshot.prev + i, s + i, j - i) || state.snapshot.prev[j] != state.snapshot.format.delim)) { if ((n = (int)sfvalue(sfstdin)) > 4 && state.snapshot.prev[n-2] == state.snapshot.format.delim) { sfwrite(sfstdout, state.snapshot.prev, n - 4); sfputc(sfstdout, '\n'); } else sfwrite(sfstdout, state.snapshot.prev, n); } } else if (k > 0) break; else if (k < 0 && (n = (int)sfvalue(sfstdin)) > 4 && (state.snapshot.prev[n-2] != state.snapshot.format.delim || state.snapshot.prev[n-3] != SNAPSHOT_deleted)) { sfwrite(sfstdout, state.snapshot.prev, n - (state.snapshot.prev[n-2] == state.snapshot.format.delim ? 4 : 1)); sfputc(sfstdout, state.snapshot.format.delim); sfputc(sfstdout, SNAPSHOT_deleted); sfputc(sfstdout, state.snapshot.format.delim); sfputc(sfstdout, '\n'); if (state.cmdflags & CMD_TRACE) error(1, "%s deleted", ftw->path); } if (!(state.snapshot.prev = sfgetr(sfstdin, '\n', 0))) break; } while (k < 0); } if (k) { if (state.snapshot.format.hard && (ftw->info & FTW_F)) { sfputc(state.snapshot.tmp, state.snapshot.format.delim); print(state.snapshot.tmp, ftw, state.snapshot.format.hard); } sfputc(state.snapshot.tmp, state.snapshot.format.delim); sfputc(state.snapshot.tmp, r); sfputc(state.snapshot.tmp, state.snapshot.format.delim); sfputr(sfstdout, sfstruse(state.snapshot.tmp), '\n'); if (state.cmdflags & CMD_TRACE) error(1, "%s %s", ftw->path, r == SNAPSHOT_new ? "new" : "changed"); } else sfstrseek(state.snapshot.tmp, SEEK_SET, 0); break; } }
bool TCompiler::compile(const char* const shaderStrings[], size_t numStrings, int compileOptions) { TScopedPoolAllocator scopedAlloc(&allocator); clearResults(); if (numStrings == 0) return true; // If compiling for WebGL, validate loop and indexing as well. if (IsWebGLBasedSpec(shaderSpec)) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. const char* sourcePath = NULL; size_t firstSource = 0; if (compileOptions & SH_SOURCE_PATH) { sourcePath = shaderStrings[0]; ++firstSource; } TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, true, sourcePath, infoSink); parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh; SetGlobalParseContext(&parseContext); // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable); // Parse shader. bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); shaderVersion = parseContext.getShaderVersion(); if (success) { TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); // Disallow expressions deemed too complex. if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) success = limitExpressionComplexity(root); if (success) success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0); if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER) success = validateOutputs(root); if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); if (success && shaderSpec == SH_CSS_SHADERS_SPEC) rewriteCSSShader(root); // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) { ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex); root->traverse(&marker); } if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX)) { ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex); root->traverse(&marker); if (marker.samplerArrayIndexIsFloatLoopIndex()) { infoSink.info.prefix(EPrefixError); infoSink.info << "sampler array index is float loop index"; success = false; } } // Built-in function emulation needs to happen after validateLimitations pass. if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)) builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); // Clamping uniform array bounds needs to happen after validateLimitations pass. if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) initializeGLPosition(root); if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { UnfoldShortCircuitAST unfoldShortCircuit; root->traverse(&unfoldShortCircuit); unfoldShortCircuit.updateTree(); } if (success && (compileOptions & SH_VARIABLES)) { collectVariables(root); if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { success = enforcePackingRestrictions(); if (!success) { infoSink.info.prefix(EPrefixError); infoSink.info << "too many uniforms"; } } if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) initializeVaryingsWithoutStaticUse(root); } if (success && (compileOptions & SH_INTERMEDIATE_TREE)) intermediate.outputTree(root); if (success && (compileOptions & SH_OBJECT_CODE)) translate(root); } // Cleanup memory. intermediate.remove(parseContext.treeRoot); SetGlobalParseContext(NULL); return success; }
int C_DECL Hlsl2Glsl_Parse( const ShHandle handle, const char* shaderString, int options ) { if (!InitThread()) return 0; if (handle == 0) return 0; HlslCrossCompiler* compiler = handle; GlobalPoolAllocator.push(); compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); if (!shaderString) return 1; TIntermediate intermediate(compiler->infoSink); TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]); GenerateBuiltInSymbolTable(compiler->infoSink, &symbolTable, compiler->getLanguage()); TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink); GlobalParseContext = &parseContext; setInitialState(); InitPreprocessor(); // // Parse the application's shaders. All the following symbol table // work will be throw-away, so push a new allocation scope that can // be thrown away, then push a scope for the current shader's globals. // bool success = true; symbolTable.push(); if (!symbolTable.atGlobalLevel()) parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); int ret = PaParseString(const_cast<char*>(shaderString), parseContext); if (ret) success = false; if (success && parseContext.treeRoot) { TIntermAggregate* aggRoot = parseContext.treeRoot->getAsAggregate(); if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); if (options & ETranslateOpIntermediate) intermediate.outputTree(parseContext.treeRoot); compiler->TransformAST (parseContext.treeRoot); compiler->ProduceGLSL (parseContext.treeRoot, (options & ETranslateOpUsePrecision) ? true : false); } else if (!success) { parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; success = false; if (options & ETranslateOpIntermediate) intermediate.outputTree(parseContext.treeRoot); } intermediate.remove(parseContext.treeRoot); // // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. // while (! symbolTable.atSharedBuiltInLevel()) symbolTable.pop(); FinalizePreprocessor(); // // Throw away all the temporary memory used by the compilation process. // GlobalPoolAllocator.pop(); return success ? 1 : 0; }
spv_result_t parsed_instruction(void* user_data, const spv_parsed_instruction_t* parsed_instruction) { intermediate_type &intermediate(*((intermediate_type *) user_data)); const uint32_t result_id(parsed_instruction->result_id); const SpvOp opcode((SpvOp) parsed_instruction->opcode); const instruction_parser parser(*parsed_instruction); switch (opcode) { case SpvOpConstant: case SpvOpSpecConstant: intermediate.constants.emplace(result_id, constant_type{ parser.single<uint32_t>(0), result_id, parser.rest<uint32_t>(2)}); break; case SpvOpSpecConstantTrue: case SpvOpSpecConstantFalse: intermediate.constants.emplace(result_id, constant_type{ parser.single<uint32_t>(0), result_id, {!!(opcode == SpvOpSpecConstantTrue)}}); break; case SpvOpSpecConstantComposite: std::cerr << "OpSpecConstantComposite not supported yet!" << std::endl; break; case SpvOpVariable: intermediate.variables.emplace(result_id, variable_type{ parser.single<uint32_t>(0), result_id, parser.single<SpvStorageClass>(2) }); break; case SpvOpName: { auto target_id(parser.single<uint32_t>(0)); intermediate.names.emplace(target_id, name_type{parser.string(1), target_id}); } break; case SpvOpMemberName: intermediate.member_names[parser.single<uint32_t>(0)].names.emplace( parser.single<uint32_t>(1), parser.string(2)); break; case SpvOpMemberDecorate: switch(parser.single<SpvDecoration>(2)) { case SpvDecorationOffset: intermediate.member_offsets[parser.single<uint32_t>(0)].offsets.emplace( parser.single<uint32_t>(1), parser.single<uint32_t>(3)); break; default: break; } break; case SpvOpTypePointer: intermediate.type_pointers.emplace(result_id, type_pointer_type{ result_id, parser.single<SpvStorageClass>(1), parser.single<uint32_t>(2) }); break; case SpvOpDecorate: { const auto target_id(parser.single<uint32_t>(0)); const auto decoration(parser.single<SpvDecoration>(1)); switch (decoration) { case SpvDecorationLinkageAttributes: intermediate.linkage_decorations.emplace(target_id, linkage_decoration_type{ target_id, parser.single<SpvLinkageType>(3) }); break; default: intermediate.decorations[target_id].push_back(decoration_type{target_id, decoration, parser.optional<uint32_t>(2, 0)}); break; } } break; case SpvOpDecorationGroup: std::cerr << "OpDecorationGroup is not yet implemented!" << std::endl; intermediate.decoration_groups.emplace(result_id, decoration_group_type{ result_id }); break; case SpvOpGroupDecorate: { const auto decoration_group(parser.single<uint32_t>(0)); intermediate.group_decorations.emplace(decoration_group, group_decorate_type{ parser.multi<uint32_t>(1), decoration_group}); } break; case SpvOpGroupMemberDecorate: { const auto decoration_group(parser.single<uint32_t>(0)); intermediate.group_member_decorations.emplace(decoration_group, group_member_decorate_type{ parser.multi<std::pair<uint32_t, uint32_t>>(1), decoration_group}); } break; case SpvOpEntryPoint: intermediate.entry_points.push_back(entry_point_type{ parser.single<SpvExecutionModel>(0), parser.single<uint32_t>(1), parser.string(2), parser.rest<uint32_t>(3)}); break; case SpvOpTypeVoid: case SpvOpTypeBool: intermediate.primitives.emplace(result_id, primitive_type{opcode, result_id}); break; case SpvOpTypeInt: case SpvOpTypeVector: case SpvOpTypeMatrix: case SpvOpTypeArray: intermediate.primitives.emplace(result_id, primitive_type{opcode, result_id, parser.single<uint32_t>(1), parser.single<uint32_t>(2)}); break; case SpvOpTypeFloat: case SpvOpTypeRuntimeArray: intermediate.primitives.emplace(result_id, primitive_type{opcode, result_id, parser.single<uint32_t>(1)}); break; case SpvOpTypeImage: intermediate.images.emplace(result_id, image_type{ result_id, parser.single<uint32_t>(1), parser.single<SpvDim>(2), parser.single<uint32_t>(3), parser.single_bool(4), parser.single_bool(5), parser.single<uint32_t>(6), parser.single<SpvImageFormat>(7) }); break; case SpvOpTypeStruct: intermediate.structs.emplace(result_id, struct_type{result_id, parser.rest<uint32_t>(1)}); break; case SpvOpTypeSampler: intermediate.samplers.emplace(result_id, sampler_type{result_id}); break; case SpvOpConstantSampler: intermediate.constant_samplers.emplace(result_id, constant_sampler_type{ result_id, parser.single<SpvSamplerAddressingMode>(1), parser.single_bool(2), parser.single<SpvSamplerFilterMode>(3)}); break; case SpvOpTypeSampledImage: intermediate.sampled_images.emplace(result_id, sampled_image_type{ result_id, parser.single<uint32_t>(1) }); break; case SpvOpSampledImage: intermediate.sampled_images_binding.emplace(result_id, sampled_image_binding_type{ parser.single<uint32_t>(0), result_id, parser.single<uint32_t>(2), parser.single<uint32_t>(2) }); break; default: break; } return SPV_SUCCESS; }
bool TCompiler::compile(const char* const shaderStrings[], const int numStrings, int compileOptions) { TScopedPoolAllocator scopedAlloc(&allocator, true); clearResults(); if (numStrings == 0) return true; // If compiling for WebGL, validate loop and indexing as well. if (shaderSpec == SH_WEBGL_SPEC) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. const char* sourcePath = NULL; int firstSource = 0; if (compileOptions & SH_SOURCE_PATH) { sourcePath = shaderStrings[0]; ++firstSource; } TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, sourcePath, infoSink); GlobalParseContext = &parseContext; // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. symbolTable.push(); if (!symbolTable.atGlobalLevel()) infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); // Parse shader. bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); if (success) { TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); if (success && (compileOptions & SH_INTERMEDIATE_TREE)) intermediate.outputTree(root); if (success && (compileOptions & SH_OBJECT_CODE)) translate(root); if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) collectAttribsUniforms(root); } // Cleanup memory. intermediate.remove(parseContext.treeRoot); // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. while (!symbolTable.atBuiltInLevel()) symbolTable.pop(); return success; }
TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], size_t numStrings, int compileOptions) { clearResults(); ASSERT(numStrings > 0); ASSERT(GetGlobalPoolAllocator()); // Reset the extension behavior for each compilation unit. ResetExtensionBehavior(extensionBehavior); // If compiling for WebGL, validate loop and indexing as well. if (IsWebGLBasedSpec(shaderSpec)) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. size_t firstSource = 0; if (compileOptions & SH_SOURCE_PATH) { mSourcePath = shaderStrings[0]; ++firstSource; } bool debugShaderPrecision = getResources().WEBGL_debug_shader_precision == 1; TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, true, infoSink, debugShaderPrecision); parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh; SetGlobalParseContext(&parseContext); // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable); // Parse shader. bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); shaderVersion = parseContext.getShaderVersion(); if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion) { infoSink.info.prefix(EPrefixError); infoSink.info << "unsupported shader version"; success = false; } TIntermNode *root = NULL; if (success) { mPragma = parseContext.pragma(); if (mPragma.stdgl.invariantAll) { symbolTable.setGlobalInvariant(); } root = parseContext.treeRoot; success = intermediate.postProcess(root); // Disallow expressions deemed too complex. if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) success = limitExpressionComplexity(root); if (success) success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0); if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER) success = validateOutputs(root); if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); if (success && shaderSpec == SH_CSS_SHADERS_SPEC) rewriteCSSShader(root); // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) { ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex); root->traverse(&marker); } if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX)) { ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex); root->traverse(&marker); if (marker.samplerArrayIndexIsFloatLoopIndex()) { infoSink.info.prefix(EPrefixError); infoSink.info << "sampler array index is float loop index"; success = false; } } // Built-in function emulation needs to happen after validateLimitations pass. if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)) builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); // Clamping uniform array bounds needs to happen after validateLimitations pass. if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) initializeGLPosition(root); if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { UnfoldShortCircuitAST unfoldShortCircuit; root->traverse(&unfoldShortCircuit); unfoldShortCircuit.updateTree(); } if (success && (compileOptions & SH_VARIABLES)) { collectVariables(root); if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { success = enforcePackingRestrictions(); if (!success) { infoSink.info.prefix(EPrefixError); infoSink.info << "too many uniforms"; } } if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) initializeVaryingsWithoutStaticUse(root); } if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)) { ScalarizeVecAndMatConstructorArgs scalarizer( shaderType, fragmentPrecisionHigh); root->traverse(&scalarizer); } if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES)) { RegenerateStructNames gen(symbolTable, shaderVersion); root->traverse(&gen); } } SetGlobalParseContext(NULL); if (success) return root; return NULL; }
void multiply_poly_poly(const uint64_t *operand1, int operand1_coeff_count, int operand1_coeff_uint64_count, const uint64_t *operand2, int operand2_coeff_count, int operand2_coeff_uint64_count, int result_coeff_count, int result_coeff_uint64_count, uint64_t *result, MemoryPool &pool) { #ifdef SEAL_DEBUG if (operand1 == nullptr && operand1_coeff_count > 0 && operand1_coeff_uint64_count > 0) { throw invalid_argument("operand1"); } if (operand1_coeff_count < 0) { throw invalid_argument("operand1_coeff_count"); } if (operand1_coeff_uint64_count < 0) { throw invalid_argument("operand1_coeff_uint64_count"); } if (operand2 == nullptr && operand2_coeff_count > 0 && operand2_coeff_uint64_count > 0) { throw invalid_argument("operand2"); } if (operand2_coeff_count < 0) { throw invalid_argument("operand2_coeff_count"); } if (operand2_coeff_uint64_count < 0) { throw invalid_argument("operand2_coeff_uint64_count"); } if (result_coeff_count < 0) { throw invalid_argument("result_coeff_count"); } if (result_coeff_uint64_count < 0) { throw invalid_argument("result_coeff_uint64_count"); } if (result == nullptr && result_coeff_count > 0 && result_coeff_uint64_count > 0) { throw invalid_argument("result"); } if (result != nullptr && (operand1 == result || operand2 == result)) { throw invalid_argument("result cannot point to the same value as operand1 or operand2"); } #endif Pointer intermediate(allocate_uint(result_coeff_uint64_count, pool)); // Clear product. set_zero_poly(result_coeff_count, result_coeff_uint64_count, result); operand1_coeff_count = get_significant_coeff_count_poly( operand1, operand1_coeff_count, operand1_coeff_uint64_count); operand2_coeff_count = get_significant_coeff_count_poly( operand2, operand2_coeff_count, operand2_coeff_uint64_count); for (int operand1_index = 0; operand1_index < operand1_coeff_count; operand1_index++) { const uint64_t *operand1_coeff = get_poly_coeff( operand1, operand1_index, operand1_coeff_uint64_count); for (int operand2_index = 0; operand2_index < operand2_coeff_count; operand2_index++) { int product_coeff_index = operand1_index + operand2_index; if (product_coeff_index >= result_coeff_count) { break; } const uint64_t *operand2_coeff = get_poly_coeff( operand2, operand2_index, operand2_coeff_uint64_count); multiply_uint_uint(operand1_coeff, operand1_coeff_uint64_count, operand2_coeff, operand2_coeff_uint64_count, result_coeff_uint64_count, intermediate.get()); uint64_t *result_coeff = get_poly_coeff( result, product_coeff_index, result_coeff_uint64_count); add_uint_uint(result_coeff, intermediate.get(), result_coeff_uint64_count, result_coeff); } } }
bool TCompiler::compile(const char* const shaderStrings[], const int numStrings, int compileOptions) { TScopedPoolAllocator scopedAlloc(&allocator, true); clearResults(); if (numStrings == 0) return true; // If compiling for WebGL, validate loop and indexing as well. if (shaderSpec == SH_WEBGL_SPEC) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. const char* sourcePath = NULL; int firstSource = 0; if (compileOptions & SH_SOURCE_PATH) { sourcePath = shaderStrings[0]; ++firstSource; } TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, true, sourcePath, infoSink); GlobalParseContext = &parseContext; // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. symbolTable.push(); if (!symbolTable.atGlobalLevel()) infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); // Parse shader. bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); if (success) { TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); if (success) success = detectRecursion(root); if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root); // Built-in function emulation needs to happen after validateLimitations pass. if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)) builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); // Call mapLongVariableNames() before collectAttribsUniforms() so in // collectAttribsUniforms() we already have the mapped symbol names and // we could composite mapped and original variable names. if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES)) mapLongVariableNames(root); if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) collectAttribsUniforms(root); if (success && (compileOptions & SH_INTERMEDIATE_TREE)) intermediate.outputTree(root); if (success && (compileOptions & SH_OBJECT_CODE)) translate(root); } // Cleanup memory. intermediate.remove(parseContext.treeRoot); // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. while (!symbolTable.atBuiltInLevel()) symbolTable.pop(); return success; }
TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], size_t numStrings, const int compileOptions) { clearResults(); ASSERT(numStrings > 0); ASSERT(GetGlobalPoolAllocator()); // Reset the extension behavior for each compilation unit. ResetExtensionBehavior(extensionBehavior); // First string is path of source file if flag is set. The actual source follows. size_t firstSource = 0; if (compileOptions & SH_SOURCE_PATH) { mSourcePath = shaderStrings[0]; ++firstSource; } TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, true, infoSink, getResources()); parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh); SetGlobalParseContext(&parseContext); // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable); // Parse shader. bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, &parseContext) == 0) && (parseContext.getTreeRoot() != nullptr); shaderVersion = parseContext.getShaderVersion(); if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion) { infoSink.info.prefix(EPrefixError); infoSink.info << "unsupported shader version"; success = false; } TIntermNode *root = nullptr; if (success) { mPragma = parseContext.pragma(); if (mPragma.stdgl.invariantAll) { symbolTable.setGlobalInvariant(); } root = parseContext.getTreeRoot(); root = intermediate.postProcess(root); // Highp might have been auto-enabled based on shader version fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); // Disallow expressions deemed too complex. if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) success = limitExpressionComplexity(root); // Create the function DAG and check there is no recursion if (success) success = initCallDag(root); if (success && (compileOptions & SH_LIMIT_CALL_STACK_DEPTH)) success = checkCallDepth(); // Checks which functions are used and if "main" exists if (success) { functionMetadata.clear(); functionMetadata.resize(mCallDag.size()); success = tagUsedFunctions(); } if (success && !(compileOptions & SH_DONT_PRUNE_UNUSED_FUNCTIONS)) success = pruneUnusedFunctions(root); // Prune empty declarations to work around driver bugs and to keep declaration output simple. if (success) PruneEmptyDeclarations(root); if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER) success = validateOutputs(root); if (success && shouldRunLoopAndIndexingValidation(compileOptions)) success = validateLimitations(root); if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); if (success && shaderSpec == SH_CSS_SHADERS_SPEC) rewriteCSSShader(root); // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) { ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex, shouldRunLoopAndIndexingValidation(compileOptions)); root->traverse(&marker); } if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX)) { ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex, shouldRunLoopAndIndexingValidation(compileOptions)); root->traverse(&marker); if (marker.samplerArrayIndexIsFloatLoopIndex()) { infoSink.info.prefix(EPrefixError); infoSink.info << "sampler array index is float loop index"; success = false; } } // Built-in function emulation needs to happen after validateLimitations pass. if (success) { initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions); builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); } // Clamping uniform array bounds needs to happen after validateLimitations pass. if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); // gl_Position is always written in compatibility output mode if (success && shaderType == GL_VERTEX_SHADER && ((compileOptions & SH_INIT_GL_POSITION) || (outputType == SH_GLSL_COMPATIBILITY_OUTPUT))) initializeGLPosition(root); // This pass might emit short circuits so keep it before the short circuit unfolding if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)) RewriteDoWhile(root, getTemporaryIndex()); if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { UnfoldShortCircuitAST unfoldShortCircuit; root->traverse(&unfoldShortCircuit); unfoldShortCircuit.updateTree(); } if (success && (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)) { RemovePow(root); } if (success && shouldCollectVariables(compileOptions)) { collectVariables(root); if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { success = enforcePackingRestrictions(); if (!success) { infoSink.info.prefix(EPrefixError); infoSink.info << "too many uniforms"; } } if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) initializeVaryingsWithoutStaticUse(root); } if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)) { ScalarizeVecAndMatConstructorArgs scalarizer( shaderType, fragmentPrecisionHigh); root->traverse(&scalarizer); } if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES)) { RegenerateStructNames gen(symbolTable, shaderVersion); root->traverse(&gen); } } SetGlobalParseContext(NULL); if (success) return root; return NULL; }
void CartSideDoubleDivPreservingRefine::postprocessRefine(Patch<NDIM>& fine, const Patch<NDIM>& coarse, const Box<NDIM>& unrestricted_fine_box, const IntVector<NDIM>& ratio) { // NOTE: This operator cannot fill the full ghost cell width of the // destination data. We instead restrict the size of the fine box to ensure // that we have adequate data to apply the divergence- and curl-preserving // corrections. const Box<NDIM> fine_box = unrestricted_fine_box * Box<NDIM>::grow(fine.getBox(), 2); #if !defined(NDEBUG) for (int d = 0; d < NDIM; ++d) { if (ratio(d) % 2 != 0) { TBOX_ERROR("CartSideDoubleDivPreservingRefine::postprocessRefine():\n" << " refinement ratio must be a power of 2 for divergence- and " "curl-preserving refinement operator." << std::endl); } } #endif Pointer<SideData<NDIM, double> > fdata = fine.getPatchData(d_u_dst_idx); #if !defined(NDEBUG) TBOX_ASSERT(fdata); #endif const int fdata_ghosts = fdata->getGhostCellWidth().max(); #if !defined(NDEBUG) TBOX_ASSERT(fdata_ghosts == fdata->getGhostCellWidth().min()); #endif const int fdata_depth = fdata->getDepth(); Pointer<SideData<NDIM, double> > cdata = coarse.getPatchData(d_u_dst_idx); #if !defined(NDEBUG) TBOX_ASSERT(cdata); const int cdata_ghosts = cdata->getGhostCellWidth().max(); TBOX_ASSERT(cdata_ghosts == cdata->getGhostCellWidth().min()); const int cdata_depth = cdata->getDepth(); TBOX_ASSERT(cdata_depth == fdata_depth); #endif if (ratio == IntVector<NDIM>(2)) { // Perform (limited) conservative prolongation of the coarse grid data. d_refine_op->refine(fine, coarse, d_u_dst_idx, d_u_dst_idx, fine_box, ratio); Pointer<SideData<NDIM, double> > u_src_data = fine.getPatchData(d_u_src_idx); Pointer<SideData<NDIM, double> > indicator_data = fine.getPatchData(d_indicator_idx); // Ensure that we do not modify any of the data from the old level by // setting the value of the fine grid data to equal u_src wherever the // indicator data equals "1". if (u_src_data && indicator_data) { for (unsigned int axis = 0; axis < NDIM; ++axis) { for (Box<NDIM>::Iterator b(SideGeometry<NDIM>::toSideBox(fine_box, axis)); b; b++) { const Index<NDIM>& i = b(); const SideIndex<NDIM> i_s(i, axis, 0); if (std::abs((*indicator_data)(i_s)-1.0) < 1.0e-12) { for (int depth = 0; depth < fdata_depth; ++depth) { (*fdata)(i_s, depth) = (*u_src_data)(i_s, depth); } } } } } // Reinterpolate data in the normal direction in the newly refined part // of the level wherever the indicator data does NOT equal "1". Notice // that this loop actually modifies only data that is NOT covered by an // overlying coarse grid cell face. if (indicator_data) { for (unsigned int axis = 0; axis < NDIM; ++axis) { for (Box<NDIM>::Iterator b(SideGeometry<NDIM>::toSideBox(fine_box, axis)); b; b++) { const Index<NDIM>& i = b(); const SideIndex<NDIM> i_s(i, axis, 0); if (!(std::abs((*indicator_data)(i_s)-1.0) < 1.0e-12)) { const Index<NDIM> i_coarse_lower = IndexUtilities::coarsen(i, ratio); const Index<NDIM> i_lower = IndexUtilities::refine(i_coarse_lower, ratio); if (i(axis) == i_lower(axis)) continue; Index<NDIM> i_coarse_upper = i_coarse_lower; i_coarse_upper(axis) += 1; const Index<NDIM> i_upper = IndexUtilities::refine(i_coarse_upper, ratio); const double w1 = static_cast<double>(i(axis) - i_lower(axis)) / static_cast<double>(ratio(axis)); const double w0 = 1.0 - w1; const SideIndex<NDIM> i_s_lower(i_lower, axis, 0); const SideIndex<NDIM> i_s_upper(i_upper, axis, 0); for (int depth = 0; depth < fdata_depth; ++depth) { (*fdata)(i_s, depth) = w0 * (*fdata)(i_s_lower, depth) + w1 * (*fdata)(i_s_upper, depth); } } } } } // Determine the box on which we need to compute the divergence- and // curl-preserving correction. const Box<NDIM> correction_box = Box<NDIM>::refine(Box<NDIM>::coarsen(fine_box, 2), 2); #if !defined(NDEBUG) TBOX_ASSERT(fdata->getGhostBox().contains(correction_box)); #endif // Apply the divergence- and curl-preserving correction to the fine grid // data. Pointer<CartesianPatchGeometry<NDIM> > pgeom_fine = fine.getPatchGeometry(); const double* const dx_fine = pgeom_fine->getDx(); for (int d = 0; d < fdata_depth; ++d) { DIV_PRESERVING_CORRECTION_FC(fdata->getPointer(0, d), fdata->getPointer(1, d), #if (NDIM == 3) fdata->getPointer(2, d), #endif fdata_ghosts, fdata->getBox().lower()(0), fdata->getBox().upper()(0), fdata->getBox().lower()(1), fdata->getBox().upper()(1), #if (NDIM == 3) fdata->getBox().lower()(2), fdata->getBox().upper()(2), #endif correction_box.lower()(0), correction_box.upper()(0), correction_box.lower()(1), correction_box.upper()(1), #if (NDIM == 3) correction_box.lower()(2), correction_box.upper()(2), #endif ratio, dx_fine); } } else { // Setup an intermediate patch. const Box<NDIM> intermediate_patch_box = Box<NDIM>::refine(coarse.getBox(), 2); Patch<NDIM> intermediate(intermediate_patch_box, coarse.getPatchDescriptor()); intermediate.allocatePatchData(d_u_dst_idx); // Setup a patch geometry object for the intermediate patch. Pointer<CartesianPatchGeometry<NDIM> > pgeom_coarse = coarse.getPatchGeometry(); const IntVector<NDIM>& ratio_to_level_zero_coarse = pgeom_coarse->getRatio(); Array<Array<bool> > touches_regular_bdry(NDIM), touches_periodic_bdry(NDIM); for (int axis = 0; axis < NDIM; ++axis) { touches_regular_bdry[axis].resizeArray(2); touches_periodic_bdry[axis].resizeArray(2); for (int upperlower = 0; upperlower < 2; ++upperlower) { touches_regular_bdry[axis][upperlower] = pgeom_coarse->getTouchesRegularBoundary(axis, upperlower); touches_periodic_bdry[axis][upperlower] = pgeom_coarse->getTouchesPeriodicBoundary(axis, upperlower); } } const double* const dx_coarse = pgeom_coarse->getDx(); const IntVector<NDIM> ratio_to_level_zero_intermediate = ratio_to_level_zero_coarse * 2; double dx_intermediate[NDIM], x_lower_intermediate[NDIM], x_upper_intermediate[NDIM]; for (int d = 0; d < NDIM; ++d) { dx_intermediate[d] = 0.5 * dx_coarse[d]; x_lower_intermediate[d] = pgeom_coarse->getXLower()[d]; x_upper_intermediate[d] = pgeom_coarse->getXUpper()[d]; } intermediate.setPatchGeometry(new CartesianPatchGeometry<NDIM>(ratio_to_level_zero_intermediate, touches_regular_bdry, touches_periodic_bdry, dx_intermediate, x_lower_intermediate, x_upper_intermediate)); // The intermediate box where we need to fill data must be large enough // to provide ghost cell values for the fine fill box. const Box<NDIM> intermediate_box = Box<NDIM>::grow(Box<NDIM>::coarsen(fine_box, ratio / 2), 2); // Setup the original velocity and indicator data. if (fine.checkAllocated(d_u_src_idx) && fine.checkAllocated(d_indicator_idx)) { intermediate.allocatePatchData(d_u_src_idx); intermediate.allocatePatchData(d_indicator_idx); Pointer<SideData<NDIM, double> > u_src_idata = intermediate.getPatchData(d_u_src_idx); Pointer<SideData<NDIM, double> > indicator_idata = intermediate.getPatchData(d_indicator_idx); u_src_idata->fillAll(std::numeric_limits<double>::quiet_NaN()); indicator_idata->fillAll(-1.0); #if !defined(NDEBUG) Pointer<SideData<NDIM, double> > u_src_fdata = fine.getPatchData(d_u_src_idx); Pointer<SideData<NDIM, double> > indicator_fdata = fine.getPatchData(d_indicator_idx); TBOX_ASSERT(u_src_fdata->getGhostBox().contains(Box<NDIM>::refine(intermediate_box, ratio / 2))); TBOX_ASSERT(indicator_fdata->getGhostBox().contains(Box<NDIM>::refine(intermediate_box, ratio / 2))); #endif d_coarsen_op->coarsen(intermediate, fine, d_u_src_idx, d_u_src_idx, intermediate_box, ratio / 2); d_coarsen_op->coarsen(intermediate, fine, d_indicator_idx, d_indicator_idx, intermediate_box, ratio / 2); } // Recursively refine from the coarse patch to the fine patch. postprocessRefine(intermediate, coarse, intermediate_box, 2); postprocessRefine(fine, intermediate, fine_box, ratio / 2); // Deallocate any allocated patch data. intermediate.deallocatePatchData(d_u_dst_idx); if (fine.checkAllocated(d_u_src_idx) && fine.checkAllocated(d_indicator_idx)) { intermediate.deallocatePatchData(d_u_src_idx); intermediate.deallocatePatchData(d_indicator_idx); } } return; } // postprocessRefine
bool TCompiler::compile(const char* const shaderStrings[], size_t numStrings, int compileOptions) { TScopedPoolAllocator scopedAlloc(&allocator, true); clearResults(); if (numStrings == 0) return true; // If compiling for WebGL, validate loop and indexing as well. if (isWebGLBasedSpec(shaderSpec)) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. const char* sourcePath = NULL; size_t firstSource = 0; if (compileOptions & SH_SOURCE_PATH) { sourcePath = shaderStrings[0]; ++firstSource; } TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, true, sourcePath, infoSink); parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh; GlobalParseContext = &parseContext; // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. symbolTable.push(); if (!symbolTable.atGlobalLevel()) { infoSink.info.prefix(EPrefixInternalError); infoSink.info << "Wrong symbol table level"; } // Parse shader. bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); if (success) { TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); if (success) success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0); if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); if (success && shaderSpec == SH_CSS_SHADERS_SPEC) rewriteCSSShader(root); // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root); // Built-in function emulation needs to happen after validateLimitations pass. if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)) builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); // Clamping uniform array bounds needs to happen after validateLimitations pass. if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); // Disallow expressions deemed too complex. if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) success = limitExpressionComplexity(root); // Call mapLongVariableNames() before collectAttribsUniforms() so in // collectAttribsUniforms() we already have the mapped symbol names and // we could composite mapped and original variable names. // Also, if we hash all the names, then no need to do this for long names. if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL) mapLongVariableNames(root); if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) { collectAttribsUniforms(root); if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { success = enforcePackingRestrictions(); if (!success) { infoSink.info.prefix(EPrefixError); infoSink.info << "too many uniforms"; } } } if (success && (compileOptions & SH_INTERMEDIATE_TREE)) intermediate.outputTree(root); if (success && (compileOptions & SH_OBJECT_CODE)) translate(root); } // Cleanup memory. intermediate.remove(parseContext.treeRoot); // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. while (!symbolTable.atBuiltInLevel()) symbolTable.pop(); return success; }
/** * Rasterize items. * This method submits the drawing opeartions required to draw this item * to the supplied DrawingContext, restricting drawing the specified area. * * This method does some common tasks and calls the item-specific rendering * function, _renderItem(), to render e.g. paths or bitmaps. * * @param flags Rendering options. This deals mainly with cache control. */ unsigned DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at) { bool outline = _drawing.outline(); bool render_filters = _drawing.renderFilters(); // stop_at is handled in DrawingGroup, but this check is required to handle the case // where a filtered item with background-accessing filter has enable-background: new if (this == stop_at) return RENDER_STOP; // If we are invisible, return immediately if (!_visible) return RENDER_OK; if (_ctm.isSingular(1e-18)) return RENDER_OK; // TODO convert outline rendering to a separate virtual function if (outline) { _renderOutline(dc, area, flags); return RENDER_OK; } // carea is the area to paint Geom::OptIntRect carea = Geom::intersect(area, _drawbox); if (!carea) return RENDER_OK; if (_antialias) { cairo_set_antialias(dc.raw(), CAIRO_ANTIALIAS_DEFAULT); } else { cairo_set_antialias(dc.raw(), CAIRO_ANTIALIAS_NONE); } // render from cache if possible if (_cached) { if (_cache) { _cache->prepare(); set_cairo_blend_operator( dc, _mix_blend_mode ); _cache->paintFromCache(dc, carea); if (!carea) return RENDER_OK; } else { // There is no cache. This could be because caching of this item // was just turned on after the last update phase, or because // we were previously outside of the canvas. Geom::OptIntRect cl = _drawing.cacheLimit(); cl.intersectWith(_drawbox); if (cl) { _cache = new DrawingCache(*cl); } } } else { // if our caching was turned off after the last update, it was already // deleted in setCached() } // determine whether this shape needs intermediate rendering. bool needs_intermediate_rendering = false; bool &nir = needs_intermediate_rendering; bool needs_opacity = (_opacity < 0.995); // this item needs an intermediate rendering if: nir |= (_clip != NULL); // 1. it has a clipping path nir |= (_mask != NULL); // 2. it has a mask nir |= (_filter != NULL && render_filters); // 3. it has a filter nir |= needs_opacity; // 4. it is non-opaque nir |= (_cache != NULL); // 5. it is cached nir |= (_mix_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom /* How the rendering is done. * * Clipping, masking and opacity are done by rendering them to a surface * and then compositing the object's rendering onto it with the IN operator. * The object itself is rendered to a group. * * Opacity is done by rendering the clipping path with an alpha * value corresponding to the opacity. If there is no clipping path, * the entire intermediate surface is painted with alpha corresponding * to the opacity value. */ // Short-circuit the simple case. // We also use this path for filter background rendering, because masking, clipping, // filters and opacity do not apply when rendering the ancestors of the filtered // element if ((flags & RENDER_FILTER_BACKGROUND) || !needs_intermediate_rendering) { return _renderItem(dc, *carea, flags & ~RENDER_FILTER_BACKGROUND, stop_at); } // iarea is the bounding box for intermediate rendering // Note 1: Pixels inside iarea but outside carea are invalid // (incomplete filter dependence region). // Note 2: We only need to render carea of clip and mask, but // iarea of the object. Geom::OptIntRect iarea = carea; // expand carea to contain the dependent area of filters. if (_filter && render_filters) { _filter->area_enlarge(*iarea, this); iarea.intersectWith(_drawbox); } DrawingSurface intermediate(*iarea); DrawingContext ict(intermediate); unsigned render_result = RENDER_OK; // 1. Render clipping path with alpha = opacity. ict.setSource(0,0,0,_opacity); // Since clip can be combined with opacity, the result could be incorrect // for overlapping clip children. To fix this we use the SOURCE operator // instead of the default OVER. ict.setOperator(CAIRO_OPERATOR_SOURCE); ict.paint(); if (_clip) { ict.pushGroup(); _clip->clip(ict, *carea); // fixme: carea or area? ict.popGroupToSource(); ict.setOperator(CAIRO_OPERATOR_IN); ict.paint(); } ict.setOperator(CAIRO_OPERATOR_OVER); // reset back to default // 2. Render the mask if present and compose it with the clipping path + opacity. if (_mask) { ict.pushGroup(); _mask->render(ict, *carea, flags); cairo_surface_t *mask_s = ict.rawTarget(); // Convert mask's luminance to alpha ink_cairo_surface_filter(mask_s, mask_s, MaskLuminanceToAlpha()); ict.popGroupToSource(); ict.setOperator(CAIRO_OPERATOR_IN); ict.paint(); ict.setOperator(CAIRO_OPERATOR_OVER); } // 3. Render object itself ict.pushGroup(); render_result = _renderItem(ict, *iarea, flags, stop_at); // 4. Apply filter. if (_filter && render_filters) { bool rendered = false; if (_filter->uses_background() && _background_accumulate) { DrawingItem *bg_root = this; for (; bg_root; bg_root = bg_root->_parent) { if (bg_root->_background_new) break; } if (bg_root) { DrawingSurface bg(*iarea); DrawingContext bgdc(bg); bg_root->render(bgdc, *iarea, flags | RENDER_FILTER_BACKGROUND, this); _filter->render(this, ict, &bgdc); rendered = true; } } if (!rendered) { _filter->render(this, ict, NULL); } // Note that because the object was rendered to a group, // the internals of the filter need to use cairo_get_group_target() // instead of cairo_get_target(). } // 5. Render object inside the composited mask + clip ict.popGroupToSource(); ict.setOperator(CAIRO_OPERATOR_IN); ict.paint(); // 6. Paint the completed rendering onto the base context (or into cache) if (_cached && _cache) { DrawingContext cachect(*_cache); cachect.rectangle(*carea); cachect.setOperator(CAIRO_OPERATOR_SOURCE); cachect.setSource(&intermediate); cachect.fill(); _cache->markClean(*carea); } dc.rectangle(*carea); dc.setSource(&intermediate); set_cairo_blend_operator( dc, _mix_blend_mode ); dc.fill(); dc.setSource(0,0,0,0); // the call above is to clear a ref on the intermediate surface held by dc return render_result; }