#define DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
cmd.draw.instanceCount = instanceCount;
cmd.draw.firstInstance = firstInstance;
cmd.draw.firstVertex = firstVertex;
- mCallStack.PushCall("Draw", "");
+ TraceCallStack::NamedParams namedParams;
+ namedParams["vertexCount"] << vertexCount;
+ namedParams["instanceCount"] << instanceCount;
+ namedParams["firstInstance"] << firstInstance;
+ namedParams["firstVertex"] << firstVertex;
+ mCallStack.PushCall("Draw", namedParams.str(), namedParams);
}
void DrawIndexed(
cmd.drawIndexed.indexCount = indexCount;
cmd.drawIndexed.vertexOffset = vertexOffset;
cmd.drawIndexed.instanceCount = instanceCount;
- mCallStack.PushCall("DrawIndexed", "");
+ TraceCallStack::NamedParams namedParams;
+ namedParams["firstIndex"] << firstIndex;
+ namedParams["firstInstance"] << firstInstance;
+ namedParams["indexCount"] << indexCount;
+ namedParams["vertexOffset"] << vertexOffset;
+ namedParams["instanceCount"] << instanceCount;
+ mCallStack.PushCall("DrawIndexed", namedParams.str(), namedParams);
}
void DrawIndexedIndirect(
cmd.drawIndexedIndirect.offset = offset;
cmd.drawIndexedIndirect.drawCount = drawCount;
cmd.drawIndexedIndirect.stride = stride;
- mCallStack.PushCall("DrawIndexedIndirect", "");
+ TraceCallStack::NamedParams namedParams;
+ namedParams["offset"] << offset;
+ namedParams["drawCount"] << drawCount;
+ namedParams["stride"] << stride;
+ mCallStack.PushCall("DrawIndexedIndirect", namedParams.str(), namedParams);
}
void Reset() override
if(cmd.data.draw.draw.instanceCount == 0)
{
mGl.DrawArrays(GetTopology(currentPipeline->inputAssemblyState.topology),
- 0,
+ cmd.data.draw.draw.firstVertex,
cmd.data.draw.draw.vertexCount);
}
else
{
mGl.DrawArraysInstanced(GetTopology(currentPipeline->inputAssemblyState.topology),
- 0,
+ cmd.data.draw.draw.firstVertex,
cmd.data.draw.draw.vertexCount,
cmd.data.draw.draw.instanceCount);
}
VisualRenderer baseVisualRenderer = VisualRenderer::New(geometry, shader);
Renderer baseRenderer = Renderer::New(geometry, shader);
- DALI_TEST_EQUALS(baseRenderer.GetPropertyCount(), 27, TEST_LOCATION);
- DALI_TEST_EQUALS(baseVisualRenderer.GetPropertyCount(), 27 + 8, TEST_LOCATION);
- DALI_TEST_EQUALS(renderer.GetPropertyCount(), 27 + 8 + 6, TEST_LOCATION);
+ DALI_TEST_EQUALS(baseRenderer.GetPropertyCount(), 28, TEST_LOCATION);
+ DALI_TEST_EQUALS(baseVisualRenderer.GetPropertyCount(), 28 + 8, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetPropertyCount(), 28 + 8 + 6, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "cornerRadius", Property::VECTOR4, true, true, true, DecoratedVisualRenderer::Property::CORNER_RADIUS, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "cornerRadiusPolicy", Property::FLOAT, true, false, true, DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, TEST_LOCATION);
Geometry geometry = CreateQuadGeometry();
Shader shader = CreateShader();
Renderer renderer = Renderer::New(geometry, shader);
- DALI_TEST_EQUALS(renderer.GetPropertyCount(), 27, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetPropertyCount(), 28, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "depthIndex", Property::INTEGER, true, false, false, Renderer::Property::DEPTH_INDEX, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "faceCullingMode", Property::INTEGER, true, false, false, Renderer::Property::FACE_CULLING_MODE, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "opacity", Property::FLOAT, true, true, true, DevelRenderer::Property::OPACITY, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "renderingBehavior", Property::INTEGER, true, false, false, DevelRenderer::Property::RENDERING_BEHAVIOR, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "blendEquation", Property::INTEGER, true, false, false, DevelRenderer::Property::BLEND_EQUATION, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "instanceCount", Property::INTEGER, true, false, false, Dali::DevelRenderer::Property::INSTANCE_COUNT, TEST_LOCATION);
END_TEST;
}
END_TEST;
}
+
+int UtcDaliRendererSetInstanceCount(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test setting the instance count results in instanced draw");
+
+ Property::Map vertexFormat{{"aPosition", Property::VECTOR2}, {"aTexCoord", Property::VECTOR2}};
+ Property::Map instanceFormat{{"aTranslation", Property::VECTOR2}, {"aSize", Property::VECTOR2}};
+
+ const float halfQuadSize = .5f;
+ struct TexturedQuadVertex
+ {
+ Vector2 aPosition;
+ Vector2 aTexCoord;
+ };
+ TexturedQuadVertex texturedQuadVertexData[4] = {
+ {Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f)},
+ {Vector2(halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f)},
+ {Vector2(-halfQuadSize, halfQuadSize), Vector2(0.f, 1.f)},
+ {Vector2(halfQuadSize, halfQuadSize), Vector2(1.f, 1.f)}};
+
+ VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
+ vertexBuffer.SetData(texturedQuadVertexData, 4);
+
+ VertexBuffer instanceBuffer = VertexBuffer::New(instanceFormat);
+ instanceBuffer.SetDivisor(1);
+
+ struct Instance
+ {
+ Vector2 aTranslation;
+ Vector2 aSize;
+ };
+ std::vector<Instance> instanceData = {{Vector2{111.f, 222.f}, Vector2{32, 32}}, {Vector2{-112.f, 342.f}, Vector2{32, 32}}, {Vector2{124.f, 294.f}, Vector2{32, 32}}, {Vector2{459.f, -392.f}, Vector2{32, 32}}};
+
+ Dali::Geometry geometry = Dali::Geometry::New();
+ geometry.AddVertexBuffer(vertexBuffer);
+ geometry.AddVertexBuffer(instanceBuffer);
+ geometry.SetType(Geometry::TRIANGLE_STRIP);
+
+ Shader shader = CreateShader();
+
+ Actor actor = Actor::New();
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ Renderer renderer = Renderer::New(geometry, shader);
+ actor.AddRenderer(renderer);
+
+ auto& graphicsController = application.GetGraphicsController();
+ graphicsController.mCallStack.EnableLogging(true);
+ graphicsController.mCommandBufferCallStack.EnableLogging(true);
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ auto& drawTrace = glAbstraction.GetDrawTrace();
+ drawTrace.Enable(true);
+ drawTrace.EnableLogging(true);
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("Without instance buffer loaded, should not draw");
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArrays"));
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArraysInstanced"));
+
+ instanceBuffer.SetData(&instanceData[0], 4);
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("With no instance count set, should not draw instanced.");
+ DALI_TEST_CHECK(drawTrace.FindMethod("DrawArrays"));
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArraysInstanced"));
+
+ renderer[DevelRenderer::Property::INSTANCE_COUNT] = 4;
+
+ Property::Value v = renderer["instanceCount"];
+ DALI_TEST_EQUALS(v, Property::Value(4), TEST_LOCATION);
+
+ drawTrace.Reset();
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("With instance count set to 4, should draw 4 instances.");
+ TraceCallStack::NamedParams params;
+ params["instanceCount"] << 4;
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArrays"));
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArraysInstanced", params));
+
+ renderer[DevelRenderer::Property::INSTANCE_COUNT] = 1;
+ drawTrace.Reset();
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("With instance count set to 1, should draw 1 instance.");
+ TraceCallStack::NamedParams params2;
+ params["instanceCount"] << 1;
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArrays"));
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArraysInstanced", params2));
+
+ renderer[DevelRenderer::Property::INSTANCE_COUNT] = 0;
+ drawTrace.Reset();
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("With instance count set to 0, should revert to DrawArrays.");
+ DALI_TEST_CHECK(drawTrace.FindMethod("DrawArrays"));
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArraysInstanced"));
+
+ END_TEST;
+}
+
+int UtcDaliRendererVertexRange(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test setting the instance count results in instanced draw");
+
+ Property::Map vertexFormat{{"aPosition", Property::VECTOR2}, {"aTexCoord", Property::VECTOR2}};
+ Property::Map instanceFormat{{"aTranslation", Property::VECTOR2}, {"aSize", Property::VECTOR2}};
+
+ const float halfQuadSize = .5f;
+ struct TexturedQuadVertex
+ {
+ Vector2 aPosition;
+ Vector2 aTexCoord;
+ };
+ TexturedQuadVertex texturedQuadVertexData[4] = {
+ {Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f)},
+ {Vector2(halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f)},
+ {Vector2(-halfQuadSize, halfQuadSize), Vector2(0.f, 1.f)},
+ {Vector2(halfQuadSize, halfQuadSize), Vector2(1.f, 1.f)}};
+
+ const int VERTEX_SET_COUNT(10);
+ std::vector<TexturedQuadVertex> vertexData;
+ vertexData.resize(VERTEX_SET_COUNT * 4);
+ for(int i = 0; i < VERTEX_SET_COUNT; ++i)
+ {
+ for(int j = 0; j < 4; ++j)
+ {
+ vertexData.push_back({texturedQuadVertexData[j].aPosition * (20.0f * i), texturedQuadVertexData[j].aTexCoord});
+ }
+ }
+
+ VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
+ vertexBuffer.SetData(&vertexData[0], VERTEX_SET_COUNT * 4);
+
+ Dali::Geometry geometry = Dali::Geometry::New();
+ geometry.AddVertexBuffer(vertexBuffer);
+ geometry.SetType(Geometry::TRIANGLE_STRIP);
+
+ Shader shader = CreateShader();
+
+ Actor actor = Actor::New();
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ for(int i = 0; i < VERTEX_SET_COUNT; ++i)
+ {
+ Renderer renderer = Renderer::New(geometry, shader);
+ renderer[DevelRenderer::Property::VERTEX_RANGE_FIRST] = i * 4;
+ renderer[DevelRenderer::Property::VERTEX_RANGE_COUNT] = 4;
+ actor.AddRenderer(renderer);
+ }
+
+ for(uint32_t i = 0; i < actor.GetRendererCount(); ++i)
+ {
+ auto renderer = actor.GetRendererAt(i);
+ DALI_TEST_EQUALS(renderer.GetProperty<int>(DevelRenderer::Property::VERTEX_RANGE_FIRST), i * 4, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetProperty<int>(DevelRenderer::Property::VERTEX_RANGE_COUNT), 4, TEST_LOCATION);
+ }
+
+ auto& graphicsController = application.GetGraphicsController();
+ graphicsController.mCallStack.EnableLogging(true);
+ graphicsController.mCommandBufferCallStack.EnableLogging(true);
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ auto& drawTrace = glAbstraction.GetDrawTrace();
+ drawTrace.Enable(true);
+ drawTrace.EnableLogging(true);
+
+ application.SendNotification();
+ application.Render();
+
+ TraceCallStack::NamedParams namedParams;
+ namedParams["first"] << 0;
+ namedParams["count"] << 4;
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArrays", namedParams));
+
+ namedParams["first"].str("");
+ namedParams["first"].clear();
+ namedParams["first"] << 4;
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArrays", namedParams));
+
+ namedParams["first"].str("");
+ namedParams["first"].clear();
+ namedParams["first"] << 8;
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArrays", namedParams));
+
+ namedParams["first"].str("");
+ namedParams["first"].clear();
+ namedParams["first"] << 12;
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArrays", namedParams));
+
+ namedParams["first"].str("");
+ namedParams["first"].clear();
+ namedParams["first"] << 16;
+ DALI_TEST_CHECK(drawTrace.FindMethodAndParams("DrawArrays", namedParams));
+
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawArrays"), 10, TEST_LOCATION);
+ END_TEST;
+}
params["divisor"] << "1";
DALI_TEST_CHECK(bufferTrace.FindMethodAndParams("VertexAttribDivisor", params));
+ tet_infoline("Test that by default, instancing isn't used");
TraceCallStack::NamedParams params2;
- DALI_TEST_CHECK(drawTrace.FindMethodAndGetParameters("DrawArraysInstanced", params2));
- std::ostringstream oss;
- oss << sizeof(instanceData) / sizeof(InstanceData);
- DALI_TEST_EQUALS(params2["instanceCount"].str(), oss.str(), TEST_LOCATION);
+ params2["instanceCount"] << 0;
+ DALI_TEST_CHECK(!drawTrace.FindMethodAndGetParameters("DrawArraysInstanced", params2));
+ DALI_TEST_CHECK(drawTrace.FindMethod("DrawArrays"));
+
+ tet_infoline("Test that instancing is used if Renderer requests an instance count");
+ drawTrace.Reset();
+
+ int instanceCount = sizeof(instanceData) / sizeof(InstanceData);
+ renderer["instanceCount"] = instanceCount;
+ application.SendNotification();
+ application.Render();
+
+ TraceCallStack::NamedParams params3;
+ params3["instanceCount"] << instanceCount;
+ DALI_TEST_CHECK(drawTrace.FindMethodAndGetParameters("DrawArraysInstanced", params3));
+ DALI_TEST_CHECK(!drawTrace.FindMethod("DrawArrays"));
END_TEST;
}
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
VisualRenderer renderer = VisualRenderer::New(geometry, shader);
Renderer baseRenderer = Renderer::New(geometry, shader);
- DALI_TEST_EQUALS(baseRenderer.GetPropertyCount(), 27, TEST_LOCATION);
- DALI_TEST_EQUALS(renderer.GetPropertyCount(), 27 + 8, TEST_LOCATION);
+ DALI_TEST_EQUALS(baseRenderer.GetPropertyCount(), 28, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetPropertyCount(), 28 + 8, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "transformOffset", Property::VECTOR2, true, true, true, VisualRenderer::Property::TRANSFORM_OFFSET, TEST_LOCATION);
TEST_RENDERER_PROPERTY(renderer, "transformSize", Property::VECTOR2, true, true, true, VisualRenderer::Property::TRANSFORM_SIZE, TEST_LOCATION);
#define DALI_RENDERER_DEVEL_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
STENCIL_OPERATION_ON_Z_PASS = Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS,
/**
- * @brief The opacity of the renderer.
- * @details Name "opacity", type Property::FLOAT.
- */
+ * @brief The opacity of the renderer.
+ * @details Name "opacity", type Property::FLOAT.
+ */
OPACITY = STENCIL_OPERATION_ON_Z_PASS + 1,
/**
- * @brief The rendering behavior of the renderer.
- * @details Name "renderingBehavior", type Property::INTEGER.
- */
+ * @brief The rendering behavior of the renderer.
+ * @details Name "renderingBehavior", type Property::INTEGER.
+ */
RENDERING_BEHAVIOR = STENCIL_OPERATION_ON_Z_PASS + 2,
/**
* @note The default value is BlendEquation::ADD
*/
BLEND_EQUATION = STENCIL_OPERATION_ON_Z_PASS + 3,
+
+ /**
+ * @brief Which vertex to render first from a vertex buffer without indices
+ * @details name "vertexRangeFirst", type INTEGER
+ */
+ VERTEX_RANGE_FIRST = INDEX_RANGE_FIRST,
+
+ /**
+ * @brief How many vertices to render to render from a vertex buffer without indices
+ * @details name "vertexRangeCount", type INTEGER
+ */
+ VERTEX_RANGE_COUNT = INDEX_RANGE_COUNT,
+
+ /**
+ * @brief How many instances to render from a vertex buffer with non-zero divisor.
+ * @note Overrides computed instance count on vertex buffer.
+ * @details name "instanceCount", type INTEGER
+ */
+ INSTANCE_COUNT = STENCIL_OPERATION_ON_Z_PASS + 4,
};
} // namespace Property
DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::DevelRenderer::Property::OPACITY)
DALI_PROPERTY("renderingBehavior", INTEGER, true, false, false, Dali::DevelRenderer::Property::RENDERING_BEHAVIOR)
DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelRenderer::Property::BLEND_EQUATION)
+DALI_PROPERTY("instanceCount", INTEGER, true, false, false, Dali::DevelRenderer::Property::INSTANCE_COUNT)
DALI_PROPERTY_TABLE_END(DEFAULT_RENDERER_PROPERTY_START_INDEX, RendererDefaultProperties)
// Property string to enumeration tables:
}
break;
}
+ case DevelRenderer::Property::INSTANCE_COUNT:
+ {
+ int instanceCount;
+ if(propertyValue.Get(instanceCount))
+ {
+ if(instanceCount != int(mInstanceCount))
+ {
+ mInstanceCount = uint32_t(instanceCount);
+ SetInstanceCountMessage(GetEventThreadServices(), GetRendererSceneObject(), mInstanceCount);
+ }
+ }
+ break;
+ }
}
}
value = mRenderingBehavior;
break;
}
+ case DevelRenderer::Property::INSTANCE_COUNT:
+ {
+ value = int(mInstanceCount);
+ break;
+ }
default:
{
// Must be a scene-graph only property
#define DALI_INTERNAL_RENDERER_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
uint32_t mIndexedDrawFirstElement; ///< Offset of first element to draw from bound index buffer
uint32_t mIndexedDrawElementCount; ///< Number of elements to draw
+ uint32_t mInstanceCount{0}; ///< Number of instances to draw
Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options
BlendingOptions mBlendingOptions; ///< Local copy of blending options bitmask
* @return The recalculated size after visual properties applied.
*/
virtual Vector4 GetVisualTransformedUpdateArea(BufferIndex bufferIndex, const Vector4& originalUpdateArea) noexcept = 0;
+
+ virtual uint32_t GetInstanceCount() const = 0;
};
} // namespace SceneGraph
void Geometry::RemoveVertexBuffer(const Render::VertexBuffer* vertexBuffer)
{
const auto&& end = mVertexBuffers.End();
- // @todo if this buffer is the only instance buffer, reduce instance count to 1.
+
for(auto&& iter = mVertexBuffers.Begin(); iter != end; ++iter)
{
if(*iter == vertexBuffer)
for(uint32_t i = 0; i < vertexBufferCount; ++i)
{
- if(mVertexBuffers[i]->GetDivisor() > 0)
- {
- mInstanceCount = mVertexBuffers[i]->GetElementCount();
- }
-
const GpuBuffer* gpuBuffer = mVertexBuffers[i]->GetGpuBuffer();
if(gpuBuffer)
{
Graphics::Controller& graphicsController,
Graphics::CommandBuffer& commandBuffer,
uint32_t elementBufferOffset,
- uint32_t elementBufferCount)
+ uint32_t elementBufferCount,
+ uint32_t instanceCount)
{
uint32_t numIndices(0u);
intptr_t firstIndexOffset(0u);
commandBuffer.BindIndexBuffer(*ibo, 0, mIndexType);
}
- commandBuffer.DrawIndexed(numIndices, mInstanceCount, firstIndexOffset, 0, 0);
+ commandBuffer.DrawIndexed(numIndices, instanceCount, firstIndexOffset, 0, 0);
}
else
{
// Un-indexed draw call
uint32_t numVertices(0u);
+ uint32_t firstVertex(0u);
// Use element buffer count for drawing arrays (needs changing API, for workaround)
if(elementBufferCount)
{
numVertices = elementBufferCount;
+ firstVertex = elementBufferOffset;
}
else if(mVertexBuffers.Count() > 0)
{
}
numVertices = elementsCount;
}
+
// Issue draw call only if there's non-zero numVertices
if(numVertices)
{
- commandBuffer.Draw(numVertices, mInstanceCount, 0, 0);
+ commandBuffer.Draw(numVertices, instanceCount, firstVertex, 0);
}
}
return true;
*
* @param[in] graphicsController The graphics controller
* @param[in,out] commandBuffer The current command buffer queue
- * @param[in] elementBufferOffset The index of first element to draw if index buffer bound
- * @param[in] elementBufferCount Number of elements to draw if index buffer bound, uses whole buffer when 0
+ * @param[in] elementBufferOffset The index of first vertex / element to draw if index buffer bound
+ * @param[in] elementBufferCount Number of vertices / elements to draw if index buffer bound, uses whole buffer when 0
+ * @param[in] instanceCount Number of instances to draw (use in conjunction with VertexBuffer divisor)
* @return true if the draw command was issued, false otherwise
*/
bool Draw(Graphics::Controller& graphicsController,
Graphics::CommandBuffer& commandBuffer,
uint32_t elementBufferOffset,
- uint32_t elementBufferCount);
+ uint32_t elementBufferCount,
+ uint32_t instanceCount);
/**
* @brief Set up the attributes bind commaneds
OwnerPointer<GpuBuffer> mIndexBuffer;
IndexType mIndexType;
Type mGeometryType;
- uint32_t mInstanceCount{0};
// Booleans
bool mIndicesChanged : 1;
// Reuse latest bound vertex attributes location, or Bind buffers to attribute locations.
if(ReuseLatestBoundVertexAttributes(mGeometry) || mGeometry->BindVertexAttributes(commandBuffer))
{
+ uint32_t instanceCount = mRenderDataProvider->GetInstanceCount();
+
if(mDrawCommands.empty())
{
- drawn = mGeometry->Draw(*mGraphicsController, commandBuffer, mIndexedDrawFirstElement, mIndexedDrawElementsCount);
+ drawn = mGeometry->Draw(*mGraphicsController, commandBuffer, mIndexedDrawFirstElement, mIndexedDrawElementsCount, instanceCount);
}
else
{
for(auto& cmd : commands)
{
- drawn |= mGeometry->Draw(*mGraphicsController, commandBuffer, cmd->firstIndex, cmd->elementCount);
+ drawn |= mGeometry->Draw(*mGraphicsController, commandBuffer, cmd->firstIndex, cmd->elementCount, instanceCount);
}
}
}
new(slot) LocalType(&renderer, &Renderer::SetRenderCallback, callback);
}
+inline void SetInstanceCountMessage(EventThreadServices& eventThreadServices, const Renderer& renderer, uint32_t instanceCount)
+{
+ using LocalType = MessageValue1<SceneGraph::Renderer, uint32_t>;
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+ new(slot) LocalType(&renderer, &SceneGraph::Renderer::SetInstanceCount, instanceCount);
+}
+
} // namespace Dali::Internal::SceneGraph
#endif //DALI_INTERNAL_SCENE_GRAPH_RENDERER_MESSAGES_H
mSceneController = nullptr;
}
-Render::RendererKey Renderer::GetRenderer()
+Render::RendererKey Renderer::GetRenderer() const
{
return mRenderer;
}
* Retrieve the Render thread renderer
* @return The associated render thread renderer
*/
- Render::RendererKey GetRenderer();
+ Render::RendererKey GetRenderer() const;
/**
* Query whether the renderer is fully opaque, fully transparent or transparent.
*/
Vector4 GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex, const Vector4& originalUpdateArea) noexcept override;
+ uint32_t GetInstanceCount() const override
+ {
+ return mInstanceCount;
+ }
+
+ void SetInstanceCount(uint32_t instanceCount)
+ {
+ mInstanceCount = instanceCount;
+ }
+
/**
* Sets RenderCallback object
*
uint32_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw
uint32_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw
+ uint32_t mInstanceCount{0}; ///< The number of instances to be drawn
uint32_t mBlendBitmask; ///< The bitmask of blending options
uint32_t mResendFlag; ///< Indicate whether data should be resent to the renderer
UniformMap::SizeType mUniformMapChangeCounter{0u}; ///< Value to check if uniform data should be updated