diff --git a/hecl/extern/athena b/hecl/extern/athena index cf3dfcddf..750d23c68 160000 --- a/hecl/extern/athena +++ b/hecl/extern/athena @@ -1 +1 @@ -Subproject commit cf3dfcddffde70b54e38f18665cc3c4dbb0f5132 +Subproject commit 750d23c686e1f571643c019ae0ed6734c8057194 diff --git a/hecl/extern/boo b/hecl/extern/boo index 21548bada..29364a802 160000 --- a/hecl/extern/boo +++ b/hecl/extern/boo @@ -1 +1 @@ -Subproject commit 21548bada8e0806adfc3fc36fa748f7355dfecbb +Subproject commit 29364a80240e2addb7edbb7f5ac4def0c650ec95 diff --git a/hecl/include/hecl/Backend/HLSL.hpp b/hecl/include/hecl/Backend/HLSL.hpp index 8e5da37a0..0a150f671 100644 --- a/hecl/include/hecl/Backend/HLSL.hpp +++ b/hecl/include/hecl/Backend/HLSL.hpp @@ -12,15 +12,18 @@ struct HLSL : 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, - const ShaderFunction& post) const; + unsigned skinSlots, unsigned texMtxs, size_t extTexCount, + const TextureInfo* extTexs) const; + std::string makeFrag(bool alphaTest, const ShaderFunction& lighting=ShaderFunction()) const; + std::string makeFrag(bool alphaTest, const ShaderFunction& lighting, + const ShaderFunction& post, size_t extTexCount, + const TextureInfo* extTexs) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; - std::string GenerateVertToFragStruct() const; + std::string GenerateVertToFragStruct(size_t extTexCount) const; std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const; + std::string GenerateAlphaTest() const; std::string EmitVec3(const atVec4f& vec) const { diff --git a/hecl/lib/Backend/GLSL.cpp b/hecl/lib/Backend/GLSL.cpp index 08fe02e1d..30579766a 100644 --- a/hecl/lib/Backend/GLSL.cpp +++ b/hecl/lib/Backend/GLSL.cpp @@ -173,18 +173,16 @@ std::string GLSL::makeVert(const char* glslVer, unsigned col, unsigned uv, unsig ++tcgIdx; } - int extIdx = 0; for (int i=0 ; i vertBlob; ComPtr fragBlob; ComPtr pipelineBlob; @@ -274,7 +309,9 @@ struct HLSLBackendFactory : IShaderBackendFactory newShaderPipeline(vertSource.c_str(), fragSource.c_str(), vertBlob, fragBlob, pipelineBlob, tag.newVertexFormat(ctx), - m_backend.m_blendSrc, m_backend.m_blendDst, tag.getPrimType(), + boo::BlendFactor(m_backend.m_blendSrc), + boo::BlendFactor(m_backend.m_blendDst), + tag.getPrimType(), tag.getDepthTest(), tag.getDepthWrite(), tag.getBackfaceCulling()); if (!objOut) @@ -378,66 +415,74 @@ struct HLSLBackendFactory : IShaderBackendFactory { m_backend.reset(ir, diag); - std::string vertSource = - m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), - tag.getSkinSlotCount(), tag.getTexMtxCount()); + struct Blobs + { + ComPtr vert; + ComPtr frag; + ComPtr pipeline; + }; + std::vector pipeBlobs; + pipeBlobs.reserve(extensionSlots.size()); - ComPtr vertBlob; - std::vector, ComPtr>> fragPipeBlobs; - fragPipeBlobs.reserve(extensionSlots.size()); - - size_t cachedSz = 6 + 8 * extensionSlots.size(); + size_t cachedSz = 2 + 12 * extensionSlots.size(); for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) { - std::string fragSource = m_backend.makeFrag(slot.lighting, slot.post); - fragPipeBlobs.emplace_back(); - std::pair, ComPtr>& fragPipeBlob = fragPipeBlobs.back(); + std::string vertSource = + m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), + tag.getSkinSlotCount(), tag.getTexMtxCount(), slot.texCount, slot.texs); + + std::string fragSource = m_backend.makeFrag(tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha, + slot.lighting, slot.post, slot.texCount, slot.texs); + pipeBlobs.emplace_back(); + Blobs& thisPipeBlobs = pipeBlobs.back(); boo::IShaderPipeline* ret = static_cast(ctx). newShaderPipeline(vertSource.c_str(), fragSource.c_str(), - vertBlob, fragPipeBlob.first, fragPipeBlob.second, + thisPipeBlobs.vert, thisPipeBlobs.frag, thisPipeBlobs.pipeline, tag.newVertexFormat(ctx), - m_backend.m_blendSrc, m_backend.m_blendDst, tag.getPrimType(), + boo::BlendFactor((slot.srcFactor == hecl::Backend::BlendFactor::Original) ? m_backend.m_blendSrc : slot.srcFactor), + boo::BlendFactor((slot.dstFactor == hecl::Backend::BlendFactor::Original) ? m_backend.m_blendDst : slot.dstFactor), + tag.getPrimType(), tag.getDepthTest(), tag.getDepthWrite(), tag.getBackfaceCulling()); if (!ret) Log.report(logvisor::Fatal, "unable to build shader"); - if (fragPipeBlob.first) - cachedSz += fragPipeBlob.first->GetBufferSize(); - if (fragPipeBlob.second) - cachedSz += fragPipeBlob.second->GetBufferSize(); + if (thisPipeBlobs.vert) + cachedSz += thisPipeBlobs.vert->GetBufferSize(); + if (thisPipeBlobs.frag) + cachedSz += thisPipeBlobs.frag->GetBufferSize(); + if (thisPipeBlobs.pipeline) + cachedSz += thisPipeBlobs.pipeline->GetBufferSize(); returnFunc(ret); } - if (vertBlob) - cachedSz += vertBlob->GetBufferSize(); 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)); - if (vertBlob) + for (const Blobs& blobs : pipeBlobs) { - w.writeUint32Big(vertBlob->GetBufferSize()); - w.writeUBytes((atUint8*)vertBlob->GetBufferPointer(), vertBlob->GetBufferSize()); - } - else - w.writeUint32Big(0); - - for (const std::pair, ComPtr>& fragPipeBlob : fragPipeBlobs) - { - if (fragPipeBlob.first) + if (blobs.vert) { - w.writeUint32Big(fragPipeBlob.first->GetBufferSize()); - w.writeUBytes((atUint8*)fragPipeBlob.first->GetBufferPointer(), fragPipeBlob.first->GetBufferSize()); + w.writeUint32Big(blobs.vert->GetBufferSize()); + w.writeUBytes((atUint8*)blobs.vert->GetBufferPointer(), blobs.vert->GetBufferSize()); } else w.writeUint32Big(0); - if (fragPipeBlob.second) + if (blobs.frag) { - w.writeUint32Big(fragPipeBlob.second->GetBufferSize()); - w.writeUBytes((atUint8*)fragPipeBlob.second->GetBufferPointer(), fragPipeBlob.second->GetBufferSize()); + w.writeUint32Big(blobs.frag->GetBufferSize()); + w.writeUBytes((atUint8*)blobs.frag->GetBufferPointer(), blobs.frag->GetBufferSize()); + } + else + w.writeUint32Big(0); + + if (blobs.pipeline) + { + w.writeUint32Big(blobs.pipeline->GetBufferSize()); + w.writeUBytes((atUint8*)blobs.pipeline->GetBufferPointer(), blobs.pipeline->GetBufferSize()); } else w.writeUint32Big(0); @@ -453,19 +498,19 @@ struct HLSLBackendFactory : IShaderBackendFactory { const ShaderTag& tag = data.m_tag; athena::io::MemoryReader r(data.m_data.get(), data.m_sz); - boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte()); - boo::BlendFactor blendDst = boo::BlendFactor(r.readUByte()); - - atUint32 vertSz = r.readUint32Big(); - ComPtr vertBlob; - if (vertSz) - { - D3DCreateBlobPROC(vertSz, &vertBlob); - r.readUBytesToBuf(vertBlob->GetBufferPointer(), vertSz); - } + hecl::Backend::BlendFactor blendSrc = hecl::Backend::BlendFactor(r.readUByte()); + hecl::Backend::BlendFactor blendDst = hecl::Backend::BlendFactor(r.readUByte()); for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) { + atUint32 vertSz = r.readUint32Big(); + ComPtr vertBlob; + if (vertSz) + { + D3DCreateBlobPROC(vertSz, &vertBlob); + r.readUBytesToBuf(vertBlob->GetBufferPointer(), vertSz); + } + atUint32 fragSz = r.readUint32Big(); ComPtr fragBlob; if (fragSz) @@ -487,7 +532,9 @@ struct HLSLBackendFactory : IShaderBackendFactory newShaderPipeline(nullptr, nullptr, vertBlob, fragBlob, pipelineBlob, tag.newVertexFormat(ctx), - blendSrc, blendDst, tag.getPrimType(), + boo::BlendFactor((slot.srcFactor == hecl::Backend::BlendFactor::Original) ? blendSrc : slot.srcFactor), + boo::BlendFactor((slot.dstFactor == hecl::Backend::BlendFactor::Original) ? blendDst : slot.dstFactor), + tag.getPrimType(), tag.getDepthTest(), tag.getDepthWrite(), tag.getBackfaceCulling()); if (!ret)