Add support for normalizing TCG configs

This commit is contained in:
Jack Andersen 2016-07-18 17:41:55 -10:00
parent 08231e5379
commit 23f52a1ead
4 changed files with 43 additions and 26 deletions

View File

@ -281,6 +281,8 @@ struct GX : IBackend
{
TexGenSrc m_src = TG_TEX0;
TexMtx m_mtx = IDENTITY;
bool m_norm = false;
PTTexMtx m_pmtx = PTIDENTITY;
/* Not actually part of GX, but a way to relate out-of-band
* texmtx animation parameters */
@ -477,6 +479,10 @@ struct GX : IBackend
return false;
if (a.m_mtx != b.m_mtx)
return false;
if (a.m_norm != b.m_norm)
return false;
if (a.m_pmtx != b.m_pmtx)
return false;
}
for (unsigned i=0 ; i<m_tevCount ; ++i)
{
@ -552,7 +558,7 @@ private:
unsigned addKColor(Diagnostics& diag, const SourceLocation& loc, const Color& color);
unsigned addKAlpha(Diagnostics& diag, const SourceLocation& loc, float alpha);
unsigned addTexCoordGen(Diagnostics& diag, const SourceLocation& loc,
TexGenSrc src, TexMtx mtx);
TexGenSrc src, TexMtx mtx, bool norm, PTTexMtx pmtx);
TEVStage& addTEVStage(Diagnostics& diag, const SourceLocation& loc);
TraceResult RecursiveTraceColor(const IR& ir, Diagnostics& diag,
const IR::Instruction& inst,
@ -561,7 +567,7 @@ private:
const IR::Instruction& inst);
unsigned RecursiveTraceTexGen(const IR& ir, Diagnostics& diag,
const IR::Instruction& inst,
TexMtx mtx);
TexMtx mtx, bool normalize, PTTexMtx pmtx);
};
}

View File

@ -44,6 +44,7 @@ struct ProgrammableCommon : IBackend
TexGenSrc m_src;
int m_uvIdx = 0;
int m_mtx = -1;
bool m_norm = false;
std::string m_gameFunction;
std::vector<atVec4f> m_gameArgs;
};
@ -53,7 +54,7 @@ struct ProgrammableCommon : IBackend
void reset(const IR& ir, Diagnostics& diag, const char* backendName);
private:
unsigned addTexCoordGen(TexGenSrc src, int uvIdx, int mtx);
unsigned addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize);
unsigned addTexSampling(unsigned mapIdx, unsigned tcgIdx);
std::string RecursiveTraceColor(const IR& ir, Diagnostics& diag,
const IR::Instruction& inst, bool toSwizzle);
@ -61,7 +62,7 @@ private:
const IR::Instruction& inst, bool toSwizzle);
unsigned RecursiveTraceTexGen(const IR& ir, Diagnostics& diag,
const IR::Instruction& inst,
int mtx);
int mtx, bool normalize);
std::string EmitSamplingUseRaw(unsigned samplingIdx) const
{

View File

@ -38,12 +38,12 @@ unsigned GX::addKAlpha(Diagnostics& diag, const SourceLocation& loc, float alpha
}
unsigned GX::addTexCoordGen(Diagnostics& diag, const SourceLocation& loc,
TexGenSrc src, TexMtx mtx)
TexGenSrc src, TexMtx mtx, bool norm, PTTexMtx pmtx)
{
for (unsigned i=0 ; i<m_tcgCount ; ++i)
{
TexCoordGen& tcg = m_tcgs[i];
if (tcg.m_src == src && tcg.m_mtx == mtx)
if (tcg.m_src == src && tcg.m_mtx == mtx && tcg.m_norm && tcg.m_pmtx)
return i;
}
if (m_tcgCount >= 8)
@ -51,6 +51,8 @@ unsigned GX::addTexCoordGen(Diagnostics& diag, const SourceLocation& loc,
GX::TexCoordGen& newTcg = m_tcgs[m_tcgCount];
newTcg.m_src = src;
newTcg.m_mtx = mtx;
newTcg.m_norm = norm;
newTcg.m_pmtx = pmtx;
return m_tcgCount++;
}
@ -69,7 +71,8 @@ GX::TEVStage& GX::addTEVStage(Diagnostics& diag, const SourceLocation& loc)
return newTEV;
}
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)
{
if (inst.m_op != IR::OpType::Call)
diag.reportBackendErr(inst.m_loc, "TexCoordGen resolution requires function");
@ -81,16 +84,17 @@ unsigned GX::RecursiveTraceTexGen(const IR& ir, Diagnostics& diag, const IR::Ins
diag.reportBackendErr(inst.m_loc, "TexCoordGen UV(layerIdx) requires one argument");
const IR::Instruction& idxInst = inst.getChildInst(ir, 0);
const atVec4f& idxImm = idxInst.getImmVec();
return addTexCoordGen(diag, inst.m_loc, TexGenSrc(TG_TEX0 + unsigned(idxImm.vec[0])), mtx);
return addTexCoordGen(diag, inst.m_loc, TexGenSrc(TG_TEX0 + unsigned(idxImm.vec[0])), mtx, normalize, pmtx);
}
else if (!tcgName.compare("Normal"))
return addTexCoordGen(diag, inst.m_loc, TG_NRM, mtx);
return addTexCoordGen(diag, inst.m_loc, TG_NRM, mtx, normalize, pmtx);
else if (!tcgName.compare("View"))
return addTexCoordGen(diag, inst.m_loc, TG_POS, mtx);
return addTexCoordGen(diag, inst.m_loc, TG_POS, mtx, normalize, pmtx);
/* Otherwise treat as game-specific function */
const IR::Instruction& tcgSrcInst = inst.getChildInst(ir, 0);
unsigned idx = RecursiveTraceTexGen(ir, diag, tcgSrcInst, TexMtx(TEXMTX0 + m_texMtxCount * 3));
unsigned idx = RecursiveTraceTexGen(ir, diag, tcgSrcInst, TexMtx(TEXMTX0 + m_texMtxCount * 3),
normalize || tcgName.back() == 'N', PTTexMtx(PTTEXMTX0 + m_texMtxCount * 3));
GX::TexCoordGen& tcg = m_tcgs[idx];
m_texMtxRefs[m_texMtxCount] = &tcg;
++m_texMtxCount;
@ -112,7 +116,8 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
case IR::OpType::Call:
{
const std::string& name = inst.m_call.m_name;
if (!name.compare("Texture"))
bool normalize = false;
if (!name.compare("Texture") || (normalize = true && !name.compare("TextureN")))
{
TEVStage& newStage = addTEVStage(diag, inst.m_loc);
@ -125,7 +130,7 @@ GX::TraceResult GX::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const I
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);
newStage.m_texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, IDENTITY, normalize, PTIDENTITY);
return TraceResult(&newStage);
}
@ -389,7 +394,8 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
case IR::OpType::Call:
{
const std::string& name = inst.m_call.m_name;
if (!name.compare("Texture"))
bool normalize = false;
if (!name.compare("Texture") || (normalize = true && !name.compare("TextureN")))
{
if (inst.getChildCount() < 2)
diag.reportBackendErr(inst.m_loc, "Texture(map, texgen) requires 2 arguments");
@ -424,7 +430,7 @@ GX::TraceResult GX::RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const I
newStage.m_alpha[0] = CA_TEXA;
const IR::Instruction& tcgInst = inst.getChildInst(ir, 1);
newStage.m_texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, IDENTITY);
newStage.m_texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, IDENTITY, normalize, PTIDENTITY);
return TraceResult(&newStage);
}

View File

@ -6,12 +6,12 @@ namespace hecl
namespace Backend
{
unsigned ProgrammableCommon::addTexCoordGen(TexGenSrc src, int uvIdx, int mtx)
unsigned ProgrammableCommon::addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize)
{
for (unsigned i=0 ; i<m_tcgs.size() ; ++i)
{
TexCoordGen& tcg = m_tcgs[i];
if (tcg.m_src == src && tcg.m_uvIdx == uvIdx && tcg.m_mtx == mtx)
if (tcg.m_src == src && tcg.m_uvIdx == uvIdx && tcg.m_mtx == mtx && tcg.m_norm == normalize)
return i;
}
m_tcgs.emplace_back();
@ -19,6 +19,7 @@ unsigned ProgrammableCommon::addTexCoordGen(TexGenSrc src, int uvIdx, int mtx)
newTcg.m_src = src;
newTcg.m_uvIdx = uvIdx;
newTcg.m_mtx = mtx;
newTcg.m_norm = normalize;
return m_tcgs.size() - 1;
}
@ -40,7 +41,7 @@ unsigned ProgrammableCommon::addTexSampling(unsigned mapIdx, unsigned tcgIdx)
}
unsigned ProgrammableCommon::RecursiveTraceTexGen(const IR& ir, Diagnostics& diag,
const IR::Instruction& inst, int mtx)
const IR::Instruction& inst, int mtx, bool normalize)
{
if (inst.m_op != IR::OpType::Call)
diag.reportBackendErr(inst.m_loc, "TexCoordGen resolution requires function");
@ -52,16 +53,17 @@ unsigned ProgrammableCommon::RecursiveTraceTexGen(const IR& ir, Diagnostics& dia
diag.reportBackendErr(inst.m_loc, "TexCoordGen UV(layerIdx) requires one argument");
const IR::Instruction& idxInst = inst.getChildInst(ir, 0);
const atVec4f& idxImm = idxInst.getImmVec();
return addTexCoordGen(TexGenSrc::UV, idxImm.vec[0], mtx);
return addTexCoordGen(TexGenSrc::UV, idxImm.vec[0], mtx, normalize);
}
else if (!tcgName.compare("Normal"))
return addTexCoordGen(TexGenSrc::Normal, -1, mtx);
return addTexCoordGen(TexGenSrc::Normal, -1, mtx, normalize);
else if (!tcgName.compare("View"))
return addTexCoordGen(TexGenSrc::Position, -1, mtx);
return addTexCoordGen(TexGenSrc::Position, -1, mtx, normalize);
/* Otherwise treat as game-specific function */
const IR::Instruction& tcgSrcInst = inst.getChildInst(ir, 0);
unsigned idx = RecursiveTraceTexGen(ir, diag, tcgSrcInst, m_texMtxRefs.size());
unsigned idx = RecursiveTraceTexGen(ir, diag, tcgSrcInst, m_texMtxRefs.size(),
normalize || tcgName.back() == 'N');
TexCoordGen& tcg = m_tcgs[idx];
m_texMtxRefs.push_back(idx);
tcg.m_gameFunction = tcgName;
@ -82,7 +84,8 @@ std::string ProgrammableCommon::RecursiveTraceColor(const IR& ir, Diagnostics& d
case IR::OpType::Call:
{
const std::string& name = inst.m_call.m_name;
if (!name.compare("Texture"))
bool normalize = false;
if (!name.compare("Texture") || (normalize = true && !name.compare("TextureN")))
{
if (inst.getChildCount() < 2)
diag.reportBackendErr(inst.m_loc, "Texture(map, texgen) requires 2 arguments");
@ -92,7 +95,7 @@ std::string ProgrammableCommon::RecursiveTraceColor(const IR& ir, Diagnostics& d
unsigned mapIdx = unsigned(mapImm.vec[0]);
const IR::Instruction& tcgInst = inst.getChildInst(ir, 1);
unsigned texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, -1);
unsigned texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, -1, normalize);
return toSwizzle ? EmitSamplingUseRaw(addTexSampling(mapIdx, texGenIdx)) :
EmitSamplingUseRGB(addTexSampling(mapIdx, texGenIdx));
@ -168,7 +171,8 @@ std::string ProgrammableCommon::RecursiveTraceAlpha(const IR& ir, Diagnostics& d
case IR::OpType::Call:
{
const std::string& name = inst.m_call.m_name;
if (!name.compare("Texture"))
bool normalize = false;
if (!name.compare("Texture") || (normalize = true && !name.compare("TextureN")))
{
if (inst.getChildCount() < 2)
diag.reportBackendErr(inst.m_loc, "Texture(map, texgen) requires 2 arguments");
@ -178,7 +182,7 @@ std::string ProgrammableCommon::RecursiveTraceAlpha(const IR& ir, Diagnostics& d
unsigned mapIdx = unsigned(mapImm.vec[0]);
const IR::Instruction& tcgInst = inst.getChildInst(ir, 1);
unsigned texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, -1);
unsigned texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, -1, normalize);
return toSwizzle ? EmitSamplingUseRaw(addTexSampling(mapIdx, texGenIdx)) :
EmitSamplingUseAlpha(addTexSampling(mapIdx, texGenIdx));