mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-08-11 06:19:07 +00:00
Metal extension shaders
This commit is contained in:
parent
80284ad816
commit
6abde07598
2
hecl/extern/boo
vendored
2
hecl/extern/boo
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 54ae8c2b1a2ce58cabbebacd0ec4c0b16d92cd8c
|
Subproject commit 4a2c32c2a97b03ee4b3fb195062833161fc0bbda
|
@ -24,14 +24,16 @@ struct Metal : ProgrammableCommon
|
|||||||
void reset(const IR& ir, Diagnostics& diag);
|
void reset(const IR& ir, Diagnostics& diag);
|
||||||
std::string makeVert(unsigned col, unsigned uv, unsigned w,
|
std::string makeVert(unsigned col, unsigned uv, unsigned w,
|
||||||
unsigned skinSlots, unsigned texMtxs) const;
|
unsigned skinSlots, unsigned texMtxs) const;
|
||||||
std::string makeFrag(const ShaderFunction& lighting=ShaderFunction()) const;
|
std::string makeFrag(size_t blockCount, const char** blockNames,
|
||||||
std::string makeFrag(const ShaderFunction& lighting,
|
const ShaderFunction& lighting=ShaderFunction()) const;
|
||||||
|
std::string makeFrag(size_t blockCount, const char** blockNames,
|
||||||
|
const ShaderFunction& lighting,
|
||||||
const ShaderFunction& post) const;
|
const ShaderFunction& post) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const;
|
std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const;
|
||||||
std::string GenerateVertToFragStruct() const;
|
std::string GenerateVertToFragStruct() const;
|
||||||
std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const;
|
std::string GenerateVertUniformStruct(unsigned skinSlots) const;
|
||||||
|
|
||||||
std::string EmitVec3(const atVec4f& vec) const
|
std::string EmitVec3(const atVec4f& vec) const
|
||||||
{
|
{
|
||||||
|
@ -260,9 +260,10 @@ struct HMDLData
|
|||||||
boo::IShaderDataBinding* newShaderDataBindng(boo::IGraphicsDataFactory::Context& ctx,
|
boo::IShaderDataBinding* newShaderDataBindng(boo::IGraphicsDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline* shader,
|
boo::IShaderPipeline* shader,
|
||||||
size_t ubufCount, boo::IGraphicsBuffer** ubufs,
|
size_t ubufCount, boo::IGraphicsBuffer** ubufs,
|
||||||
|
const boo::PipelineStage* ubufStages,
|
||||||
size_t texCount, boo::ITexture** texs)
|
size_t texCount, boo::ITexture** texs)
|
||||||
{return ctx.newShaderDataBinding(shader, m_vtxFmt, m_vbo, nullptr, m_ibo,
|
{return ctx.newShaderDataBinding(shader, m_vtxFmt, m_vbo, nullptr, m_ibo,
|
||||||
ubufCount, ubufs, nullptr, nullptr, texCount, texs);}
|
ubufCount, ubufs, ubufStages, nullptr, nullptr, texCount, texs);}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ std::string Metal::GenerateVertToFragStruct() const
|
|||||||
return retval + "};\n";
|
return retval + "};\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Metal::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const
|
std::string Metal::GenerateVertUniformStruct(unsigned skinSlots) const
|
||||||
{
|
{
|
||||||
if (skinSlots == 0)
|
if (skinSlots == 0)
|
||||||
skinSlots = 1;
|
skinSlots = 1;
|
||||||
@ -98,11 +98,10 @@ std::string Metal::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtx
|
|||||||
"{\n"
|
"{\n"
|
||||||
" float4x4 mv[%u];\n"
|
" float4x4 mv[%u];\n"
|
||||||
" float4x4 mvInv[%u];\n"
|
" float4x4 mvInv[%u];\n"
|
||||||
" float4x4 proj;\n",
|
" float4x4 proj;\n"
|
||||||
|
"};\n",
|
||||||
skinSlots, skinSlots);
|
skinSlots, skinSlots);
|
||||||
if (texMtxs)
|
return retval;
|
||||||
retval += hecl::Format(" float4x4 texMtxs[%u];\n", texMtxs);
|
|
||||||
return retval + "};\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::reset(const IR& ir, Diagnostics& diag)
|
void Metal::reset(const IR& ir, Diagnostics& diag)
|
||||||
@ -114,11 +113,16 @@ void Metal::reset(const IR& ir, Diagnostics& diag)
|
|||||||
std::string Metal::makeVert(unsigned col, unsigned uv, unsigned w,
|
std::string Metal::makeVert(unsigned col, unsigned uv, unsigned w,
|
||||||
unsigned s, unsigned tm) const
|
unsigned s, unsigned tm) const
|
||||||
{
|
{
|
||||||
|
std::string tmStr;
|
||||||
|
if (tm)
|
||||||
|
tmStr = hecl::Format(",\nconstant float4x4 texMtxs[%u] [[ buffer(3) ]]", tm);
|
||||||
std::string retval = "#include <metal_stdlib>\nusing namespace metal;\n" +
|
std::string retval = "#include <metal_stdlib>\nusing namespace metal;\n" +
|
||||||
GenerateVertInStruct(col, uv, w) + "\n" +
|
GenerateVertInStruct(col, uv, w) + "\n" +
|
||||||
GenerateVertToFragStruct() + "\n" +
|
GenerateVertToFragStruct() + "\n" +
|
||||||
GenerateVertUniformStruct(s, tm) +
|
GenerateVertUniformStruct(s) +
|
||||||
"\nvertex VertToFrag vmain(VertData v [[ stage_in ]], constant HECLVertUniform& vu [[ buffer(2) ]])\n{\n"
|
"\nvertex VertToFrag vmain(VertData v [[ stage_in ]],\n"
|
||||||
|
" constant HECLVertUniform& vu [[ buffer(2) ]]" + tmStr + ")\n"
|
||||||
|
"{\n"
|
||||||
" VertToFrag vtf;\n";
|
" VertToFrag vtf;\n";
|
||||||
|
|
||||||
if (s)
|
if (s)
|
||||||
@ -150,7 +154,7 @@ std::string Metal::makeVert(unsigned col, unsigned uv, unsigned w,
|
|||||||
retval += hecl::Format(" vtf.tcgs%u = %s;\n", tcgIdx,
|
retval += hecl::Format(" vtf.tcgs%u = %s;\n", tcgIdx,
|
||||||
EmitTexGenSource2(tcg.m_src, tcg.m_uvIdx).c_str());
|
EmitTexGenSource2(tcg.m_src, tcg.m_uvIdx).c_str());
|
||||||
else
|
else
|
||||||
retval += hecl::Format(" vtf.tcgs%u = (vu.texMtxs[%u] * %s).xy;\n", tcgIdx, tcg.m_mtx,
|
retval += hecl::Format(" vtf.tcgs%u = (texMtxs[%u] * %s).xy;\n", tcgIdx, tcg.m_mtx,
|
||||||
EmitTexGenSource4(tcg.m_src, tcg.m_uvIdx).c_str());
|
EmitTexGenSource4(tcg.m_src, tcg.m_uvIdx).c_str());
|
||||||
++tcgIdx;
|
++tcgIdx;
|
||||||
}
|
}
|
||||||
@ -158,7 +162,8 @@ std::string Metal::makeVert(unsigned col, unsigned uv, unsigned w,
|
|||||||
return retval + " return vtf;\n}\n";
|
return retval + " return vtf;\n}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Metal::makeFrag(const ShaderFunction& lighting) const
|
std::string Metal::makeFrag(size_t blockCount, const char** blockNames,
|
||||||
|
const ShaderFunction& lighting) const
|
||||||
{
|
{
|
||||||
std::string lightingSrc;
|
std::string lightingSrc;
|
||||||
if (lighting.m_source)
|
if (lighting.m_source)
|
||||||
@ -168,7 +173,16 @@ std::string Metal::makeFrag(const ShaderFunction& lighting) const
|
|||||||
if (m_texMapEnd)
|
if (m_texMapEnd)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<m_texMapEnd ; ++i)
|
for (int i=0 ; i<m_texMapEnd ; ++i)
|
||||||
texMapDecl += hecl::Format("\n, texture2d<float> tex%u [[ texture(%u) ]]", i, i);
|
texMapDecl += hecl::Format(",\ntexture2d<float> tex%u [[ texture(%u) ]]", i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string blockCall;
|
||||||
|
for (size_t i=0 ; i<blockCount ; ++i)
|
||||||
|
{
|
||||||
|
texMapDecl += hecl::Format(",\nconstant %s& block%" PRISize " [[ buffer(%" PRISize ") ]]", blockNames[i], i, i + 4);
|
||||||
|
if (blockCall.size())
|
||||||
|
blockCall += ", ";
|
||||||
|
blockCall += hecl::Format("block%" PRISize, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string retval = "#include <metal_stdlib>\nusing namespace metal;\n"
|
std::string retval = "#include <metal_stdlib>\nusing namespace metal;\n"
|
||||||
@ -181,7 +195,7 @@ std::string Metal::makeFrag(const ShaderFunction& lighting) const
|
|||||||
if (m_lighting)
|
if (m_lighting)
|
||||||
{
|
{
|
||||||
if (lighting.m_entry)
|
if (lighting.m_entry)
|
||||||
retval += hecl::Format(" float4 lighting = %s();\n", lighting.m_entry);
|
retval += hecl::Format(" float4 lighting = %s(%s, vtf.mvPos, vtf.mvNorm);\n", lighting.m_entry, blockCall.c_str());
|
||||||
else
|
else
|
||||||
retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n";
|
retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n";
|
||||||
}
|
}
|
||||||
@ -199,7 +213,8 @@ std::string Metal::makeFrag(const ShaderFunction& lighting) const
|
|||||||
return retval + "}\n";
|
return retval + "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Metal::makeFrag(const ShaderFunction& lighting,
|
std::string Metal::makeFrag(size_t blockCount, const char** blockNames,
|
||||||
|
const ShaderFunction& lighting,
|
||||||
const ShaderFunction& post) const
|
const ShaderFunction& post) const
|
||||||
{
|
{
|
||||||
std::string lightingSrc;
|
std::string lightingSrc;
|
||||||
@ -218,19 +233,28 @@ std::string Metal::makeFrag(const ShaderFunction& lighting,
|
|||||||
if (m_texMapEnd)
|
if (m_texMapEnd)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<m_texMapEnd ; ++i)
|
for (int i=0 ; i<m_texMapEnd ; ++i)
|
||||||
texMapDecl += hecl::Format("texture2d<float> tex%u [[ texture(%u) ]],\n", i, i);
|
texMapDecl += hecl::Format(",\ntexture2d<float> tex%u [[ texture(%u) ]]", i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string blockCall;
|
||||||
|
for (size_t i=0 ; i<blockCount ; ++i)
|
||||||
|
{
|
||||||
|
texMapDecl += hecl::Format(",\nconstant %s& block%" PRISize " [[ buffer(%" PRISize ") ]]", blockNames[i], i, i + 4);
|
||||||
|
if (blockCall.size())
|
||||||
|
blockCall += ", ";
|
||||||
|
blockCall += hecl::Format("block%" PRISize, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string retval = "#include <metal_stdlib>\nusing namespace metal;\n"
|
std::string retval = "#include <metal_stdlib>\nusing namespace metal;\n"
|
||||||
"constexpr sampler samp(address::repeat, filter::linear, mip_filter::linear);\n" +
|
"constexpr sampler samp(address::repeat, filter::linear, mip_filter::linear);\n" +
|
||||||
GenerateVertToFragStruct() + "\n" +
|
GenerateVertToFragStruct() + "\n" +
|
||||||
lightingSrc + "\n" +
|
lightingSrc + "\n" +
|
||||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n" + texMapDecl + ")\n{\n";
|
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]]" + texMapDecl + ")\n{\n";
|
||||||
|
|
||||||
if (m_lighting)
|
if (m_lighting)
|
||||||
{
|
{
|
||||||
if (lighting.m_entry)
|
if (lighting.m_entry)
|
||||||
retval += hecl::Format(" float4 lighting = %s();\n", lighting.m_entry);
|
retval += hecl::Format(" float4 lighting = %s(%s, vtf.mvPos, vtf.mvNorm);\n", lighting.m_entry, blockCall.c_str());
|
||||||
else
|
else
|
||||||
retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n";
|
retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n";
|
||||||
}
|
}
|
||||||
@ -274,7 +298,7 @@ struct MetalBackendFactory : IShaderBackendFactory
|
|||||||
tag.getSkinSlotCount(), tag.getTexMtxCount());
|
tag.getSkinSlotCount(), tag.getTexMtxCount());
|
||||||
cachedSz += vertSource.size() + 1;
|
cachedSz += vertSource.size() + 1;
|
||||||
|
|
||||||
std::string fragSource = m_backend.makeFrag();
|
std::string fragSource = m_backend.makeFrag(0, nullptr);
|
||||||
cachedSz += fragSource.size() + 1;
|
cachedSz += fragSource.size() + 1;
|
||||||
objOut =
|
objOut =
|
||||||
static_cast<boo::MetalDataFactory::Context&>(ctx).
|
static_cast<boo::MetalDataFactory::Context&>(ctx).
|
||||||
@ -345,7 +369,8 @@ struct MetalBackendFactory : IShaderBackendFactory
|
|||||||
fragSources.reserve(extensionSlots.size());
|
fragSources.reserve(extensionSlots.size());
|
||||||
for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots)
|
for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots)
|
||||||
{
|
{
|
||||||
fragSources.push_back(m_backend.makeFrag(slot.lighting, slot.post));
|
fragSources.push_back(m_backend.makeFrag(slot.blockCount, slot.blockNames, slot.lighting, slot.post));
|
||||||
|
fprintf(stderr, "%s\n", fragSources.back().c_str());
|
||||||
cachedSz += fragSources.back().size() + 1;
|
cachedSz += fragSources.back().size() + 1;
|
||||||
boo::IShaderPipeline* ret =
|
boo::IShaderPipeline* ret =
|
||||||
static_cast<boo::MetalDataFactory::Context&>(ctx).
|
static_cast<boo::MetalDataFactory::Context&>(ctx).
|
||||||
|
@ -144,7 +144,7 @@ struct HECLApplicationCallback : boo::IApplicationCallback
|
|||||||
vubo = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexUBO), 1);
|
vubo = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexUBO), 1);
|
||||||
|
|
||||||
/* Assemble data binding */
|
/* Assemble data binding */
|
||||||
binding = testData.newShaderDataBindng(ctx, testShaderObj, 1, (boo::IGraphicsBuffer**)&vubo, 1, &texture);
|
binding = testData.newShaderDataBindng(ctx, testShaderObj, 1, (boo::IGraphicsBuffer**)&vubo, nullptr, 1, &texture);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user