mirror of https://github.com/AxioDL/metaforce.git
GX backend fixes
This commit is contained in:
parent
d5cc16b79a
commit
978c6b1334
|
@ -5,6 +5,7 @@
|
|||
#include <inttypes.h>
|
||||
#include <system_error>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <HECL/HECL.hpp>
|
||||
#include <HECL/Database.hpp>
|
||||
|
@ -77,12 +78,18 @@ size_t BlenderConnection::_readLine(char* buf, size_t bufSz)
|
|||
}
|
||||
int ret = read(m_readpipe[0], buf, 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
{
|
||||
BlenderLog.report(LogVisor::FatalError, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
else if (ret == 1)
|
||||
{
|
||||
if (*buf == '\n')
|
||||
{
|
||||
*buf = '\0';
|
||||
if (readBytes >= 4)
|
||||
if (!memcmp(buf, "EXCEPTION", std::min(readBytes, size_t(9))))
|
||||
BlenderLog.report(LogVisor::FatalError, "Blender exception");
|
||||
return readBytes;
|
||||
}
|
||||
++readBytes;
|
||||
|
@ -91,12 +98,12 @@ size_t BlenderConnection::_readLine(char* buf, size_t bufSz)
|
|||
else
|
||||
{
|
||||
*buf = '\0';
|
||||
if (readBytes >= 4)
|
||||
if (!memcmp(buf, "EXCEPTION", std::min(readBytes, size_t(9))))
|
||||
BlenderLog.report(LogVisor::FatalError, "Blender exception");
|
||||
return readBytes;
|
||||
}
|
||||
}
|
||||
err:
|
||||
BlenderLog.report(LogVisor::FatalError, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t BlenderConnection::_writeLine(const char* buf)
|
||||
|
@ -119,6 +126,9 @@ size_t BlenderConnection::_readBuf(void* buf, size_t len)
|
|||
int ret = read(m_readpipe[0], buf, len);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (len >= 4)
|
||||
if (!memcmp((char*)buf, "EXCEPTION", std::min(len, size_t(9))))
|
||||
BlenderLog.report(LogVisor::FatalError, "Blender exception");
|
||||
return ret;
|
||||
err:
|
||||
BlenderLog.report(LogVisor::FatalError, strerror(errno));
|
||||
|
@ -372,7 +382,7 @@ bool BlenderConnection::createBlend(const ProjectPath& path, BlendType type)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool BlenderConnection::openBlend(const ProjectPath& path)
|
||||
bool BlenderConnection::openBlend(const ProjectPath& path, bool force)
|
||||
{
|
||||
if (m_lock)
|
||||
{
|
||||
|
@ -380,6 +390,8 @@ bool BlenderConnection::openBlend(const ProjectPath& path)
|
|||
"BlenderConnection::openBlend() musn't be called with stream active");
|
||||
return false;
|
||||
}
|
||||
if (!force && path == m_loadedBlend)
|
||||
return true;
|
||||
_writeLine(("OPEN \"" + path.getAbsolutePathUTF8() + "\"").c_str());
|
||||
char lineBuf[256];
|
||||
_readLine(lineBuf, sizeof(lineBuf));
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
bool createBlend(const ProjectPath& path, BlendType type);
|
||||
BlendType getBlendType() const {return m_loadedType;}
|
||||
bool openBlend(const ProjectPath& path);
|
||||
bool openBlend(const ProjectPath& path, bool force=false);
|
||||
bool saveBlend();
|
||||
void deleteBlend();
|
||||
|
||||
|
|
|
@ -210,13 +210,13 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
else:
|
||||
b_input = '%g' % node.inputs[1].default_value
|
||||
|
||||
if node.blend_type == 'MULTIPLY':
|
||||
if node.operation == 'MULTIPLY':
|
||||
if a_input == '1':
|
||||
return b_input
|
||||
elif b_input == '1':
|
||||
return a_input
|
||||
return '(%s * %s)' % (a_input, b_input)
|
||||
elif node.blend_type == 'ADD':
|
||||
elif node.operation == 'ADD':
|
||||
if a_input == '0':
|
||||
return b_input
|
||||
elif b_input == '0':
|
||||
|
|
|
@ -283,7 +283,11 @@ while True:
|
|||
writepipeline(b'ERROR')
|
||||
|
||||
elif cmdargs[0] == 'DATABEGIN':
|
||||
dataout_loop()
|
||||
try:
|
||||
dataout_loop()
|
||||
except Exception as e:
|
||||
writepipeline(b'EXCEPTION')
|
||||
raise
|
||||
|
||||
elif cmdargs[0] == 'DATAEND':
|
||||
writepipeline(b'ERROR')
|
||||
|
|
|
@ -229,19 +229,44 @@ struct GX : IBackend
|
|||
unsigned m_tevCount = 0;
|
||||
TEVStage m_tevs[16];
|
||||
|
||||
int getStageIdx(const TEVStage* stage) const
|
||||
{
|
||||
for (int i=0 ; i<m_tevCount ; ++i)
|
||||
if (&m_tevs[i] == stage)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int m_cRegMask = 0;
|
||||
int m_cRegLazy = 0;
|
||||
|
||||
int pickCLazy(Diagnostics& diag, const SourceLocation& loc)
|
||||
int pickCLazy(Diagnostics& diag, const SourceLocation& loc, int stageIdx) const
|
||||
{
|
||||
for (int i=0 ; i<3 ; ++i)
|
||||
int regMask = m_cRegMask;
|
||||
for (int i=stageIdx+1 ; i<m_tevCount ; ++i)
|
||||
{
|
||||
if (!(m_cRegMask & (1 << i)))
|
||||
const TEVStage& stage = m_tevs[i];
|
||||
for (int c=0 ; c<4 ; ++c)
|
||||
{
|
||||
m_cRegMask |= 1 << i;
|
||||
return i;
|
||||
if (stage.m_color[c] == CC_C0 ||
|
||||
stage.m_color[c] == CC_A0 ||
|
||||
stage.m_alpha[c] == CA_A0)
|
||||
regMask |= 1;
|
||||
if (stage.m_color[c] == CC_C1 ||
|
||||
stage.m_color[c] == CC_A1 ||
|
||||
stage.m_alpha[c] == CA_A1)
|
||||
regMask |= 2;
|
||||
if (stage.m_color[c] == CC_C2 ||
|
||||
stage.m_color[c] == CC_A2 ||
|
||||
stage.m_alpha[c] == CA_A2)
|
||||
regMask |= 4;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0 ; i<3 ; ++i)
|
||||
if (!(regMask & (1 << i)))
|
||||
return i;
|
||||
|
||||
diag.reportBackendErr(loc, "TEV C Register overflow");
|
||||
return -1;
|
||||
}
|
||||
|
@ -336,7 +361,8 @@ private:
|
|||
void PreTraceAlpha(const IR& ir, Diagnostics& diag,
|
||||
const IR::Instruction& inst);
|
||||
TraceResult RecursiveTraceColor(const IR& ir, Diagnostics& diag,
|
||||
const IR::Instruction& inst);
|
||||
const IR::Instruction& inst,
|
||||
bool swizzleAlpha=false);
|
||||
TraceResult RecursiveTraceAlpha(const IR& ir, Diagnostics& diag,
|
||||
const IR::Instruction& inst);
|
||||
unsigned RecursiveTraceTexGen(const IR& ir, Diagnostics& diag,
|
||||
|
|
|
@ -103,7 +103,8 @@ unsigned GX::RecursiveTraceTexGen(const IR& ir, Diagnostics& diag, const IR::Ins
|
|||
return idx;
|
||||
}
|
||||
|
||||
GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const IR::Instruction& inst)
|
||||
GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const IR::Instruction& inst,
|
||||
bool swizzleAlpha)
|
||||
{
|
||||
switch (inst.m_op)
|
||||
{
|
||||
|
@ -120,7 +121,7 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
const IR::Instruction& mapInst = inst.getChildInst(ir, 0);
|
||||
const atVec4f& mapImm = mapInst.getImmVec();
|
||||
newStage.m_texMapIdx = unsigned(mapImm.vec[0]);
|
||||
newStage.m_color[0] = CC_TEXC;
|
||||
newStage.m_color[0] = swizzleAlpha ? CC_TEXA : CC_TEXC;
|
||||
|
||||
const IR::Instruction& tcgInst = inst.getChildInst(ir, 1);
|
||||
newStage.m_texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, IDENTITY);
|
||||
|
@ -132,11 +133,11 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
const IR::Instruction& idxInst = inst.getChildInst(ir, 0);
|
||||
unsigned idx = unsigned(idxInst.getImmVec().vec[0]);
|
||||
m_cRegMask |= 1 << idx;
|
||||
return TraceResult(GX::TevColorArg(CC_C0 + idx * 2));
|
||||
return TraceResult(TevColorArg((swizzleAlpha ? CC_A0 : CC_C0) + idx * 2));
|
||||
}
|
||||
else if (!name.compare("Lighting"))
|
||||
{
|
||||
return TraceResult(CC_RASC);
|
||||
return TraceResult(swizzleAlpha ? CC_RASA : CC_RASC);
|
||||
}
|
||||
else
|
||||
diag.reportBackendErr(inst.m_loc, "GX backend unable to interpret '%s'", name.c_str());
|
||||
|
@ -169,6 +170,14 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
aTrace = RecursiveTraceColor(ir, diag, aInst);
|
||||
bTrace = RecursiveTraceColor(ir, diag, bInst);
|
||||
}
|
||||
if (aTrace.type == TraceResult::TraceTEVStage &&
|
||||
bTrace.type == TraceResult::TraceTEVStage &&
|
||||
getStageIdx(aTrace.tevStage) > getStageIdx(bTrace.tevStage))
|
||||
{
|
||||
TraceResult tmp = aTrace;
|
||||
aTrace = bTrace;
|
||||
bTrace = tmp;
|
||||
}
|
||||
|
||||
TevKColorSel newKColor = TEV_KCSEL_1;
|
||||
if (aTrace.type == TraceResult::TraceTEVKColorSel &&
|
||||
|
@ -203,8 +212,16 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
b->m_lazyCInIdx = m_cRegLazy;
|
||||
a->m_lazyOutIdx = m_cRegLazy++;
|
||||
}
|
||||
else if (b == &m_tevs[m_tevCount-1] &&
|
||||
a->m_texMapIdx == b->m_texMapIdx && a->m_texGenIdx == b->m_texGenIdx &&
|
||||
a->m_color[3] == CC_ZERO && b->m_color[0] != CC_ZERO)
|
||||
{
|
||||
a->m_color[3] = b->m_color[0];
|
||||
--m_tevCount;
|
||||
return TraceResult(a);
|
||||
}
|
||||
else
|
||||
b->m_color[3] = CC_APREV;
|
||||
b->m_color[3] = CC_CPREV;
|
||||
return TraceResult(b);
|
||||
}
|
||||
else if (aTrace.type == TraceResult::TraceTEVStage &&
|
||||
|
@ -244,7 +261,7 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
a->m_lazyOutIdx = m_cRegLazy++;
|
||||
}
|
||||
else
|
||||
b->m_color[3] = CC_APREV;
|
||||
b->m_color[3] = CC_CPREV;
|
||||
b->m_op = TEV_SUB;
|
||||
return TraceResult(b);
|
||||
}
|
||||
|
@ -268,6 +285,8 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
{
|
||||
TEVStage* a = aTrace.tevStage;
|
||||
TEVStage* b = bTrace.tevStage;
|
||||
if (b->m_color[2] != CC_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
if (b->m_prev != a)
|
||||
{
|
||||
a->m_regOut = TEVLAZY;
|
||||
|
@ -277,8 +296,6 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
}
|
||||
else
|
||||
b->m_color[2] = CC_CPREV;
|
||||
if (a->m_color[2] != CC_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
b->m_color[1] = b->m_color[0];
|
||||
b->m_color[0] = CC_ZERO;
|
||||
b->m_color[3] = CC_ZERO;
|
||||
|
@ -298,7 +315,15 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
{
|
||||
TEVStage* a = aTrace.tevStage;
|
||||
if (a->m_color[1] != CC_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
{
|
||||
if (a->m_regOut != TEVPREV)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
TEVStage& stage = addTEVStage(diag, inst.m_loc);
|
||||
stage.m_color[1] = CC_CPREV;
|
||||
stage.m_color[2] = bTrace.tevColorArg;
|
||||
stage.m_kColor = newKColor;
|
||||
return TraceResult(&stage);
|
||||
}
|
||||
a->m_color[1] = a->m_color[0];
|
||||
a->m_color[0] = CC_ZERO;
|
||||
a->m_color[2] = bTrace.tevColorArg;
|
||||
|
@ -310,7 +335,15 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
{
|
||||
TEVStage* b = bTrace.tevStage;
|
||||
if (b->m_color[1] != CC_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
{
|
||||
if (b->m_regOut != TEVPREV)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
TEVStage& stage = addTEVStage(diag, inst.m_loc);
|
||||
stage.m_color[1] = aTrace.tevColorArg;
|
||||
stage.m_color[2] = CC_CPREV;
|
||||
stage.m_kColor = newKColor;
|
||||
return TraceResult(&stage);
|
||||
}
|
||||
b->m_color[1] = b->m_color[0];
|
||||
b->m_color[0] = CC_ZERO;
|
||||
b->m_color[2] = bTrace.tevColorArg;
|
||||
|
@ -331,9 +364,9 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
|
|||
inst.m_swizzle.m_idxs[2] == -1 && inst.m_swizzle.m_idxs[3] == -1)
|
||||
{
|
||||
const IR::Instruction& cInst = inst.getChildInst(ir, 0);
|
||||
if (cInst.m_op != IR::OpCall || cInst.m_call.m_name.compare("Texture"))
|
||||
diag.reportBackendErr(inst.m_loc, "only Texture() accepted for alpha swizzle");
|
||||
return TraceResult(CC_TEXA);
|
||||
if (cInst.m_op != IR::OpCall)
|
||||
diag.reportBackendErr(inst.m_loc, "only functions accepted for alpha swizzle");
|
||||
return RecursiveTraceColor(ir, diag, cInst, true);
|
||||
}
|
||||
else
|
||||
diag.reportBackendErr(inst.m_loc, "only alpha extract may be performed with swizzle operation");
|
||||
|
@ -396,7 +429,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
|
|||
const IR::Instruction& idxInst = inst.getChildInst(ir, 0);
|
||||
unsigned idx = unsigned(idxInst.getImmVec().vec[0]);
|
||||
m_cRegMask |= 1 << idx;
|
||||
return TraceResult(GX::TevAlphaArg(CA_A0 + idx));
|
||||
return TraceResult(TevAlphaArg(CA_A0 + idx));
|
||||
}
|
||||
else if (!name.compare("Lighting"))
|
||||
{
|
||||
|
@ -542,6 +575,8 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
|
|||
{
|
||||
TEVStage* a = aTrace.tevStage;
|
||||
TEVStage* b = bTrace.tevStage;
|
||||
if (b->m_alpha[2] != CA_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
if (b->m_prev != a)
|
||||
{
|
||||
a->m_regOut = TEVLAZY;
|
||||
|
@ -551,8 +586,6 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
|
|||
}
|
||||
else
|
||||
b->m_alpha[2] = CA_APREV;
|
||||
if (a->m_alpha[2] != CA_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
b->m_alpha[1] = b->m_alpha[0];
|
||||
b->m_alpha[0] = CA_ZERO;
|
||||
b->m_alpha[3] = CA_ZERO;
|
||||
|
@ -573,7 +606,15 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
|
|||
{
|
||||
TEVStage* a = aTrace.tevStage;
|
||||
if (a->m_alpha[1] != CA_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
{
|
||||
if (a->m_regOut != TEVPREV)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
TEVStage& stage = addTEVStage(diag, inst.m_loc);
|
||||
stage.m_alpha[1] = CA_APREV;
|
||||
stage.m_alpha[2] = bTrace.tevAlphaArg;
|
||||
stage.m_kAlpha = newKAlpha;
|
||||
return TraceResult(&stage);
|
||||
}
|
||||
a->m_alpha[1] = a->m_alpha[0];
|
||||
a->m_alpha[0] = CA_ZERO;
|
||||
a->m_alpha[2] = bTrace.tevAlphaArg;
|
||||
|
@ -585,7 +626,15 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
|
|||
{
|
||||
TEVStage* b = bTrace.tevStage;
|
||||
if (b->m_alpha[1] != CA_ZERO)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
{
|
||||
if (b->m_regOut != TEVPREV)
|
||||
diag.reportBackendErr(inst.m_loc, "unable to modify TEV stage for multiply combine");
|
||||
TEVStage& stage = addTEVStage(diag, inst.m_loc);
|
||||
stage.m_alpha[1] = aTrace.tevAlphaArg;
|
||||
stage.m_alpha[2] = CA_APREV;
|
||||
stage.m_kAlpha = newKAlpha;
|
||||
return TraceResult(&stage);
|
||||
}
|
||||
b->m_alpha[1] = b->m_alpha[0];
|
||||
b->m_alpha[0] = CA_ZERO;
|
||||
b->m_alpha[2] = bTrace.tevAlphaArg;
|
||||
|
@ -600,6 +649,19 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
|
|||
|
||||
diag.reportBackendErr(inst.m_loc, "unable to convert arithmetic to TEV stage");
|
||||
}
|
||||
case IR::OpSwizzle:
|
||||
{
|
||||
if (inst.m_swizzle.m_idxs[0] == 3 && inst.m_swizzle.m_idxs[1] == -1 &&
|
||||
inst.m_swizzle.m_idxs[2] == -1 && inst.m_swizzle.m_idxs[3] == -1)
|
||||
{
|
||||
const IR::Instruction& cInst = inst.getChildInst(ir, 0);
|
||||
if (cInst.m_op != IR::OpCall)
|
||||
diag.reportBackendErr(inst.m_loc, "only functions accepted for alpha swizzle");
|
||||
return RecursiveTraceAlpha(ir, diag, cInst);
|
||||
}
|
||||
else
|
||||
diag.reportBackendErr(inst.m_loc, "only alpha extract may be performed with swizzle operation");
|
||||
}
|
||||
default:
|
||||
diag.reportBackendErr(inst.m_loc, "invalid alpha op");
|
||||
}
|
||||
|
@ -670,7 +732,7 @@ void GX::reset(const IR& ir, Diagnostics& diag)
|
|||
TEVStage& stage = m_tevs[i];
|
||||
if (stage.m_regOut == TEVLAZY)
|
||||
{
|
||||
int picked = pickCLazy(diag, stage.m_loc);
|
||||
int picked = pickCLazy(diag, stage.m_loc, i);
|
||||
stage.m_regOut = TevRegID(TEVREG0 + picked);
|
||||
for (int j=i+1 ; j<m_tevCount ; ++j)
|
||||
{
|
||||
|
@ -687,6 +749,8 @@ void GX::reset(const IR& ir, Diagnostics& diag)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,8 +62,8 @@ void Lexer::PrintTree(const Lexer::OperationNode* node, int indent)
|
|||
{
|
||||
for (int i=0 ; i<indent ; ++i)
|
||||
printf(" ");
|
||||
printf("%3d %s %s\n", n->m_tok.m_location.col, n->m_tok.typeString(),
|
||||
n->m_tok.m_tokenString.c_str());
|
||||
printf("%3d %s %s %c %g\n", n->m_tok.m_location.col, n->m_tok.typeString(),
|
||||
n->m_tok.m_tokenString.c_str(), n->m_tok.m_tokenInt, n->m_tok.m_tokenFloat);
|
||||
if (n->m_sub)
|
||||
PrintTree(n->m_sub, indent + 1);
|
||||
}
|
||||
|
@ -281,7 +281,13 @@ void Lexer::consumeAllTokens(Parser& parser)
|
|||
Lexer::OperationNode* func = n.m_prev;
|
||||
n.m_sub = func;
|
||||
n.m_prev = func->m_prev;
|
||||
func->m_prev->m_next = &n;
|
||||
if (func->m_prev)
|
||||
{
|
||||
if (func->m_prev->m_sub == func)
|
||||
func->m_prev->m_sub = &n;
|
||||
else
|
||||
func->m_prev->m_next = &n;
|
||||
}
|
||||
func->m_next = nullptr;
|
||||
func->m_prev = nullptr;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue