From 60374a472abaa11db5b9a1f0e1219479d76d9bec Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 10 Oct 2015 19:55:53 -1000 Subject: [PATCH] GX backend work --- hecl/blender/hecl/hmdl/HMDLShader.py | 104 ++++++++++++++++----------- hecl/include/HECL/Backend/GX.hpp | 3 + hecl/include/HECL/Frontend.hpp | 17 ++--- hecl/lib/Backend/GX.cpp | 52 ++++++++------ hecl/lib/Frontend/Lexer.cpp | 29 +++++--- 5 files changed, 124 insertions(+), 81 deletions(-) diff --git a/hecl/blender/hecl/hmdl/HMDLShader.py b/hecl/blender/hecl/hmdl/HMDLShader.py index 58217c6ea..41c091dda 100644 --- a/hecl/blender/hecl/hmdl/HMDLShader.py +++ b/hecl/blender/hecl/hmdl/HMDLShader.py @@ -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')) diff --git a/hecl/include/HECL/Backend/GX.hpp b/hecl/include/HECL/Backend/GX.hpp index 3477df097..6eb6dd375 100644 --- a/hecl/include/HECL/Backend/GX.hpp +++ b/hecl/include/HECL/Backend/GX.hpp @@ -2,6 +2,7 @@ #define HECLBACKEND_GX_HPP #include "Backend.hpp" +#include "HECL/Frontend.hpp" #include #include #include @@ -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); }; } diff --git a/hecl/include/HECL/Frontend.hpp b/hecl/include/HECL/Frontend.hpp index abd08d6bc..d67ba4433 100644 --- a/hecl/include/HECL/Frontend.hpp +++ b/hecl/include/HECL/Frontend.hpp @@ -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 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 m_instructions; }; diff --git a/hecl/lib/Backend/GX.cpp b/hecl/lib/Backend/GX.cpp index fa0c9de80..7bc6bda35 100644 --- a/hecl/lib/Backend/GX.cpp +++ b/hecl/lib/Backend/GX.cpp @@ -1,6 +1,5 @@ #include #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); } } diff --git a/hecl/lib/Frontend/Lexer.cpp b/hecl/lib/Frontend/Lexer.cpp index fc3a68aff..1638273b5 100644 --- a/hecl/lib/Frontend/Lexer.cpp +++ b/hecl/lib/Frontend/Lexer.cpp @@ -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 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; }