mirror of https://github.com/AxioDL/metaforce.git
Metal extension shaders
This commit is contained in:
parent
80284ad816
commit
6abde07598
|
@ -1 +1 @@
|
|||
Subproject commit 54ae8c2b1a2ce58cabbebacd0ec4c0b16d92cd8c
|
||||
Subproject commit 4a2c32c2a97b03ee4b3fb195062833161fc0bbda
|
|
@ -24,14 +24,16 @@ struct Metal : ProgrammableCommon
|
|||
void reset(const IR& ir, Diagnostics& diag);
|
||||
std::string makeVert(unsigned col, unsigned uv, unsigned w,
|
||||
unsigned skinSlots, unsigned texMtxs) const;
|
||||
std::string makeFrag(const ShaderFunction& lighting=ShaderFunction()) const;
|
||||
std::string makeFrag(const ShaderFunction& lighting,
|
||||
std::string makeFrag(size_t blockCount, const char** blockNames,
|
||||
const ShaderFunction& lighting=ShaderFunction()) const;
|
||||
std::string makeFrag(size_t blockCount, const char** blockNames,
|
||||
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 GenerateVertUniformStruct(unsigned skinSlots) const;
|
||||
|
||||
std::string EmitVec3(const atVec4f& vec) const
|
||||
{
|
||||
|
|
|
@ -260,9 +260,10 @@ struct HMDLData
|
|||
boo::IShaderDataBinding* newShaderDataBindng(boo::IGraphicsDataFactory::Context& ctx,
|
||||
boo::IShaderPipeline* shader,
|
||||
size_t ubufCount, boo::IGraphicsBuffer** ubufs,
|
||||
const boo::PipelineStage* ubufStages,
|
||||
size_t texCount, boo::ITexture** texs)
|
||||
{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";
|
||||
}
|
||||
|
||||
std::string Metal::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const
|
||||
std::string Metal::GenerateVertUniformStruct(unsigned skinSlots) const
|
||||
{
|
||||
if (skinSlots == 0)
|
||||
skinSlots = 1;
|
||||
|
@ -98,11 +98,10 @@ std::string Metal::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtx
|
|||
"{\n"
|
||||
" float4x4 mv[%u];\n"
|
||||
" float4x4 mvInv[%u];\n"
|
||||
" float4x4 proj;\n",
|
||||
" float4x4 proj;\n"
|
||||
"};\n",
|
||||
skinSlots, skinSlots);
|
||||
if (texMtxs)
|
||||
retval += hecl::Format(" float4x4 texMtxs[%u];\n", texMtxs);
|
||||
return retval + "};\n";
|
||||
return retval;
|
||||
}
|
||||
|
||||
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,
|
||||
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" +
|
||||
GenerateVertInStruct(col, uv, w) + "\n" +
|
||||
GenerateVertToFragStruct() + "\n" +
|
||||
GenerateVertUniformStruct(s, tm) +
|
||||
"\nvertex VertToFrag vmain(VertData v [[ stage_in ]], constant HECLVertUniform& vu [[ buffer(2) ]])\n{\n"
|
||||
GenerateVertUniformStruct(s) +
|
||||
"\nvertex VertToFrag vmain(VertData v [[ stage_in ]],\n"
|
||||
" constant HECLVertUniform& vu [[ buffer(2) ]]" + tmStr + ")\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n";
|
||||
|
||||
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,
|
||||
EmitTexGenSource2(tcg.m_src, tcg.m_uvIdx).c_str());
|
||||
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());
|
||||
++tcgIdx;
|
||||
}
|
||||
|
@ -158,7 +162,8 @@ std::string Metal::makeVert(unsigned col, unsigned uv, unsigned w,
|
|||
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;
|
||||
if (lighting.m_source)
|
||||
|
@ -168,7 +173,16 @@ std::string Metal::makeFrag(const ShaderFunction& lighting) const
|
|||
if (m_texMapEnd)
|
||||
{
|
||||
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"
|
||||
|
@ -181,7 +195,7 @@ std::string Metal::makeFrag(const ShaderFunction& lighting) const
|
|||
if (m_lighting)
|
||||
{
|
||||
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
|
||||
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";
|
||||
}
|
||||
|
||||
std::string Metal::makeFrag(const ShaderFunction& lighting,
|
||||
std::string Metal::makeFrag(size_t blockCount, const char** blockNames,
|
||||
const ShaderFunction& lighting,
|
||||
const ShaderFunction& post) const
|
||||
{
|
||||
std::string lightingSrc;
|
||||
|
@ -218,19 +233,28 @@ std::string Metal::makeFrag(const ShaderFunction& lighting,
|
|||
if (m_texMapEnd)
|
||||
{
|
||||
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"
|
||||
"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";
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]]" + texMapDecl + ")\n{\n";
|
||||
|
||||
if (m_lighting)
|
||||
{
|
||||
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
|
||||
retval += " float4 lighting = float4(1.0,1.0,1.0,1.0);\n";
|
||||
}
|
||||
|
@ -274,7 +298,7 @@ struct MetalBackendFactory : IShaderBackendFactory
|
|||
tag.getSkinSlotCount(), tag.getTexMtxCount());
|
||||
cachedSz += vertSource.size() + 1;
|
||||
|
||||
std::string fragSource = m_backend.makeFrag();
|
||||
std::string fragSource = m_backend.makeFrag(0, nullptr);
|
||||
cachedSz += fragSource.size() + 1;
|
||||
objOut =
|
||||
static_cast<boo::MetalDataFactory::Context&>(ctx).
|
||||
|
@ -345,7 +369,8 @@ struct MetalBackendFactory : IShaderBackendFactory
|
|||
fragSources.reserve(extensionSlots.size());
|
||||
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;
|
||||
boo::IShaderPipeline* ret =
|
||||
static_cast<boo::MetalDataFactory::Context&>(ctx).
|
||||
|
|
|
@ -144,7 +144,7 @@ struct HECLApplicationCallback : boo::IApplicationCallback
|
|||
vubo = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexUBO), 1);
|
||||
|
||||
/* 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;
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue