From 54ca41f2ed3588529810f216833720c182ec1ae6 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 2 Apr 2016 20:19:03 -1000 Subject: [PATCH] Update boo and Metal backend --- hecl/extern/boo | 2 +- hecl/include/hecl/Backend/Metal.hpp | 22 ++++- hecl/lib/Backend/Metal.cpp | 148 +++++++++++++++------------- 3 files changed, 95 insertions(+), 77 deletions(-) diff --git a/hecl/extern/boo b/hecl/extern/boo index 4c8e36f3e..843396095 160000 --- a/hecl/extern/boo +++ b/hecl/extern/boo @@ -1 +1 @@ -Subproject commit 4c8e36f3e33582bca396b3b89e29178ebc2f1728 +Subproject commit 843396095f8cbc160541edfcbf1a22c0030d397c diff --git a/hecl/include/hecl/Backend/Metal.hpp b/hecl/include/hecl/Backend/Metal.hpp index 484ca4fdf..c92e852e3 100644 --- a/hecl/include/hecl/Backend/Metal.hpp +++ b/hecl/include/hecl/Backend/Metal.hpp @@ -1,12 +1,24 @@ #ifndef HECLBACKEND_METAL_HPP #define HECLBACKEND_METAL_HPP + +#if __APPLE__ +#include +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 +#define BOO_HAS_METAL 1 +#else +#define BOO_HAS_METAL 0 +#endif +#endif + #if BOO_HAS_METAL +#include "ProgrammableCommon.hpp" + namespace hecl { namespace Backend { - + struct Metal : ProgrammableCommon { void reset(const IR& ir, Diagnostics& diag); @@ -15,21 +27,21 @@ struct Metal : ProgrammableCommon std::string makeFrag(const ShaderFunction& lighting=ShaderFunction()) const; std::string makeFrag(const ShaderFunction& lighting, const ShaderFunction& post) const; - + private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; std::string GenerateVertToFragStruct() const; std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const; - + std::string EmitVec3(const atVec4f& vec) const { return hecl::Format("float3(%g,%g,%g)", vec.vec[0], vec.vec[1], vec.vec[2]); } - + std::string EmitTexGenSource2(TexGenSrc src, int uvIdx) const; std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const; }; - + } } diff --git a/hecl/lib/Backend/Metal.cpp b/hecl/lib/Backend/Metal.cpp index ef49a4b1d..94ac9bab4 100644 --- a/hecl/lib/Backend/Metal.cpp +++ b/hecl/lib/Backend/Metal.cpp @@ -49,26 +49,26 @@ std::string Metal::GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) c "{\n" " float3 posIn [[ attribute(0) ]];\n" " float3 normIn [[ attribute(1) ]];\n"; - + unsigned idx = 2; if (col) { for (unsigned i=0 ; i tex%u [[ texture(%u) ]]", i, i); } - + std::string retval = "#include \nusing namespace metal;\n" - "constexpr sampler samp(address::repeat);\n" + + "constexpr sampler samp(address::repeat, filter::linear, mip_filter::linear);\n" + GenerateVertToFragStruct() + "\n" + lightingSrc + "\n" + "fragment float4 fmain(VertToFrag vtf [[ stage_in ]]" + texMapDecl + ")\n{\n"; - - + + if (m_lighting) { if (lighting.m_entry) @@ -185,17 +185,17 @@ std::string Metal::makeFrag(const ShaderFunction& lighting) const else retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n"; } - + unsigned sampIdx = 0; for (const TexSampling& sampling : m_texSamplings) retval += hecl::Format(" float4 sampling%u = tex%u.sample(samp, vtf.tcgs%u);\n", sampIdx++, sampling.mapIdx, sampling.tcgIdx); - + if (m_alphaExpr.size()) retval += " return float4(" + m_colorExpr + ", " + m_alphaExpr + ");\n"; else retval += " return float4(" + m_colorExpr + ", 1.0);\n"; - + return retval + "}\n"; } @@ -205,28 +205,28 @@ std::string Metal::makeFrag(const ShaderFunction& lighting, std::string lightingSrc; if (lighting.m_source) lightingSrc = lighting.m_source; - + std::string postSrc; if (post.m_source) postSrc = post.m_source; - + std::string postEntry; if (post.m_entry) postEntry = post.m_entry; - + std::string texMapDecl; if (m_texMapEnd) { for (int i=0 ; i tex%u [[ texture(%u) ]],\n", i, i); } - + std::string retval = "#include \nusing namespace metal;\n" - "constexpr sampler samp(address::repeat);\n" + + "constexpr sampler samp(address::repeat, filter::linear, mip_filter::linear);\n" + GenerateVertToFragStruct() + "\n" + lightingSrc + "\n" + "fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n" + texMapDecl + ")\n{\n"; - + if (m_lighting) { if (lighting.m_entry) @@ -234,17 +234,17 @@ std::string Metal::makeFrag(const ShaderFunction& lighting, else retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n"; } - + unsigned sampIdx = 0; for (const TexSampling& sampling : m_texSamplings) retval += hecl::Format(" float4 sampling%u = tex%u.sample(samp, vtf.tcgs%u);\n", sampIdx++, sampling.mapIdx, sampling.tcgIdx); - + if (m_alphaExpr.size()) retval += " return " + postEntry + "(float4(" + m_colorExpr + ", " + m_alphaExpr + "));\n"; else retval += " return " + postEntry + "(float4(" + m_colorExpr + ", 1.0));\n"; - + return retval + "}\n"; } @@ -255,55 +255,55 @@ namespace Runtime struct MetalBackendFactory : IShaderBackendFactory { Backend::Metal m_backend; - boo::MetalDataFactory* m_gfxFactory; - - MetalBackendFactory(boo::IGraphicsDataFactory* gfxFactory) - : m_gfxFactory(dynamic_cast(gfxFactory)) {} - + ShaderCachedData buildShaderFromIR(const ShaderTag& tag, const hecl::Frontend::IR& ir, hecl::Frontend::Diagnostics& diag, + boo::IGraphicsDataFactory::Context& ctx, boo::IShaderPipeline*& objOut) { if (!m_rtHint) Log.report(logvisor::Fatal, "ShaderCacheManager::setRenderTargetHint must be called before making metal shaders"); - + m_backend.reset(ir, diag); size_t cachedSz = 2; - + std::string vertSource = m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), tag.getSkinSlotCount(), tag.getTexMtxCount()); cachedSz += vertSource.size() + 1; - + std::string fragSource = m_backend.makeFrag(); cachedSz += fragSource.size() + 1; objOut = - m_gfxFactory->newShaderPipeline(vertSource.c_str(), fragSource.c_str(), - tag.newVertexFormat(m_gfxFactory), m_rtHint, - m_backend.m_blendSrc, m_backend.m_blendDst, - tag.getDepthTest(), tag.getDepthWrite(), - tag.getBackfaceCulling()); - if (!*objOut) + static_cast(ctx). + newShaderPipeline(vertSource.c_str(), fragSource.c_str(), + tag.newVertexFormat(ctx), m_rtHint, + m_backend.m_blendSrc, m_backend.m_blendDst, + tag.getPrimType(), + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); + if (!objOut) Log.report(logvisor::Fatal, "unable to build shader"); - + ShaderCachedData dataOut(tag, cachedSz); athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz); w.writeUByte(atUint8(m_backend.m_blendSrc)); w.writeUByte(atUint8(m_backend.m_blendDst)); w.writeString(vertSource); w.writeString(fragSource); - + return dataOut; } - - boo::IShaderPipeline* buildShaderFromCache(const ShaderCachedData& data) + + boo::IShaderPipeline* buildShaderFromCache(const ShaderCachedData& data, + boo::IGraphicsDataFactory::Context& ctx) { if (!m_rtHint) Log.report(logvisor::Fatal, "ShaderCacheManager::setRenderTargetHint must be called before making metal shaders"); - + const ShaderTag& tag = data.m_tag; athena::io::MemoryReader r(data.m_data.get(), data.m_sz); boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte()); @@ -311,34 +311,36 @@ struct MetalBackendFactory : IShaderBackendFactory std::string vertSource = r.readString(); std::string fragSource = r.readString(); boo::IShaderPipeline* ret = - m_gfxFactory->newShaderPipeline(vertSource.c_str(), fragSource.c_str(), - tag.newVertexFormat(m_gfxFactory), m_rtHint, - blendSrc, blendDst, - tag.getDepthTest(), tag.getDepthWrite(), - tag.getBackfaceCulling()); + static_cast(ctx). + newShaderPipeline(vertSource.c_str(), fragSource.c_str(), + tag.newVertexFormat(ctx), m_rtHint, + blendSrc, blendDst, tag.getPrimType(), + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); if (!ret) Log.report(logvisor::Fatal, "unable to build shader"); return ret; } - + ShaderCachedData buildExtendedShaderFromIR(const ShaderTag& tag, const hecl::Frontend::IR& ir, hecl::Frontend::Diagnostics& diag, const std::vector& extensionSlots, + boo::IGraphicsDataFactory::Context& ctx, FReturnExtensionShader returnFunc) { if (!m_rtHint) Log.report(logvisor::Fatal, "ShaderCacheManager::setRenderTargetHint must be called before making metal shaders"); - + m_backend.reset(ir, diag); size_t cachedSz = 2; - + std::string vertSource = m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), tag.getSkinSlotCount(), tag.getTexMtxCount()); cachedSz += vertSource.size() + 1; - + std::vector fragSources; fragSources.reserve(extensionSlots.size()); for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) @@ -346,16 +348,18 @@ struct MetalBackendFactory : IShaderBackendFactory fragSources.push_back(m_backend.makeFrag(slot.lighting, slot.post)); cachedSz += fragSources.back().size() + 1; boo::IShaderPipeline* ret = - m_gfxFactory->newShaderPipeline(vertSource.c_str(), fragSources.back().c_str(), - tag.newVertexFormat(m_gfxFactory), m_rtHint, - m_backend.m_blendSrc, m_backend.m_blendDst, - tag.getDepthTest(), tag.getDepthWrite(), - tag.getBackfaceCulling()); + static_cast(ctx). + newShaderPipeline(vertSource.c_str(), fragSources.back().c_str(), + tag.newVertexFormat(ctx), m_rtHint, + m_backend.m_blendSrc, m_backend.m_blendDst, + tag.getPrimType(), + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); if (!ret) Log.report(logvisor::Fatal, "unable to build shader"); returnFunc(ret); } - + ShaderCachedData dataOut(tag, cachedSz); athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz); w.writeUByte(atUint8(m_backend.m_blendSrc)); @@ -363,18 +367,19 @@ struct MetalBackendFactory : IShaderBackendFactory w.writeString(vertSource); for (const std::string src : fragSources) w.writeString(src); - + return dataOut; } - + void buildExtendedShaderFromCache(const ShaderCachedData& data, const std::vector& extensionSlots, + boo::IGraphicsDataFactory::Context& ctx, FReturnExtensionShader returnFunc) { if (!m_rtHint) Log.report(logvisor::Fatal, "ShaderCacheManager::setRenderTargetHint must be called before making metal shaders"); - + const ShaderTag& tag = data.m_tag; athena::io::MemoryReader r(data.m_data.get(), data.m_sz); boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte()); @@ -384,11 +389,12 @@ struct MetalBackendFactory : IShaderBackendFactory { std::string fragSource = r.readString(); boo::IShaderPipeline* ret = - m_gfxFactory->newShaderPipeline(vertSource.c_str(), fragSource.c_str(), - tag.newVertexFormat(m_gfxFactory), m_rtHint, - blendSrc, blendDst, - tag.getDepthTest(), tag.getDepthWrite(), - tag.getBackfaceCulling()); + static_cast(ctx). + newShaderPipeline(vertSource.c_str(), fragSource.c_str(), + tag.newVertexFormat(ctx), m_rtHint, + blendSrc, blendDst, tag.getPrimType(), + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); if (!ret) Log.report(logvisor::Fatal, "unable to build shader"); returnFunc(ret); @@ -396,11 +402,11 @@ struct MetalBackendFactory : IShaderBackendFactory } }; -IShaderBackendFactory* _NewMetalBackendFactory(boo::IGraphicsDataFactory* gfxFactory) +IShaderBackendFactory* _NewMetalBackendFactory() { - return new struct MetalBackendFactory(gfxFactory); + return new struct MetalBackendFactory(); } - + } }