From 470182de0668aeea6915bd39d5d4900aeec50d4f Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 23 Feb 2019 21:14:43 -1000 Subject: [PATCH] Support for diffuse texture identification in IR --- hecl/blender/hecl/hmdl/HMDLShader.py | 8 ++- hecl/extern/athena | 2 +- hecl/extern/boo | 2 +- hecl/include/hecl/Backend/Backend.hpp | 6 +- hecl/include/hecl/Backend/GLSL.hpp | 2 +- hecl/include/hecl/Backend/HLSL.hpp | 2 +- hecl/include/hecl/Backend/Metal.hpp | 2 +- .../hecl/Backend/ProgrammableCommon.hpp | 2 + hecl/include/hecl/Pipeline.hpp | 2 +- hecl/lib/Backend/GLSL.cpp | 8 +-- hecl/lib/Backend/HLSL.cpp | 8 +-- hecl/lib/Backend/Metal.cpp | 10 ++-- hecl/lib/Backend/ProgrammableCommon.cpp | 57 ++++++++++++++++++- hecl/lib/Frontend/Parser.cpp | 3 +- 14 files changed, 88 insertions(+), 26 deletions(-) diff --git a/hecl/blender/hecl/hmdl/HMDLShader.py b/hecl/blender/hecl/hmdl/HMDLShader.py index d47557052..e35e76f38 100644 --- a/hecl/blender/hecl/hmdl/HMDLShader.py +++ b/hecl/blender/hecl/hmdl/HMDLShader.py @@ -130,14 +130,18 @@ def recursive_color_trace(mat_obj, mesh_obj, tex_list, node, socket=None): else: raise RuntimeError("Only the 'UV', 'Normal' and 'View' sockets may be used from 'Geometry' nodes") + call_name = 'Texture' + if node.label.startswith('Diffuse'): + call_name = 'TextureD' + if socket.name == 'Value': if matrix_str: uvsource_str = matrix_str % uvsource_str - return 'Texture(%d, %s).aaa' % (get_texmap_idx(tex_list, node.texture.name), uvsource_str) + return '%s(%d, %s).aaa' % (call_name, 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 '%s(%d, %s)' % (call_name, 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") diff --git a/hecl/extern/athena b/hecl/extern/athena index c1a1c6e75..ef7a9633c 160000 --- a/hecl/extern/athena +++ b/hecl/extern/athena @@ -1 +1 @@ -Subproject commit c1a1c6e7549d37ce081353458fde9980996d40a1 +Subproject commit ef7a9633c6bd0bb1039c5267e174280a1583ec49 diff --git a/hecl/extern/boo b/hecl/extern/boo index e75735d24..f8b22ecb1 160000 --- a/hecl/extern/boo +++ b/hecl/extern/boo @@ -1 +1 @@ -Subproject commit e75735d2469b4afecb9a056a830c8a24fb8f404a +Subproject commit f8b22ecb13a7e2bc61e5622b47ac21e50bc78649 diff --git a/hecl/include/hecl/Backend/Backend.hpp b/hecl/include/hecl/Backend/Backend.hpp index 96667dbf2..56f007403 100644 --- a/hecl/include/hecl/Backend/Backend.hpp +++ b/hecl/include/hecl/Backend/Backend.hpp @@ -186,6 +186,7 @@ struct ExtensionSlot { bool noAlphaOverwrite = false; bool noReflection = false; bool forceAlphaTest = false; + bool diffuseOnly = false; ExtensionSlot(size_t blockCount = 0, const char** blockNames = nullptr, size_t texCount = 0, const Backend::TextureInfo* texs = nullptr, @@ -194,7 +195,7 @@ struct ExtensionSlot { Backend::ZTest depthTest = Backend::ZTest::Original, Backend::CullMode cullMode = Backend::CullMode::Backface, bool noDepthWrite = false, bool noColorWrite = false, bool noAlphaWrite = false, bool noAlphaOverwrite = false, - bool noReflection = false, bool forceAlphaTest = false) + bool noReflection = false, bool forceAlphaTest = false, bool diffuseOnly = false) : blockCount(blockCount) , blockNames(blockNames) , texCount(texCount) @@ -208,7 +209,8 @@ struct ExtensionSlot { , noAlphaWrite(noAlphaWrite) , noAlphaOverwrite(noAlphaOverwrite) , noReflection(noReflection) - , forceAlphaTest(forceAlphaTest) {} + , forceAlphaTest(forceAlphaTest) + , diffuseOnly(diffuseOnly) {} mutable uint64_t m_hash = 0; void calculateHash() const { diff --git a/hecl/include/hecl/Backend/GLSL.hpp b/hecl/include/hecl/Backend/GLSL.hpp index b29b94ed3..54ad60744 100644 --- a/hecl/include/hecl/Backend/GLSL.hpp +++ b/hecl/include/hecl/Backend/GLSL.hpp @@ -15,7 +15,7 @@ struct GLSL : ProgrammableCommon { BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting = Function()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, - size_t extTexCount, const TextureInfo* extTexs) const; + size_t extTexCount, const TextureInfo* extTexs, bool diffuseOnly) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; diff --git a/hecl/include/hecl/Backend/HLSL.hpp b/hecl/include/hecl/Backend/HLSL.hpp index 3207808fb..1c6cc47c2 100644 --- a/hecl/include/hecl/Backend/HLSL.hpp +++ b/hecl/include/hecl/Backend/HLSL.hpp @@ -12,7 +12,7 @@ struct HLSL : ProgrammableCommon { BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting = Function()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, - size_t extTexCount, const TextureInfo* extTexs) const; + size_t extTexCount, const TextureInfo* extTexs, bool diffuseOnly) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; diff --git a/hecl/include/hecl/Backend/Metal.hpp b/hecl/include/hecl/Backend/Metal.hpp index 4c4926edc..bf29a0ce1 100644 --- a/hecl/include/hecl/Backend/Metal.hpp +++ b/hecl/include/hecl/Backend/Metal.hpp @@ -12,7 +12,7 @@ struct Metal : ProgrammableCommon { BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting = Function()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, - size_t extTexCount, const TextureInfo* extTexs) const; + size_t extTexCount, const TextureInfo* extTexs, bool diffuseOnly) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; diff --git a/hecl/include/hecl/Backend/ProgrammableCommon.hpp b/hecl/include/hecl/Backend/ProgrammableCommon.hpp index 2f2cd1767..4caa69a4d 100644 --- a/hecl/include/hecl/Backend/ProgrammableCommon.hpp +++ b/hecl/include/hecl/Backend/ProgrammableCommon.hpp @@ -10,6 +10,7 @@ namespace hecl::Backend { struct ProgrammableCommon : IBackend { + std::string m_diffuseColorExpr; std::string m_colorExpr; std::string m_alphaExpr; BlendFactor m_blendSrc; @@ -43,6 +44,7 @@ struct ProgrammableCommon : IBackend { private: unsigned addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize); unsigned addTexSampling(unsigned mapIdx, unsigned tcgIdx); + std::string RecursiveTraceDiffuseColor(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, bool toSwizzle); std::string RecursiveTraceColor(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, bool toSwizzle); std::string RecursiveTraceAlpha(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, bool toSwizzle); unsigned RecursiveTraceTexGen(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, int mtx, bool normalize); diff --git a/hecl/include/hecl/Pipeline.hpp b/hecl/include/hecl/Pipeline.hpp index 0903ab8e5..613e31077 100644 --- a/hecl/include/hecl/Pipeline.hpp +++ b/hecl/include/hecl/Pipeline.hpp @@ -74,7 +74,7 @@ public: m_tag.getAlphaTest() || m_extension.forceAlphaTest, m_extension.noReflection ? Backend::ReflectionType::None : m_tag.getReflectionType(), m_backend.m_blendSrc, m_backend.m_blendDst, m_extension.lighting, m_extension.post, - m_extension.texCount, m_extension.texs); + m_extension.texCount, m_extension.texs, m_extension.diffuseOnly); } const hecl::Backend::ShaderTag& getTag() const { return m_tag; } const hecl::Backend::ExtensionSlot& extension() const { return m_extension; } diff --git a/hecl/lib/Backend/GLSL.cpp b/hecl/lib/Backend/GLSL.cpp index a75dc9111..6fa2687a4 100644 --- a/hecl/lib/Backend/GLSL.cpp +++ b/hecl/lib/Backend/GLSL.cpp @@ -285,7 +285,7 @@ std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alph std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, - size_t extTexCount, const TextureInfo* extTexs) const { + size_t extTexCount, const TextureInfo* extTexs, bool diffuseOnly) const { std::string lightingSrc; if (!lighting.m_source.empty()) lightingSrc = lighting.m_source; @@ -352,12 +352,12 @@ std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alph std::string reflectionExpr = GenerateReflectionExpr(reflectionType); - if (m_alphaExpr.size()) + if (m_alphaExpr.size() && !diffuseOnly) retval += " colorOut = " + postEntry + "(vec4(" + m_colorExpr + " + " + reflectionExpr + ", " + m_alphaExpr + ")) * mulColor + addColor;\n"; else - retval += " colorOut = " + postEntry + "(vec4(" + m_colorExpr + " + " + reflectionExpr + - ", 1.0)) * mulColor + addColor;\n"; + retval += " colorOut = " + postEntry + "(vec4(" + (diffuseOnly ? m_diffuseColorExpr : m_colorExpr) + " + " + + reflectionExpr + ", 1.0)) * mulColor + addColor;\n"; return retval + (alphaTest ? GenerateAlphaTest() : "") + "}\n"; } diff --git a/hecl/lib/Backend/HLSL.cpp b/hecl/lib/Backend/HLSL.cpp index 261100244..db41c3b1e 100644 --- a/hecl/lib/Backend/HLSL.cpp +++ b/hecl/lib/Backend/HLSL.cpp @@ -281,7 +281,7 @@ std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, bool alph std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, - size_t extTexCount, const TextureInfo* extTexs) const { + size_t extTexCount, const TextureInfo* extTexs, bool diffuseOnly) const { std::string lightingSrc; if (!lighting.m_source.empty()) lightingSrc = lighting.m_source; @@ -346,12 +346,12 @@ std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, bool alph std::string reflectionExpr = GenerateReflectionExpr(reflectionType); retval += " float4 colorOut;\n"; - if (m_alphaExpr.size()) + if (m_alphaExpr.size() && !diffuseOnly) retval += " colorOut = " + postEntry + "(" + (postEntry.size() ? "vtf, " : "") + "float4(" + m_colorExpr + " + " + reflectionExpr + ", " + m_alphaExpr + ")) * mulColor + addColor;\n"; else - retval += " colorOut = " + postEntry + "(" + (postEntry.size() ? "vtf, " : "") + "float4(" + m_colorExpr + - " + " + reflectionExpr + ", 1.0)) * mulColor + addColor;\n"; + retval += " colorOut = " + postEntry + "(" + (postEntry.size() ? "vtf, " : "") + "float4(" + + (diffuseOnly ? m_diffuseColorExpr : m_colorExpr) + " + " + reflectionExpr + ", 1.0)) * mulColor + addColor;\n"; return retval + (alphaTest ? GenerateAlphaTest() : "") + " return colorOut;\n}\n"; } diff --git a/hecl/lib/Backend/Metal.cpp b/hecl/lib/Backend/Metal.cpp index ca951066b..f3e2b2416 100644 --- a/hecl/lib/Backend/Metal.cpp +++ b/hecl/lib/Backend/Metal.cpp @@ -303,14 +303,14 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp retval += " out.color = float4(" + m_colorExpr + " + " + reflectionExpr + ", 1.0) * mulColor + addColor;\n"; return retval + (alphaTest ? GenerateAlphaTest() : "") + - " //out.depth = 1.0 - float(int((1.0 - vtf.mvpPos.z) * 16777216.0)) / 16777216.0;\n" " return out;\n" "}\n"; } std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, - const Function& post, size_t extTexCount, const TextureInfo* extTexs) const { + const Function& post, size_t extTexCount, const TextureInfo* extTexs, + bool diffuseOnly) const { std::string lightingSrc; if (!lighting.m_source.empty()) lightingSrc = lighting.m_source; @@ -415,7 +415,7 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp std::string reflectionExpr = GenerateReflectionExpr(reflectionType); - if (m_alphaExpr.size()) { + if (m_alphaExpr.size() && !diffuseOnly) { retval += " out.color = " + postEntry + "(" + (postEntry.size() ? ("vtf, " + (blockCall.size() ? (blockCall + ", ") : "") + (!strncmp(post.m_entry.data(), "EXT", 3) @@ -430,11 +430,11 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp ? (extTexCall.size() ? ("samp, clampSamp," + extTexCall + ", ") : "") : "")) : "") + - "float4(" + m_colorExpr + " + " + reflectionExpr + ", 1.0)) * mulColor + addColor;\n"; + "float4(" + (diffuseOnly ? m_diffuseColorExpr : m_colorExpr) + " + " + reflectionExpr + + ", 1.0)) * mulColor + addColor;\n"; } return retval + (alphaTest ? GenerateAlphaTest() : "") + - " //out.depth = 1.0 - float(int((1.0 - vtf.mvpPos.z) * 16777216.0)) / 16777216.0;\n" " return out;\n" "}\n"; } diff --git a/hecl/lib/Backend/ProgrammableCommon.cpp b/hecl/lib/Backend/ProgrammableCommon.cpp index bd1d952b4..342907bbf 100644 --- a/hecl/lib/Backend/ProgrammableCommon.cpp +++ b/hecl/lib/Backend/ProgrammableCommon.cpp @@ -95,13 +95,63 @@ unsigned ProgrammableCommon::RecursiveTraceTexGen(const IR& ir, Diagnostics& dia return idx; } +std::string ProgrammableCommon::RecursiveTraceDiffuseColor(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, + bool toSwizzle) { + switch (inst.m_op) { + case IR::OpType::Call: { + const std::string& name = inst.m_call.m_name; + bool normalize = false; + if (!name.compare("TextureD") || + ((normalize = true) && !name.compare("TextureDN"))) { + if (inst.getChildCount() < 2) + diag.reportBackendErr(inst.m_loc, "Texture(map, texgen) requires 2 arguments"); + + const IR::Instruction& mapInst = inst.getChildInst(ir, 0); + auto& mapImm = mapInst.getImmVec(); + unsigned mapIdx = unsigned(mapImm.simd[0]); + + const IR::Instruction& tcgInst = inst.getChildInst(ir, 1); + unsigned texGenIdx = RecursiveTraceTexGen(ir, diag, tcgInst, -1, normalize); + + return toSwizzle ? EmitSamplingUseRaw(addTexSampling(mapIdx, texGenIdx)) + : EmitSamplingUseRGB(addTexSampling(mapIdx, texGenIdx)); + } else + return std::string(); + } + case IR::OpType::LoadImm: { + const atVec4f& vec = inst.m_loadImm.m_immVec; + return EmitVec3(vec); + } + case IR::OpType::Arithmetic: { + const IR::Instruction& aInst = inst.getChildInst(ir, 0); + const IR::Instruction& bInst = inst.getChildInst(ir, 1); + std::string aTrace = RecursiveTraceDiffuseColor(ir, diag, aInst, false); + std::string bTrace = RecursiveTraceDiffuseColor(ir, diag, bInst, false); + return (!aTrace.empty()) ? aTrace : bTrace; + } + case IR::OpType::Swizzle: { + const IR::Instruction& aInst = inst.getChildInst(ir, 0); + std::string aTrace = RecursiveTraceDiffuseColor(ir, diag, aInst, true); + if (!aTrace.empty()) + return EmitSwizzle3(diag, inst.m_loc, aTrace, inst.m_swizzle.m_idxs); + return std::string(); + } + default: + diag.reportBackendErr(inst.m_loc, "invalid color op"); + } + + return std::string(); +} + std::string ProgrammableCommon::RecursiveTraceColor(const IR& ir, Diagnostics& diag, const IR::Instruction& inst, bool toSwizzle) { switch (inst.m_op) { case IR::OpType::Call: { const std::string& name = inst.m_call.m_name; bool normalize = false; - if (!name.compare("Texture") || (normalize = true && !name.compare("TextureN"))) { + if (!name.compare("Texture") || !name.compare("TextureD") || + ((normalize = true) && !name.compare("TextureN")) || + ((normalize = true) && !name.compare("TextureDN"))) { if (inst.getChildCount() < 2) diag.reportBackendErr(inst.m_loc, "Texture(map, texgen) requires 2 arguments"); @@ -180,7 +230,9 @@ std::string ProgrammableCommon::RecursiveTraceAlpha(const IR& ir, Diagnostics& d case IR::OpType::Call: { const std::string& name = inst.m_call.m_name; bool normalize = false; - if (!name.compare("Texture") || ((normalize = true) && !name.compare("TextureN"))) { + if (!name.compare("Texture") || !name.compare("TextureD") || + ((normalize = true) && !name.compare("TextureN")) || + ((normalize = true) && !name.compare("TextureDN"))) { if (inst.getChildCount() < 2) diag.reportBackendErr(inst.m_loc, "Texture(map, texgen) requires 2 arguments"); @@ -275,6 +327,7 @@ void ProgrammableCommon::reset(const IR& ir, Diagnostics& diag, const char* back /* Follow Color Chain */ const IR::Instruction& colorRoot = ir.m_instructions.at(rootCall.m_call.m_argInstIdxs.at(0)); + m_diffuseColorExpr = RecursiveTraceDiffuseColor(ir, diag, colorRoot, false); m_colorExpr = RecursiveTraceColor(ir, diag, colorRoot, false); /* Follow Alpha Chain */ diff --git a/hecl/lib/Frontend/Parser.cpp b/hecl/lib/Frontend/Parser.cpp index 8d20da112..7ea1534c2 100644 --- a/hecl/lib/Frontend/Parser.cpp +++ b/hecl/lib/Frontend/Parser.cpp @@ -29,7 +29,8 @@ std::string IRNode::fmt(int level, bool stripUVAnims) const { auto indent = rep(level, "\t"sv); switch (kind) { case Kind::Call: - if (stripUVAnims && (str == "Texture" || str == "TextureN") && children.size() >= 2) { + if (stripUVAnims && (str == "Texture" || str == "TextureD" || str == "TextureN" || str == "TextureDN") && + children.size() >= 2) { auto it = children.begin(); IRNode& uvNode = const_cast(*++it); if (uvNode.str != "UV" && uvNode.str != "Normal" && uvNode.str != "View") {