GX backend work

This commit is contained in:
Jack Andersen 2015-10-10 19:55:53 -10:00
parent 45b1d2edf3
commit 60374a472a
5 changed files with 124 additions and 81 deletions

View File

@ -55,8 +55,16 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
node.inputs[2].default_value[2]) node.inputs[2].default_value[2])
if node.blend_type == 'MULTIPLY': 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) return '(%s * %s)' % (a_input, b_input)
elif node.blend_type == 'ADD': 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) return '(%s + %s)' % (a_input, b_input)
else: else:
raise RuntimeError("HMDL does not support shaders with '{0}' blending modes".format(node.blend_type)) raise RuntimeError("HMDL does not support shaders with '{0}' blending modes".format(node.blend_type))
@ -74,7 +82,9 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
soc_from = node.inputs['Vector'].links[0].from_socket soc_from = node.inputs['Vector'].links[0].from_socket
if soc_from.node.type == 'GROUP': if soc_from.node.type == 'GROUP':
matrix_str = '%s(%%s, ' % soc_from.node.node_tree.name 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): for s in range(len(soc_from.node.inputs)-1):
soc = soc_from.node.inputs[s+1] soc = soc_from.node.inputs[s+1]
if len(soc.links): if len(soc.links):
@ -84,7 +94,7 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
else: else:
ncomps = len(soc.default_value) ncomps = len(soc.default_value)
matrix_str += 'vec%d(' % ncomps matrix_str += 'vec%d(' % ncomps
for c in ncomps-1: for c in range(ncomps-1):
matrix_str += '%g,' % soc.default_value[c] matrix_str += '%g,' % soc.default_value[c]
matrix_str += '%g)' % soc.default_value[ncomps-1] matrix_str += '%g)' % soc.default_value[ncomps-1]
@ -92,6 +102,8 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
matrix_str += ')' matrix_str += ')'
else: else:
matrix_str += ', ' matrix_str += ', '
else:
matrix_str += ')'
soc_from = soc_from.node.inputs[0].links[0].from_socket 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 socket.name == 'Value':
if matrix_str: if matrix_str:
uvsource_str = matrix_str % uvsource_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 socket.name == 'Color':
if matrix_str: if matrix_str:
uvsource_str = matrix_str % uvsource_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: else:
raise RuntimeError("Only the 'Value' or 'Color' output sockets may be used from Texture nodes") 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: else:
b_input = '%g' % node.inputs[1].default_value 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) 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) return '(%s + %s)' % (a_input, b_input)
else: else:
raise RuntimeError("HMDL does not support shaders with '{0}' blending modes".format(node.operation)) raise RuntimeError("HMDL does not support shaders with '{0}' blending modes".format(node.operation))
@ -218,7 +238,9 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
soc_from = node.inputs['Vector'].links[0].from_socket soc_from = node.inputs['Vector'].links[0].from_socket
if soc_from.node.type == 'GROUP': if soc_from.node.type == 'GROUP':
matrix_str = '%s(%%s, ' % soc_from.node.node_tree.name 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): for s in range(len(soc_from.node.inputs)-1):
soc = soc_from.node.inputs[s+1] soc = soc_from.node.inputs[s+1]
if len(soc.links): if len(soc.links):
@ -228,7 +250,7 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
else: else:
ncomps = len(soc.default_value) ncomps = len(soc.default_value)
matrix_str += 'vec%d(' % ncomps matrix_str += 'vec%d(' % ncomps
for c in ncomps-1: for c in range(ncomps-1):
matrix_str += '%g,' % soc.default_value[c] matrix_str += '%g,' % soc.default_value[c]
matrix_str += '%g)' % soc.default_value[ncomps-1] matrix_str += '%g)' % soc.default_value[ncomps-1]
@ -236,6 +258,8 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None):
matrix_str += ')' matrix_str += ')'
else: else:
matrix_str += ', ' matrix_str += ', '
else:
matrix_str += ')'
soc_from = soc_from.node.inputs[0].links[0].from_socket 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 socket.name == 'Value':
if matrix_str: if matrix_str:
uvsource_str = matrix_str % uvsource_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: else:
raise RuntimeError("Only the 'Value' output sockets may be used from Texture nodes") 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' return context.object and context.object.type == 'MESH'
def execute(self, context): 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 = bpy.data.texts.new('HECL SHADER')
vs.write((shad + '\n')) vs.write((shad + '\n'))

View File

@ -2,6 +2,7 @@
#define HECLBACKEND_GX_HPP #define HECLBACKEND_GX_HPP
#include "Backend.hpp" #include "Backend.hpp"
#include "HECL/Frontend.hpp"
#include <Athena/Types.hpp> #include <Athena/Types.hpp>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -247,6 +248,8 @@ struct GX : IBackend
private: private:
unsigned addKColor(const Color& color); unsigned addKColor(const Color& color);
void RecursiveTraceColor(const Frontend::IR::Instruction& inst);
void RecursiveTraceAlpha(const Frontend::IR::Instruction& inst);
}; };
} }

View File

@ -81,22 +81,22 @@ struct IR
OpSwizzle /**< Vector insertion/extraction/swizzling operation */ OpSwizzle /**< Vector insertion/extraction/swizzling operation */
}; };
using RegID = int; using RegID = ssize_t;
struct Instruction struct Instruction
{ {
OpType m_op = OpNone; OpType m_op = OpNone;
RegID m_target = -1;
struct struct
{ {
std::string m_name; std::string m_name;
RegID m_target; std::vector<size_t> m_argInstIdxs;
} m_call; } m_call;
struct struct
{ {
atVec4f m_immVec; atVec4f m_immVec;
RegID m_target;
} m_loadImm; } m_loadImm;
enum ArithmeticOpType enum ArithmeticOpType
@ -111,22 +111,19 @@ struct IR
struct struct
{ {
ArithmeticOpType m_op = ArithmeticOpNone; ArithmeticOpType m_op = ArithmeticOpNone;
RegID m_a; size_t m_instIdxs[2];
RegID m_b;
RegID m_target;
} m_arithmetic; } m_arithmetic;
struct struct
{ {
RegID m_reg; ssize_t m_idxs[4] = {-1};
int m_idxs[4] = {-1}; size_t m_instIdx;
RegID m_target;
} m_swizzle; } m_swizzle;
Instruction(OpType type) : m_op(type) {} Instruction(OpType type) : m_op(type) {}
}; };
int m_regCount = 0; size_t m_regCount = 0;
std::vector<Instruction> m_instructions; std::vector<Instruction> m_instructions;
}; };

View File

@ -1,6 +1,5 @@
#include <LogVisor/LogVisor.hpp> #include <LogVisor/LogVisor.hpp>
#include "HECL/Backend/GX.hpp" #include "HECL/Backend/GX.hpp"
#include "HECL/Frontend.hpp"
static LogVisor::LogModule Log("HECL::GX"); static LogVisor::LogModule Log("HECL::GX");
@ -20,6 +19,28 @@ unsigned GX::addKColor(const Color& color)
return m_kcolorCount++; 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) void GX::reset(const Frontend::IR& ir)
{ {
m_tevCount = 0; m_tevCount = 0;
@ -47,26 +68,17 @@ void GX::reset(const Frontend::IR& ir)
doAlpha = true; 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) const Frontend::IR::Instruction& alphaRoot =
{ ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(1));
case Frontend::IR::OpCall: RecursiveTraceAlpha(alphaRoot);
{
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");
}
} }
} }

View File

@ -399,6 +399,7 @@ void Lexer::EmitArithmetic(IR& ir, const Lexer::OperationNode* arithNode, IR::Re
size_t instCount = ir.m_instructions.size(); size_t instCount = ir.m_instructions.size();
const Lexer::OperationNode* on = arithNode->m_sub; const Lexer::OperationNode* on = arithNode->m_sub;
IR::RegID tgt = target; IR::RegID tgt = target;
size_t argInsts[2];
for (int i=0 ; i<2 ; ++i, ++tgt) for (int i=0 ; i<2 ; ++i, ++tgt)
{ {
const Parser::Token& tok = on->m_tok; 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.m_instructions.emplace_back(IR::OpLoadImm);
IR::Instruction& inst = ir.m_instructions.back(); 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[0] = tok.m_tokenFloat;
inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat; inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat;
inst.m_loadImm.m_immVec.vec[2] = 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"); LogModule.report(LogVisor::FatalError, "invalid lexer node for IR");
break; break;
}; };
argInsts[i] = ir.m_instructions.size() - 1;
if (ir.m_instructions.back().m_op == IR::OpLoadImm) if (ir.m_instructions.back().m_op == IR::OpLoadImm)
opt[i] = &ir.m_instructions.back().m_loadImm.m_immVec; opt[i] = &ir.m_instructions.back().m_loadImm.m_immVec;
on = on->m_next; 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.pop_back();
ir.m_instructions.emplace_back(IR::OpLoadImm); ir.m_instructions.emplace_back(IR::OpLoadImm);
IR::Instruction& inst = ir.m_instructions.back(); IR::Instruction& inst = ir.m_instructions.back();
inst.m_loadImm.m_target = target; inst.m_target = target;
inst.m_loadImm.m_immVec = eval; inst.m_loadImm.m_immVec = eval;
} }
else else
{ {
ir.m_instructions.emplace_back(IR::OpArithmetic); ir.m_instructions.emplace_back(IR::OpArithmetic);
IR::Instruction& inst = ir.m_instructions.back(); IR::Instruction& inst = ir.m_instructions.back();
inst.m_arithmetic.m_target = target; inst.m_target = target;
inst.m_arithmetic.m_a = target; inst.m_arithmetic.m_instIdxs[0] = argInsts[0];
inst.m_arithmetic.m_b = target + 1; inst.m_arithmetic.m_instIdxs[1] = argInsts[1];
inst.m_arithmetic.m_op = ArithType(arithNode->m_tok.m_tokenInt); inst.m_arithmetic.m_op = ArithType(arithNode->m_tok.m_tokenInt);
if (tgt > ir.m_regCount) if (tgt > ir.m_regCount)
ir.m_regCount = tgt; 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.m_instructions.emplace_back(IR::OpLoadImm);
IR::Instruction& inst = ir.m_instructions.back(); 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[0] = tok.m_tokenFloat;
inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat; inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat;
inst.m_loadImm.m_immVec.vec[2] = 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.pop_back();
ir.m_instructions.emplace_back(IR::OpLoadImm); ir.m_instructions.emplace_back(IR::OpLoadImm);
IR::Instruction& inst = ir.m_instructions.back(); IR::Instruction& inst = ir.m_instructions.back();
inst.m_loadImm.m_target = target; inst.m_target = target;
inst.m_loadImm.m_immVec = eval; inst.m_loadImm.m_immVec = eval;
} }
else else
{ {
ir.m_instructions.emplace_back(IR::OpSwizzle); ir.m_instructions.emplace_back(IR::OpSwizzle);
IR::Instruction& inst = ir.m_instructions.back(); IR::Instruction& inst = ir.m_instructions.back();
inst.m_swizzle.m_reg = target; inst.m_swizzle.m_instIdx = ir.m_instructions.size() - 2;
inst.m_swizzle.m_target = target; inst.m_target = target;
for (int i=0 ; i<str.size() ; ++i) for (int i=0 ; i<str.size() ; ++i)
inst.m_swizzle.m_idxs[i] = SwizzleCompIdx(str[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.m_instructions.emplace_back(IR::OpLoadImm);
IR::Instruction& inst = ir.m_instructions.back(); 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[0] = tok.m_tokenFloat;
inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat; inst.m_loadImm.m_immVec.vec[1] = tok.m_tokenFloat;
inst.m_loadImm.m_immVec.vec[2] = 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) void Lexer::RecursiveFuncCompile(IR& ir, const Lexer::OperationNode* funcNode, IR::RegID target)
{ {
IR::RegID tgt = target; IR::RegID tgt = target;
std::vector<size_t> instIdxs;
for (const Lexer::OperationNode* gn = funcNode->m_sub ; gn ; gn = gn->m_next, ++tgt) for (const Lexer::OperationNode* gn = funcNode->m_sub ; gn ; gn = gn->m_next, ++tgt)
{
RecursiveGroupCompile(ir, gn, tgt); RecursiveGroupCompile(ir, gn, tgt);
instIdxs.push_back(ir.m_instructions.size() - 1);
}
ir.m_instructions.emplace_back(IR::OpCall); ir.m_instructions.emplace_back(IR::OpCall);
IR::Instruction& inst = ir.m_instructions.back(); IR::Instruction& inst = ir.m_instructions.back();
inst.m_call.m_name = funcNode->m_tok.m_tokenString; 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) if (tgt > ir.m_regCount)
ir.m_regCount = tgt; ir.m_regCount = tgt;
} }