mirror of https://github.com/AxioDL/boo.git
OS X thread-local fixes
This commit is contained in:
parent
68a1e9150e
commit
8a33d74c13
|
@ -15,7 +15,7 @@ class GLDataFactory : public IGraphicsDataFactory
|
||||||
{
|
{
|
||||||
friend struct GLCommandQueue;
|
friend struct GLCommandQueue;
|
||||||
IGraphicsContext* m_parent;
|
IGraphicsContext* m_parent;
|
||||||
static thread_local struct GLData* m_deferredData;
|
static ThreadLocalPtr<struct GLData> m_deferredData;
|
||||||
std::unordered_set<struct GLData*> m_committedData;
|
std::unordered_set<struct GLData*> m_committedData;
|
||||||
std::mutex m_committedMutex;
|
std::mutex m_committedMutex;
|
||||||
std::vector<int> m_texUnis;
|
std::vector<int> m_texUnis;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "boo/System.hpp"
|
#include "boo/System.hpp"
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
|
@ -226,6 +227,28 @@ private:
|
||||||
virtual void destroyAllData()=0;
|
virtual void destroyAllData()=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Multiplatform TLS-pointer wrapper (for compilers without proper thread_local support) */
|
||||||
|
template <class T>
|
||||||
|
class ThreadLocalPtr
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
DWORD m_key;
|
||||||
|
public:
|
||||||
|
ThreadLocalPtr() {m_key = TlsAlloc();}
|
||||||
|
~ThreadLocalPtr() {TlsFree(m_key);}
|
||||||
|
T* get() {return static_cast<T*>(TlsGetValue(m_key));}
|
||||||
|
void reset(T* v=nullptr) {TlsSetValue(m_key, v);}
|
||||||
|
#else
|
||||||
|
pthread_key_t m_key;
|
||||||
|
public:
|
||||||
|
ThreadLocalPtr() {pthread_key_create(&m_key, nullptr);}
|
||||||
|
~ThreadLocalPtr() {pthread_key_delete(m_key);}
|
||||||
|
T* get() {return static_cast<T*>(pthread_getspecific(m_key));}
|
||||||
|
void reset(T* v=nullptr) {pthread_setspecific(m_key, v);}
|
||||||
|
#endif
|
||||||
|
T* operator->() {return get();}
|
||||||
|
};
|
||||||
|
|
||||||
/** Ownership token for maintaining lifetime of factory-created resources
|
/** Ownership token for maintaining lifetime of factory-created resources
|
||||||
* deletion of this token triggers mass-deallocation of the factory's
|
* deletion of this token triggers mass-deallocation of the factory's
|
||||||
* IGraphicsData (please don't delete and draw contained resources in the same frame). */
|
* IGraphicsData (please don't delete and draw contained resources in the same frame). */
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "IGraphicsCommandQueue.hpp"
|
#include "IGraphicsCommandQueue.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
@ -22,8 +23,9 @@ class MetalDataFactory : public IGraphicsDataFactory
|
||||||
{
|
{
|
||||||
friend struct MetalCommandQueue;
|
friend struct MetalCommandQueue;
|
||||||
IGraphicsContext* m_parent;
|
IGraphicsContext* m_parent;
|
||||||
struct MetalData* m_deferredData = nullptr;
|
static ThreadLocalPtr<struct MetalData> m_deferredData;
|
||||||
std::unordered_set<struct MetalData*> m_committedData;
|
std::unordered_set<struct MetalData*> m_committedData;
|
||||||
|
std::mutex m_committedMutex;
|
||||||
struct MetalContext* m_ctx;
|
struct MetalContext* m_ctx;
|
||||||
|
|
||||||
void destroyData(IGraphicsData*);
|
void destroyData(IGraphicsData*);
|
||||||
|
@ -64,7 +66,7 @@ public:
|
||||||
size_t texCount, ITexture** texs);
|
size_t texCount, ITexture** texs);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
IGraphicsDataToken commit();
|
GraphicsDataToken commit();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::GL");
|
static LogVisor::LogModule Log("boo::GL");
|
||||||
|
|
||||||
thread_local struct GLData* GLDataFactory::m_deferredData;
|
ThreadLocalPtr<struct GLData> GLDataFactory::m_deferredData;
|
||||||
struct GLData : IGraphicsData
|
struct GLData : IGraphicsData
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<class GLShaderPipeline>> m_SPs;
|
std::vector<std::unique_ptr<class GLShaderPipeline>> m_SPs;
|
||||||
|
@ -94,9 +94,9 @@ IGraphicsBufferS*
|
||||||
GLDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
GLDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, data, stride * count);
|
GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, data, stride * count);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
m_deferredData->m_SBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,9 +105,9 @@ GLDataFactory::newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data,
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> d = std::move(data);
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, d.get(), stride * count);
|
GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, d.get(), stride * count);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
m_deferredData->m_SBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,9 +249,9 @@ GLDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, Textur
|
||||||
const void* data, size_t sz)
|
const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
GLTextureS* retval = new GLTextureS(width, height, mips, fmt, data, sz);
|
GLTextureS* retval = new GLTextureS(width, height, mips, fmt, data, sz);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_STexs.emplace_back(retval);
|
m_deferredData->m_STexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,9 +261,9 @@ GLDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, Textur
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> d = std::move(data);
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
GLTextureS* retval = new GLTextureS(width, height, mips, fmt, d.get(), sz);
|
GLTextureS* retval = new GLTextureS(width, height, mips, fmt, d.get(), sz);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_STexs.emplace_back(retval);
|
m_deferredData->m_STexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,9 +272,9 @@ GLDataFactory::newStaticArrayTexture(size_t width, size_t height, size_t layers,
|
||||||
const void *data, size_t sz)
|
const void *data, size_t sz)
|
||||||
{
|
{
|
||||||
GLTextureSA* retval = new GLTextureSA(width, height, layers, fmt, data, sz);
|
GLTextureSA* retval = new GLTextureSA(width, height, layers, fmt, data, sz);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_SATexs.emplace_back(retval);
|
m_deferredData->m_SATexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,9 +473,9 @@ IShaderPipeline* GLDataFactory::newShaderPipeline
|
||||||
}
|
}
|
||||||
|
|
||||||
GLShaderPipeline* retval = new GLShaderPipeline(std::move(shader));
|
GLShaderPipeline* retval = new GLShaderPipeline(std::move(shader));
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_SPs.emplace_back(retval);
|
m_deferredData->m_SPs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,9 +569,9 @@ GLDataFactory::newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
{
|
{
|
||||||
GLShaderDataBinding* retval =
|
GLShaderDataBinding* retval =
|
||||||
new GLShaderDataBinding(pipeline, vtxFormat, ubufCount, ubufs, texCount, texs);
|
new GLShaderDataBinding(pipeline, vtxFormat, ubufCount, ubufs, texCount, texs);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_SBinds.emplace_back(retval);
|
m_deferredData->m_SBinds.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,21 +580,21 @@ GLDataFactory::GLDataFactory(IGraphicsContext* parent)
|
||||||
|
|
||||||
void GLDataFactory::reset()
|
void GLDataFactory::reset()
|
||||||
{
|
{
|
||||||
delete static_cast<GLData*>(m_deferredData);
|
delete m_deferredData.get();
|
||||||
m_deferredData = nullptr;
|
m_deferredData.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsDataToken GLDataFactory::commit()
|
GraphicsDataToken GLDataFactory::commit()
|
||||||
{
|
{
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
return GraphicsDataToken(this, nullptr);
|
return GraphicsDataToken(this, nullptr);
|
||||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
GLData* retval = m_deferredData;
|
GLData* retval = m_deferredData.get();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (std::unique_ptr<GLShaderDataBinding>& b : retval->m_SBinds)
|
for (std::unique_ptr<GLShaderDataBinding>& b : retval->m_SBinds)
|
||||||
b->m_committed = true;
|
b->m_committed = true;
|
||||||
#endif
|
#endif
|
||||||
m_deferredData = nullptr;
|
m_deferredData.reset();
|
||||||
m_committedData.insert(retval);
|
m_committedData.insert(retval);
|
||||||
/* Let's go ahead and flush to ensure our data gets to the GPU
|
/* Let's go ahead and flush to ensure our data gets to the GPU
|
||||||
While this isn't strictly required, some drivers might behave
|
While this isn't strictly required, some drivers might behave
|
||||||
|
@ -1158,9 +1158,9 @@ GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
||||||
GLGraphicsBufferD* retval = new GLGraphicsBufferD(q, use, stride * count);
|
GLGraphicsBufferD* retval = new GLGraphicsBufferD(q, use, stride * count);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_DBufs.emplace_back(retval);
|
m_deferredData->m_DBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1235,9 +1235,9 @@ GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
||||||
{
|
{
|
||||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
||||||
GLTextureD* retval = new GLTextureD(q, width, height, fmt);
|
GLTextureD* retval = new GLTextureD(q, width, height, fmt);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_DTexs.emplace_back(retval);
|
m_deferredData->m_DTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,9 +1259,9 @@ GLDataFactory::newRenderTexture(size_t width, size_t height, size_t samples)
|
||||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
||||||
GLTextureR* retval = new GLTextureR(q, width, height, samples);
|
GLTextureR* retval = new GLTextureR(q, width, height, samples);
|
||||||
q->resizeRenderTexture(retval, width, height);
|
q->resizeRenderTexture(retval, width, height);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_RTexs.emplace_back(retval);
|
m_deferredData->m_RTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,9 +1282,9 @@ IVertexFormat* GLDataFactory::newVertexFormat
|
||||||
{
|
{
|
||||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
|
||||||
GLVertexFormat* retval = new struct GLVertexFormat(q, elementCount, elements);
|
GLVertexFormat* retval = new struct GLVertexFormat(q, elementCount, elements);
|
||||||
if (!m_deferredData)
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct GLData();
|
m_deferredData.reset(new struct GLData());
|
||||||
static_cast<GLData*>(m_deferredData)->m_VFmts.emplace_back(retval);
|
m_deferredData->m_VFmts.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace boo
|
||||||
static LogVisor::LogModule Log("boo::Metal");
|
static LogVisor::LogModule Log("boo::Metal");
|
||||||
struct MetalCommandQueue;
|
struct MetalCommandQueue;
|
||||||
|
|
||||||
|
ThreadLocalPtr<struct MetalData> MetalDataFactory::m_deferredData;
|
||||||
struct MetalData : IGraphicsData
|
struct MetalData : IGraphicsData
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<class MetalShaderPipeline>> m_SPs;
|
std::vector<std::unique_ptr<class MetalShaderPipeline>> m_SPs;
|
||||||
|
@ -717,6 +718,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
/* Update dynamic data here */
|
/* Update dynamic data here */
|
||||||
MetalDataFactory* gfxF = static_cast<MetalDataFactory*>(m_parent->getDataFactory());
|
MetalDataFactory* gfxF = static_cast<MetalDataFactory*>(m_parent->getDataFactory());
|
||||||
|
std::unique_lock<std::mutex> datalk(gfxF->m_committedMutex);
|
||||||
for (MetalData* d : gfxF->m_committedData)
|
for (MetalData* d : gfxF->m_committedData)
|
||||||
{
|
{
|
||||||
for (std::unique_ptr<MetalGraphicsBufferD>& b : d->m_DBufs)
|
for (std::unique_ptr<MetalGraphicsBufferD>& b : d->m_DBufs)
|
||||||
|
@ -724,10 +726,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
for (std::unique_ptr<MetalTextureD>& t : d->m_DTexs)
|
for (std::unique_ptr<MetalTextureD>& t : d->m_DTexs)
|
||||||
t->update(m_fillBuf);
|
t->update(m_fillBuf);
|
||||||
}
|
}
|
||||||
for (std::unique_ptr<MetalGraphicsBufferD>& b : gfxF->m_deferredData->m_DBufs)
|
datalk.unlock();
|
||||||
b->update(m_fillBuf);
|
|
||||||
for (std::unique_ptr<MetalTextureD>& t : gfxF->m_deferredData->m_DTexs)
|
|
||||||
t->update(m_fillBuf);
|
|
||||||
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
|
@ -815,26 +814,32 @@ void MetalTextureD::unmap()
|
||||||
}
|
}
|
||||||
|
|
||||||
MetalDataFactory::MetalDataFactory(IGraphicsContext* parent, MetalContext* ctx)
|
MetalDataFactory::MetalDataFactory(IGraphicsContext* parent, MetalContext* ctx)
|
||||||
: m_parent(parent), m_deferredData(new struct MetalData()), m_ctx(ctx) {}
|
: m_parent(parent), m_ctx(ctx) {}
|
||||||
|
|
||||||
IGraphicsBufferS* MetalDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
IGraphicsBufferS* MetalDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(use, m_ctx, data, stride, count);
|
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(use, m_ctx, data, stride, count);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_SBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
IGraphicsBufferS* MetalDataFactory::newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count)
|
IGraphicsBufferS* MetalDataFactory::newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> d = std::move(data);
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(use, m_ctx, d.get(), stride, count);
|
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(use, m_ctx, d.get(), stride, count);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_SBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
IGraphicsBufferD* MetalDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
IGraphicsBufferD* MetalDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
||||||
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(q, use, m_ctx, stride, count);
|
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(q, use, m_ctx, stride, count);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_DBufs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_DBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,7 +847,9 @@ ITextureS* MetalDataFactory::newStaticTexture(size_t width, size_t height, size_
|
||||||
const void* data, size_t sz)
|
const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
MetalTextureS* retval = new MetalTextureS(m_ctx, width, height, mips, fmt, data, sz);
|
MetalTextureS* retval = new MetalTextureS(m_ctx, width, height, mips, fmt, data, sz);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_STexs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_STexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureS* MetalDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
ITextureS* MetalDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
|
@ -850,34 +857,44 @@ ITextureS* MetalDataFactory::newStaticTexture(size_t width, size_t height, size_
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> d = std::move(data);
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
MetalTextureS* retval = new MetalTextureS(m_ctx, width, height, mips, fmt, d.get(), sz);
|
MetalTextureS* retval = new MetalTextureS(m_ctx, width, height, mips, fmt, d.get(), sz);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_STexs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_STexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureSA* MetalDataFactory::newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
|
ITextureSA* MetalDataFactory::newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
|
||||||
const void* data, size_t sz)
|
const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
MetalTextureSA* retval = new MetalTextureSA(m_ctx, width, height, layers, fmt, data, sz);
|
MetalTextureSA* retval = new MetalTextureSA(m_ctx, width, height, layers, fmt, data, sz);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_SATexs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_SATexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureD* MetalDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
ITextureD* MetalDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
||||||
{
|
{
|
||||||
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
||||||
MetalTextureD* retval = new MetalTextureD(q, m_ctx, width, height, fmt);
|
MetalTextureD* retval = new MetalTextureD(q, m_ctx, width, height, fmt);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_DTexs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_DTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureR* MetalDataFactory::newRenderTexture(size_t width, size_t height, size_t samples)
|
ITextureR* MetalDataFactory::newRenderTexture(size_t width, size_t height, size_t samples)
|
||||||
{
|
{
|
||||||
MetalTextureR* retval = new MetalTextureR(m_ctx, width, height, samples);
|
MetalTextureR* retval = new MetalTextureR(m_ctx, width, height, samples);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_RTexs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_RTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
IVertexFormat* MetalDataFactory::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
|
IVertexFormat* MetalDataFactory::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
|
||||||
{
|
{
|
||||||
MetalVertexFormat* retval = new struct MetalVertexFormat(elementCount, elements);
|
MetalVertexFormat* retval = new struct MetalVertexFormat(elementCount, elements);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_VFmts.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_VFmts.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,7 +924,9 @@ IShaderPipeline* MetalDataFactory::newShaderPipeline(const char* vertSource, con
|
||||||
MetalShaderPipeline* retval = new MetalShaderPipeline(m_ctx, vertFunc.get(), fragFunc.get(),
|
MetalShaderPipeline* retval = new MetalShaderPipeline(m_ctx, vertFunc.get(), fragFunc.get(),
|
||||||
static_cast<const MetalVertexFormat*>(vtxFmt), targetSamples,
|
static_cast<const MetalVertexFormat*>(vtxFmt), targetSamples,
|
||||||
srcFac, dstFac, depthTest, depthWrite, backfaceCulling);
|
srcFac, dstFac, depthTest, depthWrite, backfaceCulling);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_SPs.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_SPs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,30 +939,37 @@ MetalDataFactory::newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
{
|
{
|
||||||
MetalShaderDataBinding* retval =
|
MetalShaderDataBinding* retval =
|
||||||
new MetalShaderDataBinding(m_ctx, pipeline, vbuf, instVbo, ibuf, ubufCount, ubufs, texCount, texs);
|
new MetalShaderDataBinding(m_ctx, pipeline, vbuf, instVbo, ibuf, ubufCount, ubufs, texCount, texs);
|
||||||
static_cast<MetalData*>(m_deferredData)->m_SBinds.emplace_back(retval);
|
if (!m_deferredData.get())
|
||||||
|
m_deferredData.reset(new struct MetalData());
|
||||||
|
m_deferredData->m_SBinds.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalDataFactory::reset()
|
void MetalDataFactory::reset()
|
||||||
{
|
{
|
||||||
delete static_cast<MetalData*>(m_deferredData);
|
delete m_deferredData.get();
|
||||||
m_deferredData = new struct MetalData();
|
m_deferredData.reset();
|
||||||
}
|
}
|
||||||
IGraphicsDataToken MetalDataFactory::commit()
|
GraphicsDataToken MetalDataFactory::commit()
|
||||||
{
|
{
|
||||||
MetalData* retval = static_cast<MetalData*>(m_deferredData);
|
if (!m_deferredData.get())
|
||||||
m_deferredData = new struct MetalData();
|
return GraphicsDataToken(this, nullptr);
|
||||||
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
|
MetalData* retval = m_deferredData.get();
|
||||||
|
m_deferredData.reset();
|
||||||
m_committedData.insert(retval);
|
m_committedData.insert(retval);
|
||||||
return IGraphicsDataToken(this, retval);
|
return GraphicsDataToken(this, retval);
|
||||||
}
|
}
|
||||||
void MetalDataFactory::destroyData(IGraphicsData* d)
|
void MetalDataFactory::destroyData(IGraphicsData* d)
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
MetalData* data = static_cast<MetalData*>(d);
|
MetalData* data = static_cast<MetalData*>(d);
|
||||||
m_committedData.erase(data);
|
m_committedData.erase(data);
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
void MetalDataFactory::destroyAllData()
|
void MetalDataFactory::destroyAllData()
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
for (IGraphicsData* data : m_committedData)
|
for (IGraphicsData* data : m_committedData)
|
||||||
delete static_cast<MetalData*>(data);
|
delete static_cast<MetalData*>(data);
|
||||||
m_committedData.clear();
|
m_committedData.clear();
|
||||||
|
|
Loading…
Reference in New Issue