mirror of https://github.com/AxioDL/metaforce.git
GX backend work
This commit is contained in:
parent
45b1d2edf3
commit
60374a472a
|
@ -55,8 +55,16 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
node.inputs[2].default_value[2])
|
||||
|
||||
if node.blend_type == 'MULTIPLY':
|
||||
if a_input == 'vec3(1,1,1)':
|
||||
return b_input
|
||||
elif b_input == 'vec3(1,1,1)':
|
||||
return a_input
|
||||
return '(%s * %s)' % (a_input, b_input)
|
||||
elif node.blend_type == 'ADD':
|
||||
if a_input == 'vec3(0,0,0)':
|
||||
return b_input
|
||||
elif b_input == 'vec3(0,0,0)':
|
||||
return a_input
|
||||
return '(%s + %s)' % (a_input, b_input)
|
||||
else:
|
||||
raise RuntimeError("HMDL does not support shaders with '{0}' blending modes".format(node.blend_type))
|
||||
|
@ -74,24 +82,28 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
soc_from = node.inputs['Vector'].links[0].from_socket
|
||||
|
||||
if soc_from.node.type == 'GROUP':
|
||||
matrix_str = '%s(%%s, ' % soc_from.node.node_tree.name
|
||||
for s in range(len(soc_from.node.inputs)-1):
|
||||
soc = soc_from.node.inputs[s+1]
|
||||
if len(soc.links):
|
||||
raise RuntimeError("UV Modifier nodes may not have parameter links (default values only)")
|
||||
if soc.type == 'VALUE':
|
||||
matrix_str += '%g' % soc.default_value
|
||||
else:
|
||||
ncomps = len(soc.default_value)
|
||||
matrix_str += 'vec%d(' % ncomps
|
||||
for c in ncomps-1:
|
||||
matrix_str += '%g, ' % soc.default_value[c]
|
||||
matrix_str += '%g)' % soc.default_value[ncomps-1]
|
||||
matrix_str = '%s(%%s' % soc_from.node.node_tree.name
|
||||
if len(soc_from.node.inputs)-1:
|
||||
matrix_str += ', '
|
||||
for s in range(len(soc_from.node.inputs)-1):
|
||||
soc = soc_from.node.inputs[s+1]
|
||||
if len(soc.links):
|
||||
raise RuntimeError("UV Modifier nodes may not have parameter links (default values only)")
|
||||
if soc.type == 'VALUE':
|
||||
matrix_str += '%g' % soc.default_value
|
||||
else:
|
||||
ncomps = len(soc.default_value)
|
||||
matrix_str += 'vec%d(' % ncomps
|
||||
for c in range(ncomps-1):
|
||||
matrix_str += '%g,' % soc.default_value[c]
|
||||
matrix_str += '%g)' % soc.default_value[ncomps-1]
|
||||
|
||||
if s == len(soc_from.node.inputs)-2:
|
||||
matrix_str += ')'
|
||||
else:
|
||||
matrix_str += ', '
|
||||
if s == len(soc_from.node.inputs)-2:
|
||||
matrix_str += ')'
|
||||
else:
|
||||
matrix_str += ', '
|
||||
else:
|
||||
matrix_str += ')'
|
||||
|
||||
soc_from = soc_from.node.inputs[0].links[0].from_socket
|
||||
|
||||
|
@ -129,11 +141,11 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
if socket.name == 'Value':
|
||||
if matrix_str:
|
||||
uvsource_str = matrix_str % uvsource_str
|
||||
return 'texture(%d, %s).a' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str)
|
||||
return 'Texture(%d, %s).a' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str)
|
||||
if socket.name == 'Color':
|
||||
if matrix_str:
|
||||
uvsource_str = matrix_str % uvsource_str
|
||||
return 'texture(%d, %s)' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str)
|
||||
return 'Texture(%d, %s)' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str)
|
||||
else:
|
||||
raise RuntimeError("Only the 'Value' or 'Color' output sockets may be used from Texture nodes")
|
||||
|
||||
|
@ -198,9 +210,17 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
else:
|
||||
b_input = '%g' % node.inputs[1].default_value
|
||||
|
||||
if node.operation == 'MULTIPLY':
|
||||
if node.blend_type == 'MULTIPLY':
|
||||
if a_input == '1':
|
||||
return b_input
|
||||
elif b_input == '1':
|
||||
return a_input
|
||||
return '(%s * %s)' % (a_input, b_input)
|
||||
elif node.operation == 'ADD':
|
||||
elif node.blend_type == 'ADD':
|
||||
if a_input == '0':
|
||||
return b_input
|
||||
elif b_input == '0':
|
||||
return a_input
|
||||
return '(%s + %s)' % (a_input, b_input)
|
||||
else:
|
||||
raise RuntimeError("HMDL does not support shaders with '{0}' blending modes".format(node.operation))
|
||||
|
@ -218,24 +238,28 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
soc_from = node.inputs['Vector'].links[0].from_socket
|
||||
|
||||
if soc_from.node.type == 'GROUP':
|
||||
matrix_str = '%s(%%s, ' % soc_from.node.node_tree.name
|
||||
for s in range(len(soc_from.node.inputs)-1):
|
||||
soc = soc_from.node.inputs[s+1]
|
||||
if len(soc.links):
|
||||
raise RuntimeError("UV Modifier nodes may not have parameter links (default values only)")
|
||||
if soc.type == 'VALUE':
|
||||
matrix_str += '%g' % soc.default_value
|
||||
else:
|
||||
ncomps = len(soc.default_value)
|
||||
matrix_str += 'vec%d(' % ncomps
|
||||
for c in ncomps-1:
|
||||
matrix_str += '%g, ' % soc.default_value[c]
|
||||
matrix_str += '%g)' % soc.default_value[ncomps-1]
|
||||
matrix_str = '%s(%%s' % soc_from.node.node_tree.name
|
||||
if len(soc_from.node.inputs)-1:
|
||||
matrix_str += ', '
|
||||
for s in range(len(soc_from.node.inputs)-1):
|
||||
soc = soc_from.node.inputs[s+1]
|
||||
if len(soc.links):
|
||||
raise RuntimeError("UV Modifier nodes may not have parameter links (default values only)")
|
||||
if soc.type == 'VALUE':
|
||||
matrix_str += '%g' % soc.default_value
|
||||
else:
|
||||
ncomps = len(soc.default_value)
|
||||
matrix_str += 'vec%d(' % ncomps
|
||||
for c in range(ncomps-1):
|
||||
matrix_str += '%g,' % soc.default_value[c]
|
||||
matrix_str += '%g)' % soc.default_value[ncomps-1]
|
||||
|
||||
if s == len(soc_from.node.inputs)-2:
|
||||
matrix_str += ')'
|
||||
else:
|
||||
matrix_str += ', '
|
||||
if s == len(soc_from.node.inputs)-2:
|
||||
matrix_str += ')'
|
||||
else:
|
||||
matrix_str += ', '
|
||||
else:
|
||||
matrix_str += ')'
|
||||
|
||||
soc_from = soc_from.node.inputs[0].links[0].from_socket
|
||||
|
||||
|
@ -273,7 +297,7 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
|
|||
if socket.name == 'Value':
|
||||
if matrix_str:
|
||||
uvsource_str = matrix_str % uvsource_str
|
||||
return 'texture(%d, %s).a' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str)
|
||||
return 'Texture(%d, %s).a' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str)
|
||||
else:
|
||||
raise RuntimeError("Only the 'Value' output sockets may be used from Texture nodes")
|
||||
|
||||
|
@ -348,7 +372,7 @@ class hecl_shader_operator(bpy.types.Operator):
|
|||
return context.object and context.object.type == 'MESH'
|
||||
|
||||
def execute(self, context):
|
||||
shad, texs = shader(context.object.active_material, context.object, bpy.data.filepath)
|
||||
shad, texs = shader(context.object.active_material, context.object)
|
||||
|
||||
vs = bpy.data.texts.new('HECL SHADER')
|
||||
vs.write((shad + '\n'))
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define HECLBACKEND_GX_HPP
|
||||
|
||||
#include "Backend.hpp"
|
||||
#include "HECL/Frontend.hpp"
|
||||
#include <Athena/Types.hpp>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -247,6 +248,8 @@ struct GX : IBackend
|
|||
|
||||
private:
|
||||
unsigned addKColor(const Color& color);
|
||||
void RecursiveTraceColor(const Frontend::IR::Instruction& inst);
|
||||
void RecursiveTraceAlpha(const Frontend::IR::Instruction& inst);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -81,22 +81,22 @@ struct IR
|
|||
OpSwizzle /**< Vector insertion/extraction/swizzling operation */
|
||||
};
|
||||
|
||||
using RegID = int;
|
||||
using RegID = ssize_t;
|
||||
|
||||
struct Instruction
|
||||
{
|
||||
OpType m_op = OpNone;
|
||||
RegID m_target = -1;
|
||||
|
||||
struct
|
||||
{
|
||||
std::string m_name;
|
||||
RegID m_target;
|
||||
std::vector<size_t> m_argInstIdxs;
|
||||
} m_call;
|
||||
|
||||
struct
|
||||
{
|
||||
atVec4f m_immVec;
|
||||
RegID m_target;
|
||||
} m_loadImm;
|
||||
|
||||
enum ArithmeticOpType
|
||||
|
@ -111,22 +111,19 @@ struct IR
|
|||
struct
|
||||
{
|
||||
ArithmeticOpType m_op = ArithmeticOpNone;
|
||||
RegID m_a;
|
||||
RegID m_b;
|
||||
RegID m_target;
|
||||
size_t m_instIdxs[2];
|
||||
} m_arithmetic;
|
||||
|
||||
struct
|
||||
{
|
||||
RegID m_reg;
|
||||
int m_idxs[4] = {-1};
|
||||
RegID m_target;
|
||||
ssize_t m_idxs[4] = {-1};
|
||||
size_t m_instIdx;
|
||||
} m_swizzle;
|
||||
|
||||
Instruction(OpType type) : m_op(type) {}
|
||||
};
|
||||
|
||||
int m_regCount = 0;
|
||||
size_t m_regCount = 0;
|
||||
std::vector<Instruction> m_instructions;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <LogVisor/LogVisor.hpp>
|
||||
#include "HECL/Backend/GX.hpp"
|
||||
#include "HECL/Frontend.hpp"
|
||||
|
||||
static LogVisor::LogModule Log("HECL::GX");
|
||||
|
||||
|
@ -20,6 +19,28 @@ unsigned GX::addKColor(const Color& color)
|
|||
return m_kcolorCount++;
|
||||
}
|
||||
|
||||
void GX::RecursiveTraceColor(const Frontend::IR::Instruction& inst)
|
||||
{
|
||||
switch (inst.m_op)
|
||||
{
|
||||
case Frontend::IR::OpCall:
|
||||
{
|
||||
if (!inst.m_call.m_name.compare("texture"))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
case Frontend::IR::OpArithmetic:
|
||||
default:
|
||||
Log.report(LogVisor::FatalError, "invalid color op");
|
||||
}
|
||||
}
|
||||
|
||||
void GX::RecursiveTraceAlpha(const Frontend::IR::Instruction& inst)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GX::reset(const Frontend::IR& ir)
|
||||
{
|
||||
m_tevCount = 0;
|
||||
|
@ -47,26 +68,17 @@ void GX::reset(const Frontend::IR& ir)
|
|||
doAlpha = true;
|
||||
}
|
||||
|
||||
for (const Frontend::IR::Instruction& inst : ir.m_instructions)
|
||||
/* Follow Color Chain */
|
||||
const Frontend::IR::Instruction& colorRoot =
|
||||
ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(0));
|
||||
RecursiveTraceColor(colorRoot);
|
||||
|
||||
/* Follow Alpha Chain */
|
||||
if (doAlpha)
|
||||
{
|
||||
switch (inst.m_op)
|
||||
{
|
||||
case Frontend::IR::OpCall:
|
||||
{
|
||||
const std::string& name = inst.m_call.m_name;
|
||||
if (!name.compare("ColorReg"))
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Frontend::IR::OpLoadImm:
|
||||
{
|
||||
addKColor(inst.m_loadImm.m_immVec);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Log.report(LogVisor::FatalError, "invalid inst op");
|
||||
}
|
||||
const Frontend::IR::Instruction& alphaRoot =
|
||||
ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(1));
|
||||
RecursiveTraceAlpha(alphaRoot);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -399,6 +399,7 @@ void Lexer::EmitArithmetic(IR& ir, const Lexer::OperationNode* arithNode, IR::Re
|
|||
size_t instCount = ir.m_instructions.size();
|
||||
const Lexer::OperationNode* on = arithNode->m_sub;
|
||||
IR::RegID tgt = target;
|
||||
size_t argInsts[2];
|
||||
for (int i=0 ; i<2 ; ++i, ++tgt)
|
||||
{
|
||||
const Parser::Token& tok = on->m_tok;
|
||||
|
@ -419,7 +420,7 @@ void Lexer::EmitArithmetic(IR& ir, const Lexer::OperationNode* arithNode, IR::Re
|
|||
{
|
||||
ir.m_instructions.emplace_back(IR::OpLoadImm);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_loadImm.m_target = tgt;
|
||||
inst.m_target = tgt;
|
||||
inst.m_loadImm.m_immVec.vec[0] = tok.m_tokenFloat;
|
||||
inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat;
|
||||
inst.m_loadImm.m_immVec.vec[2] = tok.m_tokenFloat;
|
||||
|
@ -433,6 +434,7 @@ void Lexer::EmitArithmetic(IR& ir, const Lexer::OperationNode* arithNode, IR::Re
|
|||
LogModule.report(LogVisor::FatalError, "invalid lexer node for IR");
|
||||
break;
|
||||
};
|
||||
argInsts[i] = ir.m_instructions.size() - 1;
|
||||
if (ir.m_instructions.back().m_op == IR::OpLoadImm)
|
||||
opt[i] = &ir.m_instructions.back().m_loadImm.m_immVec;
|
||||
on = on->m_next;
|
||||
|
@ -476,16 +478,16 @@ void Lexer::EmitArithmetic(IR& ir, const Lexer::OperationNode* arithNode, IR::Re
|
|||
ir.m_instructions.pop_back();
|
||||
ir.m_instructions.emplace_back(IR::OpLoadImm);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_loadImm.m_target = target;
|
||||
inst.m_target = target;
|
||||
inst.m_loadImm.m_immVec = eval;
|
||||
}
|
||||
else
|
||||
{
|
||||
ir.m_instructions.emplace_back(IR::OpArithmetic);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_arithmetic.m_target = target;
|
||||
inst.m_arithmetic.m_a = target;
|
||||
inst.m_arithmetic.m_b = target + 1;
|
||||
inst.m_target = target;
|
||||
inst.m_arithmetic.m_instIdxs[0] = argInsts[0];
|
||||
inst.m_arithmetic.m_instIdxs[1] = argInsts[1];
|
||||
inst.m_arithmetic.m_op = ArithType(arithNode->m_tok.m_tokenInt);
|
||||
if (tgt > ir.m_regCount)
|
||||
ir.m_regCount = tgt;
|
||||
|
@ -540,7 +542,7 @@ void Lexer::EmitVectorSwizzle(IR& ir, const Lexer::OperationNode* swizNode, IR::
|
|||
{
|
||||
ir.m_instructions.emplace_back(IR::OpLoadImm);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_loadImm.m_target = target;
|
||||
inst.m_target = target;
|
||||
inst.m_loadImm.m_immVec.vec[0] = tok.m_tokenFloat;
|
||||
inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat;
|
||||
inst.m_loadImm.m_immVec.vec[2] = tok.m_tokenFloat;
|
||||
|
@ -584,15 +586,15 @@ void Lexer::EmitVectorSwizzle(IR& ir, const Lexer::OperationNode* swizNode, IR::
|
|||
ir.m_instructions.pop_back();
|
||||
ir.m_instructions.emplace_back(IR::OpLoadImm);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_loadImm.m_target = target;
|
||||
inst.m_target = target;
|
||||
inst.m_loadImm.m_immVec = eval;
|
||||
}
|
||||
else
|
||||
{
|
||||
ir.m_instructions.emplace_back(IR::OpSwizzle);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_swizzle.m_reg = target;
|
||||
inst.m_swizzle.m_target = target;
|
||||
inst.m_swizzle.m_instIdx = ir.m_instructions.size() - 2;
|
||||
inst.m_target = target;
|
||||
for (int i=0 ; i<str.size() ; ++i)
|
||||
inst.m_swizzle.m_idxs[i] = SwizzleCompIdx(str[i]);
|
||||
}
|
||||
|
@ -621,7 +623,7 @@ void Lexer::RecursiveGroupCompile(IR& ir, const Lexer::OperationNode* groupNode,
|
|||
{
|
||||
ir.m_instructions.emplace_back(IR::OpLoadImm);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_loadImm.m_target = tgt;
|
||||
inst.m_target = tgt;
|
||||
inst.m_loadImm.m_immVec.vec[0] = tok.m_tokenFloat;
|
||||
inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat;
|
||||
inst.m_loadImm.m_immVec.vec[2] = tok.m_tokenFloat;
|
||||
|
@ -646,12 +648,17 @@ void Lexer::RecursiveGroupCompile(IR& ir, const Lexer::OperationNode* groupNode,
|
|||
void Lexer::RecursiveFuncCompile(IR& ir, const Lexer::OperationNode* funcNode, IR::RegID target)
|
||||
{
|
||||
IR::RegID tgt = target;
|
||||
std::vector<size_t> instIdxs;
|
||||
for (const Lexer::OperationNode* gn = funcNode->m_sub ; gn ; gn = gn->m_next, ++tgt)
|
||||
{
|
||||
RecursiveGroupCompile(ir, gn, tgt);
|
||||
instIdxs.push_back(ir.m_instructions.size() - 1);
|
||||
}
|
||||
ir.m_instructions.emplace_back(IR::OpCall);
|
||||
IR::Instruction& inst = ir.m_instructions.back();
|
||||
inst.m_call.m_name = funcNode->m_tok.m_tokenString;
|
||||
inst.m_call.m_target = target;
|
||||
inst.m_call.m_argInstIdxs = std::move(instIdxs);
|
||||
inst.m_target = target;
|
||||
if (tgt > ir.m_regCount)
|
||||
ir.m_regCount = tgt;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue