private bool CreateGpuPrograms(ProgramSet programSet) { // Before we start we need to make sure that the pixel shader input // parameters are the same as the vertex output, this required by // shader models 4 and 5. // This change may incrase the number of register used in older shader // models - this is why the check is present here. bool isVs4 = GpuProgramManager.Instance.IsSyntaxSupported("vs_4_0"); if (isVs4) { SynchronizePixelnToBeVertexOut(programSet); } //Grab the matching writer string language = ShaderGenerator.Instance.TargetLangauge; ProgramWriter programWriter = null; if (this.programWritersMap.ContainsKey(language)) { programWriter = this.programWritersMap[language]; } else { programWriter = ProgramWriterManager.Instance.CreateProgramWriter(language); this.programWritersMap.Add(language, programWriter); } ProgramProcessor programProcessor = null; if (this.programProcessorMap.ContainsKey(language) == false) { throw new AxiomException("Could not find processor for language " + language); } programProcessor = this.programProcessorMap[language]; bool success; //Call the pre creation of GPU programs method success = programProcessor.PreCreateGpuPrograms(programSet); if (success == false) { return(false); } //Create the vertex shader program GpuProgram vsGpuProgram; vsGpuProgram = CreateGpuProgram(programSet.CpuVertexProgram, programWriter, language, ShaderGenerator.Instance.VertexShaderProfiles, ShaderGenerator.Instance.VertexShaderProfilesList, ShaderGenerator.Instance.ShaderChachePath); if (vsGpuProgram == null) { return(false); } programSet.GpuVertexProgram = vsGpuProgram; //update flags programSet.GpuVertexProgram.IsSkeletalAnimationIncluded = programSet.CpuVertexProgram.SkeletalAnimationIncluded; //Create the fragment shader program. GpuProgram psGpuProgram; psGpuProgram = CreateGpuProgram(programSet.CpuFragmentProgram, programWriter, language, ShaderGenerator.Instance.FragmentShaderProfiles, ShaderGenerator.Instance.FragmentShaderProfilesList, ShaderGenerator.Instance.ShaderChachePath); if (psGpuProgram == null) { return(false); } programSet.GpuFragmentProgram = psGpuProgram; //Call the post creation of GPU programs method. success = programProcessor.PostCreateGpuPrograms(programSet); if (success == false) { return(false); } return(true); }
private GpuProgram CreateGpuProgram(Program shaderProgram, ProgramWriter programWriter, string language, string profiles, string[] profilesList, string cachePath) { StreamWriter sourceCodeStringStream = null; int programHashCode; string programName; //Generate source code programWriter.WriteSourceCode(sourceCodeStringStream, shaderProgram); programHashCode = sourceCodeStringStream.GetHashCode(); //Generate program name programName = programHashCode.ToString(); if (shaderProgram.Type == GpuProgramType.Vertex) { programName += "_VS"; } else if (shaderProgram.Type == GpuProgramType.Fragment) { programName += "_FS"; } HighLevelGpuProgram gpuProgram; //Try to get program by name gpuProgram = (HighLevelGpuProgram)HighLevelGpuProgramManager.Instance.GetByName(programName); //Case the program doesn't exist yet if (gpuProgram == null) { //Create new GPU program. gpuProgram = HighLevelGpuProgramManager.Instance.CreateProgram(programName, ResourceGroupManager. DefaultResourceGroupName, language, shaderProgram.Type); //Case cache directory specified -> create program from file if (cachePath == string.Empty) { string programFullName = programName + "." + language; string programFileName = cachePath + programFullName; bool writeFile = true; //Check if program file already exists if (File.Exists(programFileName)) { writeFile = true; } else { writeFile = false; } if (writeFile) { var outFile = new StreamWriter(programFileName); outFile.Write(sourceCodeStringStream); outFile.Close(); } gpuProgram.SourceFile = programFullName; } else // no cache directory specified -> create program from system memory { //TODO // gpuProgram.Source = sourceCodeStringStream; } var gpuParams = new Collections.NameValuePairList(); gpuParams.Add("entry_point", shaderProgram.EntryPointFunction.Name); gpuProgram.SetParameters(gpuParams); gpuParams.Clear(); // HLSL program requires specific target profile settings - we have to split the profile string. if (language == "hlsl") { foreach (var it in profilesList) { if (GpuProgramManager.Instance.IsSyntaxSupported(it)) { gpuParams.Add("target", it); gpuProgram.SetParameters(gpuParams); gpuParams.Clear(); break; } } } gpuParams.Add("profiles", profiles); gpuProgram.SetParameters(gpuParams); gpuProgram.Load(); //Case an error occurred if (gpuProgram.HasCompileError) { gpuProgram = null; return(gpuProgram); } //Add the created GPU prgram to local cache if (gpuProgram.Type == GpuProgramType.Vertex) { this.vertexShaderMap[programName] = gpuProgram; } else if (gpuProgram.Type == GpuProgramType.Fragment) { this.fragmentShaderMap[programName] = gpuProgram; } } return(gpuProgram); }
private GpuProgram CreateGpuProgram( Program shaderProgram, ProgramWriter programWriter, string language, string profiles, string[] profilesList, string cachePath ) { StreamWriter sourceCodeStringStream = null; int programHashCode; string programName; //Generate source code programWriter.WriteSourceCode( sourceCodeStringStream, shaderProgram ); programHashCode = sourceCodeStringStream.GetHashCode(); //Generate program name programName = programHashCode.ToString(); if ( shaderProgram.Type == GpuProgramType.Vertex ) { programName += "_VS"; } else if ( shaderProgram.Type == GpuProgramType.Fragment ) { programName += "_FS"; } HighLevelGpuProgram gpuProgram; //Try to get program by name gpuProgram = (HighLevelGpuProgram)HighLevelGpuProgramManager.Instance.GetByName( programName ); //Case the program doesn't exist yet if ( gpuProgram == null ) { //Create new GPU program. gpuProgram = HighLevelGpuProgramManager.Instance.CreateProgram( programName, ResourceGroupManager. DefaultResourceGroupName, language, shaderProgram.Type ); //Case cache directory specified -> create program from file if ( cachePath == string.Empty ) { string programFullName = programName + "." + language; string programFileName = cachePath + programFullName; bool writeFile = true; //Check if program file already exists if ( File.Exists( programFileName ) ) { writeFile = true; } else { writeFile = false; } if ( writeFile ) { var outFile = new StreamWriter( programFileName ); outFile.Write( sourceCodeStringStream ); outFile.Close(); } gpuProgram.SourceFile = programFullName; } else // no cache directory specified -> create program from system memory { //TODO // gpuProgram.Source = sourceCodeStringStream; } var gpuParams = new Collections.NameValuePairList(); gpuParams.Add( "entry_point", shaderProgram.EntryPointFunction.Name ); gpuProgram.SetParameters( gpuParams ); gpuParams.Clear(); // HLSL program requires specific target profile settings - we have to split the profile string. if ( language == "hlsl" ) { foreach ( var it in profilesList ) { if ( GpuProgramManager.Instance.IsSyntaxSupported( it ) ) { gpuParams.Add( "target", it ); gpuProgram.SetParameters( gpuParams ); gpuParams.Clear(); break; } } } gpuParams.Add( "profiles", profiles ); gpuProgram.SetParameters( gpuParams ); gpuProgram.Load(); //Case an error occurred if ( gpuProgram.HasCompileError ) { gpuProgram = null; return gpuProgram; } //Add the created GPU prgram to local cache if ( gpuProgram.Type == GpuProgramType.Vertex ) { this.vertexShaderMap[ programName ] = gpuProgram; } else if ( gpuProgram.Type == GpuProgramType.Fragment ) { this.fragmentShaderMap[ programName ] = gpuProgram; } } return gpuProgram; }