From bf6b4e37e81b72532afe2b4a56201b3bea7d4c63 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Wed, 30 Mar 2016 09:14:17 -1000 Subject: [PATCH] Major GraphicsDataFactory lambda-API refactor --- include/boo/graphicsdev/GL.hpp | 61 ++-- .../boo/graphicsdev/IGraphicsDataFactory.hpp | 74 +++-- include/boo/graphicsdev/Vulkan.hpp | 86 +++--- lib/graphicsdev/GL.cpp | 179 ++++++------ lib/graphicsdev/Vulkan.cpp | 224 +++++++-------- test/main.cpp | 262 +++++++++--------- 6 files changed, 446 insertions(+), 440 deletions(-) diff --git a/include/boo/graphicsdev/GL.hpp b/include/boo/graphicsdev/GL.hpp index 8fc69e6..42e5582 100644 --- a/include/boo/graphicsdev/GL.hpp +++ b/include/boo/graphicsdev/GL.hpp @@ -30,38 +30,45 @@ public: Platform platform() const {return Platform::OGL;} const SystemChar* platformName() const {return _S("OGL");} - IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); - IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count); + class Context : public IGraphicsDataFactory::Context + { + friend class GLDataFactory; + GLDataFactory& m_parent; + Context(GLDataFactory& parent) : m_parent(parent) {} + public: + Platform platform() const {return Platform::OGL;} + const SystemChar* platformName() const {return _S("OGL");} - ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz); - GraphicsDataToken - newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz, ITextureS*& texOut); - ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, - const void* data, size_t sz); - ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); - ITextureR* newRenderTexture(size_t width, size_t height, - bool enableShaderColorBinding, bool enableShaderDepthBinding); + IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); + IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count); - bool bindingNeedsVertexFormat() const {return true;} - IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); + ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, + const void* data, size_t sz); + ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, + const void* data, size_t sz); + ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); + ITextureR* newRenderTexture(size_t width, size_t height, + bool enableShaderColorBinding, bool enableShaderDepthBinding); - IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, - size_t texCount, const char* texArrayName, - size_t uniformBlockCount, const char** uniformBlockNames, - BlendFactor srcFac, BlendFactor dstFac, Primitive prim, - bool depthTest, bool depthWrite, bool backfaceCulling); + bool bindingNeedsVertexFormat() const {return true;} + IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); - IShaderDataBinding* - newShaderDataBinding(IShaderPipeline* pipeline, - IVertexFormat* vtxFormat, - IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, - size_t ubufCount, IGraphicsBuffer** ubufs, - size_t texCount, ITexture** texs); + IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, + size_t texCount, const char* texArrayName, + size_t uniformBlockCount, const char** uniformBlockNames, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, + bool depthTest, bool depthWrite, bool backfaceCulling); - void reset(); - GraphicsDataToken commit(); + IShaderDataBinding* + newShaderDataBinding(IShaderPipeline* pipeline, + IVertexFormat* vtxFormat, + IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, + size_t ubufCount, IGraphicsBuffer** ubufs, + const size_t* ubufOffs, const size_t* ubufSizes, + size_t texCount, ITexture** texs); + }; + + GraphicsDataToken commitTransaction(const FactoryCommitFunc&); }; } diff --git a/include/boo/graphicsdev/IGraphicsDataFactory.hpp b/include/boo/graphicsdev/IGraphicsDataFactory.hpp index 775fecd..5e728d6 100644 --- a/include/boo/graphicsdev/IGraphicsDataFactory.hpp +++ b/include/boo/graphicsdev/IGraphicsDataFactory.hpp @@ -198,39 +198,53 @@ struct IGraphicsDataFactory virtual Platform platform() const=0; virtual const SystemChar* platformName() const=0; - virtual IGraphicsBufferS* - newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)=0; - virtual IGraphicsBufferD* - newDynamicBuffer(BufferUse use, size_t stride, size_t count)=0; + struct Context + { + virtual Platform platform() const=0; + virtual const SystemChar* platformName() const=0; - virtual ITextureS* - newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz)=0; - virtual GraphicsDataToken - newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz, ITextureS*& texOut)=0; - virtual ITextureSA* - newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, - const void* data, size_t sz)=0; - virtual ITextureD* - newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0; - virtual ITextureR* - newRenderTexture(size_t width, size_t height, - bool enableShaderColorBinding, bool enableShaderDepthBinding)=0; + virtual IGraphicsBufferS* + newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)=0; + virtual IGraphicsBufferD* + newDynamicBuffer(BufferUse use, size_t stride, size_t count)=0; - virtual bool bindingNeedsVertexFormat() const=0; - virtual IVertexFormat* - newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0; + virtual ITextureS* + newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, + const void* data, size_t sz)=0; + virtual ITextureSA* + newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, + const void* data, size_t sz)=0; + virtual ITextureD* + newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0; + virtual ITextureR* + newRenderTexture(size_t width, size_t height, + bool enableShaderColorBinding, bool enableShaderDepthBinding)=0; - virtual IShaderDataBinding* - newShaderDataBinding(IShaderPipeline* pipeline, - IVertexFormat* vtxFormat, - IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, - size_t ubufCount, IGraphicsBuffer** ubufs, - size_t texCount, ITexture** texs)=0; + virtual bool bindingNeedsVertexFormat() const=0; + virtual IVertexFormat* + newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0; - virtual void reset()=0; - virtual GraphicsDataToken commit()=0; + virtual IShaderDataBinding* + newShaderDataBinding(IShaderPipeline* pipeline, + IVertexFormat* vtxFormat, + IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, + size_t ubufCount, IGraphicsBuffer** ubufs, + const size_t* ubufOffs, const size_t* ubufSizes, + size_t texCount, ITexture** texs)=0; + + IShaderDataBinding* + newShaderDataBinding(IShaderPipeline* pipeline, + IVertexFormat* vtxFormat, + IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, + size_t ubufCount, IGraphicsBuffer** ubufs, + size_t texCount, ITexture** texs) + { + return newShaderDataBinding(pipeline, vtxFormat, vbo, instVbo, ibo, + ubufCount, ubufs, nullptr, nullptr, texCount, texs); + } + }; + + virtual GraphicsDataToken commitTransaction(const std::function&)=0; private: friend class GraphicsDataToken; @@ -238,6 +252,8 @@ private: virtual void destroyAllData()=0; }; +using FactoryCommitFunc = std::function; + /** Multiplatform TLS-pointer wrapper (for compilers without proper thread_local support) */ template class ThreadLocalPtr diff --git a/include/boo/graphicsdev/Vulkan.hpp b/include/boo/graphicsdev/Vulkan.hpp index 058252a..1af7386 100644 --- a/include/boo/graphicsdev/Vulkan.hpp +++ b/include/boo/graphicsdev/Vulkan.hpp @@ -87,48 +87,56 @@ public: Platform platform() const {return Platform::Vulkan;} const SystemChar* platformName() const {return _S("Vulkan");} - IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); - IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count); - - ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz); - GraphicsDataToken newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void *data, size_t sz, ITextureS*& texOut); - ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, - const void* data, size_t sz); - ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); - ITextureR* newRenderTexture(size_t width, size_t height, - bool enableShaderColorBinding, bool enableShaderDepthBinding); - - bool bindingNeedsVertexFormat() const {return false;} - IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); - - IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, - std::vector& vertBlobOut, std::vector& fragBlobOut, - std::vector& pipelineBlob, IVertexFormat* vtxFmt, - BlendFactor srcFac, BlendFactor dstFac, Primitive prim, - bool depthTest, bool depthWrite, bool backfaceCulling); - - IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt, - BlendFactor srcFac, BlendFactor dstFac, Primitive prim, - bool depthTest, bool depthWrite, bool backfaceCulling) + class Context : public IGraphicsDataFactory::Context { - std::vector vertBlob; - std::vector fragBlob; - std::vector pipelineBlob; - return newShaderPipeline(vertSource, fragSource, vertBlob, fragBlob, pipelineBlob, - vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling); - } + friend class VulkanDataFactory; + VulkanDataFactory& m_parent; + Context(VulkanDataFactory& parent) : m_parent(parent) {} + public: + Platform platform() const {return Platform::Vulkan;} + const SystemChar* platformName() const {return _S("Vulkan");} - IShaderDataBinding* - newShaderDataBinding(IShaderPipeline* pipeline, - IVertexFormat* vtxFormat, - IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, - size_t ubufCount, IGraphicsBuffer** ubufs, - size_t texCount, ITexture** texs); + IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); + IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count); - void reset(); - GraphicsDataToken commit(); + ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, + const void* data, size_t sz); + ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, + const void* data, size_t sz); + ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); + ITextureR* newRenderTexture(size_t width, size_t height, + bool enableShaderColorBinding, bool enableShaderDepthBinding); + + bool bindingNeedsVertexFormat() const {return false;} + IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); + + IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, + std::vector& vertBlobOut, std::vector& fragBlobOut, + std::vector& pipelineBlob, IVertexFormat* vtxFmt, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, + bool depthTest, bool depthWrite, bool backfaceCulling); + + IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, + bool depthTest, bool depthWrite, bool backfaceCulling) + { + std::vector vertBlob; + std::vector fragBlob; + std::vector pipelineBlob; + return newShaderPipeline(vertSource, fragSource, vertBlob, fragBlob, pipelineBlob, + vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling); + } + + IShaderDataBinding* + newShaderDataBinding(IShaderPipeline* pipeline, + IVertexFormat* vtxFormat, + IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo, + size_t ubufCount, IGraphicsBuffer** ubufs, + const size_t* ubufOffs, const size_t* ubufSizes, + size_t texCount, ITexture** texs); + }; + + GraphicsDataToken commitTransaction(const FactoryCommitFunc&); }; } diff --git a/lib/graphicsdev/GL.cpp b/lib/graphicsdev/GL.cpp index 9c74807..e29264d 100644 --- a/lib/graphicsdev/GL.cpp +++ b/lib/graphicsdev/GL.cpp @@ -60,6 +60,8 @@ public: {glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buf);} void bindUniform(size_t idx) const {glBindBufferBase(GL_UNIFORM_BUFFER, idx, m_buf);} + void bindUniformRange(size_t idx, GLintptr off, GLsizeiptr size) const + {glBindBufferRange(GL_UNIFORM_BUFFER, idx, m_buf, off, size);} }; class GLGraphicsBufferD : public IGraphicsBufferD @@ -92,14 +94,13 @@ public: void bindVertex(int b); void bindIndex(int b); void bindUniform(size_t idx, int b); + void bindUniformRange(size_t idx, GLintptr off, GLsizeiptr size, int b); }; IGraphicsBufferS* -GLDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) +GLDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) { GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, data, stride * count); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_SBufs.emplace_back(retval); return retval; } @@ -295,42 +296,19 @@ public: }; ITextureS* -GLDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz) +GLDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, + const void* data, size_t sz) { GLTextureS* retval = new GLTextureS(width, height, mips, fmt, data, sz); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_STexs.emplace_back(retval); return retval; } -GraphicsDataToken -GLDataFactory::newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz, ITextureS*& texOut) -{ - GLTextureS* retval = new GLTextureS(width, height, mips, fmt, data, sz); - GLData* tokData = new struct GLData(); - tokData->m_STexs.emplace_back(retval); - texOut = retval; - - std::unique_lock lk(m_committedMutex); - m_committedData.insert(tokData); - lk.unlock(); - /* Let's go ahead and flush to ensure our data gets to the GPU - While this isn't strictly required, some drivers might behave - differently */ - glFlush(); - return GraphicsDataToken(this, tokData); -} - ITextureSA* -GLDataFactory::newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, - const void *data, size_t sz) +GLDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, + const void *data, size_t sz) { GLTextureSA* retval = new GLTextureSA(width, height, layers, fmt, data, sz); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_SATexs.emplace_back(retval); return retval; } @@ -452,7 +430,7 @@ static const GLenum BLEND_FACTOR_TABLE[] = GL_ONE_MINUS_SRC1_COLOR }; -IShaderPipeline* GLDataFactory::newShaderPipeline +IShaderPipeline* GLDataFactory::Context::newShaderPipeline (const char* vertSource, const char* fragSource, size_t texCount, const char* texArrayName, size_t uniformBlockCount, const char** uniformBlockNames, @@ -535,16 +513,14 @@ IShaderPipeline* GLDataFactory::newShaderPipeline Log.report(logvisor::Error, "unable to find sampler variable '%s'", texArrayName); else { - if (texCount > m_texUnis.size()) - for (size_t i=m_texUnis.size() ; i m_parent.m_texUnis.size()) + for (size_t i=m_parent.m_texUnis.size() ; im_SPs.emplace_back(retval); return retval; } @@ -567,17 +543,14 @@ struct GLShaderDataBinding : IShaderDataBinding const GLVertexFormat* m_vtxFormat; size_t m_ubufCount; std::unique_ptr m_ubufs; + std::vector> m_ubufOffs; size_t m_texCount; std::unique_ptr m_texs; -#ifndef NDEBUG - /* Debugging aids */ - bool m_committed = false; -#endif - GLShaderDataBinding(IShaderPipeline* pipeline, IVertexFormat* vtxFormat, size_t ubufCount, IGraphicsBuffer** ubufs, + const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount, ITexture** texs) : m_pipeline(static_cast(pipeline)), m_vtxFormat(static_cast(vtxFormat)), @@ -586,29 +559,57 @@ struct GLShaderDataBinding : IShaderDataBinding m_texCount(texCount), m_texs(new ITexture*[texCount]) { + if (ubufOffs && ubufSizes) + { + m_ubufOffs.reserve(ubufCount); + for (size_t i=0 ; ibind(); m_vtxFormat->bind(b); - for (size_t i=0 ; idynamic()) - static_cast(ubuf)->bindUniform(i, b); - else - static_cast(ubuf)->bindUniform(i); - glUniformBlockBinding(prog, m_pipeline->m_uniLocs.at(i), i); + for (size_t i=0 ; i& offset = m_ubufOffs[i]; + if (ubuf->dynamic()) + static_cast(ubuf)->bindUniformRange(i, offset.first, offset.second, b); + else + static_cast(ubuf)->bindUniformRange(i, offset.first, offset.second); + glUniformBlockBinding(prog, m_pipeline->m_uniLocs.at(i), i); + } + } + else + { + for (size_t i=0 ; idynamic()) + static_cast(ubuf)->bindUniform(i, b); + else + static_cast(ubuf)->bindUniform(i); + glUniformBlockBinding(prog, m_pipeline->m_uniLocs.at(i), i); + } } for (size_t i=0 ; im_SBinds.emplace_back(retval); return retval; } @@ -651,22 +651,23 @@ GLDataFactory::newShaderDataBinding(IShaderPipeline* pipeline, GLDataFactory::GLDataFactory(IGraphicsContext* parent, uint32_t drawSamples) : m_parent(parent), m_drawSamples(drawSamples) {} -void GLDataFactory::reset() -{ - delete m_deferredData.get(); - m_deferredData.reset(); -} -GraphicsDataToken GLDataFactory::commit() +GraphicsDataToken GLDataFactory::commitTransaction(const FactoryCommitFunc& trans) { - if (!m_deferredData.get()) + if (m_deferredData.get()) + Log.report(logvisor::Fatal, "nested commitTransaction usage detected"); + m_deferredData.reset(new GLData()); + + GLDataFactory::Context ctx(*this); + if (!trans(ctx)) + { + delete m_deferredData.get(); + m_deferredData.reset(); return GraphicsDataToken(this, nullptr); + } + std::unique_lock lk(m_committedMutex); GLData* retval = m_deferredData.get(); -#ifndef NDEBUG - for (std::unique_ptr& b : retval->m_SBinds) - b->m_committed = true; -#endif m_deferredData.reset(); m_committedData.insert(retval); lk.unlock(); @@ -1057,10 +1058,6 @@ struct GLCommandQueue : IGraphicsCommandQueue void setShaderDataBinding(IShaderDataBinding* binding) { -#ifndef NDEBUG - if (!binding) - Log.report(logvisor::Fatal, "binding may not be empty"); -#endif std::vector& cmds = m_cmdBufs[m_fillBuf]; cmds.emplace_back(Command::Op::SetShaderDataBinding); cmds.back().binding = binding; @@ -1281,13 +1278,13 @@ void GLGraphicsBufferD::bindIndex(int b) {glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufs[b]);} void GLGraphicsBufferD::bindUniform(size_t idx, int b) {glBindBufferBase(GL_UNIFORM_BUFFER, idx, m_bufs[b]);} +void GLGraphicsBufferD::bindUniformRange(size_t idx, GLintptr off, GLsizeiptr size, int b) +{glBindBufferRange(GL_UNIFORM_BUFFER, idx, m_bufs[b], off, size);} IGraphicsBufferD* -GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count) +GLDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count) { GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_DBufs.emplace_back(retval); return retval; } @@ -1360,11 +1357,9 @@ void GLTextureD::bind(size_t idx, int b) } ITextureD* -GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) +GLDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) { GLTextureD* retval = new GLTextureD(width, height, fmt); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_DTexs.emplace_back(retval); return retval; } @@ -1430,15 +1425,13 @@ GLTextureR::~GLTextureR() } ITextureR* -GLDataFactory::newRenderTexture(size_t width, size_t height, - bool enableShaderColorBinding, bool enableShaderDepthBinding) +GLDataFactory::Context::newRenderTexture(size_t width, size_t height, + bool enableShaderColorBinding, bool enableShaderDepthBinding) { - GLCommandQueue* q = static_cast(m_parent->getCommandQueue()); - GLTextureR* retval = new GLTextureR(q, width, height, m_drawSamples, + GLCommandQueue* q = static_cast(m_parent.m_parent->getCommandQueue()); + GLTextureR* retval = new GLTextureR(q, width, height, m_parent.m_drawSamples, enableShaderColorBinding, enableShaderDepthBinding); q->resizeRenderTexture(retval, width, height); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_RTexs.emplace_back(retval); return retval; } @@ -1455,13 +1448,11 @@ GLVertexFormat::GLVertexFormat(GLCommandQueue* q, size_t elementCount, } GLVertexFormat::~GLVertexFormat() {m_q->delVertexFormat(this);} -IVertexFormat* GLDataFactory::newVertexFormat +IVertexFormat* GLDataFactory::Context::newVertexFormat (size_t elementCount, const VertexElementDescriptor* elements) { - GLCommandQueue* q = static_cast(m_parent->getCommandQueue()); + GLCommandQueue* q = static_cast(m_parent.m_parent->getCommandQueue()); GLVertexFormat* retval = new struct GLVertexFormat(q, elementCount, elements); - if (!m_deferredData.get()) - m_deferredData.reset(new struct GLData()); m_deferredData->m_VFmts.emplace_back(retval); return retval; } diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 5df7f47..67a6c6a 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -773,6 +773,7 @@ class VulkanGraphicsBufferS : public IGraphicsBufferS ThrowIfFailed(vkCreateBuffer(ctx->m_dev, &bufInfo, nullptr, &m_bufferInfo.buffer)); } public: + size_t size() const {return m_sz;} size_t m_stride; size_t m_count; VkDescriptorBufferInfo m_bufferInfo; @@ -2047,6 +2048,7 @@ struct VulkanShaderDataBinding : IShaderDataBinding IGraphicsBuffer* m_ibuf; size_t m_ubufCount; std::unique_ptr m_ubufs; + std::vector m_ubufOffs; size_t m_texCount; std::unique_ptr m_texs; @@ -2067,6 +2069,7 @@ struct VulkanShaderDataBinding : IShaderDataBinding IShaderPipeline* pipeline, IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf, size_t ubufCount, IGraphicsBuffer** ubufs, + const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount, ITexture** texs) : m_ctx(ctx), m_pipeline(static_cast(pipeline)), @@ -2078,10 +2081,28 @@ struct VulkanShaderDataBinding : IShaderDataBinding m_texCount(texCount), m_texs(new ITexture*[texCount]) { + if (ubufOffs && ubufSizes) + { + m_ubufOffs.reserve(ubufCount); + for (size_t i=0 ; i 0) @@ -2151,22 +2172,49 @@ struct VulkanShaderDataBinding : IShaderDataBinding } size_t binding = 0; - for (size_t i=0 ; ibuffer; + modInfo.offset += origInfo->offset; + writes[totalWrites].pBufferInfo = &modInfo; + writes[totalWrites].dstArrayElement = 0; + writes[totalWrites].dstBinding = binding; + ++totalWrites; + } + ++binding; } - ++binding; } + else + { + for (size_t i=0 ; im_dev, &renderPass, nullptr, &ctx->m_pass)); } -IShaderPipeline* VulkanDataFactory::newShaderPipeline +IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline (const char* vertSource, const char* fragSource, std::vector& vertBlobOut, std::vector& fragBlobOut, std::vector& pipelineBlob, IVertexFormat* vtxFmt, @@ -2918,12 +2966,12 @@ IShaderPipeline* VulkanDataFactory::newShaderPipeline smCreateInfo.codeSize = vertBlobOut.size() * sizeof(unsigned int); smCreateInfo.pCode = vertBlobOut.data(); VkShaderModule vertModule; - ThrowIfFailed(vkCreateShaderModule(m_ctx->m_dev, &smCreateInfo, nullptr, &vertModule)); + ThrowIfFailed(vkCreateShaderModule(m_parent.m_ctx->m_dev, &smCreateInfo, nullptr, &vertModule)); smCreateInfo.codeSize = fragBlobOut.size() * sizeof(unsigned int); smCreateInfo.pCode = fragBlobOut.data(); VkShaderModule fragModule; - ThrowIfFailed(vkCreateShaderModule(m_ctx->m_dev, &smCreateInfo, nullptr, &fragModule)); + ThrowIfFailed(vkCreateShaderModule(m_parent.m_ctx->m_dev, &smCreateInfo, nullptr, &fragModule)); VkPipelineCacheCreateInfo cacheDataInfo = {}; cacheDataInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; @@ -2933,180 +2981,116 @@ IShaderPipeline* VulkanDataFactory::newShaderPipeline cacheDataInfo.pInitialData = pipelineBlob.data(); VkPipelineCache pipelineCache; - ThrowIfFailed(vkCreatePipelineCache(m_ctx->m_dev, &cacheDataInfo, nullptr, &pipelineCache)); + ThrowIfFailed(vkCreatePipelineCache(m_parent.m_ctx->m_dev, &cacheDataInfo, nullptr, &pipelineCache)); - VulkanShaderPipeline* retval = new VulkanShaderPipeline(m_ctx, vertModule, fragModule, pipelineCache, + VulkanShaderPipeline* retval = new VulkanShaderPipeline(m_parent.m_ctx, vertModule, fragModule, pipelineCache, static_cast(vtxFmt), srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling); if (pipelineBlob.empty()) { size_t cacheSz = 0; - ThrowIfFailed(vkGetPipelineCacheData(m_ctx->m_dev, pipelineCache, &cacheSz, nullptr)); + ThrowIfFailed(vkGetPipelineCacheData(m_parent.m_ctx->m_dev, pipelineCache, &cacheSz, nullptr)); if (cacheSz) { pipelineBlob.resize(cacheSz); - ThrowIfFailed(vkGetPipelineCacheData(m_ctx->m_dev, pipelineCache, &cacheSz, pipelineBlob.data())); + ThrowIfFailed(vkGetPipelineCacheData(m_parent.m_ctx->m_dev, pipelineCache, &cacheSz, pipelineBlob.data())); pipelineBlob.resize(cacheSz); } } - vkDestroyPipelineCache(m_ctx->m_dev, pipelineCache, nullptr); - vkDestroyShaderModule(m_ctx->m_dev, fragModule, nullptr); - vkDestroyShaderModule(m_ctx->m_dev, vertModule, nullptr); + vkDestroyPipelineCache(m_parent.m_ctx->m_dev, pipelineCache, nullptr); + vkDestroyShaderModule(m_parent.m_ctx->m_dev, fragModule, nullptr); + vkDestroyShaderModule(m_parent.m_ctx->m_dev, vertModule, nullptr); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); static_cast(m_deferredData.get())->m_SPs.emplace_back(retval); return retval; } -IGraphicsBufferS* VulkanDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) +IGraphicsBufferS* VulkanDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) { - VulkanGraphicsBufferS* retval = new VulkanGraphicsBufferS(use, m_ctx, data, stride, count); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); + VulkanGraphicsBufferS* retval = new VulkanGraphicsBufferS(use, m_parent.m_ctx, data, stride, count); static_cast(m_deferredData.get())->m_SBufs.emplace_back(retval); return retval; } -IGraphicsBufferD* VulkanDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count) +IGraphicsBufferD* VulkanDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count) { - VulkanCommandQueue* q = static_cast(m_parent->getCommandQueue()); - VulkanGraphicsBufferD* retval = new VulkanGraphicsBufferD(q, use, m_ctx, stride, count); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); + VulkanCommandQueue* q = static_cast(m_parent.m_parent->getCommandQueue()); + VulkanGraphicsBufferD* retval = new VulkanGraphicsBufferD(q, use, m_parent.m_ctx, stride, count); static_cast(m_deferredData.get())->m_DBufs.emplace_back(retval); return retval; } -ITextureS* VulkanDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, - TextureFormat fmt, const void* data, size_t sz) +ITextureS* VulkanDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, + TextureFormat fmt, const void* data, size_t sz) { - VulkanTextureS* retval = new VulkanTextureS(m_ctx, width, height, mips, fmt, data, sz); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); + VulkanTextureS* retval = new VulkanTextureS(m_parent.m_ctx, width, height, mips, fmt, data, sz); static_cast(m_deferredData.get())->m_STexs.emplace_back(retval); return retval; } -GraphicsDataToken -VulkanDataFactory::newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz, ITextureS*& texOut) +ITextureSA* VulkanDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, + TextureFormat fmt, const void* data, size_t sz) { - VulkanTextureS* retval = new VulkanTextureS(m_ctx, width, height, mips, fmt, data, sz); - VulkanData* tokData = new struct VulkanData(m_ctx); - tokData->m_STexs.emplace_back(retval); - texOut = retval; - - uint32_t memTypeBits = ~0; - VkDeviceSize memSize = SizeTextureForGPU(retval, m_ctx, memTypeBits, 0); - - /* allocate memory */ - VkMemoryAllocateInfo memAlloc = {}; - memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - memAlloc.pNext = nullptr; - memAlloc.memoryTypeIndex = 0; - memAlloc.allocationSize = memSize; - ThrowIfFalse(MemoryTypeFromProperties(m_ctx, memTypeBits, 0, &memAlloc.memoryTypeIndex)); - ThrowIfFailed(vkAllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &tokData->m_texMem)); - - /* Place texture */ - PlaceTextureForGPU(retval, m_ctx, tokData->m_texMem); - - /* Execute static uploads */ - ThrowIfFailed(vkEndCommandBuffer(m_ctx->m_loadCmdBuf)); - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &m_ctx->m_loadCmdBuf; - ThrowIfFailed(vkQueueSubmit(m_ctx->m_queue, 1, &submitInfo, m_ctx->m_loadFence)); - - /* Block handle return until data is ready on GPU */ - ThrowIfFailed(vkWaitForFences(m_ctx->m_dev, 1, &m_ctx->m_loadFence, VK_TRUE, -1)); - - /* Reset fence and command buffer */ - ThrowIfFailed(vkResetFences(m_ctx->m_dev, 1, &m_ctx->m_loadFence)); - ThrowIfFailed(vkResetCommandBuffer(m_ctx->m_loadCmdBuf, 0)); - VkCommandBufferBeginInfo cmdBufBeginInfo = {}; - cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmdBufBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - ThrowIfFailed(vkBeginCommandBuffer(m_ctx->m_loadCmdBuf, &cmdBufBeginInfo)); - - /* Delete upload objects */ - retval->deleteUploadObjects(); - - /* All set! */ - std::unique_lock lk(m_committedMutex); - m_committedData.insert(tokData); - return GraphicsDataToken(this, tokData); -} - -ITextureSA* VulkanDataFactory::newStaticArrayTexture(size_t width, size_t height, size_t layers, - TextureFormat fmt, const void* data, size_t sz) -{ - VulkanTextureSA* retval = new VulkanTextureSA(m_ctx, width, height, layers, fmt, data, sz); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); + VulkanTextureSA* retval = new VulkanTextureSA(m_parent.m_ctx, width, height, layers, fmt, data, sz); static_cast(m_deferredData.get())->m_SATexs.emplace_back(retval); return retval; } -ITextureD* VulkanDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) +ITextureD* VulkanDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) { - VulkanCommandQueue* q = static_cast(m_parent->getCommandQueue()); - VulkanTextureD* retval = new VulkanTextureD(q, m_ctx, width, height, fmt); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); + VulkanCommandQueue* q = static_cast(m_parent.m_parent->getCommandQueue()); + VulkanTextureD* retval = new VulkanTextureD(q, m_parent.m_ctx, width, height, fmt); static_cast(m_deferredData.get())->m_DTexs.emplace_back(retval); return retval; } -ITextureR* VulkanDataFactory::newRenderTexture(size_t width, size_t height, - bool enableShaderColorBinding, bool enableShaderDepthBinding) +ITextureR* VulkanDataFactory::Context::newRenderTexture(size_t width, size_t height, + bool enableShaderColorBinding, bool enableShaderDepthBinding) { - VulkanCommandQueue* q = static_cast(m_parent->getCommandQueue()); - VulkanTextureR* retval = new VulkanTextureR(m_ctx, q, width, height, m_drawSamples, + VulkanCommandQueue* q = static_cast(m_parent.m_parent->getCommandQueue()); + VulkanTextureR* retval = new VulkanTextureR(m_parent.m_ctx, q, width, height, m_parent.m_drawSamples, enableShaderColorBinding, enableShaderDepthBinding); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); static_cast(m_deferredData.get())->m_RTexs.emplace_back(retval); return retval; } -IVertexFormat* VulkanDataFactory::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements) +IVertexFormat* VulkanDataFactory::Context::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements) { VulkanVertexFormat* retval = new struct VulkanVertexFormat(elementCount, elements); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); static_cast(m_deferredData.get())->m_VFmts.emplace_back(retval); return retval; } -IShaderDataBinding* VulkanDataFactory::newShaderDataBinding(IShaderPipeline* pipeline, +IShaderDataBinding* VulkanDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline, IVertexFormat* /*vtxFormat*/, IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf, size_t ubufCount, IGraphicsBuffer** ubufs, + const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount, ITexture** texs) { VulkanShaderDataBinding* retval = - new VulkanShaderDataBinding(m_ctx, pipeline, vbuf, instVbuf, ibuf, ubufCount, ubufs, texCount, texs); - if (!m_deferredData.get()) - m_deferredData.reset(new struct VulkanData(m_ctx)); + new VulkanShaderDataBinding(m_parent.m_ctx, pipeline, vbuf, instVbuf, ibuf, + ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs); static_cast(m_deferredData.get())->m_SBinds.emplace_back(retval); return retval; } -void VulkanDataFactory::reset() +GraphicsDataToken VulkanDataFactory::commitTransaction + (const std::function& trans) { - delete static_cast(m_deferredData.get()); - m_deferredData.reset(); -} + if (m_deferredData.get()) + Log.report(logvisor::Fatal, "nested commitTransaction usage detected"); + m_deferredData.reset(new VulkanData(m_ctx)); -GraphicsDataToken VulkanDataFactory::commit() -{ - if (!m_deferredData.get()) + Context ctx(*this); + if (!trans(ctx)) + { + delete m_deferredData.get(); + m_deferredData.reset(); return GraphicsDataToken(this, nullptr); + } VulkanData* retval = static_cast(m_deferredData.get()); diff --git a/test/main.cpp b/test/main.cpp index a0d14e9..b208b56 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -228,92 +228,128 @@ struct TestApplicationCallback : IApplicationCallback IGraphicsDataFactory* factory = self->mainWindow->getLoadContextDataFactory(); - /* Create render target */ - int x, y, w, h; - self->mainWindow->getWindowFrame(x, y, w, h); - self->m_renderTarget = factory->newRenderTexture(w, h, false, false); - - /* Make Tri-strip VBO */ - struct Vert + GraphicsDataToken data = factory->commitTransaction([&](IGraphicsDataFactory::Context& ctx) -> bool { - float pos[3]; - float uv[2]; - }; - static const Vert quad[4] = - { - {{0.5,0.5},{1.0,1.0}}, - {{-0.5,0.5},{0.0,1.0}}, - {{0.5,-0.5},{1.0,0.0}}, - {{-0.5,-0.5},{0.0,0.0}} - }; - IGraphicsBuffer* vbo = - factory->newStaticBuffer(BufferUse::Vertex, quad, sizeof(Vert), 4); + /* Create render target */ + int x, y, w, h; + self->mainWindow->getWindowFrame(x, y, w, h); + self->m_renderTarget = ctx.newRenderTexture(w, h, false, false); - /* Make vertex format */ - VertexElementDescriptor descs[2] = - { - {vbo, nullptr, VertexSemantic::Position3}, - {vbo, nullptr, VertexSemantic::UV2} - }; - IVertexFormat* vfmt = factory->newVertexFormat(2, descs); - - /* Make ramp texture */ - using Pixel = uint8_t[4]; - static Pixel tex[256][256]; - for (int i=0 ; i<256 ; ++i) - for (int j=0 ; j<256 ; ++j) + /* Make Tri-strip VBO */ + struct Vert { - tex[i][j][0] = i; - tex[i][j][1] = j; - tex[i][j][2] = 0; - tex[i][j][3] = 0xff; + float pos[3]; + float uv[2]; + }; + static const Vert quad[4] = + { + {{0.5,0.5},{1.0,1.0}}, + {{-0.5,0.5},{0.0,1.0}}, + {{0.5,-0.5},{1.0,0.0}}, + {{-0.5,-0.5},{0.0,0.0}} + }; + IGraphicsBuffer* vbo = + ctx.newStaticBuffer(BufferUse::Vertex, quad, sizeof(Vert), 4); + + /* Make vertex format */ + VertexElementDescriptor descs[2] = + { + {vbo, nullptr, VertexSemantic::Position3}, + {vbo, nullptr, VertexSemantic::UV2} + }; + IVertexFormat* vfmt = ctx.newVertexFormat(2, descs); + + /* Make ramp texture */ + using Pixel = uint8_t[4]; + static Pixel tex[256][256]; + for (int i=0 ; i<256 ; ++i) + for (int j=0 ; j<256 ; ++j) + { + tex[i][j][0] = i; + tex[i][j][1] = j; + tex[i][j][2] = 0; + tex[i][j][3] = 0xff; + } + ITexture* texture = + ctx.newStaticTexture(256, 256, 1, TextureFormat::RGBA8, tex, 256*256*4); + + /* Make shader pipeline */ + IShaderPipeline* pipeline = nullptr; + if (ctx.platform() == IGraphicsDataFactory::Platform::OGL) + { + GLDataFactory::Context& glF = dynamic_cast(ctx); + + static const char* VS = + "#version 330\n" + "layout(location=0) in vec3 in_pos;\n" + "layout(location=1) in vec2 in_uv;\n" + "out vec2 out_uv;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(in_pos, 1.0);\n" + " out_uv = in_uv;\n" + "}\n"; + + static const char* FS = + "#version 330\n" + BOO_GLSL_BINDING_HEAD + "precision highp float;\n" + "TBINDING0 uniform sampler2D texs[1];\n" + "layout(location=0) out vec4 out_frag;\n" + "in vec2 out_uv;\n" + "void main()\n" + "{\n" + " out_frag = texture(texs[0], out_uv);\n" + "}\n"; + + pipeline = glF.newShaderPipeline(VS, FS, 1, "texs", 0, nullptr, + BlendFactor::One, BlendFactor::Zero, + Primitive::TriStrips, true, true, false); } - ITexture* texture = - factory->newStaticTexture(256, 256, 1, TextureFormat::RGBA8, tex, 256*256*4); - - /* Make shader pipeline */ - IShaderPipeline* pipeline = nullptr; - if (factory->platform() == IGraphicsDataFactory::Platform::OGL) - { - GLDataFactory* glF = dynamic_cast(factory); - - static const char* VS = - "#version 330\n" - "layout(location=0) in vec3 in_pos;\n" - "layout(location=1) in vec2 in_uv;\n" - "out vec2 out_uv;\n" - "void main()\n" - "{\n" - " gl_Position = vec4(in_pos, 1.0);\n" - " out_uv = in_uv;\n" - "}\n"; - - static const char* FS = - "#version 330\n" - BOO_GLSL_BINDING_HEAD - "precision highp float;\n" - "TBINDING0 uniform sampler2D texs[1];\n" - "layout(location=0) out vec4 out_frag;\n" - "in vec2 out_uv;\n" - "void main()\n" - "{\n" - " out_frag = texture(texs[0], out_uv);\n" - "}\n"; - - pipeline = glF->newShaderPipeline(VS, FS, 1, "texs", 0, nullptr, - BlendFactor::One, BlendFactor::Zero, - Primitive::TriStrips, true, true, false); - } #if _WIN32 - else if (factory->platform() == IGraphicsDataFactory::Platform::D3D12 || - factory->platform() == IGraphicsDataFactory::Platform::D3D11) - { - ID3DDataFactory* d3dF = dynamic_cast(factory); + else if (ctx.platform() == IGraphicsDataFactory::Platform::D3D12 || + ctx.platform() == IGraphicsDataFactory::Platform::D3D11) + { + ID3DDataFactory* d3dF = dynamic_cast(factory); - static const char* VS = - "struct VertData {float3 in_pos : POSITION; float2 in_uv : UV;};\n" - "struct VertToFrag {float4 out_pos : SV_Position; float2 out_uv : UV;};\n" - "VertToFrag main(in VertData v)\n" + static const char* VS = + "struct VertData {float3 in_pos : POSITION; float2 in_uv : UV;};\n" + "struct VertToFrag {float4 out_pos : SV_Position; float2 out_uv : UV;};\n" + "VertToFrag main(in VertData v)\n" + "{\n" + " VertToFrag retval;\n" + " retval.out_pos = float4(v.in_pos, 1.0);\n" + " retval.out_uv = v.in_uv;\n" + " return retval;\n" + "}\n"; + + static const char* PS = + "SamplerState samp : register(s0);\n" + "Texture2D tex : register(t0);\n" + "struct VertToFrag {float4 out_pos : SV_Position; float2 out_uv : UV;};\n" + "float4 main(in VertToFrag d) : SV_Target0\n" + "{\n" + " return tex.Sample(samp, d.out_uv);\n" + "}\n"; + + ComPtr vsCompile; + ComPtr psCompile; + ComPtr cachedPipeline; + pipeline = d3dF->newShaderPipeline(VS, PS, vsCompile, psCompile, cachedPipeline, vfmt, + BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, + true, true, false); + } +#elif BOO_HAS_METAL + else if (ctx.platform() == IGraphicsDataFactory::Platform::Metal) + { + MetalDataFactory* metalF = dynamic_cast(factory); + + static const char* VS = + "#include \n" + "using namespace metal;\n" + "struct VertData {float3 in_pos [[ attribute(0) ]]; float2 in_uv [[ attribute(1) ]];};\n" + "struct VertToFrag {float4 out_pos [[ position ]]; float2 out_uv;};\n" + "vertex VertToFrag vmain(VertData v [[ stage_in ]])\n" "{\n" " VertToFrag retval;\n" " retval.out_pos = float4(v.in_pos, 1.0);\n" @@ -321,62 +357,26 @@ struct TestApplicationCallback : IApplicationCallback " return retval;\n" "}\n"; - static const char* PS = - "SamplerState samp : register(s0);\n" - "Texture2D tex : register(t0);\n" - "struct VertToFrag {float4 out_pos : SV_Position; float2 out_uv : UV;};\n" - "float4 main(in VertToFrag d) : SV_Target0\n" + static const char* FS = + "#include \n" + "using namespace metal;\n" + "constexpr sampler samp(address::repeat);\n" + "struct VertToFrag {float4 out_pos [[ position ]]; float2 out_uv;};\n" + "fragment float4 fmain(VertToFrag d [[ stage_in ]], texture2d tex [[ texture(0) ]])\n" "{\n" - " return tex.Sample(samp, d.out_uv);\n" + " return tex.sample(samp, d.out_uv);\n" "}\n"; - ComPtr vsCompile; - ComPtr psCompile; - ComPtr cachedPipeline; - pipeline = d3dF->newShaderPipeline(VS, PS, vsCompile, psCompile, cachedPipeline, vfmt, - BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, - true, true, false); - } -#elif BOO_HAS_METAL - else if (factory->platform() == IGraphicsDataFactory::Platform::Metal) - { - MetalDataFactory* metalF = dynamic_cast(factory); - - static const char* VS = - "#include \n" - "using namespace metal;\n" - "struct VertData {float3 in_pos [[ attribute(0) ]]; float2 in_uv [[ attribute(1) ]];};\n" - "struct VertToFrag {float4 out_pos [[ position ]]; float2 out_uv;};\n" - "vertex VertToFrag vmain(VertData v [[ stage_in ]])\n" - "{\n" - " VertToFrag retval;\n" - " retval.out_pos = float4(v.in_pos, 1.0);\n" - " retval.out_uv = v.in_uv;\n" - " return retval;\n" - "}\n"; - - static const char* FS = - "#include \n" - "using namespace metal;\n" - "constexpr sampler samp(address::repeat);\n" - "struct VertToFrag {float4 out_pos [[ position ]]; float2 out_uv;};\n" - "fragment float4 fmain(VertToFrag d [[ stage_in ]], texture2d tex [[ texture(0) ]])\n" - "{\n" - " return tex.sample(samp, d.out_uv);\n" - "}\n"; - - pipeline = metalF->newShaderPipeline(VS, FS, vfmt, 1, - BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, - true, true, false); - } + pipeline = metalF->newShaderPipeline(VS, FS, vfmt, 1, + BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, + true, true, false); + } #endif - /* Make shader data binding */ - self->m_binding = - factory->newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, 1, &texture); - - /* Commit objects */ - GraphicsDataToken data = factory->commit(); + /* Make shader data binding */ + self->m_binding = + ctx.newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, 1, &texture); + }); /* Return control to client */ lk.unlock();