}
void BeginRenderPass(
- Graphics::RenderPass& renderPass,
- Graphics::RenderTarget& renderTarget,
+ Graphics::RenderPass* renderPass,
+ Graphics::RenderTarget* renderTarget,
Graphics::Extent2D renderArea,
std::vector<Graphics::ClearValue> clearValues) override
{
mCallStack.PushCall("EndRenderPass", "");
}
+ void ExecuteCommandBuffers(std::vector<CommandBuffer*>&& commandBuffers) override
+ {
+ mCallStack.PushCall("ExecuteCommandBuffers", "");
+ }
+
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
if(createInfo.viewportState)
viewportState = *createInfo.viewportState;
- if(createInfo.framebufferState)
- framebufferState = *createInfo.framebufferState;
-
if(createInfo.depthStencilState)
depthStencilState = *createInfo.depthStencilState;
// INTERNAL INCLUDES
#include "graphics-types.h"
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics
{
class Buffer;
class Pipeline;
* 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;
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
CommandBuffer(CommandBuffer&&) = default;
CommandBuffer& operator=(CommandBuffer&&) = default;
};
-} // Namespace Graphics
} // Namespace Dali
#endif
}
/**
- * @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
ProgramState* programState{nullptr};
ColorBlendState* colorBlendState{nullptr};
ViewportState* viewportState{nullptr};
- FramebufferState* framebufferState{nullptr};
Pipeline* basePipeline{nullptr};
DepthStencilState* depthStencilState{nullptr};
RasterizationState* rasterizationState{nullptr};
*
*/
-// EXTERNAL INCLUDES
-#include <memory>
-
// INTERNAL INCLUDES
#include "graphics-render-pass.h"
#include "graphics-types.h"
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics
{
class RenderTarget;
/**
}
/**
- * @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;
}
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
}
/**
+ * @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.
*
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};
};
#include "graphics-types.h"
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics
{
+class Framebuffer;
/**
* @brief RenderTarget object binds to any presentable graphics output.
*/
RenderTarget& operator=(RenderTarget&&) = default;
};
-} // Namespace Graphics
} // Namespace Dali
#endif
\ No newline at end of file
};
/**
+ * @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
};
/**
+ * 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>>
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;
}
// 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)
{
// 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
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)
{
}
+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,
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.
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
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()
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,
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).
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();
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
if(instruction.mFrameBuffer)
{
+
//instruction.mFrameBuffer->Bind(*mImpl->currentContext);
// @todo Temporarily set per renderer per pipeline. Should use RenderPass instead
}
// @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.
{
mImpl->currentContext->Flush();
}
+
+ // End render pass
+ mainCommandBuffer->EndRenderPass();
+ mImpl->renderAlgorithms.SubmitCommandBuffer();
}
GLenum attachments[] = {GL_DEPTH, GL_STENCIL};
void RenderManager::PostRender(bool uploadOnly)
{
+ // Submit main command buffer
+ //mImpl->renderAlgorithms.SubmitCommandBuffer();
+
if(!uploadOnly)
{
if(mImpl->currentContext->IsSurfacelessContextSupported())
{
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 ) );
}
}
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
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
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;
mGeometry->Upload(*mGraphicsController);
}
-void Renderer::Render(Context& context,
+bool Renderer::Render(Context& context,
BufferIndex bufferIndex,
const SceneGraph::NodeDataProvider& node,
const Matrix& modelMatrix,
// Before doing anything test if the call happens in the right queue
if(mDrawCommands.empty() && queueIndex > 0)
{
- return;
+ return false;
}
// Prepare commands
// Have commands but nothing to be drawn - abort
if(!mDrawCommands.empty() && commands.empty())
{
- return;
+ return false;
}
// Create command buffer if not present
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
// @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)
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(
.SetVertexInputState(&vertexInputState)
.SetRasterizationState(&rasterizationState)
.SetColorBlendState(&colorBlendState)
- .SetFramebufferState(&framebufferState)
.SetProgramState(&programState)
.SetNextExtension(&mLegacyProgram),
std::move(oldPipeline));
* @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,
const void* data,
uint32_t size);
+ [[nodiscard]] Graphics::CommandBuffer* GetGraphicsCommandBuffer() const
+ {
+ return mGraphicsCommandBuffer.get();
+ }
+
private:
struct UniformIndexMap;