From: <re...@us...> - 2008-10-22 00:15:48
|
Revision: 31463 http://crystal.svn.sourceforge.net/crystal/?rev=31463&view=rev Author: res2002 Date: 2008-10-22 00:15:38 +0000 (Wed, 22 Oct 2008) Log Message: ----------- When precaching keep a map of conditions set for a variant. Traversing the variant tree is not enough as some conditions that were culled from the tree should actually be true for a variant. Such conditions were ignored before. This fixes wrong shader code being precached for some variants. Modified Paths: -------------- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.cpp CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.h CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condition.h CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.cpp CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.h CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.cpp CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.h Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.cpp =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.cpp 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.cpp 2008-10-22 00:15:38 UTC (rev 31463) @@ -963,7 +963,8 @@ return result; } -void csConditionEvaluator::ForceConditionResults (const csBitArray& condResults) +void csConditionEvaluator::ForceConditionResults ( + const csBitArray& condSet, const csBitArray& condResults) { /* Hack: it can happen that while evaluating a shader, new conditions * are added (notably when a shader source is retrieved from an @@ -974,10 +975,12 @@ condChecked.SetSize (GetNumConditions ()); condResult.SetSize (GetNumConditions ()); } + condChecked.Clear(); + condResult.Clear(); for (size_t i = 0; i < condResults.GetSize(); i++) { - condChecked.Set (i, true); + condChecked.Set (i, condSet[i]); condResult.Set (i, condResults[i]); } } Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.h =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.h 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condeval.h 2008-10-22 00:15:38 UTC (rev 31463) @@ -781,7 +781,8 @@ bool Evaluate (csConditionID condition, const CS::Graphics::RenderMeshModes& modes, const csShaderVariableStack* stack); - void ForceConditionResults (const csBitArray& condResults); + void ForceConditionResults (const csBitArray& condSet, + const csBitArray& condResults); /** * Start an evaluation. If this is the first nested evaluation the evaluation cache Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condition.h =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condition.h 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/condition.h 2008-10-22 00:15:38 UTC (rev 31463) @@ -70,6 +70,7 @@ typedef size_t csConditionID; const csConditionID csCondAlwaysFalse = (csConditionID)~0; const csConditionID csCondAlwaysTrue = (csConditionID)~1; + const csConditionID csCondUnknown = (csConditionID)~2; /// An actual operand. struct CondOperand Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.cpp =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.cpp 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.cpp 2008-10-22 00:15:38 UTC (rev 31463) @@ -56,21 +56,31 @@ struct Node { - static const csConditionID csCondUnknown = (csConditionID)~2; - Node* parent; csConditionID condition; Node* branches[2]; Variables values; MyBitArrayTemp conditionAffectedSVs; + MyBitArrayTemp conditionResults; Node (Node* p) : parent (p), condition (csCondUnknown) { + if (p != 0) conditionResults = p->conditionResults; branches[bTrue] = 0; branches[bFalse] = 0; } + void SetConditionResult (csConditionID cond, bool val) + { + if (conditionResults.GetSize() <= cond) + conditionResults.SetSize (cond+1); + if (val) + conditionResults.SetBit (cond); + + if (branches[bTrue]) branches[bTrue]->SetConditionResult (cond, val); + if (branches[bFalse]) branches[bFalse]->SetConditionResult (cond, val); + } }; csFixedSizeAllocator<sizeof (Node), TempHeapAlloc> nodeAlloc; @@ -127,7 +137,7 @@ NodeStackEntry* newPair = nodeStackEntryAlloc.Alloc(); newPair->branches[bTrue].Push (root); nodeStack.Push (newPair); - cheapshotCondition = (csConditionID)~2; + cheapshotCondition = csCondUnknown; } ~ConditionTree () { @@ -160,7 +170,7 @@ } Logic3 r; - bool isLeaf = node->condition == Node::csCondUnknown; + bool isLeaf = node->condition == csCondUnknown; bool doCheck = true; if (node->parent != 0) { @@ -208,9 +218,11 @@ switch (r.state) { case Logic3::Truth: + node->SetConditionResult (condition, true); newCurrent.branches[bTrue].Push (node); break; case Logic3::Lie: + node->SetConditionResult (condition, false); newCurrent.branches[bFalse].Push (node); break; case Logic3::Uncertain: @@ -273,6 +285,7 @@ { nn->values = (b == bTrue) ? trueVals : falseVals; } + nn->SetConditionResult (condition, b == bTrue); //node->branches[b] = nn; CommitNode commitNode; commitNode.owner = node; @@ -296,9 +309,11 @@ switch (r.state) { case Logic3::Truth: + node->SetConditionResult (condition, true); newCurrent.branches[bTrue].Push (node); break; case Logic3::Lie: + node->SetConditionResult (condition, false); newCurrent.branches[bFalse].Push (node); break; case Logic3::Uncertain: @@ -399,12 +414,11 @@ void ConditionTree::ToResolver (iConditionResolver* resolver, Node* node, csConditionNode* parent) { - if (node->condition == Node::csCondUnknown) return; - csConditionNode* trueNode; csConditionNode* falseNode; - resolver->AddNode (parent, node->condition, trueNode, falseNode); + resolver->AddNode (parent, node->condition, trueNode, falseNode, + node->conditionResults); if (node->branches[bTrue] != 0) ToResolver (resolver, node->branches[bTrue], trueNode); if (node->branches[bFalse] != 0) Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.h =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.h 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/cpi/docwrap.h 2008-10-22 00:15:38 UTC (rev 31463) @@ -75,7 +75,8 @@ */ virtual void AddNode (csConditionNode* parent, csConditionID condition, csConditionNode*& trueNode, - csConditionNode*& falseNode) = 0; + csConditionNode*& falseNode, + const MyBitArrayTemp& conditionResults) = 0; /// Finish adding of nodes. Frees up some tempoarily used resources. virtual void FinishAdding () = 0; Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.cpp =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.cpp 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.cpp 2008-10-22 00:15:38 UTC (rev 31463) @@ -47,8 +47,10 @@ //--------------------------------------------------------------------------- csShaderConditionResolver::csShaderConditionResolver ( - csConditionEvaluator& evaluator) - : rootNode (0), nextVariant (0), evaluator (evaluator) + csConditionEvaluator& evaluator, bool keepVariantToConditionsMap) + : rootNode (0), nextVariant (0), + keepVariantToConditionsMap (keepVariantToConditionsMap), + evaluator (evaluator) { SetEvalParams (0, 0); } @@ -141,8 +143,17 @@ void csShaderConditionResolver::AddNode (csConditionNode* parent, csConditionID condition, csConditionNode*& trueNode, - csConditionNode*& falseNode) + csConditionNode*& falseNode, + const MyBitArrayTemp& conditionResults) { + if (condition == csCondUnknown) + { + CS_ASSERT(parent->variant != csArrayItemNotFound); + if (keepVariantToConditionsMap) + variantConditions.PutUnique (parent->variant, conditionResults); + return; + } + if (rootNode == 0) { // This is the first condition, new node gets root @@ -222,36 +233,24 @@ } } -bool csShaderConditionResolver::SetVariantRecursive (size_t variant, - csConditionNode* node, - csBitArray& conditionResults) -{ - if (node->variant != csArrayItemNotFound) - { - return node->variant == variant; - } - - if (SetVariantRecursive (variant, node->trueNode, conditionResults)) - { - conditionResults.SetBit (node->condition); - return true; - } - else if (SetVariantRecursive (variant, node->falseNode, conditionResults)) - return true; - else - return false; -} - void csShaderConditionResolver::SetVariant (size_t variant) { if (rootNode == 0) return; + CS_ASSERT(keepVariantToConditionsMap); csBitArray conditionResults (evaluator.GetNumConditions()); - if (SetVariantRecursive (variant, rootNode->trueNode, conditionResults)) - conditionResults.SetBit (rootNode->condition); - else - SetVariantRecursive (variant, rootNode->falseNode, conditionResults); - evaluator.ForceConditionResults (conditionResults); + csBitArray conditionSet (evaluator.GetNumConditions()); + MyBitArrayTemp* conditionResultsPtr = variantConditions.GetElementPointer ( + variant); + CS_ASSERT(conditionResultsPtr); + + size_t i = 0; + for (; i < conditionResultsPtr->GetSize(); i++) + { + conditionResults.Set (i, (*conditionResultsPtr)[i]); + conditionSet.SetBit (i); + } + evaluator.ForceConditionResults (conditionSet, conditionResults); } void csShaderConditionResolver::DumpConditionTree (csString& out) @@ -488,9 +487,10 @@ * cache file format changes. */ static const uint32 cacheFileMagic = 0x06737863; -void csXMLShader::Load (iDocumentNode* source, bool noCacheRead) +void csXMLShader::Load (iDocumentNode* source, bool forPrecache) { - techsResolver = new csShaderConditionResolver (*sharedEvaluator); + techsResolver = new csShaderConditionResolver (*sharedEvaluator, + forPrecache); CS::PluginCommon::ShaderCacheHelper::ShaderDocHasher hasher ( compiler->objectreg, source); @@ -513,7 +513,7 @@ bool cacheValid = (shaderCache != 0) && !cacheType.IsEmpty() && !cacheID_header.IsEmpty(); if (!cacheValid) shaderCache.Invalidate(); - bool readFromCache = cacheValid && !noCacheRead; + bool readFromCache = cacheValid && !forPrecache; csRef<iFile> cacheFile; if (cacheValid) @@ -570,8 +570,8 @@ { csRef<iDataBuffer> hashStream = hasher.GetHashStream (); /* @@@ Actually, the cache tag wouldn't have to be that large. - In theory, anything would work as long as (a) it changes when the - shader or some file it uses changes (b) the tag is reasonably + In theory, anything would work as long as (a) it changes when + some file the shader uses changes (b) the tag is reasonably unique (also over multiple program runs). E.g. a UUID, recomputed when the shader is 'touched', could do as well. */ @@ -620,7 +620,8 @@ { // Make sure resolver is pristine delete techsResolver; - techsResolver = new csShaderConditionResolver (*sharedEvaluator); + techsResolver = new csShaderConditionResolver (*sharedEvaluator, + forPrecache); } } @@ -706,14 +707,14 @@ for (size_t t = 0; t < techVar.techniques.GetSize(); t++) { ShaderTechVariant::Technique& tech = techVar.techniques[t]; - tech.resolver = new csShaderConditionResolver (*sharedEvaluator); + tech.resolver = new csShaderConditionResolver (*sharedEvaluator, true); tech.resolver->SetVariant (t); csRef<iHierarchicalCache> techCache; techCache = shaderCache->GetRootedCache ( csString().Format ("/%s/%zu/%zu", cacheScope_tech.GetData(), tvi, t)); - LoadTechnique (tech, techCache, tvi); + LoadTechnique (tech, techCache, tvi, true); if (compiler->do_verbose) compiler->Report (CS_REPORTER_SEVERITY_NOTIFY, @@ -1195,7 +1196,7 @@ ConditionsReader condReader (*sharedEvaluator, conditionsBuf); - tech.resolver = new csShaderConditionResolver (*sharedEvaluator); + tech.resolver = new csShaderConditionResolver (*sharedEvaluator, false); if (!tech.resolver->ReadFromCache (cacheFile, condReader)) { delete tech.resolver; @@ -1214,9 +1215,10 @@ void csXMLShader::LoadTechnique (ShaderTechVariant::Technique& tech, iHierarchicalCache* cacheTo, - size_t dbgTechNum) + size_t dbgTechNum, bool forPrecache) { - tech.resolver = new csShaderConditionResolver (*sharedEvaluator); + tech.resolver = new csShaderConditionResolver (*sharedEvaluator, + forPrecache); csRefArray<iDocumentNode> extraNodes; static const char* const extraNodeNames[] = { "vp", "fp", "vproc", 0 }; Modified: CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.h =================================================================== --- CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.h 2008-10-21 19:32:00 UTC (rev 31462) +++ CS/trunk/plugins/video/render3d/shader/shadercompiler/xmlshader/shader.h 2008-10-22 00:15:38 UTC (rev 31463) @@ -84,6 +84,8 @@ csConditionNode* rootNode; size_t nextVariant; csHash<size_t, MyBitArrayTemp, TempHeapAlloc> variantIDs; + bool keepVariantToConditionsMap; + csHash<MyBitArrayTemp, size_t, TempHeapAlloc> variantConditions; const CS::Graphics::RenderMeshModes* modes; const csShaderVariableStack* stack; @@ -105,11 +107,12 @@ const ConditionsWriter& condWrite); bool SetVariantRecursive (size_t variant, csConditionNode* node, - csBitArray& conditionResults); + csBitArray& condSet, csBitArray& conditionResults); public: csConditionEvaluator& evaluator; - csShaderConditionResolver (csConditionEvaluator& evaluator); + csShaderConditionResolver (csConditionEvaluator& evaluator, + bool keepVariantToConditionsMap); virtual ~csShaderConditionResolver (); virtual const char* ParseCondition (const char* str, size_t len, @@ -121,7 +124,8 @@ virtual void AddNode (csConditionNode* parent, csConditionID condition, csConditionNode*& trueNode, - csConditionNode*& falseNode); + csConditionNode*& falseNode, + const MyBitArrayTemp& conditionResults); virtual void FinishAdding (); void SetEvalParams (const CS::Graphics::RenderMeshModes* modes, @@ -272,7 +276,7 @@ protected: void InternalRemove() { SelfDestruct(); } - void Load (iDocumentNode* source, bool noCacheRead); + void Load (iDocumentNode* source, bool forPrecache); void PrepareTechVar (ShaderTechVariant& techVar, int forcepriority); @@ -280,7 +284,8 @@ bool LoadTechniqueFromCache (ShaderTechVariant::Technique& tech, iHierarchicalCache* cache); void LoadTechnique (ShaderTechVariant::Technique& tech, - iHierarchicalCache* cacheTo, size_t dbgTechNum); + iHierarchicalCache* cacheTo, size_t dbgTechNum, + bool forPrecache = true); public: CS_LEAKGUARD_DECLARE (csXMLShader); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |