Changes to support new boo object tracker API

This commit is contained in:
Jack Andersen 2017-11-04 20:15:03 -10:00
parent f9a431d62c
commit d2fda8a373
10 changed files with 168 additions and 124 deletions

2
hecl/extern/boo vendored

@ -1 +1 @@
Subproject commit 10364557b99f0b48d1ab61ed02355f61c8fdbac1 Subproject commit 3a7987bb21b0db3873948e82520fa88c6981f436

View File

@ -91,7 +91,7 @@ public:
uint64_t getMetaData() const {return m_meta;} uint64_t getMetaData() const {return m_meta;}
/* For shader constructors that require vertex format up-front (HLSL) */ /* For shader constructors that require vertex format up-front (HLSL) */
boo::IVertexFormat* newVertexFormat(boo::IGraphicsDataFactory::Context& ctx) const; boo::ObjToken<boo::IVertexFormat> newVertexFormat(boo::IGraphicsDataFactory::Context& ctx) const;
}; };
/** /**
@ -196,13 +196,13 @@ class IShaderBackendFactory
friend class ShaderCacheManager; friend class ShaderCacheManager;
protected: protected:
unsigned m_rtHint = 1; unsigned m_rtHint = 1;
using FReturnExtensionShader = std::function<void(boo::IShaderPipeline*)>; using FReturnExtensionShader = std::function<void(const boo::ObjToken<boo::IShaderPipeline>&)>;
virtual ShaderCachedData buildShaderFromIR(const ShaderTag& tag, virtual ShaderCachedData buildShaderFromIR(const ShaderTag& tag,
const hecl::Frontend::IR& ir, const hecl::Frontend::IR& ir,
hecl::Frontend::Diagnostics& diag, hecl::Frontend::Diagnostics& diag,
boo::IGraphicsDataFactory::Context& ctx, boo::IGraphicsDataFactory::Context& ctx,
boo::IShaderPipeline*& objOut)=0; boo::ObjToken<boo::IShaderPipeline>& objOut)=0;
virtual boo::IShaderPipeline* buildShaderFromCache(const ShaderCachedData& data, virtual boo::ObjToken<boo::IShaderPipeline> buildShaderFromCache(const ShaderCachedData& data,
boo::IGraphicsDataFactory::Context& ctx)=0; boo::IGraphicsDataFactory::Context& ctx)=0;
virtual ShaderCachedData buildExtendedShaderFromIR(const ShaderTag& tag, virtual ShaderCachedData buildExtendedShaderFromIR(const ShaderTag& tag,
const hecl::Frontend::IR& ir, const hecl::Frontend::IR& ir,
@ -215,7 +215,7 @@ protected:
boo::IGraphicsDataFactory::Context& ctx, boo::IGraphicsDataFactory::Context& ctx,
FReturnExtensionShader returnFunc)=0; FReturnExtensionShader returnFunc)=0;
public: public:
virtual ~IShaderBackendFactory() {} virtual ~IShaderBackendFactory() = default;
}; };
/** /**
@ -223,8 +223,7 @@ public:
*/ */
struct ShaderPipelines struct ShaderPipelines
{ {
boo::GraphicsDataToken m_token; std::vector<boo::ObjToken<boo::IShaderPipeline>> m_pipelines;
std::vector<boo::IShaderPipeline*> m_pipelines;
}; };
/** /**
@ -256,9 +255,9 @@ class ShaderCacheManager
void bootstrapIndex(); void bootstrapIndex();
ShaderCachedData lookupData(const Hash& hash); ShaderCachedData lookupData(const Hash& hash);
bool addData(const ShaderCachedData& data); bool addData(const ShaderCachedData& data);
boo::IShaderPipeline* buildFromCache(const ShaderCachedData& foundData, boo::ObjToken<boo::IShaderPipeline> buildFromCache(const ShaderCachedData& foundData,
boo::IGraphicsDataFactory::Context& ctx); boo::IGraphicsDataFactory::Context& ctx);
std::vector<boo::IShaderPipeline*> buildExtendedFromCache(const ShaderCachedData& foundData, std::vector<boo::ObjToken<boo::IShaderPipeline>> buildExtendedFromCache(const ShaderCachedData& foundData,
boo::IGraphicsDataFactory::Context& ctx); boo::IGraphicsDataFactory::Context& ctx);
public: public:
ShaderCacheManager(const FileStoreManager& storeMgr, ShaderCacheManager(const FileStoreManager& storeMgr,
@ -293,23 +292,26 @@ public:
*/ */
struct HMDLData struct HMDLData
{ {
boo::IGraphicsBufferS* m_vbo; boo::ObjToken<boo::IGraphicsBufferS> m_vbo;
boo::IGraphicsBufferS* m_ibo; boo::ObjToken<boo::IGraphicsBufferS> m_ibo;
boo::IVertexFormat* m_vtxFmt = nullptr; boo::ObjToken<boo::IVertexFormat> m_vtxFmt;
HMDLData(boo::IGraphicsDataFactory::Context& ctx, HMDLData(boo::IGraphicsDataFactory::Context& ctx,
const void* metaData, const void* vbo, const void* ibo); const void* metaData, const void* vbo, const void* ibo);
/* For binding constructors that require vertex format up front (GLSL) */ /* For binding constructors that require vertex format up front (GLSL) */
static boo::IVertexFormat* NewVertexFormat(boo::IGraphicsDataFactory::Context& ctx, const HMDLMeta& meta, static boo::ObjToken<boo::IVertexFormat>
boo::IGraphicsBuffer* vbo=nullptr, boo::IGraphicsBuffer* ibo=nullptr); NewVertexFormat(boo::IGraphicsDataFactory::Context& ctx, const HMDLMeta& meta,
const boo::ObjToken<boo::IGraphicsBuffer>& vbo={},
const boo::ObjToken<boo::IGraphicsBuffer>& ibo={});
boo::IShaderDataBinding* newShaderDataBindng(boo::IGraphicsDataFactory::Context& ctx, boo::ObjToken<boo::IShaderDataBinding>
boo::IShaderPipeline* shader, newShaderDataBindng(boo::IGraphicsDataFactory::Context& ctx,
size_t ubufCount, boo::IGraphicsBuffer** ubufs, const boo::ObjToken<boo::IShaderPipeline>& shader,
size_t ubufCount, const boo::ObjToken<boo::IGraphicsBuffer>* ubufs,
const boo::PipelineStage* ubufStages, const boo::PipelineStage* ubufStages,
size_t texCount, boo::ITexture** texs) size_t texCount, const boo::ObjToken<boo::ITexture>* texs)
{return ctx.newShaderDataBinding(shader, m_vtxFmt, m_vbo, nullptr, m_ibo, {return ctx.newShaderDataBinding(shader, m_vtxFmt, m_vbo.get(), nullptr, m_ibo.get(),
ubufCount, ubufs, ubufStages, nullptr, nullptr, ubufCount, ubufs, ubufStages, nullptr, nullptr,
texCount, texs, nullptr, nullptr);} texCount, texs, nullptr, nullptr);}
}; };

View File

@ -51,13 +51,13 @@ private:
/** Efficient way to get bucket and block simultaneously */ /** Efficient way to get bucket and block simultaneously */
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); } DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
/** Buffer pool token */ /** Factory pointer for building additional buffers */
boo::GraphicsBufferPoolToken m_token; boo::IGraphicsDataFactory* m_factory = nullptr;
/** Private bucket info */ /** Private bucket info */
struct Bucket struct Bucket
{ {
boo::IGraphicsBufferD* buffer; boo::ObjToken<boo::IGraphicsBufferD> buffer;
uint8_t* cpuBuffer = nullptr; uint8_t* cpuBuffer = nullptr;
std::atomic_size_t useCount = {}; std::atomic_size_t useCount = {};
bool dirty = false; bool dirty = false;
@ -80,7 +80,7 @@ private:
void increment(UniformBufferPool& pool) void increment(UniformBufferPool& pool)
{ {
if (useCount.fetch_add(1) == 0) if (useCount.fetch_add(1) == 0)
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Uniform, buffer = pool.m_factory->newPoolBuffer(boo::BufferUse::Uniform,
pool.m_stride, pool.m_countPerBucket); pool.m_stride, pool.m_countPerBucket);
} }
@ -93,8 +93,7 @@ private:
buffer->unmap(); buffer->unmap();
cpuBuffer = nullptr; cpuBuffer = nullptr;
} }
pool.m_token.deletePoolBuffer(buffer); buffer.reset();
buffer = nullptr;
} }
} }
}; };
@ -168,7 +167,7 @@ public:
return reinterpret_cast<UniformStruct&>(bucket.cpuBuffer[m_div.rem * m_pool->m_stride]); return reinterpret_cast<UniformStruct&>(bucket.cpuBuffer[m_div.rem * m_pool->m_stride]);
} }
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const std::pair<boo::ObjToken<boo::IGraphicsBufferD>, IndexTp> getBufferInfo() const
{ {
Bucket& bucket = *m_pool->m_buckets[m_div.quot]; Bucket& bucket = *m_pool->m_buckets[m_div.quot];
return {bucket.buffer, m_div.rem * m_pool->m_stride}; return {bucket.buffer, m_div.rem * m_pool->m_stride};
@ -192,12 +191,15 @@ public:
/** Allocate free block into client-owned Token */ /** Allocate free block into client-owned Token */
Token allocateBlock(boo::IGraphicsDataFactory* factory) Token allocateBlock(boo::IGraphicsDataFactory* factory)
{ {
if (!m_token) m_factory = factory;
m_token = factory->newBufferPool();
return Token(this); return Token(this);
} }
void doDestroy() { m_token.doDestroy(); } void doDestroy()
{
for (auto& bucket : m_buckets)
bucket->buffer.reset();
}
}; };
} }

View File

@ -51,13 +51,13 @@ private:
/** Efficient way to get bucket and element simultaneously */ /** Efficient way to get bucket and element simultaneously */
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); } DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
/** Buffer pool token */ /** Factory pointer for building additional buffers */
boo::GraphicsBufferPoolToken m_token; boo::IGraphicsDataFactory* m_factory = nullptr;
/** Private bucket info */ /** Private bucket info */
struct Bucket struct Bucket
{ {
boo::IGraphicsBufferD* buffer; boo::ObjToken<boo::IGraphicsBufferD> buffer;
uint8_t* cpuBuffer = nullptr; uint8_t* cpuBuffer = nullptr;
std::atomic_size_t useCount = {}; std::atomic_size_t useCount = {};
bool dirty = false; bool dirty = false;
@ -80,7 +80,7 @@ private:
void increment(VertexBufferPool& pool) void increment(VertexBufferPool& pool)
{ {
if (useCount.fetch_add(1) == 0) if (useCount.fetch_add(1) == 0)
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Vertex, buffer = pool.m_factory->newPoolBuffer(boo::BufferUse::Vertex,
pool.m_stride, pool.m_countPerBucket); pool.m_stride, pool.m_countPerBucket);
} }
@ -93,8 +93,7 @@ private:
buffer->unmap(); buffer->unmap();
cpuBuffer = nullptr; cpuBuffer = nullptr;
} }
pool.m_token.deletePoolBuffer(buffer); buffer.reset();
buffer = nullptr;
} }
} }
}; };
@ -170,7 +169,7 @@ public:
return reinterpret_cast<VertStruct*>(&bucket.cpuBuffer[m_div.rem * m_pool->m_stride]); return reinterpret_cast<VertStruct*>(&bucket.cpuBuffer[m_div.rem * m_pool->m_stride]);
} }
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const std::pair<boo::ObjToken<boo::IGraphicsBufferD>, IndexTp> getBufferInfo() const
{ {
Bucket& bucket = *m_pool->m_buckets[m_div.quot]; Bucket& bucket = *m_pool->m_buckets[m_div.quot];
return {bucket.buffer, m_div.rem}; return {bucket.buffer, m_div.rem};
@ -194,12 +193,15 @@ public:
/** Allocate free block into client-owned Token */ /** Allocate free block into client-owned Token */
Token allocateBlock(boo::IGraphicsDataFactory* factory, IndexTp count) Token allocateBlock(boo::IGraphicsDataFactory* factory, IndexTp count)
{ {
if (!m_token) m_factory = factory;
m_token = factory->newBufferPool();
return Token(this, count); return Token(this, count);
} }
void doDestroy() { m_token.doDestroy(); } void doDestroy()
{
for (auto& bucket : m_buckets)
bucket->buffer.reset();
}
static constexpr IndexTp bucketCapacity() { return m_countPerBucket; } static constexpr IndexTp bucketCapacity() { return m_countPerBucket; }
}; };

View File

@ -390,7 +390,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
const hecl::Frontend::IR& ir, const hecl::Frontend::IR& ir,
hecl::Frontend::Diagnostics& diag, hecl::Frontend::Diagnostics& diag,
boo::IGraphicsDataFactory::Context& ctx, boo::IGraphicsDataFactory::Context& ctx,
boo::IShaderPipeline*& objOut) boo::ObjToken<boo::IShaderPipeline>& objOut)
{ {
m_backend.reset(ir, diag); m_backend.reset(ir, diag);
size_t cachedSz = 3; size_t cachedSz = 3;
@ -433,7 +433,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
return dataOut; return dataOut;
} }
boo::IShaderPipeline* buildShaderFromCache(const ShaderCachedData& data, boo::ObjToken<boo::IShaderPipeline> buildShaderFromCache(const ShaderCachedData& data,
boo::IGraphicsDataFactory::Context& ctx) boo::IGraphicsDataFactory::Context& ctx)
{ {
const ShaderTag& tag = data.m_tag; const ShaderTag& tag = data.m_tag;
@ -450,7 +450,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
if (texMapEnd > 8) if (texMapEnd > 8)
Log.report(logvisor::Fatal, "maximum of 8 texture maps supported"); Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
boo::IShaderPipeline* ret = auto ret =
static_cast<boo::GLDataFactory::Context&>(ctx). static_cast<boo::GLDataFactory::Context&>(ctx).
newShaderPipeline(vertSource.c_str(), fragSource.c_str(), newShaderPipeline(vertSource.c_str(), fragSource.c_str(),
texMapEnd, STD_TEXNAMES, texMapEnd, STD_TEXNAMES,
@ -520,7 +520,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
break; break;
} }
boo::IShaderPipeline* ret = auto ret =
static_cast<boo::GLDataFactory::Context&>(ctx). static_cast<boo::GLDataFactory::Context&>(ctx).
newShaderPipeline(sources.back().first.c_str(), sources.back().second.c_str(), newShaderPipeline(sources.back().first.c_str(), sources.back().second.c_str(),
8, STD_TEXNAMES, bc, bn, 8, STD_TEXNAMES, bc, bn,
@ -602,7 +602,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
break; break;
} }
boo::IShaderPipeline* ret = auto ret =
static_cast<boo::GLDataFactory::Context&>(ctx). static_cast<boo::GLDataFactory::Context&>(ctx).
newShaderPipeline(vertSource.c_str(), fragSource.c_str(), newShaderPipeline(vertSource.c_str(), fragSource.c_str(),
8, STD_TEXNAMES, bc, bn, 8, STD_TEXNAMES, bc, bn,

View File

@ -443,7 +443,7 @@ struct MetalBackendFactory : IShaderBackendFactory
const hecl::Frontend::IR& ir, const hecl::Frontend::IR& ir,
hecl::Frontend::Diagnostics& diag, hecl::Frontend::Diagnostics& diag,
boo::IGraphicsDataFactory::Context& ctx, boo::IGraphicsDataFactory::Context& ctx,
boo::IShaderPipeline*& objOut) boo::ObjToken<boo::IShaderPipeline>& objOut)
{ {
if (!m_rtHint) if (!m_rtHint)
Log.report(logvisor::Fatal, Log.report(logvisor::Fatal,
@ -455,15 +455,17 @@ struct MetalBackendFactory : IShaderBackendFactory
std::string vertSource = std::string vertSource =
m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(),
tag.getSkinSlotCount(), tag.getTexMtxCount(), 0, nullptr, tag.getReflectionType()); tag.getSkinSlotCount(), tag.getTexMtxCount(), 0, nullptr, tag.getReflectionType());
cachedSz += vertSource.size() + 1;
std::string fragSource = m_backend.makeFrag(0, nullptr, std::string fragSource = m_backend.makeFrag(0, nullptr,
tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha, tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha,
tag.getReflectionType()); tag.getReflectionType());
cachedSz += fragSource.size() + 1;
std::vector<uint8_t> vertBlob;
std::vector<uint8_t> fragBlob;
objOut = objOut =
static_cast<boo::MetalDataFactory::Context&>(ctx). static_cast<boo::MetalDataFactory::Context&>(ctx).
newShaderPipeline(vertSource.c_str(), fragSource.c_str(), newShaderPipeline(vertSource.c_str(), fragSource.c_str(),
&vertBlob, &fragBlob,
tag.newVertexFormat(ctx), m_rtHint, tag.newVertexFormat(ctx), m_rtHint,
boo::BlendFactor(m_backend.m_blendSrc), boo::BlendFactor(m_backend.m_blendSrc),
boo::BlendFactor(m_backend.m_blendDst), boo::BlendFactor(m_backend.m_blendDst),
@ -473,17 +475,22 @@ struct MetalBackendFactory : IShaderBackendFactory
if (!objOut) if (!objOut)
Log.report(logvisor::Fatal, "unable to build shader"); Log.report(logvisor::Fatal, "unable to build shader");
cachedSz += vertBlob.size() + 4;
cachedSz += fragBlob.size() + 4;
ShaderCachedData dataOut(tag, cachedSz); ShaderCachedData dataOut(tag, cachedSz);
athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz); athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz);
w.writeUByte(atUint8(m_backend.m_blendSrc)); w.writeUByte(atUint8(m_backend.m_blendSrc));
w.writeUByte(atUint8(m_backend.m_blendDst)); w.writeUByte(atUint8(m_backend.m_blendDst));
w.writeString(vertSource); w.writeUint32Big(vertBlob.size());
w.writeString(fragSource); w.writeUBytes(vertBlob.data(), vertBlob.size());
w.writeUint32Big(fragBlob.size());
w.writeUBytes(fragBlob.data(), fragBlob.size());
return dataOut; return dataOut;
} }
boo::IShaderPipeline* buildShaderFromCache(const ShaderCachedData& data, boo::ObjToken<boo::IShaderPipeline> buildShaderFromCache(const ShaderCachedData& data,
boo::IGraphicsDataFactory::Context& ctx) boo::IGraphicsDataFactory::Context& ctx)
{ {
if (!m_rtHint) if (!m_rtHint)
@ -494,15 +501,28 @@ struct MetalBackendFactory : IShaderBackendFactory
athena::io::MemoryReader r(data.m_data.get(), data.m_sz, false, false); athena::io::MemoryReader r(data.m_data.get(), data.m_sz, false, false);
boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte()); boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte());
boo::BlendFactor blendDst = boo::BlendFactor(r.readUByte()); boo::BlendFactor blendDst = boo::BlendFactor(r.readUByte());
std::string vertSource = r.readString(); std::vector<uint8_t> vertBlob;
std::string fragSource = r.readString(); std::vector<uint8_t> fragBlob;
atUint32 vertLen = r.readUint32Big();
if (vertLen)
{
vertBlob.resize(vertLen);
r.readUBytesToBuf(&vertBlob[0], vertLen);
}
atUint32 fragLen = r.readUint32Big();
if (fragLen)
{
fragBlob.resize(fragLen);
r.readUBytesToBuf(&fragBlob[0], fragLen);
}
if (r.hasError()) if (r.hasError())
return nullptr; return nullptr;
boo::IShaderPipeline* ret = auto ret =
static_cast<boo::MetalDataFactory::Context&>(ctx). static_cast<boo::MetalDataFactory::Context&>(ctx).
newShaderPipeline(vertSource.c_str(), fragSource.c_str(), newShaderPipeline(nullptr, nullptr,
&vertBlob, &fragBlob,
tag.newVertexFormat(ctx), m_rtHint, tag.newVertexFormat(ctx), m_rtHint,
blendSrc, blendDst, tag.getPrimType(), blendSrc, blendDst, tag.getPrimType(),
tag.getDepthTest() ? boo::ZTest::LEqual : boo::ZTest::None, tag.getDepthWrite(), true, true, tag.getDepthTest() ? boo::ZTest::LEqual : boo::ZTest::None, tag.getDepthWrite(), true, true,
@ -526,19 +546,19 @@ struct MetalBackendFactory : IShaderBackendFactory
m_backend.reset(ir, diag); m_backend.reset(ir, diag);
size_t cachedSz = 2; size_t cachedSz = 2;
std::vector<std::pair<std::string, std::string>> sources; std::vector<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> blobs;
sources.reserve(extensionSlots.size()); blobs.reserve(extensionSlots.size());
for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots)
{ {
sources.emplace_back(m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), std::string vertSource =
m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(),
tag.getSkinSlotCount(), tag.getTexMtxCount(), slot.texCount, slot.texs, tag.getSkinSlotCount(), tag.getTexMtxCount(), slot.texCount, slot.texs,
slot.noReflection ? Backend::ReflectionType::None : tag.getReflectionType()), slot.noReflection ? Backend::ReflectionType::None : tag.getReflectionType());
std::string fragSource =
m_backend.makeFrag(slot.blockCount, slot.blockNames, m_backend.makeFrag(slot.blockCount, slot.blockNames,
tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha, tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha,
slot.noReflection ? Backend::ReflectionType::None : tag.getReflectionType(), slot.noReflection ? Backend::ReflectionType::None : tag.getReflectionType(),
slot.lighting, slot.post, slot.texCount, slot.texs)); slot.lighting, slot.post, slot.texCount, slot.texs);
cachedSz += sources.back().first.size() + 1;
cachedSz += sources.back().second.size() + 1;
boo::ZTest zTest; boo::ZTest zTest;
switch (slot.depthTest) switch (slot.depthTest)
@ -561,9 +581,11 @@ struct MetalBackendFactory : IShaderBackendFactory
break; break;
} }
boo::IShaderPipeline* ret = blobs.emplace_back();
auto ret =
static_cast<boo::MetalDataFactory::Context&>(ctx). static_cast<boo::MetalDataFactory::Context&>(ctx).
newShaderPipeline(sources.back().first.c_str(), sources.back().second.c_str(), newShaderPipeline(vertSource.c_str(), fragSource.c_str(),
&blobs.back().first, &blobs.back().second,
tag.newVertexFormat(ctx), m_rtHint, tag.newVertexFormat(ctx), m_rtHint,
boo::BlendFactor((slot.srcFactor == hecl::Backend::BlendFactor::Original) ? m_backend.m_blendSrc : slot.srcFactor), 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), boo::BlendFactor((slot.dstFactor == hecl::Backend::BlendFactor::Original) ? m_backend.m_blendDst : slot.dstFactor),
@ -573,6 +595,9 @@ struct MetalBackendFactory : IShaderBackendFactory
(tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None)); (tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None));
if (!ret) if (!ret)
Log.report(logvisor::Fatal, "unable to build shader"); Log.report(logvisor::Fatal, "unable to build shader");
cachedSz += blobs.back().first.size() + 4;
cachedSz += blobs.back().second.size() + 4;
returnFunc(ret); returnFunc(ret);
} }
@ -580,10 +605,12 @@ struct MetalBackendFactory : IShaderBackendFactory
athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz); athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz);
w.writeUByte(atUint8(m_backend.m_blendSrc)); w.writeUByte(atUint8(m_backend.m_blendSrc));
w.writeUByte(atUint8(m_backend.m_blendDst)); w.writeUByte(atUint8(m_backend.m_blendDst));
for (auto& src : sources) for (auto& blob : blobs)
{ {
w.writeString(src.first); w.writeUint32Big(blob.first.size());
w.writeString(src.second); w.writeUBytes(blob.first.data(), blob.first.size());
w.writeUint32Big(blob.second.size());
w.writeUBytes(blob.second.data(), blob.second.size());
} }
return dataOut; return dataOut;
@ -608,8 +635,20 @@ struct MetalBackendFactory : IShaderBackendFactory
for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots)
{ {
std::string vertSource = r.readString(); std::vector<uint8_t> vertBlob;
std::string fragSource = r.readString(); std::vector<uint8_t> fragBlob;
atUint32 vertLen = r.readUint32Big();
if (vertLen)
{
vertBlob.resize(vertLen);
r.readUBytesToBuf(&vertBlob[0], vertLen);
}
atUint32 fragLen = r.readUint32Big();
if (fragLen)
{
fragBlob.resize(fragLen);
r.readUBytesToBuf(&fragBlob[0], fragLen);
}
if (r.hasError()) if (r.hasError())
return false; return false;
@ -635,9 +674,10 @@ struct MetalBackendFactory : IShaderBackendFactory
break; break;
} }
boo::IShaderPipeline* ret = auto ret =
static_cast<boo::MetalDataFactory::Context&>(ctx). static_cast<boo::MetalDataFactory::Context&>(ctx).
newShaderPipeline(vertSource.c_str(), fragSource.c_str(), newShaderPipeline(nullptr, nullptr,
&vertBlob, &fragBlob,
tag.newVertexFormat(ctx), m_rtHint, tag.newVertexFormat(ctx), m_rtHint,
boo::BlendFactor((slot.srcFactor == hecl::Backend::BlendFactor::Original) ? blendSrc : slot.srcFactor), boo::BlendFactor((slot.srcFactor == hecl::Backend::BlendFactor::Original) ? blendSrc : slot.srcFactor),
boo::BlendFactor((slot.dstFactor == hecl::Backend::BlendFactor::Original) ? blendDst : slot.dstFactor), boo::BlendFactor((slot.dstFactor == hecl::Backend::BlendFactor::Original) ? blendDst : slot.dstFactor),

View File

@ -419,6 +419,7 @@ BlenderConnection::BlenderConnection(int verbosityLevel)
int devNull = open("/dev/null", O_WRONLY); int devNull = open("/dev/null", O_WRONLY);
dup2(devNull, STDOUT_FILENO); dup2(devNull, STDOUT_FILENO);
dup2(devNull, STDERR_FILENO); dup2(devNull, STDERR_FILENO);
close(devNull);
} }
char errbuf[256]; char errbuf[256];

View File

@ -23,12 +23,14 @@ HMDLData::HMDLData(boo::IGraphicsDataFactory::Context& ctx,
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, ibo, 4, meta.indexCount); m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, ibo, 4, meta.indexCount);
if (ctx.bindingNeedsVertexFormat()) if (ctx.bindingNeedsVertexFormat())
m_vtxFmt = NewVertexFormat(ctx, meta, m_vbo, m_ibo); m_vtxFmt = NewVertexFormat(ctx, meta, m_vbo.get(), m_ibo.get());
} }
/* For binding constructors that require vertex format up front (GLSL) */ /* For binding constructors that require vertex format up front (GLSL) */
boo::IVertexFormat* HMDLData::NewVertexFormat(boo::IGraphicsDataFactory::Context& ctx, const HMDLMeta& meta, boo::ObjToken<boo::IVertexFormat>
boo::IGraphicsBuffer* vbo, boo::IGraphicsBuffer* ibo) HMDLData::NewVertexFormat(boo::IGraphicsDataFactory::Context& ctx, const HMDLMeta& meta,
const boo::ObjToken<boo::IGraphicsBuffer>& vbo,
const boo::ObjToken<boo::IGraphicsBuffer>& ibo)
{ {
size_t elemCount = 2 + meta.colorCount + meta.uvCount + meta.weightCount; size_t elemCount = 2 + meta.colorCount + meta.uvCount + meta.weightCount;
std::unique_ptr<boo::VertexElementDescriptor[]> vdescs(new boo::VertexElementDescriptor[elemCount]); std::unique_ptr<boo::VertexElementDescriptor[]> vdescs(new boo::VertexElementDescriptor[elemCount]);
@ -64,7 +66,7 @@ boo::IVertexFormat* HMDLData::NewVertexFormat(boo::IGraphicsDataFactory::Context
} }
/* For shader constructors that require vertex format up-front (HLSL/Metal/Vulkan) */ /* For shader constructors that require vertex format up-front (HLSL/Metal/Vulkan) */
boo::IVertexFormat* ShaderTag::newVertexFormat(boo::IGraphicsDataFactory::Context& ctx) const boo::ObjToken<boo::IVertexFormat> ShaderTag::newVertexFormat(boo::IGraphicsDataFactory::Context& ctx) const
{ {
size_t elemCount = 2 + m_colorCount + m_uvCount + m_weightCount; size_t elemCount = 2 + m_colorCount + m_uvCount + m_weightCount;
std::unique_ptr<boo::VertexElementDescriptor[]> vdescs(new boo::VertexElementDescriptor[elemCount]); std::unique_ptr<boo::VertexElementDescriptor[]> vdescs(new boo::VertexElementDescriptor[elemCount]);

View File

@ -370,7 +370,7 @@ bool ShaderCacheManager::addData(const ShaderCachedData& data)
return true; return true;
} }
boo::IShaderPipeline* boo::ObjToken<boo::IShaderPipeline>
ShaderCacheManager::buildFromCache(const ShaderCachedData& foundData, ShaderCacheManager::buildFromCache(const ShaderCachedData& foundData,
boo::IGraphicsDataFactory::Context& ctx) boo::IGraphicsDataFactory::Context& ctx)
{ {
@ -390,10 +390,10 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const std::string& source,
ShaderCachedData foundData = lookupData(tag); ShaderCachedData foundData = lookupData(tag);
if (foundData) if (foundData)
{ {
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64());
boo::IShaderPipeline* build = buildFromCache(foundData, ctx); boo::ObjToken<boo::IShaderPipeline> build = buildFromCache(foundData, ctx);
if (build) if (build)
{ {
ret->m_pipelines.push_back(build); ret->m_pipelines.push_back(build);
@ -402,7 +402,7 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const std::string& source,
return false; return false;
}); });
if (ret->m_token) if (ret->m_pipelines.size())
{ {
m_pipelineLookup[tag] = ret; m_pipelineLookup[tag] = ret;
return ret; return ret;
@ -410,12 +410,12 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const std::string& source,
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.c_str()); Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.c_str());
} }
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
hecl::Frontend::IR ir = FE.compileSource(source, diagName); hecl::Frontend::IR ir = FE.compileSource(source, diagName);
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64());
FE.getDiagnostics().reset(diagName); FE.getDiagnostics().reset(diagName);
boo::IShaderPipeline* build; boo::ObjToken<boo::IShaderPipeline> build;
addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build)); addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build));
ret->m_pipelines.push_back(build); ret->m_pipelines.push_back(build);
return true; return true;
@ -437,10 +437,10 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const hecl::Frontend::IR&
ShaderCachedData foundData = lookupData(tag); ShaderCachedData foundData = lookupData(tag);
if (foundData) if (foundData)
{ {
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64());
boo::IShaderPipeline* build = buildFromCache(foundData, ctx); boo::ObjToken<boo::IShaderPipeline> build = buildFromCache(foundData, ctx);
if (build) if (build)
{ {
ret->m_pipelines.push_back(build); ret->m_pipelines.push_back(build);
@ -449,7 +449,7 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const hecl::Frontend::IR&
return false; return false;
}); });
if (ret->m_token) if (ret->m_pipelines.size())
{ {
m_pipelineLookup[tag] = ret; m_pipelineLookup[tag] = ret;
return ret; return ret;
@ -457,11 +457,11 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const hecl::Frontend::IR&
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.c_str()); Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.c_str());
} }
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64());
FE.getDiagnostics().reset(diagName); FE.getDiagnostics().reset(diagName);
boo::IShaderPipeline* build; boo::ObjToken<boo::IShaderPipeline> build;
addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build)); addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build));
ret->m_pipelines.push_back(build); ret->m_pipelines.push_back(build);
return true; return true;
@ -470,14 +470,14 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const hecl::Frontend::IR&
return ret; return ret;
} }
std::vector<boo::IShaderPipeline*> std::vector<boo::ObjToken<boo::IShaderPipeline>>
ShaderCacheManager::buildExtendedFromCache(const ShaderCachedData& foundData, ShaderCacheManager::buildExtendedFromCache(const ShaderCachedData& foundData,
boo::IGraphicsDataFactory::Context& ctx) boo::IGraphicsDataFactory::Context& ctx)
{ {
std::vector<boo::IShaderPipeline*> shaders; std::vector<boo::ObjToken<boo::IShaderPipeline>> shaders;
shaders.reserve(m_extensions.m_extensionSlots.size()); shaders.reserve(m_extensions.m_extensionSlots.size());
if (!m_factory->buildExtendedShaderFromCache(foundData, m_extensions.m_extensionSlots, ctx, if (!m_factory->buildExtendedShaderFromCache(foundData, m_extensions.m_extensionSlots, ctx,
[&](boo::IShaderPipeline* shader){shaders.push_back(shader);})) [&](const boo::ObjToken<boo::IShaderPipeline>& shader){shaders.push_back(shader);}))
return {}; return {};
if (shaders.size() != m_extensions.m_extensionSlots.size()) if (shaders.size() != m_extensions.m_extensionSlots.size())
Log.report(logvisor::Fatal, "buildShaderFromCache returned %" PRISize " times, expected %" PRISize, Log.report(logvisor::Fatal, "buildShaderFromCache returned %" PRISize " times, expected %" PRISize,
@ -498,16 +498,14 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const std::string&
ShaderCachedData foundData = lookupData(tag); ShaderCachedData foundData = lookupData(tag);
if (foundData) if (foundData)
{ {
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64());
ret->m_pipelines = buildExtendedFromCache(foundData, ctx); ret->m_pipelines = buildExtendedFromCache(foundData, ctx);
if (ret->m_pipelines.size()) return ret->m_pipelines.size() != 0;
return true;
return false;
}); });
if (ret->m_token) if (ret->m_pipelines.size())
{ {
m_pipelineLookup[tag] = ret; m_pipelineLookup[tag] = ret;
return ret; return ret;
@ -517,14 +515,14 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const std::string&
hecl::Frontend::IR ir = FE.compileSource(source, diagName); hecl::Frontend::IR ir = FE.compileSource(source, diagName);
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size()); ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size());
FE.getDiagnostics().reset(diagName); FE.getDiagnostics().reset(diagName);
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64());
ShaderCachedData data = ShaderCachedData data =
m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx, m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx,
[&](boo::IShaderPipeline* shader){ret->m_pipelines.push_back(shader);}); [&](const boo::ObjToken<boo::IShaderPipeline>& shader){ret->m_pipelines.push_back(shader);});
if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size()) if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size())
Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize, Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize,
ret->m_pipelines.size(), m_extensions.m_extensionSlots.size()); ret->m_pipelines.size(), m_extensions.m_extensionSlots.size());
@ -548,16 +546,14 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const hecl::Fronte
ShaderCachedData foundData = lookupData(tag); ShaderCachedData foundData = lookupData(tag);
if (foundData) if (foundData)
{ {
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.c_str(), tag.val64());
ret->m_pipelines = buildExtendedFromCache(foundData, ctx); ret->m_pipelines = buildExtendedFromCache(foundData, ctx);
if (ret->m_pipelines.size()) return ret->m_pipelines.size() != 0;
return true;
return false;
}); });
if (ret->m_token) if (ret->m_pipelines.size() != 0)
{ {
m_pipelineLookup[tag] = ret; m_pipelineLookup[tag] = ret;
return ret; return ret;
@ -565,14 +561,14 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const hecl::Fronte
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.c_str()); Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.c_str());
} }
ret->m_token = factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size()); ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size());
FE.getDiagnostics().reset(diagName); FE.getDiagnostics().reset(diagName);
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64()); Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.c_str(), tag.val64());
ShaderCachedData data = ShaderCachedData data =
m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx, m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx,
[&](boo::IShaderPipeline* shader){ret->m_pipelines.push_back(shader);}); [&](const boo::ObjToken<boo::IShaderPipeline>& shader){ret->m_pipelines.push_back(shader);});
if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size()) if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size())
Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize, Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize,
ret->m_pipelines.size(), m_extensions.m_extensionSlots.size()); ret->m_pipelines.size(), m_extensions.m_extensionSlots.size());

View File

@ -46,9 +46,9 @@ struct HECLApplicationCallback : boo::IApplicationCallback
m_mainWindow = app->newWindow(_S("HECL Test"), 1); m_mainWindow = app->newWindow(_S("HECL Test"), 1);
m_mainWindow->setCallback(&m_windowCb); m_mainWindow->setCallback(&m_windowCb);
boo::ITextureR* renderTex = nullptr; boo::ObjToken<boo::ITextureR> renderTex;
boo::IGraphicsBufferD* vubo = nullptr; boo::ObjToken<boo::IGraphicsBuffer> vubo;
boo::IShaderDataBinding* binding = nullptr; boo::ObjToken<boo::IShaderDataBinding> binding;
struct VertexUBO struct VertexUBO
{ {
@ -94,7 +94,6 @@ struct HECLApplicationCallback : boo::IApplicationCallback
std::shared_ptr<hecl::Runtime::ShaderPipelines> testShaderObj = std::shared_ptr<hecl::Runtime::ShaderPipelines> testShaderObj =
shaderMgr.buildShader(testShaderTag, testShader, "testShader", *gfxF); shaderMgr.buildShader(testShaderTag, testShader, "testShader", *gfxF);
boo::GraphicsDataToken data =
gfxF->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool gfxF->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
boo::SWindowRect mainWindowRect = m_mainWindow->getWindowFrame(); boo::SWindowRect mainWindowRect = m_mainWindow->getWindowFrame();
@ -149,14 +148,14 @@ struct HECLApplicationCallback : boo::IApplicationCallback
tex[i][j][2] = 0; tex[i][j][2] = 0;
tex[i][j][3] = 0xff; tex[i][j][3] = 0xff;
} }
boo::ITexture* texture = boo::ObjToken<boo::ITexture> texture =
ctx.newStaticTexture(256, 256, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, tex, 256*256*4); ctx.newStaticTexture(256, 256, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, tex, 256*256*4).get();
/* Make vertex uniform buffer */ /* Make vertex uniform buffer */
vubo = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexUBO), 1); vubo = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexUBO), 1).get();
/* Assemble data binding */ /* Assemble data binding */
binding = testData.newShaderDataBindng(ctx, testShaderObj->m_pipelines[0], 1, (boo::IGraphicsBuffer**)&vubo, nullptr, 1, &texture); binding = testData.newShaderDataBindng(ctx, testShaderObj->m_pipelines[0], 1, &vubo, nullptr, 1, &texture);
return true; return true;
}); });
@ -209,7 +208,7 @@ struct HECLApplicationCallback : boo::IApplicationCallback
vuboData.modelview[3][0] = sinf(frameIdx / 60.0) * 0.5; vuboData.modelview[3][0] = sinf(frameIdx / 60.0) * 0.5;
vuboData.modelview[3][1] = cosf(frameIdx / 60.0) * 0.5; vuboData.modelview[3][1] = cosf(frameIdx / 60.0) * 0.5;
vubo->load(&vuboData, sizeof(vuboData)); vubo.cast<boo::IGraphicsBufferD>()->load(&vuboData, sizeof(vuboData));
gfxQ->setShaderDataBinding(binding); gfxQ->setShaderDataBinding(binding);
gfxQ->drawIndexed(0, 4); gfxQ->drawIndexed(0, 4);