GX shader cook fixes; Resource cook passes

This commit is contained in:
Jack Andersen 2018-04-01 18:26:21 -10:00
parent c9f61eb9da
commit 94988eb9e5
7 changed files with 94 additions and 28 deletions

View File

@ -55,7 +55,8 @@ class VertPool:
# Per-loop pool attributes
for f in bm.faces:
lightmapped = material_slots[f.material_index].material['retro_lightmapped']
lightmapped = f.material_index < len(material_slots) and \
material_slots[f.material_index].material['retro_lightmapped']
for l in f.loops:
if rna_loops:
nf = rna_loops[l.index].normal.copy().freeze()

View File

@ -168,8 +168,9 @@ public:
{
hecl::MultiProgressPrinter printer(true);
hecl::ClientProcess cp(&printer, m_info.verbosityLevel);
for (const hecl::ProjectPath& path : m_selectedItems)
m_useProj->cookPath(path, printer, m_recursive, m_info.force, m_fast, m_spec, &cp);
for (int i=0 ; i<m_spec->m_numCookPasses ; ++i)
for (const hecl::ProjectPath& path : m_selectedItems)
m_useProj->cookPath(path, printer, m_recursive, m_info.force, m_fast, m_spec, &cp, i);
cp.waitUntilComplete();
return 0;
}

View File

@ -564,6 +564,7 @@ private:
unsigned addTexCoordGen(Diagnostics& diag, const SourceLocation& loc,
TexGenSrc src, TexMtx mtx, bool norm, PTTexMtx pmtx);
TEVStage& addTEVStage(Diagnostics& diag, const SourceLocation& loc);
TEVStage& addAlphaTEVStage(Diagnostics& diag, const SourceLocation& loc);
TraceResult RecursiveTraceColor(const IR& ir, Diagnostics& diag,
const IR::Instruction& inst,
bool swizzleAlpha=false);

View File

@ -103,8 +103,8 @@ public:
virtual void doExtract(const ExtractPassInfo& info, const MultiProgressPrinter& progress)
{(void)info;(void)progress;}
virtual bool canCook(const ProjectPath& path, blender::Token& btok)
{(void)path;LogModule.report(logvisor::Error, "not implemented");return false;}
virtual bool canCook(const ProjectPath& path, blender::Token& btok, int cookPass = -1)
{(void)path;LogModule.report(logvisor::Error, "not implemented");(void)cookPass;return false;}
virtual const DataSpecEntry* overrideDataSpec(const ProjectPath& path,
const Database::DataSpecEntry* oldEntry,
blender::Token& btok) const
@ -145,11 +145,13 @@ struct DataSpecEntry
SystemStringView m_name;
SystemStringView m_desc;
SystemStringView m_pakExt;
int m_numCookPasses;
std::function<std::unique_ptr<IDataSpec>(Project&, DataSpecTool)> m_factory;
DataSpecEntry(SystemStringView name, SystemStringView desc, SystemStringView pakExt,
DataSpecEntry(SystemStringView name, SystemStringView desc, SystemStringView pakExt, int numCookPasses,
std::function<std::unique_ptr<IDataSpec>(Project& project, DataSpecTool)>&& factory)
: m_name(name), m_desc(desc), m_pakExt(pakExt), m_factory(std::move(factory)) {}
: m_name(name), m_desc(desc), m_pakExt(pakExt), m_numCookPasses(numCookPasses),
m_factory(std::move(factory)) {}
};
/**
@ -404,6 +406,10 @@ public:
* @param fast enables faster (draft) extraction for supported data types
* @param spec if non-null, cook using a manually-selected dataspec
* @param cp if non-null, cook asynchronously via the ClientProcess
* @param cookPass cookPath() should be called the number of times
* prescribed in DataSpecEntry at the root-most invocation.
* This value conveys the pass index through the call tree.
* Negative values mean "cook always".
* @return true on success
*
* Object cooking is generally an expensive process for large projects.
@ -412,7 +418,8 @@ public:
*/
bool cookPath(const ProjectPath& path, const MultiProgressPrinter& feedbackCb,
bool recursive=false, bool force=false, bool fast=false,
const DataSpecEntry* spec=nullptr, ClientProcess* cp=nullptr);
const DataSpecEntry* spec=nullptr, ClientProcess* cp=nullptr,
int cookPass = -1);
/**
* @brief Begin package process for specified !world.blend or directory

View File

@ -78,6 +78,18 @@ GX::TEVStage& GX::addTEVStage(Diagnostics& diag, const SourceLocation& loc)
return newTEV;
}
GX::TEVStage& GX::addAlphaTEVStage(Diagnostics& diag, const SourceLocation& loc)
{
++m_alphaTraceStage;
while (m_tevCount < m_alphaTraceStage + 1)
{
TEVStage& stage = addTEVStage(diag, loc);
stage.m_color[3] = CC_CPREV;
stage.m_alpha[3] = CA_APREV;
}
return m_tevs[m_alphaTraceStage];
}
unsigned GX::RecursiveTraceTexGen(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, TexMtx mtx,
bool normalize, PTTexMtx pmtx)
{
@ -431,10 +443,10 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
unsigned mapIdx = unsigned(mapImm.vec[0]);
int foundStage = -1;
for (int i=0 ; i<int(m_tevCount) ; ++i)
for (int i=m_alphaTraceStage+1 ; i<int(m_tevCount) ; ++i)
{
TEVStage& testStage = m_tevs[i];
if (testStage.m_texMapIdx == mapIdx && i > m_alphaTraceStage)
if (testStage.m_texMapIdx == mapIdx)
{
foundStage = i;
break;
@ -449,7 +461,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
return TraceResult(&stage);
}
TEVStage& newStage = addTEVStage(diag, inst.m_loc);
TEVStage& newStage = addAlphaTEVStage(diag, inst.m_loc);
newStage.m_color[3] = CC_CPREV;
newStage.m_texMapIdx = mapIdx;
@ -480,6 +492,8 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
const atVec4f& vec = inst.m_loadImm.m_immVec;
if (vec.vec[0] == 0.f)
return TraceResult(CA_ZERO);
else if (vec.vec[0] == 1.f)
return TraceResult(TEV_KASEL_1);
unsigned idx = addKAlpha(diag, inst.m_loc, vec.vec[0]);
return TraceResult(TevKAlphaSel(TEV_KASEL_K0_A + idx));
}
@ -566,7 +580,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
else if (aTrace.type == TraceResult::Type::TEVAlphaArg &&
bTrace.type == TraceResult::Type::TEVAlphaArg)
{
TEVStage& stage = addTEVStage(diag, inst.m_loc);
TEVStage& stage = addAlphaTEVStage(diag, inst.m_loc);
stage.m_alpha[0] = aTrace.tevAlphaArg;
stage.m_alpha[3] = bTrace.tevAlphaArg;
stage.m_kAlpha = newKAlpha;
@ -614,7 +628,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
else if (aTrace.type == TraceResult::Type::TEVAlphaArg &&
bTrace.type == TraceResult::Type::TEVAlphaArg)
{
TEVStage& stage = addTEVStage(diag, inst.m_loc);
TEVStage& stage = addAlphaTEVStage(diag, inst.m_loc);
stage.m_alpha[0] = aTrace.tevAlphaArg;
stage.m_alpha[3] = bTrace.tevAlphaArg;
stage.m_kAlpha = newKAlpha;
@ -649,7 +663,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
else if (aTrace.type == TraceResult::Type::TEVAlphaArg &&
bTrace.type == TraceResult::Type::TEVAlphaArg)
{
TEVStage& stage = addTEVStage(diag, inst.m_loc);
TEVStage& stage = addAlphaTEVStage(diag, inst.m_loc);
stage.m_color[3] = CC_CPREV;
stage.m_alpha[1] = aTrace.tevAlphaArg;
stage.m_alpha[2] = bTrace.tevAlphaArg;
@ -664,7 +678,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
{
if (a->m_aRegOut != TEVPREV)
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
TEVStage& stage = addTEVStage(diag, inst.m_loc);
TEVStage& stage = addAlphaTEVStage(diag, inst.m_loc);
stage.m_alpha[1] = CA_APREV;
stage.m_alpha[2] = bTrace.tevAlphaArg;
stage.m_kAlpha = newKAlpha;
@ -684,7 +698,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
{
if (b->m_aRegOut != TEVPREV)
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
TEVStage& stage = addTEVStage(diag, inst.m_loc);
TEVStage& stage = addAlphaTEVStage(diag, inst.m_loc);
stage.m_alpha[1] = aTrace.tevAlphaArg;
stage.m_alpha[2] = CA_APREV;
stage.m_kAlpha = newKAlpha;
@ -765,14 +779,48 @@ void GX::reset(const IR& ir, Diagnostics& diag)
/* Follow Color Chain */
const IR::Instruction& colorRoot =
ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(0));
RecursiveTraceColor(ir, diag, colorRoot);
TraceResult result = RecursiveTraceColor(ir, diag, colorRoot);
switch (result.type)
{
case TraceResult::Type::TEVColorArg:
{
TEVStage& stage = addTEVStage(diag, colorRoot.m_loc);
stage.m_color[3] = result.tevColorArg;
break;
}
case TraceResult::Type::TEVKColorSel:
{
TEVStage& stage = addTEVStage(diag, colorRoot.m_loc);
stage.m_color[3] = CC_KONST;
stage.m_kColor = result.tevKColorSel;
break;
}
default: break;
}
/* Follow Alpha Chain */
if (rootCall.m_call.m_argInstIdxs.size() > 1)
{
const IR::Instruction& alphaRoot =
ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(1));
RecursiveTraceAlpha(ir, diag, alphaRoot);
TraceResult result = RecursiveTraceAlpha(ir, diag, alphaRoot);
switch (result.type)
{
case TraceResult::Type::TEVAlphaArg:
{
TEVStage& stage = addAlphaTEVStage(diag, alphaRoot.m_loc);
stage.m_alpha[3] = result.tevAlphaArg;
break;
}
case TraceResult::Type::TEVKAlphaSel:
{
TEVStage& stage = addAlphaTEVStage(diag, alphaRoot.m_loc);
stage.m_alpha[3] = CA_KONST;
stage.m_kAlpha = result.tevKAlphaSel;
break;
}
default: break;
}
/* Ensure Alpha reaches end of chain */
if (m_alphaTraceStage >= 0)

View File

@ -195,7 +195,11 @@ void MultiProgressPrinter::DoPrint()
}
}
if (m_mainIndeterminate)
if (m_mainIndeterminate
#ifndef _WIN32
&& m_termInfo.xtermColor
#endif
)
{
DrawIndeterminateBar();
hecl::Printf(_S("\n"));
@ -248,7 +252,11 @@ void MultiProgressPrinter::DoPrint()
}
m_dirty = false;
}
else if (m_mainIndeterminate)
else if (m_mainIndeterminate
#ifndef _WIN32
&& m_termInfo.xtermColor
#endif
)
{
m_termInfo.width = (hecl::GuiMode ? 120 : std::max(80, hecl::ConsoleWidth()));
MoveCursorUp(m_curProgLines);

View File

@ -388,11 +388,11 @@ public:
static void VisitFile(const ProjectPath& path, bool force, bool fast,
std::vector<std::unique_ptr<IDataSpec>>& specInsts,
CookProgress& progress, ClientProcess* cp)
CookProgress& progress, ClientProcess* cp, int cookPass)
{
for (auto& spec : specInsts)
{
if (spec->canCook(path, hecl::blender::SharedBlenderToken))
if (spec->canCook(path, hecl::blender::SharedBlenderToken, cookPass))
{
if (cp)
{
@ -425,7 +425,7 @@ static void VisitFile(const ProjectPath& path, bool force, bool fast,
static void VisitDirectory(const ProjectPath& dir,
bool recursive, bool force, bool fast,
std::vector<std::unique_ptr<IDataSpec>>& specInsts,
CookProgress& progress, ClientProcess* cp)
CookProgress& progress, ClientProcess* cp, int cookPass)
{
if (dir.getLastComponent().size() > 1 && dir.getLastComponent()[0] == _S('.'))
return;
@ -448,7 +448,7 @@ static void VisitDirectory(const ProjectPath& dir,
if (child.second.getPathType() == ProjectPath::Type::File)
{
progress.changeFile(child.first.c_str(), progNum++/progDenom);
VisitFile(child.second, force, fast, specInsts, progress, cp);
VisitFile(child.second, force, fast, specInsts, progress, cp, cookPass);
}
}
progress.reportDirComplete();
@ -462,7 +462,7 @@ static void VisitDirectory(const ProjectPath& dir,
{
case ProjectPath::Type::Directory:
{
VisitDirectory(child.second, recursive, force, fast, specInsts, progress, cp);
VisitDirectory(child.second, recursive, force, fast, specInsts, progress, cp, cookPass);
break;
}
default: break;
@ -473,7 +473,7 @@ static void VisitDirectory(const ProjectPath& dir,
bool Project::cookPath(const ProjectPath& path, const hecl::MultiProgressPrinter& progress,
bool recursive, bool force, bool fast, const DataSpecEntry* spec,
ClientProcess* cp)
ClientProcess* cp, int cookPass)
{
/* Construct DataSpec instances for cooking */
if (spec)
@ -501,12 +501,12 @@ bool Project::cookPath(const ProjectPath& path, const hecl::MultiProgressPrinter
case ProjectPath::Type::Glob:
{
cookProg.changeFile(path.getLastComponent().data(), 0.f);
VisitFile(path, force, fast, m_cookSpecs, cookProg, cp);
VisitFile(path, force, fast, m_cookSpecs, cookProg, cp, cookPass);
break;
}
case ProjectPath::Type::Directory:
{
VisitDirectory(path, recursive, force, fast, m_cookSpecs, cookProg, cp);
VisitDirectory(path, recursive, force, fast, m_cookSpecs, cookProg, cp, cookPass);
break;
}
default: break;