2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-03 07:55:52 +00:00

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 # Per-loop pool attributes
for f in bm.faces: 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: for l in f.loops:
if rna_loops: if rna_loops:
nf = rna_loops[l.index].normal.copy().freeze() nf = rna_loops[l.index].normal.copy().freeze()

View File

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

View File

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

View File

@ -103,8 +103,8 @@ public:
virtual void doExtract(const ExtractPassInfo& info, const MultiProgressPrinter& progress) virtual void doExtract(const ExtractPassInfo& info, const MultiProgressPrinter& progress)
{(void)info;(void)progress;} {(void)info;(void)progress;}
virtual bool canCook(const ProjectPath& path, blender::Token& btok) virtual bool canCook(const ProjectPath& path, blender::Token& btok, int cookPass = -1)
{(void)path;LogModule.report(logvisor::Error, "not implemented");return false;} {(void)path;LogModule.report(logvisor::Error, "not implemented");(void)cookPass;return false;}
virtual const DataSpecEntry* overrideDataSpec(const ProjectPath& path, virtual const DataSpecEntry* overrideDataSpec(const ProjectPath& path,
const Database::DataSpecEntry* oldEntry, const Database::DataSpecEntry* oldEntry,
blender::Token& btok) const blender::Token& btok) const
@ -145,11 +145,13 @@ struct DataSpecEntry
SystemStringView m_name; SystemStringView m_name;
SystemStringView m_desc; SystemStringView m_desc;
SystemStringView m_pakExt; SystemStringView m_pakExt;
int m_numCookPasses;
std::function<std::unique_ptr<IDataSpec>(Project&, DataSpecTool)> m_factory; 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) 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 fast enables faster (draft) extraction for supported data types
* @param spec if non-null, cook using a manually-selected dataspec * @param spec if non-null, cook using a manually-selected dataspec
* @param cp if non-null, cook asynchronously via the ClientProcess * @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 * @return true on success
* *
* Object cooking is generally an expensive process for large projects. * Object cooking is generally an expensive process for large projects.
@ -412,7 +418,8 @@ public:
*/ */
bool cookPath(const ProjectPath& path, const MultiProgressPrinter& feedbackCb, bool cookPath(const ProjectPath& path, const MultiProgressPrinter& feedbackCb,
bool recursive=false, bool force=false, bool fast=false, 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 * @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; 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, unsigned GX::RecursiveTraceTexGen(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, TexMtx mtx,
bool normalize, PTTexMtx pmtx) 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]); unsigned mapIdx = unsigned(mapImm.vec[0]);
int foundStage = -1; 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]; TEVStage& testStage = m_tevs[i];
if (testStage.m_texMapIdx == mapIdx && i > m_alphaTraceStage) if (testStage.m_texMapIdx == mapIdx)
{ {
foundStage = i; foundStage = i;
break; break;
@ -449,7 +461,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
return TraceResult(&stage); 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_color[3] = CC_CPREV;
newStage.m_texMapIdx = mapIdx; 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; const atVec4f& vec = inst.m_loadImm.m_immVec;
if (vec.vec[0] == 0.f) if (vec.vec[0] == 0.f)
return TraceResult(CA_ZERO); 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]); unsigned idx = addKAlpha(diag, inst.m_loc, vec.vec[0]);
return TraceResult(TevKAlphaSel(TEV_KASEL_K0_A + idx)); 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 && else if (aTrace.type == TraceResult::Type::TEVAlphaArg &&
bTrace.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[0] = aTrace.tevAlphaArg;
stage.m_alpha[3] = bTrace.tevAlphaArg; stage.m_alpha[3] = bTrace.tevAlphaArg;
stage.m_kAlpha = newKAlpha; 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 && else if (aTrace.type == TraceResult::Type::TEVAlphaArg &&
bTrace.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[0] = aTrace.tevAlphaArg;
stage.m_alpha[3] = bTrace.tevAlphaArg; stage.m_alpha[3] = bTrace.tevAlphaArg;
stage.m_kAlpha = newKAlpha; 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 && else if (aTrace.type == TraceResult::Type::TEVAlphaArg &&
bTrace.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_color[3] = CC_CPREV;
stage.m_alpha[1] = aTrace.tevAlphaArg; stage.m_alpha[1] = aTrace.tevAlphaArg;
stage.m_alpha[2] = bTrace.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) if (a->m_aRegOut != TEVPREV)
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine"); 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[1] = CA_APREV;
stage.m_alpha[2] = bTrace.tevAlphaArg; stage.m_alpha[2] = bTrace.tevAlphaArg;
stage.m_kAlpha = newKAlpha; stage.m_kAlpha = newKAlpha;
@ -684,7 +698,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
{ {
if (b->m_aRegOut != TEVPREV) if (b->m_aRegOut != TEVPREV)
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine"); 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[1] = aTrace.tevAlphaArg;
stage.m_alpha[2] = CA_APREV; stage.m_alpha[2] = CA_APREV;
stage.m_kAlpha = newKAlpha; stage.m_kAlpha = newKAlpha;
@ -765,14 +779,48 @@ void GX::reset(const IR& ir, Diagnostics& diag)
/* Follow Color Chain */ /* Follow Color Chain */
const IR::Instruction& colorRoot = const IR::Instruction& colorRoot =
ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(0)); 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 */ /* Follow Alpha Chain */
if (rootCall.m_call.m_argInstIdxs.size() > 1) if (rootCall.m_call.m_argInstIdxs.size() > 1)
{ {
const IR::Instruction& alphaRoot = const IR::Instruction& alphaRoot =
ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(1)); 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 */ /* Ensure Alpha reaches end of chain */
if (m_alphaTraceStage >= 0) 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(); DrawIndeterminateBar();
hecl::Printf(_S("\n")); hecl::Printf(_S("\n"));
@ -248,7 +252,11 @@ void MultiProgressPrinter::DoPrint()
} }
m_dirty = false; 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())); m_termInfo.width = (hecl::GuiMode ? 120 : std::max(80, hecl::ConsoleWidth()));
MoveCursorUp(m_curProgLines); MoveCursorUp(m_curProgLines);

View File

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