private void WriteProgramDependencies(StreamWriter stream, Program program) { for (int i = 0; i < program.DependencyCount; i++) { string curDependency = program.GetDependency(i); CacheDependencyFunctions(curDependency); } stream.WriteLine("//-----------------------------------------------------------------------------"); stream.WriteLine("// PROGRAM DEPENDENCIES"); stream.WriteLine(); var forwardDecl = new List <FunctionInvocation>(); var functionList = program.Functions; int itFunction = 0; Function curFunction = functionList[0]; var atomInstances = curFunction.AtomInstances; int itAtom = 0; int itAtomEnd = atomInstances.Count; //Now iterate over all function atoms for ( ; itAtom != itAtomEnd; itAtom++) { //Skip non function invocation atom if (atomInstances[itAtom] is FunctionInvocation == false) { continue; } var funcInvoc = atomInstances[itAtom] as FunctionInvocation; forwardDecl.Add(funcInvoc); // Now look into that function for other non-builtin functions and add them to the declaration list // Look for non-builtin functions // Do so by assuming that these functions do not have several variations. // Also, because GLSL is C based, functions must be defined before they are used // so we can make the assumption that we already have this function cached. // // If we find a function, look it up in the map and write it out DiscoverFunctionDependencies(funcInvoc, forwardDecl); } //Now remove duplicate declarations forwardDecl.Sort(); forwardDecl = forwardDecl.Distinct(new FunctionInvocation.FunctionInvocationComparer()).ToList(); for (int i = 0; i < program.DependencyCount; i++) { string curDependency = program.GetDependency(i); foreach (var key in this.definesMap.Keys) { if (this.definesMap[key] == curDependency) { stream.Write(this.definesMap[key]); stream.Write("\n"); } } } // Parse the source shader and write out only the needed functions foreach (var it in forwardDecl) { var invoc = new FunctionInvocation(string.Empty, 0, 0, string.Empty); string body = string.Empty; //find the function in the cache foreach (var key in this.functionCacheMap.Keys) { if (!(it == key)) { continue; } invoc = key; body = this.functionCacheMap[key]; break; } if (invoc.FunctionName.Length > 0) { //Write out the funciton name from the cached FunctionInvocation stream.Write(invoc.ReturnType); stream.Write(" "); stream.Write(invoc.FunctionName); stream.Write("("); int itOperand = 0; int itOperandEnd = invoc.OperandList.Count; while (itOperand != itOperandEnd) { Operand op = invoc.OperandList[itOperand]; Operand.OpSemantic opSemantic = op.Semantic; string paramName = op.Parameter.Name; int opMask = op.Mask; GpuProgramParameters.GpuConstantType gpuType = GpuProgramParameters.GpuConstantType.Unknown; switch (opSemantic) { case Operand.OpSemantic.In: stream.Write("in "); break; case Operand.OpSemantic.Out: stream.Write("out "); break; case Operand.OpSemantic.InOut: stream.Write("inout "); break; default: break; } //Swizzle masks are onluy defined for types like vec2, vec3, vec4 if (opMask == (int)Operand.OpMask.All) { gpuType = op.Parameter.Type; } else { gpuType = Operand.GetGpuConstantType(opMask); } //We need a valid type otherwise glsl compilation will not work if (gpuType == GpuProgramParameters.GpuConstantType.Unknown) { throw new Core.AxiomException("Cannot convert Operand.OpMask to GpuConstantType"); } stream.Write(this.gpuConstTypeMap[gpuType] + " " + paramName); itOperand++; //Prepare for the next operand if (itOperand != itOperandEnd) { stream.Write(", "); } } stream.WriteLine(); stream.WriteLine("{"); stream.WriteLine(body); stream.WriteLine("}"); stream.WriteLine(); } } }
private void WriteForwardDeclarations(StreamWriter stream, Program program) { stream.WriteLine("//-----------------------------------------------------------------------------"); stream.WriteLine("// FORWARD DECLARATIONS"); stream.WriteLine("//-----------------------------------------------------------------------------"); var forwardDecl = new List <string>(); // hold all generated function declarations var functionList = program.Functions; foreach (var curFunction in functionList) { var atomInstances = curFunction.AtomInstances; for (int i = 0; i < atomInstances.Count; i++) { var itAtom = atomInstances[i]; //Skip non function invocation atoms if (!(itAtom is FunctionInvocation)) { continue; } var funcInvoc = itAtom as FunctionInvocation; int itOperator = 0; int itOperatorEnd = funcInvoc.OperandList.Count; //Start with function declaration string funcDecl = funcInvoc.ReturnType + " " + funcInvoc.FunctionName + "("; //Now iterate overall operands while (itOperator != itOperatorEnd) { Parameter param = funcInvoc.OperandList[itOperator].Parameter; Operand.OpSemantic opSemantic = funcInvoc.OperandList[itOperator].Semantic; int opMask = funcInvoc.OperandList[itOperator].Mask; Axiom.Graphics.GpuProgramParameters.GpuConstantType gpuType = GpuProgramParameters.GpuConstantType.Unknown; //Write the semantic in, out, inout switch (opSemantic) { case Operand.OpSemantic.In: funcDecl += "in "; break; case Operand.OpSemantic.Out: funcDecl += "out "; break; case Operand.OpSemantic.InOut: funcDecl += "inout "; break; default: break; } //Swizzle masks are only defined fro types like vec2, vec3, vec4 if (opMask == (int)Operand.OpMask.All) { gpuType = param.Type; } else { //Now we have to conver the mask to operator gpuType = Operand.GetGpuConstantType(opMask); } //We need a valid type otherwise glsl compilation will not work if (gpuType == GpuProgramParameters.GpuConstantType.Unknown) { throw new Core.AxiomException("Cannot convert Operand.OpMask to GpuConstantType"); } //Write the operand type. funcDecl += this.gpuConstTypeMap[gpuType]; itOperator++; //move over all operators with indirection while ((itOperator != itOperatorEnd) && (funcInvoc.OperandList[itOperator].IndirectionLevel != 0)) { itOperator++; } //Prepare for the next operand if (itOperator != itOperatorEnd) { funcDecl += ", "; } } //Write function call closer. funcDecl += ");\n"; //Push the generated declaration into the vector //duplicate declarations will be removed later. forwardDecl.Add(funcDecl); } } //Now remove duplicate declaration, first we have to sort the vector. forwardDecl.Sort(); forwardDecl = forwardDecl.Distinct().ToList(); foreach (var it in forwardDecl) { stream.Write(it); } }