GX backend fixes

This commit is contained in:
Jack Andersen 2015-10-15 22:02:59 -10:00
parent d5cc16b79a
commit 978c6b1334
7 changed files with 149 additions and 37 deletions

View File

@ -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));

View File

@ -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();

View File

@ -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':

View File

@ -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')

View File

@ -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,

View File

@ -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("");
}
}

View File

@ -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;
}