return mIndexBufferBinding;
}
- const auto& GetRenderTargetBinding() const
+ const RenderTargetBinding& GetRenderTargetBinding() const
{
return mRenderTargetBinding;
}
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 ),
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
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
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
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 );
// 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
return mImpl->AllocateRenderCommand();
}
-
} // namespace VulkanAPI
} // namespace Graphics
} // namespace Dali
std::unique_ptr<API::RenderCommand> AllocateRenderCommand() override;
- void BeginFrame() override;
+ virtual void BeginFrame() override;
void EndFrame() override;
if( !mVulkanPipeline )
{
auto pipeline = dynamic_cast<const VulkanAPI::Pipeline*>( mPipeline );
+ if(!pipeline)
+ {
+ return;
+ }
mVkDescriptorSetLayouts.clear();
mVkDescriptorSetLayouts = pipeline->GetVkDescriptorSetLayouts();
mVulkanPipeline = pipeline->GetVkPipeline();
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,
* 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
info.setEnabledLayerCount(0);
}
#else
- //info.setEnabledLayerCount(0);
+ info.setEnabledLayerCount(0);
#endif
mInstance = VkAssert(vk::createInstance(info, *mAllocator));
{
auto& swapBuffer = mSwapchainBuffer[mCurrentBufferIndex];
- // end render pass
- EndPrimaryRenderPass( swapBuffer );
-
// end command buffer
swapBuffer.masterCmdBuffer->End();
}
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:
// 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>
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 );
cmd.BindRenderTarget(renderTargetBinding);
auto opacity = sgRenderer->GetOpacity( bufferIndex );
+
if( sgRenderer->IsPreMultipliedAlphaEnabled() )
{
float alpha = color.a * opacity;
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 );
}
} // 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
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 );
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 )
isRenderingToFbo );
}
}
+
+ // Prepare pipelines
+
+
// generate graphics objects
- (*mImpl);
+
SubmitRenderInstructions( mImpl->graphics.GetController(), mImpl->renderInstructions, bufferIndex );
}
}
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 )
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 ),
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();
// 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()
);
}
-
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{}
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 ) )
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 )
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
*/
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
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
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);
* 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