DE_DECLARE_COMMAND_LINE_OPT(OptimizeSpirv, bool);
DE_DECLARE_COMMAND_LINE_OPT(ShaderCacheTruncate, bool);
DE_DECLARE_COMMAND_LINE_OPT(RenderDoc, bool);
+DE_DECLARE_COMMAND_LINE_OPT(CaseFraction, std::vector<int>);
static void parseIntList (const char* src, std::vector<int>* dst)
{
<< Option<ShaderCache> (DE_NULL, "deqp-shadercache", "Enable or disable shader cache", s_enableNames, "enable")
<< Option<ShaderCacheFilename> (DE_NULL, "deqp-shadercache-filename", "Write shader cache to given file", "shadercache.bin")
<< Option<ShaderCacheTruncate> (DE_NULL, "deqp-shadercache-truncate", "Truncate shader cache before running tests", s_enableNames, "enable")
- << Option<RenderDoc> (DE_NULL, "deqp-renderdoc", "Enable RenderDoc frame markers", s_enableNames, "disable");
+ << Option<RenderDoc> (DE_NULL, "deqp-renderdoc", "Enable RenderDoc frame markers", s_enableNames, "disable")
+ << Option<CaseFraction> (DE_NULL, "deqp-case-fraction", "Run a fraction of the test cases (e.g. N,M means run group%M==N)", parseIntList, "");
}
void registerLegacyOptions (de::cmdline::Parser& parser)
int CommandLine::getOptimizationRecipe (void) const { return m_cmdLine.getOption<opt::Optimization>(); }
bool CommandLine::isSpirvOptimizationEnabled (void) const { return m_cmdLine.getOption<opt::OptimizeSpirv>(); }
bool CommandLine::isRenderDocEnabled (void) const { return m_cmdLine.getOption<opt::RenderDoc>(); }
+const std::vector<int>& CommandLine::getCaseFraction (void) const { return m_cmdLine.getOption<opt::CaseFraction>(); }
const char* CommandLine::getGLContextType (void) const
{
}
else if (cmdLine.hasOption<opt::CasePath>())
m_casePaths = de::MovePtr<const CasePaths>(new CasePaths(cmdLine.getOption<opt::CasePath>()));
+
+ m_caseFraction = cmdLine.getOption<opt::CaseFraction>();
+
+ if (m_caseFraction.size() == 2 &&
+ (m_caseFraction[0] < 0 || m_caseFraction[1] <= 0 || m_caseFraction[0] >= m_caseFraction[1]))
+ throw Exception("Invalid case fraction. First element must be less than second element. Second element must be positive. First element must be non-negative.");
+
+ if (m_caseFraction.size() != 0 && m_caseFraction.size() != 2)
+ throw Exception("Invalid case fraction. Must have two components.");
}
CaseListFilter::~CaseListFilter (void)
//! Check if test case is in supplied test case list.
bool checkTestCaseName (const char* caseName) const;
+ //! Check if test group passes the case fraction filter.
+ bool checkCaseFraction (int i) const {
+ return m_caseFraction.size() != 2 ||
+ ((i % m_caseFraction[1]) == m_caseFraction[0]);
+ }
+
private:
CaseListFilter (const CaseListFilter&); // not allowed!
CaseListFilter& operator= (const CaseListFilter&); // not allowed!
CaseTreeNode* m_caseTree;
de::MovePtr<const CasePaths> m_casePaths;
+ std::vector<int> m_caseFraction;
};
/*--------------------------------------------------------------------*//*!
//! Enable RenderDoc frame markers (--deqp-renderdoc)
bool isRenderDocEnabled (void) const;
+ //! Get case list fraction
+ const std::vector<int>& getCaseFraction (void) const;
+
/*--------------------------------------------------------------------*//*!
* \brief Creates case list filter
* \param archive Resources
const CaseListFilter& caseListFilter)
: m_inflater (inflater)
, m_caseListFilter (caseListFilter)
+ , m_groupNumber (0)
{
// Init traverse state and "seek" to first reportable node.
NodeIter iter(&rootNode);
{
// Push child to stack.
TestNode* childNode = iter.children[iter.curChildNdx];
+
+ // Check whether this is a bottom-level group (child is executable)
+ // and whether that group should be filtered out.
+ if (isTestNodeTypeExecutable(childNode->getNodeType()) &&
+ !m_caseListFilter.checkCaseFraction(m_groupNumber)) {
+ break;
+ }
m_sessionStack.push_back(NodeIter(childNode));
}
else
default:
DE_ASSERT(false);
}
+ m_groupNumber++;
}
m_sessionStack.pop_back();