Metal autorelease pools at API boundaries

This commit is contained in:
Jack Andersen 2017-10-27 00:09:22 -10:00
parent d1b980b529
commit 3c207386e7

View File

@ -50,7 +50,7 @@ class MetalDataFactoryImpl : public MetalDataFactory
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf); void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf);
public: public:
MetalDataFactoryImpl(IGraphicsContext* parent, MetalContext* ctx, uint32_t sampleCount); MetalDataFactoryImpl(IGraphicsContext* parent, MetalContext* ctx, uint32_t sampleCount);
~MetalDataFactoryImpl() {} ~MetalDataFactoryImpl() = default;
Platform platform() const {return Platform::Metal;} Platform platform() const {return Platform::Metal;}
const char* platformName() const {return "Metal";} const char* platformName() const {return "Metal";}
@ -890,12 +890,15 @@ struct MetalCommandQueue : IGraphicsCommandQueue
MetalShaderDataBinding* m_boundData = nullptr; MetalShaderDataBinding* m_boundData = nullptr;
MTLPrimitiveType m_currentPrimitive = MTLPrimitiveTypeTriangle; MTLPrimitiveType m_currentPrimitive = MTLPrimitiveTypeTriangle;
void setShaderDataBinding(IShaderDataBinding* binding) void setShaderDataBinding(IShaderDataBinding* binding)
{
@autoreleasepool
{ {
MetalShaderDataBinding* cbind = static_cast<MetalShaderDataBinding*>(binding); MetalShaderDataBinding* cbind = static_cast<MetalShaderDataBinding*>(binding);
cbind->bind(m_enc, m_fillBuf); cbind->bind(m_enc, m_fillBuf);
m_boundData = cbind; m_boundData = cbind;
m_currentPrimitive = cbind->m_pipeline->m_drawPrim; m_currentPrimitive = cbind->m_pipeline->m_drawPrim;
} }
}
MetalTextureR* m_boundTarget = nullptr; MetalTextureR* m_boundTarget = nullptr;
void _setRenderTarget(ITextureR* target, bool clearColor, bool clearDepth) void _setRenderTarget(ITextureR* target, bool clearColor, bool clearDepth)
@ -1221,69 +1224,90 @@ MetalDataFactoryImpl::MetalDataFactoryImpl(IGraphicsContext* parent, MetalContex
IGraphicsBufferS* MetalDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) IGraphicsBufferS* MetalDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(d, use, factory.m_ctx, data, stride, count); MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(d, use, factory.m_ctx, data, stride, count);
d->m_SBufs.emplace_back(retval); d->m_SBufs.emplace_back(retval);
return retval; return retval;
}
} }
IGraphicsBufferD* MetalDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count) IGraphicsBufferD* MetalDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue()); MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue());
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(d, q, use, factory.m_ctx, stride, count); MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(d, q, use, factory.m_ctx, stride, count);
d->m_DBufs.emplace_back(retval); d->m_DBufs.emplace_back(retval);
return retval; return retval;
}
} }
ITextureS* MetalDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, ITextureS* MetalDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
TextureClampMode clampMode, const void* data, size_t sz) TextureClampMode clampMode, const void* data, size_t sz)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalTextureS* retval = new MetalTextureS(d, factory.m_ctx, width, height, mips, fmt, data, sz); MetalTextureS* retval = new MetalTextureS(d, factory.m_ctx, width, height, mips, fmt, data, sz);
d->m_STexs.emplace_back(retval); d->m_STexs.emplace_back(retval);
return retval; return retval;
}
} }
ITextureSA* MetalDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips, ITextureSA* MetalDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, TextureClampMode clampMode, TextureFormat fmt, TextureClampMode clampMode,
const void* data, size_t sz) const void* data, size_t sz)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalTextureSA* retval = new MetalTextureSA(d, factory.m_ctx, width, height, layers, mips, fmt, data, sz); MetalTextureSA* retval = new MetalTextureSA(d, factory.m_ctx, width, height, layers, mips, fmt, data, sz);
d->m_SATexs.emplace_back(retval); d->m_SATexs.emplace_back(retval);
return retval; return retval;
}
} }
ITextureD* MetalDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt, ITextureD* MetalDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt,
TextureClampMode clampMode) TextureClampMode clampMode)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue()); MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue());
MetalTextureD* retval = new MetalTextureD(d, q, factory.m_ctx, width, height, fmt); MetalTextureD* retval = new MetalTextureD(d, q, factory.m_ctx, width, height, fmt);
d->m_DTexs.emplace_back(retval); d->m_DTexs.emplace_back(retval);
return retval; return retval;
}
} }
ITextureR* MetalDataFactory::Context::newRenderTexture(size_t width, size_t height, TextureClampMode clampMode, ITextureR* MetalDataFactory::Context::newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
size_t colorBindCount, size_t depthBindCount) size_t colorBindCount, size_t depthBindCount)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalTextureR* retval = new MetalTextureR(d, factory.m_ctx, width, height, factory.m_sampleCount, MetalTextureR* retval = new MetalTextureR(d, factory.m_ctx, width, height, factory.m_sampleCount,
colorBindCount, depthBindCount); colorBindCount, depthBindCount);
d->m_RTexs.emplace_back(retval); d->m_RTexs.emplace_back(retval);
return retval; return retval;
}
} }
IVertexFormat* MetalDataFactory::Context::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements, IVertexFormat* MetalDataFactory::Context::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
@autoreleasepool
{
MetalData* d = MetalDataFactoryImpl::m_deferredData.get(); MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
MetalVertexFormat* retval = new struct MetalVertexFormat(d, elementCount, elements); MetalVertexFormat* retval = new struct MetalVertexFormat(d, elementCount, elements);
d->m_VFmts.emplace_back(retval); d->m_VFmts.emplace_back(retval);
return retval; return retval;
}
} }
IShaderPipeline* MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char* fragSource, IShaderPipeline* MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char* fragSource,
@ -1375,6 +1399,8 @@ MetalDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline,
const int* texBindIdxs, const bool* depthBind, const int* texBindIdxs, const bool* depthBind,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
@autoreleasepool
{
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent); MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
MetalShaderDataBinding* retval = MetalShaderDataBinding* retval =
new MetalShaderDataBinding(MetalDataFactoryImpl::m_deferredData.get(), new MetalShaderDataBinding(MetalDataFactoryImpl::m_deferredData.get(),
@ -1384,6 +1410,7 @@ MetalDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline,
depthBind, baseVert, baseInst); depthBind, baseVert, baseInst);
MetalDataFactoryImpl::m_deferredData->m_SBinds.emplace_back(retval); MetalDataFactoryImpl::m_deferredData->m_SBinds.emplace_back(retval);
return retval; return retval;
}
} }
GraphicsDataToken MetalDataFactoryImpl::commitTransaction(const FactoryCommitFunc& trans) GraphicsDataToken MetalDataFactoryImpl::commitTransaction(const FactoryCommitFunc& trans)