[Vulkan] Pipelines created in the render algorithms
authoradam.b <jsr184@gmail.com>
Wed, 6 Jun 2018 16:06:43 +0000 (17:06 +0100)
committerDavid Steele <david.steele@samsung.com>
Tue, 12 Jun 2018 20:31:31 +0000 (21:31 +0100)
- blending modes
- depth modes
- clear color from rendertask/instruction
- render pass changes whenever new render target is bound

Change-Id: I6a97d5db5a408fc5ac343fe8a6637c5308e6ecbe

15 files changed:
dali/graphics-api/graphics-api-render-command.h
dali/graphics/vulkan/api/vulkan-api-controller.cpp
dali/graphics/vulkan/api/vulkan-api-controller.h
dali/graphics/vulkan/api/vulkan-api-render-command.cpp
dali/graphics/vulkan/vulkan-command-buffer.cpp
dali/graphics/vulkan/vulkan-command-buffer.h
dali/graphics/vulkan/vulkan-graphics.cpp
dali/graphics/vulkan/vulkan-swapchain.cpp
dali/internal/event/rendering/renderer-impl.cpp
dali/internal/update/graphics/graphics-algorithms.cpp
dali/internal/update/manager/update-manager.cpp
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h
dali/internal/update/rendering/scene-graph-shader.cpp
dali/internal/update/rendering/scene-graph-shader.h

index aaf78ad..6d022af 100644 (file)
@@ -669,7 +669,7 @@ public:
     return mIndexBufferBinding;
   }
 
-  const auto& GetRenderTargetBinding() const
+  const RenderTargetBinding& GetRenderTargetBinding() const
   {
     return mRenderTargetBinding;
   }
index 23b71bd..df6d592 100644 (file)
@@ -53,6 +53,29 @@ namespace VulkanAPI
 
 struct Controller::Impl
 {
+  struct RenderPassChange
+  {
+    // only move semantics
+    RenderPassChange( vk::RenderPassBeginInfo _beginInfo,
+                      std::vector<vk::ClearValue>&& _clearColorValues,
+                      const Vulkan::RefCountedFramebuffer& _framebuffer,
+                      uint32_t _offset )
+    : beginInfo( std::move(_beginInfo) ),
+      colorValues( std::move(_clearColorValues) ),
+      framebuffer( _framebuffer ),
+      offset( _offset )
+      {
+      }
+
+    // no default constructor!
+    RenderPassChange() = delete;
+
+    vk::RenderPassBeginInfo beginInfo     {};
+    std::vector<vk::ClearValue>           colorValues {};
+    Vulkan::RefCountedFramebuffer         framebuffer {};
+    uint32_t offset { 0 };
+  };
+
   Impl( Controller& owner, Dali::Graphics::Vulkan::Graphics& graphics )
   : mGraphics( graphics ),
     mOwner( owner ),
@@ -81,30 +104,49 @@ struct Controller::Impl
     return true;
   }
 
+
   void BeginFrame()
   {
+    // for all swapchains acquire new framebuffer
     auto surface = mGraphics.GetSurface( 0u );
 
     auto swapchain = mGraphics.GetSwapchainForFBID( 0u );
 
-    auto framebuffer = swapchain->AcquireNextFramebuffer();
-
-    swapchain->BeginPrimaryRenderPass( {
-                                         { 1.0f, 1.0f, 1.0f, 1.0f }
-                                       }  );
+    swapchain->AcquireNextFramebuffer();
 
+    mCurrentFramebuffer.Reset();
   }
 
   void EndFrame()
   {
+    // swap all swapchains
     auto swapchain = mGraphics.GetSwapchainForFBID( 0u );
 
-    // execute as secondary buffers
-    swapchain->GetPrimaryCommandBuffer()
-             ->ExecuteCommands( mSecondaryCommandBufferRefs );
+    auto primaryCommandBuffer = swapchain->GetPrimaryCommandBuffer();
+
+    for( auto i = 0u; i < mRenderPasses.size(); ++i )
+    {
+      if( i != 0u )
+      {
+        primaryCommandBuffer->EndRenderPass();
+      }
+
+      const auto& rp = mRenderPasses[i];
+      uint32_t offset = rp.offset;
+      uint32_t count = uint32_t(
+                 (i == mRenderPasses.size()-1) ?
+                 mSecondaryCommandBufferRefs.size() - rp.offset :
+                 mRenderPasses[i+1].offset - rp.offset );
+
+      primaryCommandBuffer->BeginRenderPass( rp.beginInfo, vk::SubpassContents::eSecondaryCommandBuffers );
+      primaryCommandBuffer->ExecuteCommands( mSecondaryCommandBufferRefs, offset, count );
+    }
+
+    primaryCommandBuffer->EndRenderPass();
 
     swapchain->Present();
     mSecondaryCommandBufferRefs.clear();
+    mRenderPasses.clear();
   }
 
   API::TextureFactory& GetTextureFactory() const
@@ -131,6 +173,60 @@ struct Controller::Impl
     return std::make_unique<VulkanAPI::RenderCommand>( mOwner, mGraphics );
   }
 
+  bool UpdateRenderPass( const API::RenderCommand::RenderTargetBinding& renderTargetBinding )
+  {
+    Vulkan::RefCountedFramebuffer framebuffer{ nullptr };
+    if( renderTargetBinding.framebuffer.Exists() )
+    {
+      // @todo use VulkanAPI::Framebuffer when available
+      //framebuffer = static_cast<VulkanAPI::Framebuffer&>(renderTargetBinding.framebuffer.Get()).GetVkHandle();
+    }
+    else
+    {
+      // use first surface/swapchain as render target
+      auto surface = mGraphics.GetSurface( 0u );
+      auto swapchain = mGraphics.GetSwapchainForFBID( 0u );
+      framebuffer = swapchain->GetCurrentFramebuffer();
+    }
+
+    // If there is no framebuffer the it means DALi tries to use
+    // default framebuffer. For now just substitute with surface/swapchain
+    if( framebuffer != mCurrentFramebuffer )
+    {
+      auto primaryCommandBuffer = mGraphics.GetSwapchainForFBID(0)->GetPrimaryCommandBuffer();
+
+      mCurrentFramebuffer = framebuffer;
+      mCurrentFramebuffer->GetRenderPassVkHandle();
+      auto newColors = mCurrentFramebuffer->GetDefaultClearValues();
+      newColors[0].color.setFloat32( { renderTargetBinding.clearColors[0].r,
+                                       renderTargetBinding.clearColors[0].g,
+                                       renderTargetBinding.clearColors[0].b,
+                                       renderTargetBinding.clearColors[0].a
+                                     } );
+      mRenderPasses.emplace_back(
+                                // render pass
+                                vk::RenderPassBeginInfo{}
+                                    .setRenderPass( mCurrentFramebuffer->GetRenderPassVkHandle() )
+                                    .setFramebuffer( mCurrentFramebuffer->GetVkHandle() )
+                                    .setRenderArea( vk::Rect2D( {0, 0}, {mCurrentFramebuffer->GetWidth(), mCurrentFramebuffer->GetHeight()} ) )
+                                    .setClearValueCount( uint32_t( mCurrentFramebuffer->GetDefaultClearValues().size() ) )
+                                    .setPClearValues( newColors.data() ),
+
+                                // colors
+                                std::move(newColors),
+
+                                // framebuffer
+                                framebuffer,
+
+                                // offset when to begin new render pass
+                                0 );
+      return true;
+    }
+
+    // same render pass
+    return false;
+  }
+
   /**
    * Submits number of commands in one go ( simiar to vkCmdExecuteCommands )
    * @param commands
@@ -149,6 +245,13 @@ struct Controller::Impl
       mBufferTransferRequests.clear();
     }
 
+    // the list of commands may be empty, but still we may have scheduled memory
+    // transfers
+    if( commands.empty() )
+    {
+      return;
+    }
+
     std::vector<Vulkan::RefCountedCommandBuffer> cmdBufRefs{};
 
     // Update uniform buffers
@@ -168,13 +271,22 @@ struct Controller::Impl
       apiCommand->PrepareResources();
     }
 
+    // Begin render pass for render target
+    // clear color obtained from very first command in the batch
+    auto firstCommand = static_cast<VulkanAPI::RenderCommand*>(commands[0]);
+    UpdateRenderPass( firstCommand->GetRenderTargetBinding() );
+
     // set up writes
     for( auto&& command : commands )
     {
       //const auto& vertexBufferBindings = command->GetVertexBufferBindings();
       auto apiCommand = static_cast<VulkanAPI::RenderCommand*>(command);
 
-      //apiCommand->PreparePipeline();
+      // skip if there's no valid pipeline
+      if( !apiCommand->GetVulkanPipeline() )
+      {
+        continue;
+      }
 
       // start new command buffer
       auto cmdbuf = mGraphics.CreateCommandBuffer( false );//mCommandPool->NewCommandBuffer( false );
@@ -244,6 +356,9 @@ struct Controller::Impl
   // and ready to be used for the next frame.
   std::vector<Vulkan::RefCountedCommandBuffer> mSecondaryCommandBufferRefs;
 
+  Vulkan::RefCountedFramebuffer mCurrentFramebuffer;
+  std::vector<RenderPassChange> mRenderPasses;
+
 };
 
 // TODO: @todo temporarily ignore missing return type, will be fixed later
@@ -373,7 +488,6 @@ std::unique_ptr<API::RenderCommand> Controller::AllocateRenderCommand()
   return mImpl->AllocateRenderCommand();
 }
 
-
 } // namespace VulkanAPI
 } // namespace Graphics
 } // namespace Dali
index ed182ed..7f53116 100644 (file)
@@ -106,7 +106,7 @@ public:
 
   std::unique_ptr<API::RenderCommand> AllocateRenderCommand() override;
 
-  void BeginFrame() override;
+  virtual void BeginFrame() override;
 
   void EndFrame() override;
 
index 374849f..75c4d0a 100644 (file)
@@ -66,6 +66,10 @@ void RenderCommand::PrepareResources()
     if( !mVulkanPipeline )
     {
       auto pipeline = dynamic_cast<const VulkanAPI::Pipeline*>( mPipeline );
+      if(!pipeline)
+      {
+        return;
+      }
       mVkDescriptorSetLayouts.clear();
       mVkDescriptorSetLayouts = pipeline->GetVkDescriptorSetLayouts();
       mVulkanPipeline = pipeline->GetVkPipeline();
index a6f79ac..1c41026 100644 (file)
@@ -231,24 +231,35 @@ void CommandBuffer::EndRenderPass()
   mCommandBuffer.endRenderPass();
 }
 
-void CommandBuffer::ExecuteCommands( std::vector< Dali::Graphics::Vulkan::Handle< CommandBuffer>> commandBuffers )
+void CommandBuffer::ExecuteCommands( const std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>>& commandBuffers, uint32_t offset, uint32_t count )
 {
   assert( mAllocateInfo.level == vk::CommandBufferLevel::ePrimary
           && "Cannot record command: ExecuteCommands\tReason: The command buffer recording this command is not primary" );
 
   auto vkBuffers = std::vector< vk::CommandBuffer >{};
   vkBuffers.reserve( commandBuffers.size());
-  for( auto&& buf : commandBuffers )
+
+  auto iter = commandBuffers.begin();
+  std::advance(iter, offset);
+
+  for( uint32_t i = 0; i < count; ++i )
   {
+    const auto& buf = *iter;
     assert(buf->mAllocateInfo.level == vk::CommandBufferLevel::eSecondary &&
-            "Cannot record command: Execute Commands\tReason: A command buffer provided for execution is not secondary" );
+           "Cannot record command: Execute Commands\tReason: A command buffer provided for execution is not secondary" );
 
     vkBuffers.emplace_back( buf->GetVkHandle());
+    ++iter;
   }
 
   mCommandBuffer.executeCommands( vkBuffers );
 }
 
+void CommandBuffer::ExecuteCommands( const std::vector< Dali::Graphics::Vulkan::Handle< CommandBuffer>>& commandBuffers )
+{
+  ExecuteCommands( commandBuffers, 0, uint32_t(commandBuffers.size()) );
+}
+
 void CommandBuffer::PipelineBarrier( vk::PipelineStageFlags srcStageMask,
                                      vk::PipelineStageFlags dstStageMask,
                                      vk::DependencyFlags dependencyFlags,
index 7b366be..e7554cf 100644 (file)
@@ -176,7 +176,13 @@ public:
    * Executes secondary command buffers within primary command buffer
    * @param commandBuffers
    */
-  void ExecuteCommands( std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>> commandBuffers );
+  void ExecuteCommands( const std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>>& commandBuffers );
+
+  /**
+   * Executes secondary command buffers within primary command buffer
+   * @param commandBuffers
+   */
+  void ExecuteCommands( const std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>>& commandBuffers, uint32_t offset, uint32_t count );
 
   /**
    * Copies buffer into the specified image
index 52e1ec1..b28e3c5 100644 (file)
@@ -791,7 +791,7 @@ Graphics::CreateInstance( const std::vector< const char* >& extensions,
     info.setEnabledLayerCount(0);
   }
 #else
-  //info.setEnabledLayerCount(0);
+  info.setEnabledLayerCount(0);
 #endif
 
   mInstance = VkAssert(vk::createInstance(info, *mAllocator));
index 0d9599c..eea2f6c 100644 (file)
@@ -517,9 +517,6 @@ struct Swapchain::Impl
   {
     auto& swapBuffer = mSwapchainBuffer[mCurrentBufferIndex];
 
-    // end render pass
-    EndPrimaryRenderPass( swapBuffer );
-
     // end command buffer
     swapBuffer.masterCmdBuffer->End();
 
index 36af143..c244e3f 100644 (file)
@@ -1002,50 +1002,32 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
-      unsigned int bitMask = mSceneObject->GetBlendingOptions();
-      BlendingOptions blendingOptions;
-      blendingOptions.SetBitmask( bitMask );
-      value = static_cast<int>( blendingOptions.GetBlendEquationRgb() );
+      value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
       break;
     }
     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
     {
-      unsigned int bitMask = mSceneObject->GetBlendingOptions();
-      BlendingOptions blendingOptions;
-      blendingOptions.SetBitmask( bitMask );
-      value = static_cast<int>( blendingOptions.GetBlendEquationAlpha() );
+      value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
       break;
     }
     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
     {
-      unsigned int bitMask = mSceneObject->GetBlendingOptions();
-      BlendingOptions blendingOptions;
-      blendingOptions.SetBitmask( bitMask );
-      value = static_cast<int>( blendingOptions.GetBlendSrcFactorRgb() );
+      value = static_cast<int>( mBlendingOptions.GetBlendSrcFactorRgb() );
       break;
     }
     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
     {
-      unsigned int bitMask = mSceneObject->GetBlendingOptions();
-      BlendingOptions blendingOptions;
-      blendingOptions.SetBitmask( bitMask );
-      value = static_cast<int>( blendingOptions.GetBlendDestFactorRgb() );
+      value = static_cast<int>( mBlendingOptions.GetBlendDestFactorRgb() );
       break;
     }
     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
     {
-      unsigned int bitMask = mSceneObject->GetBlendingOptions();
-      BlendingOptions blendingOptions;
-      blendingOptions.SetBitmask( bitMask );
-      value = static_cast<int>( blendingOptions.GetBlendSrcFactorAlpha() );
+      value = static_cast<int>( mBlendingOptions.GetBlendSrcFactorAlpha() );
       break;
     }
     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
     {
-      unsigned int bitMask = mSceneObject->GetBlendingOptions();
-      BlendingOptions blendingOptions;
-      blendingOptions.SetBitmask( bitMask );
-      value = static_cast<int>( blendingOptions.GetBlendDestFactorAlpha() );
+      value = static_cast<int>( mBlendingOptions.GetBlendDestFactorAlpha() );
       break;
     }
     case Dali::Renderer::Property::BLEND_COLOR:
index 4b814f3..9474009 100644 (file)
@@ -17,9 +17,9 @@
 
 // CLASS HEADER
 #include <dali/internal/update/graphics/graphics-algorithms.h>
+#include <dali/internal/update/nodes/scene-graph-layer.h>
 
 // EXTERNAL INCLUDES
-#include <glm/glm.hpp>
 #include <dali/graphics-api/graphics-api-controller.h>
 #include <dali/graphics-api/graphics-api-render-command.h>
 
@@ -48,17 +48,65 @@ static constexpr float CLIP_MATRIX_DATA[] = {
 static const Matrix CLIP_MATRIX(CLIP_MATRIX_DATA);
 
 
+
+constexpr Graphics::API::BlendFactor ConvertBlendFactor( BlendFactor::Type blendFactor )
+{
+  switch( blendFactor )
+  {
+    case BlendFactor::ZERO:
+      return Graphics::API::BlendFactor::ZERO;
+    case BlendFactor::ONE:
+      return Graphics::API::BlendFactor::ONE;
+    case BlendFactor::SRC_COLOR:
+      return Graphics::API::BlendFactor::SRC_COLOR;
+    case BlendFactor::ONE_MINUS_SRC_COLOR:
+      return Graphics::API::BlendFactor::ONE_MINUS_SRC_COLOR;
+    case BlendFactor::SRC_ALPHA:
+      return Graphics::API::BlendFactor::SRC_ALPHA;
+    case BlendFactor::ONE_MINUS_SRC_ALPHA:
+      return Graphics::API::BlendFactor::ONE_MINUS_SRC_ALPHA;
+    case BlendFactor::DST_ALPHA:
+      return Graphics::API::BlendFactor::DST_ALPHA;
+    case BlendFactor::ONE_MINUS_DST_ALPHA:
+      return Graphics::API::BlendFactor::ONE_MINUS_DST_ALPHA;
+    case BlendFactor::DST_COLOR:
+      return Graphics::API::BlendFactor::DST_COLOR;
+    case BlendFactor::ONE_MINUS_DST_COLOR:
+      return Graphics::API::BlendFactor::ONE_MINUS_DST_COLOR;
+    case BlendFactor::SRC_ALPHA_SATURATE:
+      return Graphics::API::BlendFactor::SRC_ALPHA_SATURATE;
+    case BlendFactor::CONSTANT_COLOR:
+      return Graphics::API::BlendFactor::CONSTANT_COLOR;
+    case BlendFactor::ONE_MINUS_CONSTANT_COLOR:
+      return Graphics::API::BlendFactor::ONE_MINUS_CONSTANT_COLOR;
+    case BlendFactor::CONSTANT_ALPHA:
+      return Graphics::API::BlendFactor::CONSTANT_ALPHA;
+    case BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
+      return Graphics::API::BlendFactor::ONE_MINUS_CONSTANT_ALPHA;
+  }
+  return Graphics::API::BlendFactor{};
+}
+
+constexpr Graphics::API::BlendOp ConvertBlendEquation( BlendEquation::Type blendEquation )
+{
+  switch( blendEquation )
+  {
+    case BlendEquation::ADD:
+      return Graphics::API::BlendOp::ADD;
+    case BlendEquation::SUBTRACT:
+      return Graphics::API::BlendOp::SUBTRACT;
+    case BlendEquation::REVERSE_SUBTRACT:
+      return Graphics::API::BlendOp::REVERSE_SUBTRACT;
+  }
+  return Graphics::API::BlendOp{};
+}
+
 void SubmitRenderItemList( Graphics::API::Controller&           graphics,
                            BufferIndex                          bufferIndex,
                            Matrix                               viewProjection,
                            RenderInstruction&                   instruction,
                            const RenderList&                    renderItemList )
 {
-  // TODO: @todo Set shaders and other properties
-  //commandBuilder.Set( );
-
-  // TODO: @todo Clipping...
-  //using InternalTextureSet = Dali::Internal::SceneGraph::TextureSet;
   auto numberOfRenderItems = renderItemList.Count();
 
   const auto viewMatrix = instruction.GetViewMatrix( bufferIndex );
@@ -97,6 +145,7 @@ void SubmitRenderItemList( Graphics::API::Controller&           graphics,
       cmd.BindRenderTarget(renderTargetBinding);
 
       auto opacity = sgRenderer->GetOpacity( bufferIndex );
+
       if( sgRenderer->IsPreMultipliedAlphaEnabled() )
       {
         float alpha = color.a * opacity;
@@ -112,14 +161,8 @@ void SubmitRenderItemList( Graphics::API::Controller&           graphics,
       Matrix::Multiply(mvp2, mvp, CLIP_MATRIX);
       sgRenderer->WriteUniform("uModelMatrix", item.mModelMatrix);
       sgRenderer->WriteUniform("uMvpMatrix", mvp2);
-
       sgRenderer->WriteUniform("uViewMatrix", *viewMatrix);
       sgRenderer->WriteUniform("uModelView", item.mModelViewMatrix);
-
-
-
-     // sgRenderer->WriteUniform("uNormalMatrix", normal);
-
       sgRenderer->WriteUniform("uProjection", vulkanProjectionMatrix);
       sgRenderer->WriteUniform("uSize", item.mSize);
       sgRenderer->WriteUniform("uColor", color );
@@ -152,22 +195,224 @@ void SubmitInstruction( Graphics::API::Controller& graphics,
 }
 } // namespace
 
-void SubmitRenderInstructions( Graphics::API::Controller&  graphics,
+
+
+bool PrepareGraphicsPipeline( Graphics::API::Controller& controller,
+                              RenderInstruction& instruction,
+                              const RenderList* renderList,
+                              RenderItem& item,
+                              BufferIndex bufferIndex )
+{
+  using namespace Dali::Graphics::API;
+
+  // for each renderer within node
+  for( auto rendererIndex = 0u; rendererIndex < item.mNode->GetRendererCount(); ++rendererIndex )
+  {
+    // vertex input state
+    VertexInputState vi{};
+
+    auto *renderer = item.mNode->GetRendererAt(rendererIndex);
+    auto *geometry = renderer->GetGeometry();
+    auto gfxShader = renderer->GetShader()
+                             .GetGfxObject();
+
+    if( !gfxShader.Exists() )
+    {
+      continue;
+    }
+    /**
+     * Prepare vertex attribute buffer bindings
+     */
+    uint32_t                                                    bindingIndex{0u};
+    std::vector<Graphics::API::Accessor<Graphics::API::Buffer>> vertexBuffers{};
+
+    for (auto &&vertexBuffer : geometry->GetVertexBuffers())
+    {
+      vertexBuffers.push_back(vertexBuffer->GetGfxObject());
+      auto attributeCountInForBuffer = vertexBuffer->GetAttributeCount();
+
+      // update vertex buffer if necessary
+      vertexBuffer->Update(controller);
+
+      // store buffer binding
+      vi.bufferBindings
+        .emplace_back(vertexBuffer->GetFormat()
+                                  ->size, VertexInputRate::PER_VERTEX);
+
+      for (auto i = 0u; i < attributeCountInForBuffer; ++i)
+      {
+        // create attribute description
+        vi.attributes
+          .emplace_back(
+            gfxShader.Get()
+                     .GetVertexAttributeLocation(vertexBuffer->GetAttributeName(i)),
+            bindingIndex, (vertexBuffer->GetFormat()
+                                       ->components[i]).offset,
+            VertexInputFormat::UNDEFINED);
+
+      }
+      bindingIndex++;
+    }
+
+    // Invalid input attributes!
+    if (gfxShader
+          .Get()
+          .GetVertexAttributeLocations()
+          .size() != vi.attributes
+                       .size())
+      continue; // incompatible pipeline!
+
+    // set optional index buffer
+    auto topology         = PrimitiveTopology::TRIANGLE_STRIP;
+    auto geometryTopology = geometry->GetType();
+    switch (geometryTopology)
+    {
+      case Dali::Geometry::Type::TRIANGLE_STRIP:
+      {
+        topology = PrimitiveTopology::TRIANGLE_STRIP;
+        break;
+      }
+      default:
+      {
+        topology = PrimitiveTopology::TRIANGLE_LIST;
+      }
+    }
+
+    /**
+     * 1. DEPTH MDOE
+     */
+    // use correct depth mode
+    DepthStencilState depthStencilState;
+    depthStencilState.SetDepthTestEnable(false)
+                     .SetDepthCompareOp(CompareOp::GREATER_OR_EQUAL);
+
+    if ((renderer->GetDepthTestMode() == DepthTestMode::AUTO && !renderList->GetSourceLayer()
+                                                                           ->IsDepthTestDisabled())
+        || (renderer->GetDepthTestMode() == DepthTestMode::ON))
+    {
+      depthStencilState.SetDepthTestEnable(true);
+      if (renderer->GetDepthWriteMode() == DepthWriteMode::ON)
+      {
+        depthStencilState.SetDepthWriteEnable(true);
+      }
+    }
+
+    /**
+     * 2. BLENDING
+     */
+    ColorBlendState colorBlendState{};
+    colorBlendState.SetBlendEnable(false);
+    if( renderer->GetBlendMode() != BlendMode::OFF)
+    {
+      colorBlendState.SetBlendEnable(true);
+      const auto& options = renderer->GetBlendingOptions();
+      colorBlendState
+        .SetSrcColorBlendFactor(ConvertBlendFactor(options.GetBlendSrcFactorRgb()))
+        .SetSrcAlphaBlendFactor(ConvertBlendFactor(options.GetBlendSrcFactorAlpha()))
+        .SetDstColorBlendFactor(ConvertBlendFactor(options.GetBlendDestFactorRgb()))
+        .SetDstAlphaBlendFactor(ConvertBlendFactor(options.GetBlendDestFactorAlpha()))
+        .SetColorBlendOp(ConvertBlendEquation(options.GetBlendEquationRgb()))
+        .SetAlphaBlendOp(ConvertBlendEquation(options.GetBlendEquationAlpha()));
+    }
+
+    /**
+     * 3. VIEWPORT
+     */
+    ViewportState viewportState{};
+    if (instruction.mIsViewportSet)
+    {
+      viewportState.SetViewport({float(instruction.mViewport
+                                                  .x), float(instruction.mViewport
+                                                                        .y),
+                                  float(instruction.mViewport
+                                                   .width), float(instruction.mViewport
+                                                                             .height),
+                                  0.0, 1.0});
+    }
+    else
+    {
+      viewportState.SetViewport({0.0, 0.0, 0.0, 0.0,
+                                  0.0, 1.0});
+    }
+
+
+    // create pipeline
+    auto pipeline = controller.CreatePipeline(controller.GetPipelineFactory()
+
+                // vertex input
+              .SetVertexInputState(vi)
+
+                // shaders
+              .SetShaderState(ShaderState()
+                                .SetShaderProgram(gfxShader.Get()))
+
+                // input assembly
+              .SetInputAssemblyState(InputAssemblyState()
+                                       .SetTopology(topology)
+                                       .SetPrimitiveRestartEnable(true))
+
+                // viewport ( if zeroes then framebuffer size used )
+              .SetViewportState(viewportState)
+
+                // depth stencil
+              .SetDepthStencilState(depthStencilState)
+
+
+                // color blend
+              .SetColorBlendState(colorBlendState
+                                    .SetColorComponentsWriteBits(0xff)
+                                    .SetLogicOpEnable(false))
+
+                // rasterization
+              .SetRasterizationState(RasterizationState()
+                                       .SetCullMode(CullMode::NONE)
+                                       .SetPolygonMode(PolygonMode::FILL)
+                                       .SetFrontFace(FrontFace::CLOCKWISE)));
+
+    // bind pipeline to the renderer
+    renderer->BindPipeline(std::move(pipeline));
+  }
+
+  return true;
+}
+
+void PrepareRendererPipelines( Graphics::API::Controller& controller,
                                RenderInstructionContainer& renderInstructions,
-                               BufferIndex                 bufferIndex )
+                               BufferIndex bufferIndex )
 {
-  graphics.BeginFrame();
+  for( auto i = 0u; i < renderInstructions.Count( bufferIndex ); ++i )
+  {
+    RenderInstruction &ri = renderInstructions.At(bufferIndex, i);
+    for (auto renderListIndex = 0u; renderListIndex < ri.RenderListCount(); ++renderListIndex)
+    {
+      const auto *renderList = ri.GetRenderList(renderListIndex);
+      for (auto renderItemIndex = 0u; renderItemIndex < renderList->Count(); ++renderItemIndex)
+      {
+        auto &item = renderList->GetItem(renderItemIndex);
+        PrepareGraphicsPipeline(controller, ri, renderList, item, bufferIndex);
+      }
+    }
+  }
+}
 
+void SubmitRenderInstructions( Graphics::API::Controller&  controller,
+                               RenderInstructionContainer& renderInstructions,
+                               BufferIndex                 bufferIndex )
+{
+  PrepareRendererPipelines( controller, renderInstructions, bufferIndex );
 
   auto numberOfInstructions = renderInstructions.Count( bufferIndex );
+
+  controller.BeginFrame();
+
   for( size_t i = 0; i < numberOfInstructions; ++i )
   {
     RenderInstruction& instruction = renderInstructions.At( bufferIndex, i );
 
-    SubmitInstruction( graphics, bufferIndex, instruction );
+    SubmitInstruction( controller, bufferIndex, instruction );
   }
 
-  graphics.EndFrame( );
+  controller.EndFrame();
 }
 
 } // namespace SceneGraph
index e73143a..eb3e792 100644 (file)
@@ -715,8 +715,8 @@ void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
 
 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
 {
-  const unsigned int rendererCount = mImpl->renderers.Count();
-  for( unsigned int i = 0; i < rendererCount; ++i )
+  auto rendererCount = mImpl->renderers.Count();
+  for( auto i = 0u; i < rendererCount; ++i )
   {
     //Apply constraints
     ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
@@ -824,6 +824,8 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
       cameraIterator->Update( bufferIndex );
     }
 
+    auto* impl = mImpl.get();
+    impl = impl;
     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
     //reset the update buffer index and make sure there is enough room in the instruction container
     if( mImpl->renderersAdded )
@@ -854,8 +856,12 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
                                               isRenderingToFbo );
         }
       }
+
+      // Prepare pipelines
+
+
       // generate graphics objects
-      (*mImpl);
+
       SubmitRenderInstructions( mImpl->graphics.GetController(), mImpl->renderInstructions, bufferIndex );
     }
   }
@@ -940,7 +946,9 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
 
 void UpdateManager::SetBackgroundColor( const Vector4& color )
 {
-  DALI_ASSERT_ALWAYS( true && "GRAPHICS: FIXME" );
+  mImpl->taskList.GetTasks()[0]->SetClearEnabled( true );
+  mImpl->taskList.GetTasks()[0]->SetClearColor( 0, color );
+  mImpl->taskList.GetTasks()[0]->SetClearColor( 1, color );
 }
 
 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
index 6da52cc..5a0838e 100644 (file)
@@ -119,8 +119,8 @@ Renderer::Renderer()
   mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
   mIndexedDrawFirstElement( 0u ),
   mIndexedDrawElementsCount( 0u ),
-  mBlendBitmask( 0u ),
   mRegenerateUniformMap( 0u ),
+  mBlendOptions(),
   mDepthFunction( DepthFunction::LESS ),
   mFaceCullingMode( FaceCullingMode::NONE ),
   mBlendMode( BlendMode::AUTO ),
@@ -223,49 +223,16 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
     return;
   }
 
-  using Graphics::API::Pipeline;
-
-  // vertex input state
-  VertexInputState vi{};
   /**
    * Prepare vertex attribute buffer bindings
    */
-  uint32_t bindingIndex{0u};
   std::vector<Graphics::API::Accessor<Graphics::API::Buffer>> vertexBuffers{};
 
   for(auto&& vertexBuffer : mGeometry->GetVertexBuffers())
   {
     vertexBuffers.push_back( vertexBuffer->GetGfxObject() );
-    auto attributeCountInForBuffer = vertexBuffer->GetAttributeCount();
-
-    // update vertex buffer if necessary
-    vertexBuffer->Update(controller);
-
-    // store buffer binding
-    vi.bufferBindings
-      .emplace_back( vertexBuffer->GetFormat()->size, VertexInputRate::PER_VERTEX);
-
-    for (auto i = 0u; i < attributeCountInForBuffer; ++i)
-    {
-      // create attribute description
-      vi.attributes
-        .emplace_back(
-          gfxShader.Get().GetVertexAttributeLocation( vertexBuffer->GetAttributeName( i ) ),
-          bindingIndex, (vertexBuffer->GetFormat()->components[i]).offset,
-                      VertexInputFormat::UNDEFINED);
-
-    }
-    bindingIndex++;
   }
 
-
-  // Invalid input attributes!
-  if (mShader->GetGfxObject()
-             .Get()
-             .GetVertexAttributeLocations()
-             .size() != vi.attributes.size())
-    return;
-
   auto &shader = mShader->GetGfxObject().Get();
   auto uboCount = shader.GetUniformBlockCount();
 
@@ -418,21 +385,6 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
 
   // set optional index buffer
   bool usesIndexBuffer{false};
-  auto topology  = PrimitiveTopology::TRIANGLE_STRIP;
-  auto geometryTopology = mGeometry->GetType();
-  switch (geometryTopology)
-  {
-    case Dali::Geometry::Type::TRIANGLE_STRIP:
-    {
-      topology = PrimitiveTopology::TRIANGLE_STRIP;
-      break;
-    }
-    default:
-    {
-      topology = PrimitiveTopology::TRIANGLE_LIST;
-    }
-  }
-
   if ((usesIndexBuffer = mGeometry->HasIndexBuffer()))
   {
     mGfxRenderCommand->BindIndexBuffer(Graphics::API::RenderCommand::IndexBufferBinding()
@@ -441,62 +393,10 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
     );
   }
 
-
   mGfxRenderCommand->PushConstants( std::move(pushConstantsBindings) );
   mGfxRenderCommand->BindVertexBuffers( std::move( vertexBuffers ) );
   mGfxRenderCommand->BindTextures( std::move(textureBindings) );
 
-  // create pipeline
-  if(!mGfxPipeline)
-  {
-    mGfxPipeline = controller.CreatePipeline(controller.GetPipelineFactory()
-
-                                                       // vertex input
-                                                       .SetVertexInputState( vi )
-
-                                                       // shaders
-                                                       .SetShaderState( ShaderState()
-                                                                                  .SetShaderProgram( shader ))
-
-                                                       // input assembly
-                                                       .SetInputAssemblyState( InputAssemblyState()
-                                                                                  .SetTopology( topology )
-                                                                                  .SetPrimitiveRestartEnable( true ))
-
-                                                         // viewport ( if zeroes then framebuffer size used )
-                                                       .SetViewportState( ViewportState()
-                                                                                  .SetViewport( { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 } ))
-
-                                                       // depth stencil
-                                                       .SetDepthStencilState( DepthStencilState()
-                                                                                  .SetDepthTestEnable(
-                                                                                    mDepthTestMode != DepthTestMode::ON ? false : true
-                                                                                  )
-                                                       .SetDepthWriteEnable( true )
-                                                       .SetDepthCompareOp( CompareOp::GREATER_OR_EQUAL ))
-
-
-                                                       // color blend
-                                                       .SetColorBlendState( ColorBlendState()
-                                                                                  .SetBlendEnable( mBlendMode != BlendMode::OFF ? true : false  )
-                                                                                  .SetColorComponentsWriteBits( 0xff )
-                                                                                  .SetSrcColorBlendFactor( Graphics::API::BlendFactor::SRC_ALPHA )
-                                                                                  .SetDstColorBlendFactor( Graphics::API::BlendFactor::ONE_MINUS_SRC_ALPHA )
-                                                                                  .SetSrcAlphaBlendFactor( Graphics::API::BlendFactor::ONE )
-                                                                                  .SetDstAlphaBlendFactor( Graphics::API::BlendFactor::ONE_MINUS_SRC_ALPHA )
-                                                                                  .SetColorBlendOp( BlendOp::ADD )
-                                                                                  .SetAlphaBlendOp( BlendOp::ADD )
-                                                                                  .SetLogicOpEnable( false ))
-
-                                                       // rasterization
-                                                       .SetRasterizationState( RasterizationState()
-                                                                                  .SetCullMode( CullMode::NONE )
-                                                                                  .SetPolygonMode( PolygonMode::FILL )
-                                                                                  .SetFrontFace( FrontFace::CLOCKWISE )));
-  }
-
-  // bind pipeline
-  mGfxRenderCommand->BindPipeline( *mGfxPipeline.get() );
   if(usesIndexBuffer)
   {
     mGfxRenderCommand->Draw(std::move(Graphics::API::RenderCommand::DrawCommand{}
@@ -520,6 +420,11 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
 
 void Renderer::WriteUniform( const std::string& name, const void* data, uint32_t size )
 {
+  if( !mShader->GetGfxObject().Exists() )
+  {
+    // Invalid pipeline
+    return;
+  }
   auto& gfxShader = mShader->GetGfxObject().Get();
   auto uniformInfo = Graphics::API::ShaderDetails::UniformInfo{};
   if( gfxShader.GetNamedUniform( name, uniformInfo ) )
@@ -588,17 +493,25 @@ BlendMode::Type Renderer::GetBlendMode() const
   return mBlendMode;
 }
 
+void Renderer::SetBlendingOptions( const BlendingOptions& options )
+{
+  if( mBlendOptions.GetBitmask() != options.GetBitmask())
+  {
+    mBlendOptions.SetBitmask( options.GetBitmask() );
+  }
+}
+
 void Renderer::SetBlendingOptions( unsigned int options )
 {
-  if( mBlendBitmask != options)
+  if( options != mBlendOptions.GetBitmask() )
   {
-    mBlendBitmask = options;
+    mBlendOptions.SetBitmask( options );
   }
 }
 
-unsigned int Renderer::GetBlendingOptions() const
+const BlendingOptions& Renderer::GetBlendingOptions() const
 {
-  return mBlendBitmask;
+  return mBlendOptions;
 }
 
 void Renderer::SetBlendColor( const Vector4& blendColor )
index e80d6ab..4987366 100644 (file)
@@ -179,10 +179,15 @@ public:
   void SetBlendingOptions( unsigned int options );
 
   /**
+   * Set the blending options. This should only be called from the update thread.
+   * @param[in] options blending options.
+   */
+  void SetBlendingOptions( const BlendingOptions& options );
+  /**
    * Get the blending options
    * @return The the blending mode
    */
-  unsigned int GetBlendingOptions() const;
+  const BlendingOptions& GetBlendingOptions() const;
 
   /**
    * Set the blend color for blending operation
@@ -388,6 +393,12 @@ public:
    */
   void TextureSetDeleted();
 
+  void BindPipeline( std::unique_ptr<Graphics::API::Pipeline> pipeline )
+  {
+    mGfxPipeline = std::move(pipeline);
+    mGfxRenderCommand->BindPipeline( *mGfxPipeline.get() );
+  }
+
 public: // Implementation of ConnectionChangePropagator
   /**
    * @copydoc ConnectionChangePropagator::AddObserver
@@ -449,13 +460,17 @@ private:
 
   size_t                       mIndexedDrawFirstElement;          ///< first element index to be drawn using indexed draw
   size_t                       mIndexedDrawElementsCount;         ///< number of elements to be drawn using indexed draw
-  unsigned int                 mBlendBitmask;                     ///< The bitmask of blending options
+
   unsigned int                 mRegenerateUniformMap;             ///< 2 if the map should be regenerated, 1 if it should be copied.
   unsigned int                 mResendFlag;                       ///< Indicate whether data should be resent to the renderer
 
+  BlendingOptions              mBlendOptions;                     ///< The blending options
+
   DepthFunction::Type          mDepthFunction:3;                  ///< Local copy of the depth function
   FaceCullingMode::Type        mFaceCullingMode:2;                ///< Local copy of the mode of face culling
+
   BlendMode::Type              mBlendMode:2;                      ///< Local copy of the mode of blending
+
   DepthWriteMode::Type         mDepthWriteMode:2;                 ///< Local copy of the depth write mode
   DepthTestMode::Type          mDepthTestMode:2;                  ///< Local copy of the depth test mode
 
index 1b9f593..a54665d 100644 (file)
@@ -48,11 +48,17 @@ void Shader::Initialize( Integration::Graphics::Graphics& graphics, ShaderCache&
   mShaderCache = &shaderCache;
 }
 
+const Graphics::API::Accessor<Graphics::API::Shader>& Shader::GetGfxObject() const
+{
+  return mGraphicsShader;
+}
+
 Graphics::API::Accessor<Graphics::API::Shader>& Shader::GetGfxObject()
 {
   return mGraphicsShader;
 }
 
+
 void Shader::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
 {
   mConnectionObservers.Add(observer);
index aafd412..7ca7f93 100644 (file)
@@ -93,6 +93,12 @@ public:
    * Get the graphics shader object
    * @return the graphics shader object
    */
+  const Graphics::API::Accessor<Graphics::API::Shader>& GetGfxObject() const;
+
+  /**
+   * Get the graphics shader object
+   * @return the graphics shader object
+   */
   Graphics::API::Accessor<Graphics::API::Shader>& GetGfxObject();
 
 public: // Messages