Esempio n. 1
0
/// 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;
}
Esempio n. 2
0
    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();
    }
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
    }

}
Esempio n. 6
0
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;
    }
}
Esempio n. 7
0
//
// 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;
}
Esempio n. 8
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;
	}
}
Esempio n. 9
0
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);
        }
    }
Esempio n. 11
0
//
// 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;
}
Esempio n. 12
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;
	}
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
        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);
                }
            }
        }
Esempio n. 19
0
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;
}
Esempio n. 20
0
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
Esempio n. 22
0
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;
}
Esempio n. 23
0
/**
 * 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;
}