- auto& reflection = mGraphicsController->GetProgramReflection(program.GetGraphicsProgram());
-
- /**
- * Bind Attributes
- */
- uint32_t base = 0;
- for(auto&& vertexBuffer : mGeometry->GetVertexBuffers())
- {
- const VertexBuffer::Format& vertexFormat = *vertexBuffer->GetFormat();
-
- vertexInputState.bufferBindings.emplace_back(vertexFormat.size, // stride
- Graphics::VertexInputRate::PER_VERTEX);
-
- const uint32_t attributeCount = vertexBuffer->GetAttributeCount();
- for(uint32_t i = 0; i < attributeCount; ++i)
- {
- if(mUpdateAttributeLocations)
- {
- auto attributeName = vertexBuffer->GetAttributeName(i);
- int32_t pLocation = reflection.GetVertexAttributeLocation(std::string(attributeName.GetStringView()));
- if(-1 == pLocation)
- {
- DALI_LOG_WARNING("Attribute not found in the shader: %s\n", attributeName.GetCString());
- }
- mAttributeLocations.PushBack(pLocation);
- }
-
- auto location = static_cast<uint32_t>(mAttributeLocations[base + i]);
-
- vertexInputState.attributes.emplace_back(location,
- bindingIndex,
- vertexFormat.components[i].offset,
- GetPropertyVertexFormat(vertexFormat.components[i].type));
- }
- base += attributeCount;
- ++bindingIndex;
- }
- mUpdateAttributeLocations = false;
-
- // Get the topology
- inputAssemblyState.SetTopology(mGeometry->GetTopology());
-
- // Get the program
- programState.SetProgram(program.GetGraphicsProgram());
-
- Graphics::RasterizationState rasterizationState{};
-
- //Set cull face mode
- const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera();
- if(cam->GetReflectionUsed())
- {
- auto adjFaceCullingMode = mFaceCullingMode;
- switch(mFaceCullingMode)
- {
- case FaceCullingMode::Type::FRONT:
- {
- adjFaceCullingMode = FaceCullingMode::Type::BACK;
- break;
- }
- case FaceCullingMode::Type::BACK:
- {
- adjFaceCullingMode = FaceCullingMode::Type::FRONT;
- break;
- }
- default:
- {
- // nothing to do, leave culling as it is
- }
- }
- rasterizationState.SetCullMode(ConvertCullFace(adjFaceCullingMode));
- }
- else
- {
- rasterizationState.SetCullMode(ConvertCullFace(mFaceCullingMode));
- }
-
- rasterizationState.SetFrontFace(Graphics::FrontFace::COUNTER_CLOCKWISE);
-
- /**
- * Set Polygon mode
- */
- switch(mGeometry->GetTopology())
- {
- case Graphics::PrimitiveTopology::TRIANGLE_LIST:
- case Graphics::PrimitiveTopology::TRIANGLE_STRIP:
- case Graphics::PrimitiveTopology::TRIANGLE_FAN:
- rasterizationState.SetPolygonMode(Graphics::PolygonMode::FILL);
- break;
- case Graphics::PrimitiveTopology::LINE_LIST:
- case Graphics::PrimitiveTopology::LINE_LOOP:
- case Graphics::PrimitiveTopology::LINE_STRIP:
- rasterizationState.SetPolygonMode(Graphics::PolygonMode::LINE);
- break;
- case Graphics::PrimitiveTopology::POINT_LIST:
- rasterizationState.SetPolygonMode(Graphics::PolygonMode::POINT);
- break;
- }
-
- // @todo Add blend barrier to the Graphics API if we are using advanced
- // blending options. Command?
-
- Graphics::ColorBlendState colorBlendState{};
- colorBlendState.SetBlendEnable(false);
-
- if(blend)
- {
- colorBlendState.SetBlendEnable(true);
-
- Graphics::BlendOp rgbOp = ConvertBlendEquation(mBlendingOptions.GetBlendEquationRgb());
- Graphics::BlendOp alphaOp = ConvertBlendEquation(mBlendingOptions.GetBlendEquationRgb());
- if(mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipliedAlphaEnabled)
- {
- if(rgbOp != alphaOp)
- {
- DALI_LOG_ERROR("Advanced Blend Equation MUST be applied by using BlendEquation.\n");
- alphaOp = rgbOp;
- }
- }
-
- colorBlendState
- .SetSrcColorBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendSrcFactorRgb()))
- .SetSrcAlphaBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendSrcFactorAlpha()))
- .SetDstColorBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendDestFactorRgb()))
- .SetDstAlphaBlendFactor(ConvertBlendFactor(mBlendingOptions.GetBlendDestFactorAlpha()))
- .SetColorBlendOp(rgbOp)
- .SetAlphaBlendOp(alphaOp);
-
- // Blend color is optional and rarely used
- auto* blendColor = const_cast<Vector4*>(mBlendingOptions.GetBlendColor());
- if(blendColor)
- {
- colorBlendState.SetBlendConstants(blendColor->AsFloat());
- }
- }
-
- mUpdated = true;
-
- // Create the pipeline
- Graphics::PipelineCreateInfo createInfo;
- createInfo
- .SetInputAssemblyState(&inputAssemblyState)
- .SetVertexInputState(&vertexInputState)
- .SetRasterizationState(&rasterizationState)
- .SetColorBlendState(&colorBlendState)
- .SetProgramState(&programState);
-
- // Store a pipeline per renderer per render (renderer can be owned by multiple nodes,
- // and re-drawn in multiple instructions).
- // @todo This is only needed because ColorBlend state can change. Fixme!
- // This is ameliorated by the fact that implementation caches pipelines, and we're only storing
- // handles.
- auto hash = HashedPipeline::GetHash(&node, &instruction, blend);
- HashedPipeline* hashedPipeline = nullptr;
- for(auto& element : mGraphicsPipelines)
- {
- if(element.mHash == hash)
- {
- hashedPipeline = &element;
- break;
- }
- }