Added RenderPass and RenderTarget support 15/255315/17
authoradam.b <adam.b@samsung.com>
Thu, 1 Apr 2021 12:44:13 +0000 (13:44 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Tue, 13 Apr 2021 10:58:17 +0000 (11:58 +0100)
Change-Id: I324b4f47c389fbef6c6b18f91acee2948cd5fa48

15 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h
automated-tests/src/dali/dali-test-suite-utils/test-graphics-pipeline.cpp
dali/graphics-api/graphics-command-buffer.h
dali/graphics-api/graphics-pipeline-create-info.h
dali/graphics-api/graphics-render-pass-create-info.h
dali/graphics-api/graphics-render-target-create-info.h
dali/graphics-api/graphics-render-target.h
dali/graphics-api/graphics-types.h
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/renderers/render-frame-buffer.cpp
dali/internal/render/renderers/render-frame-buffer.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h

index c10c3f1..4f8a184 100644 (file)
@@ -509,8 +509,8 @@ public:
   }
 
   void BeginRenderPass(
-    Graphics::RenderPass&             renderPass,
-    Graphics::RenderTarget&           renderTarget,
+    Graphics::RenderPass*             renderPass,
+    Graphics::RenderTarget*           renderTarget,
     Graphics::Extent2D                renderArea,
     std::vector<Graphics::ClearValue> clearValues) override
   {
@@ -531,6 +531,11 @@ public:
     mCallStack.PushCall("EndRenderPass", "");
   }
 
+  void ExecuteCommandBuffers(std::vector<CommandBuffer*>&& commandBuffers) override
+  {
+    mCallStack.PushCall("ExecuteCommandBuffers", "");
+  }
+
   void Draw(
     uint32_t vertexCount,
     uint32_t instanceCount,
index 83d535c..9e80f8f 100644 (file)
@@ -32,9 +32,6 @@ TestGraphicsPipeline::TestGraphicsPipeline(TestGlAbstraction& gl, const Graphics
   if(createInfo.viewportState)
     viewportState = *createInfo.viewportState;
 
-  if(createInfo.framebufferState)
-    framebufferState = *createInfo.framebufferState;
-
   if(createInfo.depthStencilState)
     depthStencilState = *createInfo.depthStencilState;
 
index 0b81870..7056e47 100644 (file)
@@ -21,9 +21,7 @@
 // INTERNAL INCLUDES
 #include "graphics-types.h"
 
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics
 {
 class Buffer;
 class Pipeline;
@@ -179,13 +177,14 @@ public:
    * Calling EndRenderPass() is necessary to finalize the render pass.
    *
    * @param[in] renderPass valid render pass object
-   * @param[in] renderTarget valid render target
+   * @param[in] renderTarget valid render target, must not be used when framebuffer set
+   * @param[in] framebuffer valid framebuffer, must not be used with renderTarget
    * @param[in] renderArea area to draw
    * @param[in] clearValues clear values (compatible with renderpass spec)
    */
   virtual void BeginRenderPass(
-    RenderPass&             renderPass,
-    RenderTarget&           renderTarget,
+    RenderPass*             renderPass,
+    RenderTarget*           renderTarget,
     Extent2D                renderArea,
     std::vector<ClearValue> clearValues) = 0;
 
@@ -201,6 +200,13 @@ public:
   virtual void EndRenderPass() = 0;
 
   /**
+   * @brief Executes a list of secondary command buffers
+   *
+   * @param[in] commandBuffers List of buffers to execute
+   */
+  virtual void ExecuteCommandBuffers( std::vector<CommandBuffer*>&& commandBuffers ) = 0;
+
+  /**
    * @brief Draw primitives
    *
    * @param[in] vertexCount number of vertices
@@ -296,7 +302,6 @@ protected:
   CommandBuffer(CommandBuffer&&) = default;
   CommandBuffer& operator=(CommandBuffer&&) = default;
 };
-} // Namespace Graphics
 } // Namespace Dali
 
 #endif
index d4b4014..0ddcbd7 100644 (file)
@@ -93,18 +93,6 @@ struct PipelineCreateInfo
   }
 
   /**
-   * @brief Sets the framebuffer state.
-   *
-   * @param[in] value pointer to valid framebuffer state structure
-   * @return reference to this structure
-   */
-  auto& SetFramebufferState(FramebufferState* value)
-  {
-    framebufferState = value;
-    return *this;
-  }
-
-  /**
    * @brief Sets the base pipeline.
    *
    * Setting base pipeline allows inheriting that pipeline state
@@ -208,7 +196,6 @@ struct PipelineCreateInfo
   ProgramState*            programState{nullptr};
   ColorBlendState*         colorBlendState{nullptr};
   ViewportState*           viewportState{nullptr};
-  FramebufferState*        framebufferState{nullptr};
   Pipeline*                basePipeline{nullptr};
   DepthStencilState*       depthStencilState{nullptr};
   RasterizationState*      rasterizationState{nullptr};
index 22152e3..04cd95f 100644 (file)
  *
  */
 
-// EXTERNAL INCLUDES
-#include <memory>
-
 // INTERNAL INCLUDES
 #include "graphics-render-pass.h"
 #include "graphics-types.h"
 
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics
 {
 class RenderTarget;
 /**
@@ -55,14 +50,14 @@ struct RenderPassCreateInfo
   }
 
   /**
-   * @brief Binds render target to render pass
+   * @brief Sets array of attachment descriptions
    *
-   * @param[in] value valid RenderTarget object
+   * @param[in] value pointer valid array of attachment descriptions
    * @return reference to this structure
    */
-  auto& SetRenderTarget(RenderTarget* value)
+  auto& SetAttachments(const std::vector<AttachmentDescription>& value)
   {
-    renderTarget = value;
+    attachments = &value;
     return *this;
   }
 
@@ -81,12 +76,10 @@ struct RenderPassCreateInfo
 
   GraphicsStructureType type{GraphicsStructureType::RENDERPASS_CREATE_INFO_STRUCT};
   ExtensionCreateInfo*  nextExtension{nullptr};
-  RenderTarget*         renderTarget{nullptr};
-
+  const std::vector<AttachmentDescription>* attachments{nullptr};
   const AllocationCallbacks* allocationCallbacks{nullptr};
 };
 
-} // namespace Graphics
 } // namespace Dali
 
 #endif // DALI_GRAPHICS_FRAMEBUFFER_FACTORY_H
\ No newline at end of file
index 8ec8664..9cb92c3 100644 (file)
@@ -54,6 +54,58 @@ struct RenderTargetCreateInfo
   }
 
   /**
+   * @brief Sets surface associated with the RenderTarget
+   *
+   * The surface is a a pointer to any native surface object.
+   *
+   * @param[in] value Pointer to the native surface
+   * @return reference to this structure
+   */
+  auto& SetSurface( Surface* value )
+  {
+    surface = value;
+    return *this;
+  }
+
+  /**
+   * @brief Sets framebuffer associated with the RenderTarget
+   *
+   * The framebuffer and surface must not be set together.
+   *
+   * @param[in] value Pointer to the Framebuffer object
+   * @return reference to this structure
+   */
+  auto& SetFramebuffer( Framebuffer* value )
+  {
+    framebuffer = value;
+    return *this;
+  }
+
+  /**
+   * @brief Sets render target size
+   *
+   * @param[in] value Size of render target
+   * @return reference to this structure
+   */
+  auto& SetExtent( Extent2D value )
+  {
+    extent = value;
+    return *this;
+  }
+
+  /**
+   * @brief Sets pre-transform of the render target
+   *
+   * @param[in] value transform flags
+   * @return reference to this structure
+   */
+  auto& SetPreTransform( RenderTargetTransformFlags value )
+  {
+    preTransform = value;
+    return *this;
+  }
+
+  /**
    * @brief Sets allocation callbacks which will be used when object is created
    * and destroyed.
    *
@@ -66,8 +118,12 @@ struct RenderTargetCreateInfo
     return *this;
   }
 
-  GraphicsStructureType type{GraphicsStructureType::RENDER_TARGET_CREATE_INFO_STRUCT};
-  ExtensionCreateInfo*  nextExtension{nullptr};
+  GraphicsStructureType         type{GraphicsStructureType::RENDER_TARGET_CREATE_INFO_STRUCT};
+  Surface*                      surface{nullptr};
+  Framebuffer*                  framebuffer{nullptr};
+  Extent2D                      extent{};
+  RenderTargetTransformFlags    preTransform{0u};
+  ExtensionCreateInfo*          nextExtension{nullptr};
 
   const AllocationCallbacks* allocationCallbacks{nullptr};
 };
index fe291ad..a320119 100644 (file)
 
 #include "graphics-types.h"
 
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics
 {
+class Framebuffer;
 /**
  * @brief RenderTarget object binds to any presentable graphics output.
  */
@@ -42,7 +41,6 @@ protected:
   RenderTarget& operator=(RenderTarget&&) = default;
 };
 
-} // Namespace Graphics
 } // Namespace Dali
 
 #endif
\ No newline at end of file
index 1cffb5b..f32bffb 100644 (file)
@@ -1302,6 +1302,96 @@ enum class GraphicsStructureType : uint32_t
 };
 
 /**
+ * @brief Enum describes load operation associated
+ * with particular framebuffer attachment
+ */
+enum class AttachmentLoadOp
+{
+  LOAD, ///< Load previous content
+  CLEAR, ///< Clear the attachment
+  DONT_CARE ///< Let driver decide
+};
+
+/**
+ * @brief Enum describes store operation associated
+ * with particular framebuffer attachment
+ */
+enum class AttachmentStoreOp
+{
+  STORE, ///< Store content (color attachemnts)
+  DONT_CARE ///< Let driver decide (depth/stencil attachemnt with no intention of reading)
+};
+
+/**
+ * @brief The structure describes the read/write
+ * modes of a single framebuffer attachment
+ *
+ * The attachment description specifies what is going to
+ * happen to the attachment at the beginning and end of the
+ * render pass.
+ *
+ * The stencil operation is separated as it may be set
+ * independent from the depth component (use loadOp, storeOp
+ * to set up the depth component and stencilLoadOp, stencilStoreOp
+ * for stencil component).
+ */
+struct AttachmentDescription
+{
+  /**
+   * @brief Sets load operation for the attachment
+   *
+   * @param value Load operation
+   * @return this structure
+   */
+  auto& SetLoadOp( AttachmentLoadOp value )
+  {
+    loadOp = value;
+    return *this;
+  }
+
+  /**
+   * @brief Sets store operation for the attachment
+   *
+   * @param value Store operation
+   * @return this structure
+   */
+  auto& SetStoreOp( AttachmentStoreOp value )
+  {
+    storeOp = value;
+    return *this;
+  }
+
+  /**
+   * @brief Sets load operation for the stencil part of attachment
+   *
+   * @param value load operation
+   * @return this structure
+   */
+  auto& SetStencilLoadOp( AttachmentLoadOp value )
+  {
+    stencilLoadOp = value;
+    return *this;
+  }
+
+  /**
+   * @brief Sets store operation for the stencil part of attachment
+   *
+   * @param value store operation
+   * @return this structure
+   */
+  auto& SetStencilStoreOp( AttachmentStoreOp value )
+  {
+    stencilStoreOp = value;
+    return *this;
+  }
+
+  AttachmentLoadOp loadOp{};
+  AttachmentStoreOp storeOp{};
+  AttachmentLoadOp stencilLoadOp{};
+  AttachmentStoreOp stencilStoreOp{};
+};
+
+/**
  * @brief Helper function to be used by the extension developers
  *
  * The value of custom type must be unique and recognizable by the
@@ -1396,6 +1486,34 @@ struct DefaultDeleter
 };
 
 /**
+ * Surface type is just a void* to any native object.
+ */
+using Surface = void;
+
+/**
+ * @brief Enum describing preTransform of render target
+ */
+enum class RenderTargetTransformFlagBits
+{
+  TRANSFORM_IDENTITY_BIT = 0x00000001,
+  ROTATE_90_BIT = 0x00000002,
+  ROTATE_180_BIT = 0x00000004,
+  ROTATE_270_BIT = 0x00000008,
+  HORIZONTAL_MIRROR_BIT = 0x00000010,
+  HORIZONTAL_MIRROR_ROTATE_90_BIT = 0x00000020,
+  HORIZONTAL_MIRROR_ROTATE_180_BIT = 0x00000040,
+  HORIZONTAL_MIRROR_ROTATE_270_BIT = 0x00000080,
+};
+
+using RenderTargetTransformFlags = uint32_t;
+
+template<typename T>
+inline RenderTargetTransformFlags operator|(T flags, RenderTargetTransformFlagBits bit)
+{
+  return static_cast<RenderTargetTransformFlags>(flags) | static_cast<RenderTargetTransformFlags>(bit);
+}
+
+/**
  * unique_ptr defined in the Graphics scope
  */
 template<class T, class D = DefaultDeleter<T>>
index 5aa3c14..7ab6f37 100644 (file)
@@ -473,18 +473,6 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
   bool              usedStencilBuffer(false);
   bool              firstDepthBufferUse(true);
 
-  if(!mGraphicsCommandBuffer)
-  {
-    mGraphicsCommandBuffer = mGraphicsController.CreateCommandBuffer(
-      Graphics::CommandBufferCreateInfo()
-        .SetLevel(Graphics::CommandBufferLevel::SECONDARY),
-      nullptr);
-  }
-  else
-  {
-    mGraphicsCommandBuffer->Reset();
-  }
-
   mViewportRectangle = viewport;
   mGraphicsCommandBuffer->SetViewport(ViewportFromClippingBox(mViewportRectangle, orientation));
   mHasLayerScissor = false;
@@ -519,10 +507,11 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
   }
 
   // Submit scissor/viewport
-  Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
-  submitInfo.cmdBuffer.push_back(mGraphicsCommandBuffer.get());
-  mGraphicsController.SubmitCommandBuffers(submitInfo);
+  //Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
+  //submitInfo.cmdBuffer.push_back(mGraphicsCommandBuffer.get());
+  //mGraphicsController.SubmitCommandBuffers(submitInfo);
 
+  mGraphicsRenderItemCommandBuffers.clear();
   // Loop through all RenderList in the RenderList, set up any prerequisites to render them, then perform the render.
   for(uint32_t index = 0u; index < count; ++index)
   {
@@ -550,6 +539,8 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
     // The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
     SetupClipping(item, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction);
 
+
+
     if(DALI_LIKELY(item.mRenderer))
     {
       // Set up the depth buffer based on per-renderer flags if depth buffer is available
@@ -572,12 +563,21 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
         auto const MAX_QUEUE = item.mRenderer->GetDrawCommands().empty() ? 1 : DevelRenderer::RENDER_QUEUE_MAX;
         for(auto queue = 0u; queue < MAX_QUEUE; ++queue)
         {
-          // Render the item.
-          item.mRenderer->Render(context, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque, boundTextures, instruction, queue);
+          // Render the item. If rendered, add its command buffer into the list
+          if( item.mRenderer->Render(context, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque, boundTextures, instruction, queue) )
+          {
+            mGraphicsRenderItemCommandBuffers.emplace_back( item.mRenderer->GetGraphicsCommandBuffer() );
+          }
         }
       }
     }
   }
+
+  // Execute command buffers
+  if(!mGraphicsRenderItemCommandBuffers.empty())
+  {
+    mGraphicsCommandBuffer->ExecuteCommandBuffers( std::move(mGraphicsRenderItemCommandBuffers) );
+  }
 }
 
 RenderAlgorithms::RenderAlgorithms(Graphics::Controller& graphicsController)
@@ -587,6 +587,34 @@ RenderAlgorithms::RenderAlgorithms(Graphics::Controller& graphicsController)
 {
 }
 
+void RenderAlgorithms::ResetCommandBuffer()
+{
+  // Reset main command buffer
+  if(!mGraphicsCommandBuffer)
+  {
+    mGraphicsCommandBuffer = mGraphicsController.CreateCommandBuffer(
+      Graphics::CommandBufferCreateInfo()
+        .SetLevel(Graphics::CommandBufferLevel::SECONDARY),
+      nullptr);
+  }
+  else
+  {
+    mGraphicsCommandBuffer->Reset();
+  }
+
+  // Reset list of secondary buffers to submit
+  mGraphicsRenderItemCommandBuffers.clear();
+}
+
+void RenderAlgorithms::SubmitCommandBuffer()
+{
+  // Submit main command buffer
+  Graphics::SubmitInfo submitInfo;
+  submitInfo.cmdBuffer.push_back(  mGraphicsCommandBuffer.get() );
+  submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH;
+  mGraphicsController.SubmitCommandBuffers( submitInfo );
+}
+
 void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction&            instruction,
                                                 Context&                            context,
                                                 BufferIndex                         bufferIndex,
index d887a74..c7f6994 100644 (file)
@@ -72,6 +72,21 @@ public:
                                 const Rect<int>&                     rootClippingRect,
                                 int                                  orientation);
 
+  /**
+   * Resets main command buffer (per scene)
+   */
+  void ResetCommandBuffer();
+
+  /**
+   * Submits main command buffer (per scene)
+   */
+  void SubmitCommandBuffer();
+
+  [[nodiscard]] Graphics::CommandBuffer* GetMainCommandBuffer() const
+  {
+    return mGraphicsCommandBuffer.get();
+  }
+
 private:
   /**
    * @brief Calculate a 2D AABB (axis aligned bounding box) in screen space.
@@ -151,6 +166,8 @@ private:
   Graphics::Controller&                        mGraphicsController;
   Graphics::UniquePtr<Graphics::CommandBuffer> mGraphicsCommandBuffer{};
 
+  std::vector<Graphics::CommandBuffer*> mGraphicsRenderItemCommandBuffers{};
+
   ScissorStackType  mScissorStack;        ///< Contains the currently applied scissor hierarchy (so we can undo clips)
   Dali::ClippingBox mViewportRectangle;   ///< The viewport dimensions, used to translate AABBs to scissor coordinates
   bool              mHasLayerScissor : 1; ///< Marks if the currently process render instruction has a layer-based clipping region
index 3ff05d9..2bab722 100644 (file)
@@ -87,6 +87,10 @@ struct RenderManager::Impl
     threadPool->Initialize(1u);
 
     uniformBufferManager.reset(new Render::UniformBufferManager(&graphicsController));
+
+    // initialize main command buffer
+    auto info = Graphics::CommandBufferCreateInfo().SetLevel( Graphics::CommandBufferLevel::PRIMARY );
+    mainCommandBuffer = graphicsController.CreateCommandBuffer( info, nullptr );
   }
 
   ~Impl()
@@ -178,6 +182,12 @@ struct RenderManager::Impl
   std::unique_ptr<Dali::ThreadPool> threadPool;            ///< The thread pool
   Vector<Graphics::Texture*>        boundTextures;         ///< The textures bound for rendering
   Vector<Graphics::Texture*>        textureDependencyList; ///< The dependency list of binded textures
+
+  Graphics::UniquePtr<Graphics::CommandBuffer> mainCommandBuffer; ///< Main command buffer
+
+  Graphics::UniquePtr<Graphics::RenderPass> mainRenderPass; ///< Main renderpass
+
+
 };
 
 RenderManager* RenderManager::New(Graphics::Controller&               graphicsController,
@@ -489,6 +499,9 @@ void RenderManager::PreRender(Integration::RenderStatus& status, bool forceClear
 
   const bool haveInstructions = count > 0u;
 
+  // Reset main command buffer
+  mImpl->mainCommandBuffer->Reset();
+
   DALI_LOG_INFO(gLogFilter, Debug::General, "Render: haveInstructions(%s) || mImpl->lastFrameWasRendered(%s) || forceClear(%s)\n", haveInstructions ? "true" : "false", mImpl->lastFrameWasRendered ? "true" : "false", forceClear ? "true" : "false");
 
   // Only render if we have instructions to render, or the last frame was rendered (and therefore a clear is required).
@@ -787,6 +800,11 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
 void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect<int>& clippingRect)
 {
+  // Reset main algorithms command buffer
+  mImpl->renderAlgorithms.ResetCommandBuffer();
+
+  auto mainCommandBuffer = mImpl->renderAlgorithms.GetMainCommandBuffer();
+
   Internal::Scene&   sceneInternal = GetImplementation(scene);
   SceneGraph::Scene* sceneObject   = sceneInternal.GetSceneObject();
 
@@ -824,7 +842,27 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
     if(instruction.mFrameBuffer)
     {
+      auto& clearValues = instruction.mFrameBuffer->GetGraphicsRenderPassClearValues();
+      // todo: use no-clear renderpass instead (not implemented yet)
+
+      // Set the clear color for first color attachment
+      if( instruction.mIsClearColorSet )
+      {
+        clearValues[0].color = {
+          instruction.mClearColor.r,
+          instruction.mClearColor.g,
+          instruction.mClearColor.b,
+          instruction.mClearColor.a
+        };
+      }
       // offscreen buffer
+      mainCommandBuffer->BeginRenderPass(
+        instruction.mFrameBuffer->GetGraphicsRenderPass( Graphics::AttachmentLoadOp::CLEAR, Graphics::AttachmentStoreOp::STORE ),
+        instruction.mFrameBuffer->GetGraphicsRenderTarget(),
+        { instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() },
+        clearValues
+        );
+
       if(mImpl->currentContext != &mImpl->context)
       {
         // Switch to shared context for off-screen buffer
@@ -863,6 +901,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
     if(instruction.mFrameBuffer)
     {
+
       //instruction.mFrameBuffer->Bind(*mImpl->currentContext);
       // @todo Temporarily set per renderer per pipeline. Should use RenderPass instead
 
@@ -878,12 +917,19 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     }
 
     // @todo Should this be a command in it's own right?
+    // @todo yes
     if(!instruction.mFrameBuffer)
     {
       mImpl->currentContext->Viewport(surfaceRect.x,
                                       surfaceRect.y,
                                       surfaceRect.width,
                                       surfaceRect.height);
+      /*
+      mainCommandBuffer->SetViewport( {surfaceRect.x,
+                                        surfaceRect.y,
+                                        surfaceRect.width,
+                                        surfaceRect.height} );
+      */
     }
 
     // Clear the entire color, depth and stencil buffers for the default framebuffer, if required.
@@ -1080,6 +1126,10 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     {
       mImpl->currentContext->Flush();
     }
+
+    // End render pass
+    mainCommandBuffer->EndRenderPass();
+    mImpl->renderAlgorithms.SubmitCommandBuffer();
   }
 
   GLenum attachments[] = {GL_DEPTH, GL_STENCIL};
@@ -1088,6 +1138,9 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
 void RenderManager::PostRender(bool uploadOnly)
 {
+  // Submit main command buffer
+  //mImpl->renderAlgorithms.SubmitCommandBuffer();
+
   if(!uploadOnly)
   {
     if(mImpl->currentContext->IsSurfacelessContextSupported())
index b88a805..44f4345 100644 (file)
@@ -92,7 +92,58 @@ void FrameBuffer::Bind()
 {
   if(!mGraphicsObject)
   {
-    mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, nullptr);
+    mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, std::move(mGraphicsObject));
+
+    // Create render target
+    Graphics::RenderTargetCreateInfo rtInfo{};
+    rtInfo
+      .SetFramebuffer( mGraphicsObject.get() )
+      .SetExtent( {mWidth, mHeight} )
+      .SetPreTransform( 0 | Graphics::RenderTargetTransformFlagBits::TRANSFORM_IDENTITY_BIT );
+    mRenderTarget = mGraphicsController->CreateRenderTarget( rtInfo, std::move(mRenderTarget) );
+
+    std::vector<Graphics::AttachmentDescription> attachmentDescriptions;
+
+    // Default behaviour for color attachments is to CLEAR and STORE
+    //@todo Ideally, we should create new render pass whenever
+    //      the loadop, storeop changes and the list of such renderpasses
+    //      should be managed accordingly (as in Vulkan)
+    mClearValues.clear();
+    for(auto& att: mCreateInfo.colorAttachments )
+    {
+      if(att.texture)
+      {
+        Graphics::AttachmentDescription desc{};
+        desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR);
+        desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE);
+        attachmentDescriptions.push_back(desc);
+        mClearValues.emplace_back();
+      }
+    }
+
+    if(mCreateInfo.depthStencilAttachment.depthTexture)
+    {
+      Graphics::AttachmentDescription depthStencilDesc{};
+      depthStencilDesc.SetStencilLoadOp( Graphics::AttachmentLoadOp::CLEAR )
+      .SetStoreOp( Graphics::AttachmentStoreOp::DONT_CARE );
+      if(mCreateInfo.depthStencilAttachment.stencilTexture)
+      {
+        depthStencilDesc.SetStencilLoadOp( Graphics::AttachmentLoadOp::CLEAR)
+        .SetStoreOp( Graphics::AttachmentStoreOp::DONT_CARE);
+      }
+      mClearValues.emplace_back();
+      attachmentDescriptions.push_back(depthStencilDesc);
+    }
+
+    Graphics::RenderPassCreateInfo rpInfo{};
+    rpInfo.SetAttachments( attachmentDescriptions );
+
+    // Add default render pass (loadOp = clear)
+    mRenderPass.emplace_back( mGraphicsController->CreateRenderPass( rpInfo, nullptr ) );
+
+    // Add default render pass (loadOp = dontcare)
+    attachmentDescriptions[0].SetLoadOp( Graphics::AttachmentLoadOp::DONT_CARE );
+    mRenderPass.emplace_back( mGraphicsController->CreateRenderPass( rpInfo, nullptr ) );
   }
 }
 
@@ -106,6 +157,21 @@ uint32_t FrameBuffer::GetHeight() const
   return mHeight;
 }
 
+[[nodiscard]] Graphics::RenderPass* FrameBuffer::GetGraphicsRenderPass( Graphics::AttachmentLoadOp colorLoadOp,
+                                                                        Graphics::AttachmentStoreOp colorStoreOp ) const
+{
+  // clear only when requested
+  if( colorLoadOp == Graphics::AttachmentLoadOp::CLEAR )
+  {
+    return mRenderPass[0].get();
+  }
+  else
+  {
+    return mRenderPass[1].get();
+  }
+}
+
+
 } // namespace Render
 
 } // namespace Internal
index ce39488..01caa58 100644 (file)
@@ -121,6 +121,24 @@ public:
     return mGraphicsObject.get();
   }
 
+  [[nodiscard]] Graphics::RenderTarget* GetGraphicsRenderTarget() const
+  {
+    return mRenderTarget.get();
+  }
+
+  [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass( Graphics::AttachmentLoadOp colorLoadOp,
+                                                             Graphics::AttachmentStoreOp colorStoreOp ) const;
+
+  /**
+   * The function returns initialized array of clear values
+   * which then can be modified and assed to BeginRenderPass()
+   * command.
+   */
+  [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
+  {
+    return mClearValues;
+  }
+
 private:
   /**
    * @brief Undefined copy constructor. FrameBuffer cannot be copied
@@ -138,6 +156,19 @@ private:
 
   Graphics::FramebufferCreateInfo mCreateInfo;
 
+  // Render pass and render target
+
+  /**
+   * Render passes are created on fly depending on Load and Store operations
+   * The default render pass (most likely to be used) is the load = CLEAR
+   * amd store = STORE for color attachment.
+   */
+  std::vector<Graphics::UniquePtr<Graphics::RenderPass>> mRenderPass{};
+  Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr};
+
+  // clear colors
+  std::vector<Graphics::ClearValue> mClearValues{};
+
   uint32_t mWidth;
   uint32_t mHeight;
 
index 3e2d510..622031b 100644 (file)
@@ -570,7 +570,7 @@ void Renderer::Upload()
   mGeometry->Upload(*mGraphicsController);
 }
 
-void Renderer::Render(Context&                                             context,
+bool Renderer::Render(Context&                                             context,
                       BufferIndex                                          bufferIndex,
                       const SceneGraph::NodeDataProvider&                  node,
                       const Matrix&                                        modelMatrix,
@@ -586,7 +586,7 @@ void Renderer::Render(Context&                                             conte
   // Before doing anything test if the call happens in the right queue
   if(mDrawCommands.empty() && queueIndex > 0)
   {
-    return;
+    return false;
   }
 
   // Prepare commands
@@ -602,7 +602,7 @@ void Renderer::Render(Context&                                             conte
   // Have commands but nothing to be drawn - abort
   if(!mDrawCommands.empty() && commands.empty())
   {
-    return;
+    return false;
   }
 
   // Create command buffer if not present
@@ -661,7 +661,7 @@ void Renderer::Render(Context&                                             conte
   if(!program)
   {
     DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast<void*>(&mRenderDataProvider->GetShader()));
-    return;
+    return false;
   }
 
   // Temporarily create a pipeline here - this will be used for transporting
@@ -698,14 +698,16 @@ void Renderer::Render(Context&                                             conte
   // @todo We should return the command buffer(s) and let the calling method submit
   // If not drawn, then don't add command buffer to submit info, and if empty, don't
   // submit.
+  /*
   if(drawn)
   {
     Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
     submitInfo.cmdBuffer.push_back(commandBuffer.get());
     mGraphicsController->SubmitCommandBuffers(submitInfo);
   }
-
+  */
   mUpdated = false;
+  return drawn;
 }
 
 void Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program)
@@ -1237,15 +1239,6 @@ Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
 
   mUpdated = true;
 
-  // @todo Should instead set framebuffer once through Renderpass, rather than modifying
-  // pipeline repeatedly.
-  Graphics::FramebufferState framebufferState{};
-  if(instruction.mFrameBuffer)
-  {
-    instruction.mFrameBuffer->Bind(); // Ensure graphics object is created.
-    framebufferState.SetFramebuffer(*instruction.mFrameBuffer->GetGraphicsObject());
-  }
-
   // Create a new pipeline
   // @todo Passed as pointers - shallow copy will break. Implementation MUST deep copy.
   return mGraphicsController->CreatePipeline(
@@ -1254,7 +1247,6 @@ Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
       .SetVertexInputState(&vertexInputState)
       .SetRasterizationState(&rasterizationState)
       .SetColorBlendState(&colorBlendState)
-      .SetFramebufferState(&framebufferState)
       .SetProgramState(&programState)
       .SetNextExtension(&mLegacyProgram),
     std::move(oldPipeline));
index 0d31f7a..2d4e19e 100644 (file)
@@ -377,7 +377,7 @@ public:
    * @param[in] instruction. for use case like reflection where CullFace needs to be adjusted
 
    */
-  void Render(Context&                                             context,
+  bool Render(Context&                                             context,
               BufferIndex                                          bufferIndex,
               const SceneGraph::NodeDataProvider&                  node,
               const Matrix&                                        modelMatrix,
@@ -431,6 +431,11 @@ public:
                     const void*                                        data,
                     uint32_t                                           size);
 
+  [[nodiscard]] Graphics::CommandBuffer* GetGraphicsCommandBuffer() const
+  {
+    return mGraphicsCommandBuffer.get();
+  }
+
 private:
   struct UniformIndexMap;