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

View File

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

View File

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

View File

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

View File

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