void CompileShader(const String& fileName) { String file = GetFileName(fileName); XMLFile doc(context_); File source(context_); source.Open(fileName); if (!doc.Load(source)) ErrorExit("Could not open input file " + fileName); XMLElement shaders = doc.GetRoot("shaders"); if (!shaders) ErrorExit("No shaders element in " + source.GetName()); if (compileVS_) { ShaderParser vsParser; if (!vsParser.Parse(VS, shaders, defines_, defineValues_)) ErrorExit("VS: " + vsParser.GetErrorMessage()); const HashMap<String, unsigned>& combinations = vsParser.GetAllCombinations(); for (HashMap<String, unsigned>::ConstIterator i = combinations.Begin(); i != combinations.End(); ++i) { if (!compileVariation_ || i->first_ == variationName_) { ShaderCombination src = vsParser.GetCombination(i->first_); CompiledVariation compile; compile.type_ = VS; compile.name_ = file; compile.outFileName_ = outDir_ + file; if (!src.name_.Empty()) { compile.name_ += "_" + src.name_; compile.outFileName_ += "_" + src.name_; } compile.outFileName_ += useSM3_ ? ".vs3" : ".vs2"; compile.defines_ = src.defines_; compile.defineValues_ = src.defineValues_; variations_.Push(compile); workList_.Push(&variations_.Back()); } } } if (compilePS_) { ShaderParser psParser; if (!psParser.Parse(PS, shaders, defines_, defineValues_)) ErrorExit("PS: " + psParser.GetErrorMessage()); const HashMap<String, unsigned>& combinations = psParser.GetAllCombinations(); for (HashMap<String, unsigned>::ConstIterator i = combinations.Begin(); i != combinations.End(); ++i) { if (!compileVariation_ || i->first_ == variationName_) { ShaderCombination src = psParser.GetCombination(i->first_); CompiledVariation compile; compile.type_ = PS; compile.name_ = file; compile.outFileName_ = outDir_ + file; if (!src.name_.Empty()) { compile.name_ += "_" + src.name_; compile.outFileName_ += "_" + src.name_; } compile.outFileName_ += useSM3_ ? ".ps3" : ".ps2"; compile.defines_ = src.defines_; compile.defineValues_ = src.defineValues_; variations_.Push(compile); workList_.Push(&variations_.Back()); } } } if (variations_.Empty()) { PrintLine("No variations to compile"); return; } // Load the shader source code { String inputFileName = inDir_ + file + ".hlsl"; File hlslFile(context_, inputFileName); if (!hlslFile.IsOpen()) ErrorExit("Could not open input file " + inputFileName); hlslCode_.Clear(); while (!hlslFile.IsEof()) hlslCode_ += hlslFile.ReadLine() + "\n"; } if (!compileVariation_) { // Create and start worker threads. Use all logical CPUs except one to not lock up the computer completely unsigned numWorkerThreads = GetNumLogicalCPUs() - 1; if (!numWorkerThreads) numWorkerThreads = 1; Vector<SharedPtr<WorkerThread> > workerThreads; workerThreads.Resize(numWorkerThreads); for (unsigned i = 0; i < workerThreads.Size(); ++i) { workerThreads[i] = new WorkerThread(); workerThreads[i]->Run(); } // This will wait until the thread functions have stopped for (unsigned i = 0; i < workerThreads.Size(); ++i) workerThreads[i]->Stop(); } else { WorkerThread dummyThread; dummyThread.ThreadFunction(); } // Check that all shaders compiled for (List<CompiledVariation>::Iterator i = variations_.Begin(); i != variations_.End(); ++i) { if (!i->errorMsg_.Empty()) { if (i->type_ == VS) ErrorExit("Failed to compile vertex shader " + i->name_ + ": " + i->errorMsg_); else ErrorExit("Failed to compile pixel shader " + i->name_ + ": " + i->errorMsg_); } } }