From 6600ff208cad0f506cde16ac26cdc86b4d9d7070 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Wed, 23 Mar 2016 22:05:19 -1000 Subject: [PATCH] Draw primitive now settable via pipeline object --- include/boo/graphicsdev/D3D.hpp | 2 +- include/boo/graphicsdev/GL.hpp | 2 +- .../boo/graphicsdev/IGraphicsDataFactory.hpp | 7 +++++ include/boo/graphicsdev/Metal.hpp | 2 +- include/boo/graphicsdev/Vulkan.hpp | 2 +- lib/audiodev/AQS.cpp | 12 ++++----- lib/graphicsdev/GL.cpp | 27 ++++++++++++++----- lib/graphicsdev/Metal.mm | 25 ++++++++++++----- test/main.cpp | 25 ++++++++--------- 9 files changed, 69 insertions(+), 35 deletions(-) diff --git a/include/boo/graphicsdev/D3D.hpp b/include/boo/graphicsdev/D3D.hpp index 4363054..b3bae2b 100644 --- a/include/boo/graphicsdev/D3D.hpp +++ b/include/boo/graphicsdev/D3D.hpp @@ -27,7 +27,7 @@ public: virtual IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, ComPtr& vertBlobOut, ComPtr& fragBlobOut, ComPtr& pipelineBlob, IVertexFormat* vtxFmt, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling)=0; }; diff --git a/include/boo/graphicsdev/GL.hpp b/include/boo/graphicsdev/GL.hpp index b0f994c..8fc69e6 100644 --- a/include/boo/graphicsdev/GL.hpp +++ b/include/boo/graphicsdev/GL.hpp @@ -50,7 +50,7 @@ public: IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, size_t texCount, const char* texArrayName, size_t uniformBlockCount, const char** uniformBlockNames, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling); IShaderDataBinding* diff --git a/include/boo/graphicsdev/IGraphicsDataFactory.hpp b/include/boo/graphicsdev/IGraphicsDataFactory.hpp index b5a57d7..775fecd 100644 --- a/include/boo/graphicsdev/IGraphicsDataFactory.hpp +++ b/include/boo/graphicsdev/IGraphicsDataFactory.hpp @@ -155,6 +155,13 @@ struct IShaderDataBinding {}; struct IGraphicsData {}; class GraphicsDataToken; +/** Used by platform shader pipeline constructors */ +enum class Primitive +{ + Triangles, + TriStrips +}; + /** Used by platform shader pipeline constructors */ enum class BlendFactor { diff --git a/include/boo/graphicsdev/Metal.hpp b/include/boo/graphicsdev/Metal.hpp index 2021dd0..982f50e 100644 --- a/include/boo/graphicsdev/Metal.hpp +++ b/include/boo/graphicsdev/Metal.hpp @@ -57,7 +57,7 @@ public: IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt, unsigned targetSamples, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling); IShaderDataBinding* diff --git a/include/boo/graphicsdev/Vulkan.hpp b/include/boo/graphicsdev/Vulkan.hpp index 8accb63..19d7d79 100644 --- a/include/boo/graphicsdev/Vulkan.hpp +++ b/include/boo/graphicsdev/Vulkan.hpp @@ -110,7 +110,7 @@ public: bool depthTest, bool depthWrite, bool backfaceCulling); IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling) { std::vector vertBlob; diff --git a/lib/audiodev/AQS.cpp b/lib/audiodev/AQS.cpp index 7a5f4e2..9e73da6 100644 --- a/lib/audiodev/AQS.cpp +++ b/lib/audiodev/AQS.cpp @@ -43,17 +43,17 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine std::mutex m_engineMutex; std::condition_variable m_engineCv; - static void Callback(AQSAudioVoiceEngine* voice, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) + static void Callback(AQSAudioVoiceEngine* engine, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { - std::unique_lock lk(voice->m_engineMutex); - voice->m_engineCv.wait(lk); + std::unique_lock lk(engine->m_engineMutex); + engine->m_engineCv.wait(lk); - voice->_pumpAndMixVoices(voice->m_mixInfo.m_periodFrames, reinterpret_cast(inBuffer->mAudioData)); - inBuffer->mAudioDataByteSize = voice->m_frameBytes; + engine->_pumpAndMixVoices(engine->m_mixInfo.m_periodFrames, reinterpret_cast(inBuffer->mAudioData)); + inBuffer->mAudioDataByteSize = engine->m_frameBytes; AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, nullptr); } - static void DummyCallback(AQSAudioVoiceEngine* voice, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {} + static void DummyCallback(AQSAudioVoiceEngine* engine, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {} AudioChannelSet _getAvailableSet() { diff --git a/lib/graphicsdev/GL.cpp b/lib/graphicsdev/GL.cpp index 4185ddb..9c74807 100644 --- a/lib/graphicsdev/GL.cpp +++ b/lib/graphicsdev/GL.cpp @@ -338,12 +338,14 @@ GLDataFactory::newStaticArrayTexture(size_t width, size_t height, size_t layers, class GLShaderPipeline : public IShaderPipeline { friend class GLDataFactory; + friend class GLCommandQueue; friend struct GLShaderDataBinding; GLuint m_vert = 0; GLuint m_frag = 0; GLuint m_prog = 0; GLenum m_sfactor = GL_ONE; GLenum m_dfactor = GL_ZERO; + GLenum m_drawPrim = GL_TRIANGLES; bool m_depthTest = true; bool m_depthWrite = true; bool m_backfaceCulling = true; @@ -396,6 +398,7 @@ public: m_depthWrite = other.m_depthWrite; m_backfaceCulling = other.m_backfaceCulling; m_uniLocs = std::move(other.m_uniLocs); + m_drawPrim = other.m_drawPrim; return *this; } GLShaderPipeline(GLShaderPipeline&& other) {*this = std::move(other);} @@ -427,6 +430,12 @@ public: } }; +static const GLenum PRIMITIVE_TABLE[] = +{ + GL_TRIANGLES, + GL_TRIANGLE_STRIP +}; + static const GLenum BLEND_FACTOR_TABLE[] = { GL_ZERO, @@ -447,7 +456,7 @@ IShaderPipeline* GLDataFactory::newShaderPipeline (const char* vertSource, const char* fragSource, size_t texCount, const char* texArrayName, size_t uniformBlockCount, const char** uniformBlockNames, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling) { GLShaderPipeline shader; @@ -461,6 +470,7 @@ IShaderPipeline* GLDataFactory::newShaderPipeline shader.m_depthTest = depthTest; shader.m_depthWrite = depthWrite; shader.m_backfaceCulling = backfaceCulling; + shader.m_drawPrim = PRIMITIVE_TABLE[int(prim)]; glShaderSource(shader.m_vert, 1, &vertSource, nullptr); glCompileShader(shader.m_vert); @@ -929,13 +939,18 @@ struct GLCommandQueue : IGraphicsCommandQueue posts.swap(self->m_pendingPosts2); } std::vector& cmds = self->m_cmdBufs[self->m_drawBuf]; + GLenum currentPrim = GL_TRIANGLES; for (const Command& cmd : cmds) { switch (cmd.m_op) { case Command::Op::SetShaderDataBinding: - static_cast(cmd.binding)->bind(self->m_drawBuf); + { + const GLShaderDataBinding* binding = static_cast(cmd.binding); + binding->bind(self->m_drawBuf); + currentPrim = binding->m_pipeline->m_drawPrim; break; + } case Command::Op::SetRenderTarget: { const GLTextureR* tex = static_cast(cmd.target); @@ -966,16 +981,16 @@ struct GLCommandQueue : IGraphicsCommandQueue glClear(cmd.flags); break; case Command::Op::Draw: - glDrawArrays(GL_TRIANGLE_STRIP, cmd.start, cmd.count); + glDrawArrays(currentPrim, cmd.start, cmd.count); break; case Command::Op::DrawIndexed: - glDrawElements(GL_TRIANGLE_STRIP, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start); + glDrawElements(currentPrim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start); break; case Command::Op::DrawInstances: - glDrawArraysInstanced(GL_TRIANGLE_STRIP, cmd.start, cmd.count, cmd.instCount); + glDrawArraysInstanced(currentPrim, cmd.start, cmd.count, cmd.instCount); break; case Command::Op::DrawInstancesIndexed: - glDrawElementsInstanced(GL_TRIANGLE_STRIP, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount); + glDrawElementsInstanced(currentPrim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount); break; case Command::Op::ResolveBindTexture: { diff --git a/lib/graphicsdev/Metal.mm b/lib/graphicsdev/Metal.mm index 4328699..e570a67 100644 --- a/lib/graphicsdev/Metal.mm +++ b/lib/graphicsdev/Metal.mm @@ -417,15 +417,24 @@ static const MTLBlendFactor BLEND_FACTOR_TABLE[] = MTLBlendFactorOneMinusDestinationAlpha }; +static const MTLPrimitiveType PRIMITIVE_TABLE[] = +{ + MTLPrimitiveTypeTriangle, + MTLPrimitiveTypeTriangleStrip +}; + class MetalShaderPipeline : public IShaderPipeline { friend class MetalDataFactory; + friend class MetalCommandQueue; MTLCullMode m_cullMode = MTLCullModeNone; + MTLPrimitiveType m_drawPrim; MetalShaderPipeline(MetalContext* ctx, id vert, id frag, const MetalVertexFormat* vtxFmt, NSUInteger targetSamples, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling) + : m_drawPrim(PRIMITIVE_TABLE[int(prim)]) { if (backfaceCulling) m_cullMode = MTLCullModeBack; @@ -591,11 +600,13 @@ struct MetalCommandQueue : IGraphicsCommandQueue } MetalShaderDataBinding* m_boundData = nullptr; + MTLPrimitiveType m_currentPrimitive = MTLPrimitiveTypeTriangle; void setShaderDataBinding(IShaderDataBinding* binding) { MetalShaderDataBinding* cbind = static_cast(binding); cbind->bind(m_enc, m_fillBuf); m_boundData = cbind; + m_currentPrimitive = cbind->m_pipeline->m_drawPrim; } MetalTextureR* m_boundTarget = nullptr; @@ -661,12 +672,12 @@ struct MetalCommandQueue : IGraphicsCommandQueue void draw(size_t start, size_t count) { - [m_enc drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:start vertexCount:count]; + [m_enc drawPrimitives:m_currentPrimitive vertexStart:start vertexCount:count]; } void drawIndexed(size_t start, size_t count) { - [m_enc drawIndexedPrimitives:MTLPrimitiveTypeTriangleStrip + [m_enc drawIndexedPrimitives:m_currentPrimitive indexCount:count indexType:MTLIndexTypeUInt32 indexBuffer:GetBufferGPUResource(m_boundData->m_ibuf, m_fillBuf) @@ -675,13 +686,13 @@ struct MetalCommandQueue : IGraphicsCommandQueue void drawInstances(size_t start, size_t count, size_t instCount) { - [m_enc drawPrimitives:MTLPrimitiveTypeTriangleStrip + [m_enc drawPrimitives:m_currentPrimitive vertexStart:start vertexCount:count instanceCount:instCount]; } void drawInstancesIndexed(size_t start, size_t count, size_t instCount) { - [m_enc drawIndexedPrimitives:MTLPrimitiveTypeTriangleStrip + [m_enc drawIndexedPrimitives:m_currentPrimitive indexCount:count indexType:MTLIndexTypeUInt32 indexBuffer:GetBufferGPUResource(m_boundData->m_ibuf, m_fillBuf) @@ -951,7 +962,7 @@ IVertexFormat* MetalDataFactory::newVertexFormat(size_t elementCount, const Vert IShaderPipeline* MetalDataFactory::newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt, unsigned targetSamples, - BlendFactor srcFac, BlendFactor dstFac, + BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool depthTest, bool depthWrite, bool backfaceCulling) { MTLCompileOptions* compOpts = [MTLCompileOptions new]; @@ -974,7 +985,7 @@ IShaderPipeline* MetalDataFactory::newShaderPipeline(const char* vertSource, con MetalShaderPipeline* retval = new MetalShaderPipeline(m_ctx, vertFunc, fragFunc, static_cast(vtxFmt), targetSamples, - srcFac, dstFac, depthTest, depthWrite, backfaceCulling); + srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling); if (!m_deferredData.get()) m_deferredData.reset(new struct MetalData()); m_deferredData->m_SPs.emplace_back(retval); diff --git a/test/main.cpp b/test/main.cpp index 246d653..d53bbb8 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -126,7 +126,7 @@ struct CTestWindowCallback : IWindowCallback SWindowRect m_lastRect; bool m_rectDirty = false; bool m_windowInvalid = false; - + void resized(const SWindowRect& rect) { m_lastRect = rect; @@ -209,7 +209,7 @@ struct CTestWindowCallback : IWindowCallback } }; - + struct TestApplicationCallback : IApplicationCallback { IWindow* mainWindow; @@ -219,19 +219,19 @@ struct TestApplicationCallback : IApplicationCallback IShaderDataBinding* m_binding = nullptr; ITextureR* m_renderTarget = nullptr; - + std::mutex m_mt; std::condition_variable m_cv; - + std::mutex m_initmt; std::condition_variable m_initcv; static void LoaderProc(TestApplicationCallback* self) { std::unique_lock lk(self->m_initmt); - + IGraphicsDataFactory* factory = self->mainWindow->getLoadContextDataFactory(); - + /* Create render target */ int x, y, w, h; self->mainWindow->getWindowFrame(x, y, w, h); @@ -306,7 +306,7 @@ struct TestApplicationCallback : IApplicationCallback pipeline = glF->newShaderPipeline(VS, FS, 1, "texs", 0, nullptr, BlendFactor::One, BlendFactor::Zero, - true, true, false); + Primitive::TriStrips, true, true, false); } #if _WIN32 else if (factory->platform() == IGraphicsDataFactory::Platform::D3D12 || @@ -344,7 +344,7 @@ struct TestApplicationCallback : IApplicationCallback else if (factory->platform() == IGraphicsDataFactory::Platform::Metal) { MetalDataFactory* metalF = dynamic_cast(factory); - + static const char* VS = "#include \n" "using namespace metal;\n" @@ -357,7 +357,7 @@ struct TestApplicationCallback : IApplicationCallback " retval.out_uv = v.in_uv;\n" " return retval;\n" "}\n"; - + static const char* FS = "#include \n" "using namespace metal;\n" @@ -367,9 +367,10 @@ struct TestApplicationCallback : IApplicationCallback "{\n" " return tex.sample(samp, d.out_uv);\n" "}\n"; - + pipeline = metalF->newShaderPipeline(VS, FS, vfmt, 1, - BlendFactor::One, BlendFactor::Zero, true, true, false); + BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, + true, true, false); } #endif @@ -379,7 +380,7 @@ struct TestApplicationCallback : IApplicationCallback /* Commit objects */ GraphicsDataToken data = factory->commit(); - + /* Return control to client */ lk.unlock(); self->m_initcv.notify_one();