mirror of https://github.com/AxioDL/boo.git
macOS HIDPI fixes; buffer pools
This commit is contained in:
parent
4c0c01f84f
commit
fa45c6750a
|
@ -19,9 +19,13 @@ class GLDataFactory : public IGraphicsDataFactory
|
|||
uint32_t m_drawSamples;
|
||||
static ThreadLocalPtr<struct GLData> m_deferredData;
|
||||
std::unordered_set<struct GLData*> m_committedData;
|
||||
std::unordered_set<struct GLPool*> m_committedPools;
|
||||
std::mutex m_committedMutex;
|
||||
void destroyData(IGraphicsData*);
|
||||
void destroyAllData();
|
||||
void destroyPool(IGraphicsBufferPool*);
|
||||
IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use,
|
||||
size_t stride, size_t count);
|
||||
public:
|
||||
GLDataFactory(IGraphicsContext* parent, uint32_t drawSamples);
|
||||
~GLDataFactory() {destroyAllData();}
|
||||
|
@ -50,7 +54,8 @@ public:
|
|||
bool enableShaderColorBinding, bool enableShaderDepthBinding);
|
||||
|
||||
bool bindingNeedsVertexFormat() const {return true;}
|
||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
|
||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
||||
size_t baseVert = 0, size_t baseInst = 0);
|
||||
|
||||
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||
size_t texCount, const char** texNames,
|
||||
|
@ -64,10 +69,11 @@ public:
|
|||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, ITexture** texs);
|
||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0);
|
||||
};
|
||||
|
||||
GraphicsDataToken commitTransaction(const FactoryCommitFunc&);
|
||||
GraphicsBufferPoolToken newBufferPool();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -152,6 +152,10 @@ struct IShaderDataBinding {};
|
|||
struct IGraphicsData {};
|
||||
class GraphicsDataToken;
|
||||
|
||||
/** Opaque object for maintaining ownership of factory-created pool buffers */
|
||||
struct IGraphicsBufferPool {};
|
||||
class GraphicsBufferPoolToken;
|
||||
|
||||
/** Used wherever distinction of pipeline stages is needed */
|
||||
enum class PipelineStage
|
||||
{
|
||||
|
@ -226,7 +230,8 @@ struct IGraphicsDataFactory
|
|||
|
||||
virtual bool bindingNeedsVertexFormat() const=0;
|
||||
virtual IVertexFormat*
|
||||
newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0;
|
||||
newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
||||
size_t baseVert = 0, size_t baseInst = 0)=0;
|
||||
|
||||
virtual IShaderDataBinding*
|
||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||
|
@ -234,32 +239,39 @@ struct IGraphicsDataFactory
|
|||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, ITexture** texs)=0;
|
||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0)=0;
|
||||
|
||||
IShaderDataBinding*
|
||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||
IVertexFormat* vtxFormat,
|
||||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
size_t texCount, ITexture** texs)
|
||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0)
|
||||
{
|
||||
return newShaderDataBinding(pipeline, vtxFormat, vbo, instVbo, ibo,
|
||||
ubufCount, ubufs, ubufStages, nullptr, nullptr, texCount, texs);
|
||||
ubufCount, ubufs, ubufStages, nullptr,
|
||||
nullptr, texCount, texs, baseVert, baseInst);
|
||||
}
|
||||
};
|
||||
|
||||
virtual GraphicsDataToken commitTransaction(const std::function<bool(Context& ctx)>&)=0;
|
||||
virtual GraphicsBufferPoolToken newBufferPool()=0;
|
||||
|
||||
private:
|
||||
friend class GraphicsDataToken;
|
||||
virtual void destroyData(IGraphicsData*)=0;
|
||||
virtual void destroyAllData()=0;
|
||||
|
||||
friend class GraphicsBufferPoolToken;
|
||||
virtual void destroyPool(IGraphicsBufferPool*)=0;
|
||||
virtual IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use,
|
||||
size_t stride, size_t count)=0;
|
||||
};
|
||||
|
||||
using FactoryCommitFunc = std::function<bool(IGraphicsDataFactory::Context& ctx)>;
|
||||
|
||||
/** Ownership token for maintaining lifetime of factory-created resources
|
||||
* deletion of this token triggers mass-deallocation of the factory's
|
||||
/** Ownership token for maintaining lifetime of factory-created resources.
|
||||
* Deletion of this token triggers mass-deallocation of the factory's
|
||||
* IGraphicsData (please don't delete and draw contained resources in the same frame). */
|
||||
class GraphicsDataToken
|
||||
{
|
||||
|
@ -305,6 +317,59 @@ public:
|
|||
operator bool() const {return m_factory && m_data;}
|
||||
};
|
||||
|
||||
/** Ownership token for maintaining lifetimes of an appendable list of dynamic buffers.
|
||||
* Deletion of this token triggers mass-deallocation of the IGraphicsBufferPool
|
||||
* (please don't delete and draw contained resources in the same frame). */
|
||||
class GraphicsBufferPoolToken
|
||||
{
|
||||
friend class GLDataFactory;
|
||||
friend class D3D12DataFactory;
|
||||
friend class D3D11DataFactory;
|
||||
friend class MetalDataFactory;
|
||||
friend class VulkanDataFactory;
|
||||
IGraphicsDataFactory* m_factory = nullptr;
|
||||
IGraphicsBufferPool* m_pool = nullptr;
|
||||
GraphicsBufferPoolToken(IGraphicsDataFactory* factory, IGraphicsBufferPool* pool)
|
||||
: m_factory(factory), m_pool(pool) {}
|
||||
public:
|
||||
void doDestroy()
|
||||
{
|
||||
if (m_factory && m_pool)
|
||||
{
|
||||
m_factory->destroyPool(m_pool);
|
||||
m_factory = nullptr;
|
||||
m_pool = nullptr;
|
||||
}
|
||||
}
|
||||
GraphicsBufferPoolToken() = default;
|
||||
GraphicsBufferPoolToken(const GraphicsBufferPoolToken& other) = delete;
|
||||
GraphicsBufferPoolToken(GraphicsBufferPoolToken&& other)
|
||||
{
|
||||
m_factory = other.m_factory;
|
||||
other.m_factory = nullptr;
|
||||
m_pool = other.m_pool;
|
||||
other.m_pool = nullptr;
|
||||
}
|
||||
GraphicsBufferPoolToken& operator=(const GraphicsBufferPoolToken& other) = delete;
|
||||
GraphicsBufferPoolToken& operator=(GraphicsBufferPoolToken&& other)
|
||||
{
|
||||
doDestroy();
|
||||
m_factory = other.m_factory;
|
||||
other.m_factory = nullptr;
|
||||
m_pool = other.m_pool;
|
||||
other.m_pool = nullptr;
|
||||
return *this;
|
||||
}
|
||||
~GraphicsBufferPoolToken() {doDestroy();}
|
||||
operator bool() const {return m_factory && m_pool;}
|
||||
|
||||
IGraphicsBufferD* newPoolBuffer(BufferUse use,
|
||||
size_t stride, size_t count)
|
||||
{
|
||||
return m_factory->newPoolBuffer(m_pool, use, stride, count);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // IGFXDATAFACTORY_HPP
|
||||
|
|
|
@ -21,12 +21,16 @@ class MetalDataFactory : public IGraphicsDataFactory
|
|||
IGraphicsContext* m_parent;
|
||||
static ThreadLocalPtr<struct MetalData> m_deferredData;
|
||||
std::unordered_set<struct MetalData*> m_committedData;
|
||||
std::unordered_set<struct MetalPool*> m_committedPools;
|
||||
std::mutex m_committedMutex;
|
||||
struct MetalContext* m_ctx;
|
||||
uint32_t m_sampleCount;
|
||||
|
||||
void destroyData(IGraphicsData*);
|
||||
void destroyAllData();
|
||||
void destroyPool(IGraphicsBufferPool*);
|
||||
IGraphicsBufferD* newPoolBuffer(IGraphicsBufferPool* pool, BufferUse use,
|
||||
size_t stride, size_t count);
|
||||
public:
|
||||
MetalDataFactory(IGraphicsContext* parent, MetalContext* ctx, uint32_t sampleCount);
|
||||
~MetalDataFactory() {}
|
||||
|
@ -55,7 +59,8 @@ public:
|
|||
bool enableShaderColorBinding, bool enableShaderDepthBinding);
|
||||
|
||||
bool bindingNeedsVertexFormat() const {return false;}
|
||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
|
||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
||||
size_t baseVert = 0, size_t baseInst = 0);
|
||||
|
||||
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||
IVertexFormat* vtxFmt, unsigned targetSamples,
|
||||
|
@ -68,10 +73,11 @@ public:
|
|||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, ITexture** texs);
|
||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0);
|
||||
};
|
||||
|
||||
virtual GraphicsDataToken commitTransaction(const std::function<bool(IGraphicsDataFactory::Context& ctx)>&);
|
||||
GraphicsDataToken commitTransaction(const std::function<bool(IGraphicsDataFactory::Context& ctx)>&);
|
||||
GraphicsBufferPoolToken newBufferPool();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@ struct GLData : IGraphicsData
|
|||
std::vector<std::unique_ptr<struct GLVertexFormat>> m_VFmts;
|
||||
};
|
||||
|
||||
struct GLPool : IGraphicsBufferPool
|
||||
{
|
||||
std::vector<std::unique_ptr<class GLGraphicsBufferD>> m_DBufs;
|
||||
};
|
||||
|
||||
static const GLenum USE_TABLE[] =
|
||||
{
|
||||
GL_INVALID_ENUM,
|
||||
|
@ -533,9 +538,11 @@ struct GLVertexFormat : IVertexFormat
|
|||
GLCommandQueue* m_q;
|
||||
GLuint m_vao[3] = {};
|
||||
size_t m_elementCount;
|
||||
GLuint m_baseVert, m_baseInst;
|
||||
std::unique_ptr<VertexElementDescriptor[]> m_elements;
|
||||
GLVertexFormat(GLCommandQueue* q, size_t elementCount,
|
||||
const VertexElementDescriptor* elements);
|
||||
const VertexElementDescriptor* elements,
|
||||
size_t baseVert, size_t baseInst);
|
||||
~GLVertexFormat();
|
||||
void bind(int idx) const {glBindVertexArray(m_vao[idx]);}
|
||||
};
|
||||
|
@ -652,10 +659,11 @@ GLDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline,
|
|||
IGraphicsBuffer*, IGraphicsBuffer*, IGraphicsBuffer*,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, ITexture** texs)
|
||||
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst)
|
||||
{
|
||||
GLShaderDataBinding* retval =
|
||||
new GLShaderDataBinding(pipeline, vtxFormat, ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs);
|
||||
new GLShaderDataBinding(pipeline, vtxFormat, ubufCount, ubufs,
|
||||
ubufOffs, ubufSizes, texCount, texs);
|
||||
m_deferredData->m_SBinds.emplace_back(retval);
|
||||
return retval;
|
||||
}
|
||||
|
@ -690,6 +698,14 @@ GraphicsDataToken GLDataFactory::commitTransaction(const FactoryCommitFunc& tran
|
|||
return GraphicsDataToken(this, retval);
|
||||
}
|
||||
|
||||
GraphicsBufferPoolToken GLDataFactory::newBufferPool()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
GLPool* retval = new GLPool;
|
||||
m_committedPools.insert(retval);
|
||||
return GraphicsBufferPoolToken(this, retval);
|
||||
}
|
||||
|
||||
void GLDataFactory::destroyData(IGraphicsData* d)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
|
@ -703,7 +719,27 @@ void GLDataFactory::destroyAllData()
|
|||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
for (IGraphicsData* data : m_committedData)
|
||||
delete static_cast<GLData*>(data);
|
||||
for (IGraphicsBufferPool* pool : m_committedPools)
|
||||
delete static_cast<GLPool*>(pool);
|
||||
m_committedData.clear();
|
||||
m_committedPools.clear();
|
||||
}
|
||||
|
||||
void GLDataFactory::destroyPool(IGraphicsBufferPool* p)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
GLPool* pool = static_cast<GLPool*>(p);
|
||||
m_committedPools.erase(pool);
|
||||
delete pool;
|
||||
}
|
||||
|
||||
IGraphicsBufferD* GLDataFactory::newPoolBuffer(IGraphicsBufferPool* p, BufferUse use,
|
||||
size_t stride, size_t count)
|
||||
{
|
||||
GLPool* pool = static_cast<GLPool*>(p);
|
||||
GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count);
|
||||
pool->m_DBufs.emplace_back(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const GLint SEMANTIC_COUNT_TABLE[] =
|
||||
|
@ -844,8 +880,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
|
||||
for (int b=0 ; b<3 ; ++b)
|
||||
{
|
||||
size_t offset = 0;
|
||||
size_t instOffset = 0;
|
||||
size_t offset = fmt->m_baseVert * stride;
|
||||
size_t instOffset = fmt->m_baseInst * instStride;
|
||||
glBindVertexArray(fmt->m_vao[b]);
|
||||
IGraphicsBuffer* lastVBO = nullptr;
|
||||
IGraphicsBuffer* lastEBO = nullptr;
|
||||
|
@ -1259,6 +1295,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
for (std::unique_ptr<GLTextureD>& t : d->m_DTexs)
|
||||
t->update(m_completeBuf);
|
||||
}
|
||||
for (GLPool* p : gfxF->m_committedPools)
|
||||
{
|
||||
for (std::unique_ptr<GLGraphicsBufferD>& b : p->m_DBufs)
|
||||
b->update(m_completeBuf);
|
||||
}
|
||||
datalk.unlock();
|
||||
glFlush();
|
||||
|
||||
|
@ -1464,10 +1505,12 @@ GLDataFactory::Context::newRenderTexture(size_t width, size_t height,
|
|||
}
|
||||
|
||||
GLVertexFormat::GLVertexFormat(GLCommandQueue* q, size_t elementCount,
|
||||
const VertexElementDescriptor* elements)
|
||||
const VertexElementDescriptor* elements,
|
||||
size_t baseVert, size_t baseInst)
|
||||
: m_q(q),
|
||||
m_elementCount(elementCount),
|
||||
m_elements(new VertexElementDescriptor[elementCount])
|
||||
m_elements(new VertexElementDescriptor[elementCount]),
|
||||
m_baseVert(baseVert), m_baseInst(baseInst)
|
||||
{
|
||||
for (size_t i=0 ; i<elementCount ; ++i)
|
||||
m_elements[i] = elements[i];
|
||||
|
@ -1476,10 +1519,11 @@ GLVertexFormat::GLVertexFormat(GLCommandQueue* q, size_t elementCount,
|
|||
GLVertexFormat::~GLVertexFormat() {m_q->delVertexFormat(this);}
|
||||
|
||||
IVertexFormat* GLDataFactory::Context::newVertexFormat
|
||||
(size_t elementCount, const VertexElementDescriptor* elements)
|
||||
(size_t elementCount, const VertexElementDescriptor* elements,
|
||||
size_t baseVert, size_t baseInst)
|
||||
{
|
||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent.m_parent->getCommandQueue());
|
||||
GLVertexFormat* retval = new struct GLVertexFormat(q, elementCount, elements);
|
||||
GLVertexFormat* retval = new struct GLVertexFormat(q, elementCount, elements, baseVert, baseInst);
|
||||
m_deferredData->m_VFmts.emplace_back(retval);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ struct MetalData : IGraphicsData
|
|||
std::vector<std::unique_ptr<struct MetalVertexFormat>> m_VFmts;
|
||||
};
|
||||
|
||||
struct MetalPool : IGraphicsBufferPool
|
||||
{
|
||||
std::vector<std::unique_ptr<class MetalGraphicsBufferD>> m_DBufs;
|
||||
};
|
||||
|
||||
#define MTL_STATIC MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeShared
|
||||
#define MTL_DYNAMIC MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeShared
|
||||
|
||||
|
@ -401,29 +406,29 @@ struct MetalVertexFormat : IVertexFormat
|
|||
{
|
||||
size_t m_elementCount;
|
||||
MTLVertexDescriptor* m_vdesc;
|
||||
size_t m_stride = 0;
|
||||
size_t m_instStride = 0;
|
||||
MetalVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
|
||||
: m_elementCount(elementCount)
|
||||
{
|
||||
size_t stride = 0;
|
||||
size_t instStride = 0;
|
||||
for (size_t i=0 ; i<elementCount ; ++i)
|
||||
{
|
||||
const VertexElementDescriptor* elemin = &elements[i];
|
||||
int semantic = int(elemin->semantic & VertexSemantic::SemanticMask);
|
||||
if ((elemin->semantic & VertexSemantic::Instanced) != VertexSemantic::None)
|
||||
instStride += SEMANTIC_SIZE_TABLE[semantic];
|
||||
m_instStride += SEMANTIC_SIZE_TABLE[semantic];
|
||||
else
|
||||
stride += SEMANTIC_SIZE_TABLE[semantic];
|
||||
m_stride += SEMANTIC_SIZE_TABLE[semantic];
|
||||
}
|
||||
|
||||
m_vdesc = [MTLVertexDescriptor vertexDescriptor];
|
||||
MTLVertexBufferLayoutDescriptor* layoutDesc = m_vdesc.layouts[0];
|
||||
layoutDesc.stride = stride;
|
||||
layoutDesc.stride = m_stride;
|
||||
layoutDesc.stepFunction = MTLVertexStepFunctionPerVertex;
|
||||
layoutDesc.stepRate = 1;
|
||||
|
||||
layoutDesc = m_vdesc.layouts[1];
|
||||
layoutDesc.stride = instStride;
|
||||
layoutDesc.stride = m_instStride;
|
||||
layoutDesc.stepFunction = MTLVertexStepFunctionPerInstance;
|
||||
layoutDesc.stepRate = 1;
|
||||
|
||||
|
@ -475,14 +480,16 @@ class MetalShaderPipeline : public IShaderPipeline
|
|||
{
|
||||
friend class MetalDataFactory;
|
||||
friend class MetalCommandQueue;
|
||||
friend struct MetalShaderDataBinding;
|
||||
MTLCullMode m_cullMode = MTLCullModeNone;
|
||||
MTLPrimitiveType m_drawPrim;
|
||||
const MetalVertexFormat* m_vtxFmt;
|
||||
|
||||
MetalShaderPipeline(MetalContext* ctx, id<MTLFunction> vert, id<MTLFunction> frag,
|
||||
const MetalVertexFormat* vtxFmt, NSUInteger targetSamples,
|
||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||
bool depthTest, bool depthWrite, bool backfaceCulling)
|
||||
: m_drawPrim(PRIMITIVE_TABLE[int(prim)])
|
||||
: m_drawPrim(PRIMITIVE_TABLE[int(prim)]), m_vtxFmt(vtxFmt)
|
||||
{
|
||||
if (backfaceCulling)
|
||||
m_cullMode = MTLCullModeBack;
|
||||
|
@ -580,12 +587,15 @@ struct MetalShaderDataBinding : IShaderDataBinding
|
|||
std::unique_ptr<bool[]> m_fubufs;
|
||||
size_t m_texCount;
|
||||
std::unique_ptr<ITexture*[]> m_texs;
|
||||
size_t m_baseVert;
|
||||
size_t m_baseInst;
|
||||
|
||||
MetalShaderDataBinding(MetalContext* ctx,
|
||||
IShaderPipeline* pipeline,
|
||||
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, ITexture** texs)
|
||||
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst)
|
||||
: m_pipeline(static_cast<MetalShaderPipeline*>(pipeline)),
|
||||
m_vbuf(vbuf),
|
||||
m_instVbo(instVbo),
|
||||
|
@ -593,7 +603,9 @@ struct MetalShaderDataBinding : IShaderDataBinding
|
|||
m_ubufCount(ubufCount),
|
||||
m_ubufs(new IGraphicsBuffer*[ubufCount]),
|
||||
m_texCount(texCount),
|
||||
m_texs(new ITexture*[texCount])
|
||||
m_texs(new ITexture*[texCount]),
|
||||
m_baseVert(baseVert),
|
||||
m_baseInst(baseInst)
|
||||
{
|
||||
if (ubufCount && ubufStages)
|
||||
{
|
||||
|
@ -631,10 +643,13 @@ struct MetalShaderDataBinding : IShaderDataBinding
|
|||
void bind(id<MTLRenderCommandEncoder> enc, int b)
|
||||
{
|
||||
m_pipeline->bind(enc);
|
||||
|
||||
if (m_vbuf)
|
||||
[enc setVertexBuffer:GetBufferGPUResource(m_vbuf, b) offset:0 atIndex:0];
|
||||
[enc setVertexBuffer:GetBufferGPUResource(m_vbuf, b)
|
||||
offset:m_pipeline->m_vtxFmt->m_stride * m_baseVert atIndex:0];
|
||||
if (m_instVbo)
|
||||
[enc setVertexBuffer:GetBufferGPUResource(m_instVbo, b) offset:0 atIndex:1];
|
||||
[enc setVertexBuffer:GetBufferGPUResource(m_instVbo, b)
|
||||
offset:m_pipeline->m_vtxFmt->m_instStride * m_baseInst atIndex:1];
|
||||
if (m_ubufOffs)
|
||||
for (size_t i=0 ; i<m_ubufCount ; ++i)
|
||||
{
|
||||
|
@ -871,6 +886,11 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
|||
for (std::unique_ptr<MetalTextureD>& t : d->m_DTexs)
|
||||
t->update(m_fillBuf);
|
||||
}
|
||||
for (MetalPool* p : gfxF->m_committedPools)
|
||||
{
|
||||
for (std::unique_ptr<MetalGraphicsBufferD>& b : p->m_DBufs)
|
||||
b->update(m_fillBuf);
|
||||
}
|
||||
datalk.unlock();
|
||||
|
||||
@autoreleasepool
|
||||
|
@ -1048,7 +1068,8 @@ ITextureR* MetalDataFactory::Context::newRenderTexture(size_t width, size_t heig
|
|||
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)
|
||||
{
|
||||
MetalVertexFormat* retval = new struct MetalVertexFormat(elementCount, elements);
|
||||
m_deferredData->m_VFmts.emplace_back(retval);
|
||||
|
@ -1091,11 +1112,12 @@ MetalDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline,
|
|||
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, ITexture** texs)
|
||||
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst)
|
||||
{
|
||||
MetalShaderDataBinding* retval =
|
||||
new MetalShaderDataBinding(m_parent.m_ctx, pipeline, vbuf, instVbo, ibuf,
|
||||
ubufCount, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs);
|
||||
ubufCount, ubufs, ubufStages, ubufOffs,
|
||||
ubufSizes, texCount, texs, baseVert, baseInst);
|
||||
m_deferredData->m_SBinds.emplace_back(retval);
|
||||
return retval;
|
||||
}
|
||||
|
@ -1120,6 +1142,15 @@ GraphicsDataToken MetalDataFactory::commitTransaction(const FactoryCommitFunc& t
|
|||
m_committedData.insert(retval);
|
||||
return GraphicsDataToken(this, retval);
|
||||
}
|
||||
|
||||
GraphicsBufferPoolToken MetalDataFactory::newBufferPool()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
MetalPool* retval = new MetalPool;
|
||||
m_committedPools.insert(retval);
|
||||
return GraphicsBufferPoolToken(this, retval);
|
||||
}
|
||||
|
||||
void MetalDataFactory::destroyData(IGraphicsData* d)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
|
@ -1127,12 +1158,34 @@ void MetalDataFactory::destroyData(IGraphicsData* d)
|
|||
m_committedData.erase(data);
|
||||
delete data;
|
||||
}
|
||||
|
||||
void MetalDataFactory::destroyAllData()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
for (IGraphicsData* data : m_committedData)
|
||||
delete static_cast<MetalData*>(data);
|
||||
for (IGraphicsBufferPool* pool : m_committedPools)
|
||||
delete static_cast<MetalPool*>(pool);
|
||||
m_committedData.clear();
|
||||
m_committedPools.clear();
|
||||
}
|
||||
|
||||
void MetalDataFactory::destroyPool(IGraphicsBufferPool* p)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
MetalPool* pool = static_cast<MetalPool*>(p);
|
||||
m_committedPools.erase(pool);
|
||||
delete pool;
|
||||
}
|
||||
|
||||
IGraphicsBufferD* MetalDataFactory::newPoolBuffer(IGraphicsBufferPool* p, BufferUse use,
|
||||
size_t stride, size_t count)
|
||||
{
|
||||
MetalPool* pool = static_cast<MetalPool*>(p);
|
||||
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
||||
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(q, use, m_ctx, stride, count);
|
||||
pool->m_DBufs.emplace_back(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentWindow,
|
||||
|
|
|
@ -1123,8 +1123,9 @@ static boo::ESpecialKey translateKeycode(short code)
|
|||
|
||||
- (void)reshape
|
||||
{
|
||||
boo::SWindowRect rect = {int(self.frame.origin.x), int(self.frame.origin.y),
|
||||
int(self.frame.size.width), int(self.frame.size.height)};
|
||||
NSRect frame = [self convertRectToBacking:self.frame];
|
||||
boo::SWindowRect rect = {int(frame.origin.x), int(frame.origin.y),
|
||||
int(frame.size.width), int(frame.size.height)};
|
||||
if (resp->booContext->m_callback)
|
||||
resp->booContext->m_callback->resized(rect);
|
||||
[super reshape];
|
||||
|
@ -1145,6 +1146,11 @@ static boo::ESpecialKey translateKeycode(short code)
|
|||
return resp;
|
||||
}
|
||||
|
||||
- (BOOL)wantsBestResolutionOpenGLSurface
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if BOO_HAS_METAL
|
||||
|
@ -1193,8 +1199,9 @@ static boo::ESpecialKey translateKeycode(short code)
|
|||
|
||||
- (void)reshapeHandler
|
||||
{
|
||||
boo::SWindowRect rect = {int(self.frame.origin.x), int(self.frame.origin.y),
|
||||
int(self.frame.size.width), int(self.frame.size.height)};
|
||||
NSRect frame = [self convertRectToBacking:self.frame];
|
||||
boo::SWindowRect rect = {int(frame.origin.x), int(frame.origin.y),
|
||||
int(frame.size.width), int(frame.size.height)};
|
||||
boo::MetalContext::Window& w = m_ctx->m_windows[m_window];
|
||||
std::unique_lock<std::mutex> lk(w.m_resizeLock);
|
||||
if (resp->booContext->m_callback)
|
||||
|
@ -1351,7 +1358,8 @@ public:
|
|||
|
||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const
|
||||
{
|
||||
NSRect wFrame = [[m_nsWindow contentView] frame];
|
||||
NSView* view = [m_nsWindow contentView];
|
||||
NSRect wFrame = [view convertRectToBacking:view.frame];
|
||||
xOut = wFrame.origin.x;
|
||||
yOut = wFrame.origin.y;
|
||||
wOut = wFrame.size.width;
|
||||
|
@ -1360,7 +1368,8 @@ public:
|
|||
|
||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const
|
||||
{
|
||||
NSRect wFrame = [[m_nsWindow contentView] frame];
|
||||
NSView* view = [m_nsWindow contentView];
|
||||
NSRect wFrame = [view convertRectToBacking:view.frame];
|
||||
xOut = wFrame.origin.x;
|
||||
yOut = wFrame.origin.y;
|
||||
wOut = wFrame.size.width;
|
||||
|
@ -1525,7 +1534,8 @@ IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx,
|
|||
styleMask:NSWindowStyleMaskTitled|
|
||||
NSWindowStyleMaskClosable|
|
||||
NSWindowStyleMaskMiniaturizable|
|
||||
NSWindowStyleMaskTitled
|
||||
NSWindowStyleMaskTitled|
|
||||
NSWindowStyleMaskResizable
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES];
|
||||
self.releasedWhenClosed = NO;
|
||||
|
|
Loading…
Reference in New Issue